mirror of
https://gitlab.com/phoenix-dvpmt/mmoitems.git
synced 2024-12-23 04:47:34 +01:00
moved flags to mythicLib, entityHandler rework
This commit is contained in:
parent
c07fc26eca
commit
f5ea91fd44
@ -21,14 +21,10 @@ import net.Indyuce.mmoitems.command.MMOItemsCommandTreeRoot;
|
||||
import net.Indyuce.mmoitems.comp.*;
|
||||
import net.Indyuce.mmoitems.comp.denizen.DenizenHook;
|
||||
import net.Indyuce.mmoitems.comp.eco.VaultSupport;
|
||||
import net.Indyuce.mmoitems.comp.enchants.advanced_enchants.AdvancedEnchantmentsHook;
|
||||
import net.Indyuce.mmoitems.comp.enchants.CrazyEnchantsStat;
|
||||
import net.Indyuce.mmoitems.comp.enchants.EnchantPlugin;
|
||||
import net.Indyuce.mmoitems.comp.enchants.MythicEnchantsSupport;
|
||||
import net.Indyuce.mmoitems.comp.flags.DefaultFlags;
|
||||
import net.Indyuce.mmoitems.comp.flags.FlagPlugin;
|
||||
import net.Indyuce.mmoitems.comp.flags.ResidenceFlags;
|
||||
import net.Indyuce.mmoitems.comp.flags.WorldGuardFlags;
|
||||
import net.Indyuce.mmoitems.comp.enchants.advanced_enchants.AdvancedEnchantmentsHook;
|
||||
import net.Indyuce.mmoitems.comp.inventory.*;
|
||||
import net.Indyuce.mmoitems.comp.itemglow.ItemGlowListener;
|
||||
import net.Indyuce.mmoitems.comp.itemglow.NoGlowListener;
|
||||
@ -96,7 +92,6 @@ public class MMOItems extends LuminePlugin {
|
||||
private EquipListener equipListener;
|
||||
|
||||
private PlaceholderParser placeholderParser = new DefaultPlaceholderParser();
|
||||
private FlagPlugin flagPlugin = new DefaultFlags();
|
||||
private VaultSupport vaultSupport;
|
||||
private RPGHandler rpgPlugin;
|
||||
|
||||
@ -104,14 +99,6 @@ public class MMOItems extends LuminePlugin {
|
||||
public void load() {
|
||||
plugin = this;
|
||||
|
||||
if (getServer().getPluginManager().getPlugin("WorldGuard") != null)
|
||||
try {
|
||||
flagPlugin = new WorldGuardFlags();
|
||||
getLogger().log(Level.INFO, "Hooked onto WorldGuard");
|
||||
} catch (Exception exception) {
|
||||
getLogger().log(Level.WARNING, "Could not initialize support with WorldGuard 7: " + exception.getMessage());
|
||||
}
|
||||
|
||||
if (getServer().getPluginManager().getPlugin("WorldEdit") != null)
|
||||
try {
|
||||
new WorldEditSupport();
|
||||
@ -237,10 +224,6 @@ public class MMOItems extends LuminePlugin {
|
||||
PlayerData.get(player).getInventory().updateCheck();
|
||||
}, 100, getConfig().getInt("inventory-update-delay"));
|
||||
|
||||
if (Bukkit.getPluginManager().getPlugin("Residence") != null) {
|
||||
flagPlugin = new ResidenceFlags();
|
||||
getLogger().log(Level.INFO, "Hooked onto Residence");
|
||||
}
|
||||
|
||||
if (Bukkit.getPluginManager().getPlugin("mcMMO") != null)
|
||||
Bukkit.getPluginManager().registerEvents(new McMMONonRPGHook(), this);
|
||||
@ -371,14 +354,6 @@ public class MMOItems extends LuminePlugin {
|
||||
return setManager;
|
||||
}
|
||||
|
||||
public FlagPlugin getFlags() {
|
||||
return flagPlugin;
|
||||
}
|
||||
|
||||
public void setFlags(FlagPlugin value) {
|
||||
flagPlugin = value;
|
||||
}
|
||||
|
||||
public RPGHandler getRPG() {
|
||||
return rpgPlugin;
|
||||
}
|
||||
|
@ -6,14 +6,16 @@ import io.lumine.mythic.lib.MythicLib;
|
||||
import io.lumine.mythic.lib.api.item.ItemTag;
|
||||
import io.lumine.mythic.lib.api.item.NBTItem;
|
||||
import io.lumine.mythic.lib.api.item.SupportedNBTTagValues;
|
||||
import io.lumine.mythic.lib.comp.target.InteractionType;
|
||||
import net.Indyuce.mmoitems.api.Type;
|
||||
import net.Indyuce.mmoitems.api.player.PlayerData;
|
||||
import org.apache.commons.codec.binary.Base64;
|
||||
import org.bukkit.ChatColor;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.attribute.Attribute;
|
||||
import org.bukkit.entity.*;
|
||||
import org.bukkit.entity.Entity;
|
||||
import org.bukkit.entity.LivingEntity;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.entity.Projectile;
|
||||
import org.bukkit.event.entity.EntityDamageByEntityEvent;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.inventory.meta.ItemMeta;
|
||||
@ -28,366 +30,398 @@ import java.util.*;
|
||||
@SuppressWarnings("unused")
|
||||
public class MMOUtils {
|
||||
|
||||
/**
|
||||
* @return The skull texture URL from a given player head
|
||||
*/
|
||||
public static String getSkullTextureURL(ItemStack item) {
|
||||
try {
|
||||
ItemMeta meta = item.getItemMeta();
|
||||
Field profileField = meta.getClass().getDeclaredField("profile");
|
||||
profileField.setAccessible(true);
|
||||
Collection<Property> properties = ((GameProfile) profileField.get(item.getItemMeta())).getProperties().get("textures");
|
||||
Property property = properties.toArray(new Property[0])[0];
|
||||
return new String(Base64.decodeBase64(property.getValue())).replace("{textures:{SKIN:{url:\"", "").replace("\"}}}", "");
|
||||
} catch (Exception e) {
|
||||
return "";
|
||||
}
|
||||
}
|
||||
/**
|
||||
* @return The skull texture URL from a given player head
|
||||
*/
|
||||
public static String getSkullTextureURL(ItemStack item) {
|
||||
try {
|
||||
ItemMeta meta = item.getItemMeta();
|
||||
Field profileField = meta.getClass().getDeclaredField("profile");
|
||||
profileField.setAccessible(true);
|
||||
Collection<Property> properties = ((GameProfile) profileField.get(item.getItemMeta())).getProperties().get("textures");
|
||||
Property property = properties.toArray(new Property[0])[0];
|
||||
return new String(Base64.decodeBase64(property.getValue())).replace("{textures:{SKIN:{url:\"", "").replace("\"}}}", "");
|
||||
} catch (Exception e) {
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param item The item stack you are testing.
|
||||
* @param type MMOItem Type you are expecting {@link Type#getId()}
|
||||
* @param id MMOItem ID you are expecting
|
||||
* @return If the given item is the desired MMOItem
|
||||
*/
|
||||
public static boolean isMMOItem(@Nullable ItemStack item, @NotNull String type, @NotNull String id) {
|
||||
if (item == null)
|
||||
return false;
|
||||
/**
|
||||
* @param item The item stack you are testing.
|
||||
* @param type MMOItem Type you are expecting {@link Type#getId()}
|
||||
* @param id MMOItem ID you are expecting
|
||||
* @return If the given item is the desired MMOItem
|
||||
*/
|
||||
public static boolean isMMOItem(@Nullable ItemStack item, @NotNull String type, @NotNull String id) {
|
||||
if (item == null)
|
||||
return false;
|
||||
|
||||
// Make it into an NBT Item
|
||||
NBTItem asNBT = NBTItem.get(item);
|
||||
// Make it into an NBT Item
|
||||
NBTItem asNBT = NBTItem.get(item);
|
||||
|
||||
// ID Matches?
|
||||
String itemID = getID(asNBT);
|
||||
// ID Matches?
|
||||
String itemID = getID(asNBT);
|
||||
|
||||
// Not a MMOItem
|
||||
if (itemID == null)
|
||||
return false;
|
||||
// Not a MMOItem
|
||||
if (itemID == null)
|
||||
return false;
|
||||
|
||||
// ID matches?
|
||||
if (!itemID.equals(id))
|
||||
return false;
|
||||
// ID matches?
|
||||
if (!itemID.equals(id))
|
||||
return false;
|
||||
|
||||
// If the type matches too, we are set.
|
||||
return asNBT.getType().equals(type);
|
||||
}
|
||||
// If the type matches too, we are set.
|
||||
return asNBT.getType().equals(type);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param nbtItem The NBTItem you are testing
|
||||
* @return The MMOItem Type of this item, if it is a MMOItem
|
||||
*/
|
||||
@Nullable
|
||||
public static Type getType(@Nullable NBTItem nbtItem) {
|
||||
if (nbtItem == null || !nbtItem.hasType())
|
||||
return null;
|
||||
/**
|
||||
* @param nbtItem The NBTItem you are testing
|
||||
* @return The MMOItem Type of this item, if it is a MMOItem
|
||||
*/
|
||||
@Nullable
|
||||
public static Type getType(@Nullable NBTItem nbtItem) {
|
||||
if (nbtItem == null || !nbtItem.hasType())
|
||||
return null;
|
||||
|
||||
// Try that one instead
|
||||
return MMOItems.plugin.getTypes().get(nbtItem.getType());
|
||||
}
|
||||
// Try that one instead
|
||||
return MMOItems.plugin.getTypes().get(nbtItem.getType());
|
||||
}
|
||||
|
||||
/**
|
||||
* @param nbtItem The NBTItem you are testing
|
||||
* @return The MMOItem ID of this item, if it is a MMOItem
|
||||
*/
|
||||
@Nullable
|
||||
public static String getID(@Nullable NBTItem nbtItem) {
|
||||
if (nbtItem == null || !nbtItem.hasType())
|
||||
return null;
|
||||
/**
|
||||
* @param nbtItem The NBTItem you are testing
|
||||
* @return The MMOItem ID of this item, if it is a MMOItem
|
||||
*/
|
||||
@Nullable
|
||||
public static String getID(@Nullable NBTItem nbtItem) {
|
||||
if (nbtItem == null || !nbtItem.hasType())
|
||||
return null;
|
||||
|
||||
ItemTag type = ItemTag.getTagAtPath("MMOITEMS_ITEM_ID", nbtItem, SupportedNBTTagValues.STRING);
|
||||
if (type == null)
|
||||
return null;
|
||||
ItemTag type = ItemTag.getTagAtPath("MMOITEMS_ITEM_ID", nbtItem, SupportedNBTTagValues.STRING);
|
||||
if (type == null)
|
||||
return null;
|
||||
|
||||
return (String) type.getValue();
|
||||
}
|
||||
return (String) type.getValue();
|
||||
}
|
||||
|
||||
/**
|
||||
* * Returns either the normalized vector, or null vector if input is null
|
||||
* vector which cannot be normalized.
|
||||
*
|
||||
* @param vector Vector which can be of length 0
|
||||
* @return Normalized vector or 0 depending on input
|
||||
*/
|
||||
public static Vector normalize(Vector vector) {
|
||||
return vector.getX() == 0 && vector.getY() == 0 ? vector : vector.normalize();
|
||||
}
|
||||
/**
|
||||
* * Returns either the normalized vector, or null vector if input is null
|
||||
* vector which cannot be normalized.
|
||||
*
|
||||
* @param vector Vector which can be of length 0
|
||||
* @return Normalized vector or 0 depending on input
|
||||
*/
|
||||
public static Vector normalize(Vector vector) {
|
||||
return vector.getX() == 0 && vector.getY() == 0 ? vector : vector.normalize();
|
||||
}
|
||||
|
||||
/**
|
||||
* Double.parseDouble(String) cannot be used when asking for player input in
|
||||
* stat edition because the exception message is confusing. This method has
|
||||
* a better exception message
|
||||
*
|
||||
* @param format Format to parse into a number
|
||||
* @return Parsed double
|
||||
*/
|
||||
public static double parseDouble(String format) {
|
||||
try {
|
||||
return Double.parseDouble(format);
|
||||
} catch (IllegalArgumentException exception) {
|
||||
throw new IllegalArgumentException("Could not read number from '" + format + "'");
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Double.parseDouble(String) cannot be used when asking for player input in
|
||||
* stat edition because the exception message is confusing. This method has
|
||||
* a better exception message
|
||||
*
|
||||
* @param format Format to parse into a number
|
||||
* @return Parsed double
|
||||
*/
|
||||
public static double parseDouble(String format) {
|
||||
try {
|
||||
return Double.parseDouble(format);
|
||||
} catch (IllegalArgumentException exception) {
|
||||
throw new IllegalArgumentException("Could not read number from '" + format + "'");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an UUID from thay string, or null if it is not in UUID format.
|
||||
*/
|
||||
@Nullable
|
||||
public static UUID UUIDFromString(@org.jetbrains.annotations.Nullable String anything) {
|
||||
if (anything == null)
|
||||
return null;
|
||||
/**
|
||||
* Returns an UUID from thay string, or null if it is not in UUID format.
|
||||
*/
|
||||
@Nullable
|
||||
public static UUID UUIDFromString(@org.jetbrains.annotations.Nullable String anything) {
|
||||
if (anything == null)
|
||||
return null;
|
||||
|
||||
// Correct Format?
|
||||
if (anything.matches("[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}"))
|
||||
// Correct Format?
|
||||
if (anything.matches("[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}"))
|
||||
|
||||
// Return thay
|
||||
return UUID.fromString(anything);
|
||||
// Return thay
|
||||
return UUID.fromString(anything);
|
||||
|
||||
// No
|
||||
return null;
|
||||
}
|
||||
// No
|
||||
return null;
|
||||
}
|
||||
|
||||
public static LivingEntity getDamager(EntityDamageByEntityEvent event) {
|
||||
public static LivingEntity getDamager(EntityDamageByEntityEvent event) {
|
||||
|
||||
// Check direct damager
|
||||
if (event.getDamager() instanceof LivingEntity) return (LivingEntity) event.getDamager();
|
||||
// Check direct damager
|
||||
if (event.getDamager() instanceof LivingEntity) return (LivingEntity) event.getDamager();
|
||||
|
||||
/*
|
||||
* Checks projectile and add damage type, which supports every vanilla
|
||||
* projectile like snowballs, tridents and arrows
|
||||
*/
|
||||
if (event.getDamager() instanceof Projectile) {
|
||||
Projectile proj = (Projectile) event.getDamager();
|
||||
if (proj.getShooter() instanceof LivingEntity)
|
||||
return (LivingEntity) proj.getShooter();
|
||||
}
|
||||
/*
|
||||
* Checks projectile and add damage type, which supports every vanilla
|
||||
* projectile like snowballs, tridents and arrows
|
||||
*/
|
||||
if (event.getDamager() instanceof Projectile) {
|
||||
Projectile proj = (Projectile) event.getDamager();
|
||||
if (proj.getShooter() instanceof LivingEntity)
|
||||
return (LivingEntity) proj.getShooter();
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* The last 5 seconds of nausea are useless, night vision flashes in the
|
||||
* last 10 seconds, blindness takes a few seconds to decay as well, and
|
||||
* there can be small server lags. It's best to apply a specific duration
|
||||
* for every type of permanent effect.
|
||||
*
|
||||
* @param type Potion effect type
|
||||
* @return The duration that MMOItems should be using to give player
|
||||
* "permanent" potion effects, depending on the potion effect type
|
||||
*/
|
||||
public static int getEffectDuration(PotionEffectType type) {
|
||||
return type.equals(PotionEffectType.NIGHT_VISION) || type.equals(PotionEffectType.CONFUSION) ? 260 : type.equals(PotionEffectType.BLINDNESS) ? 140 : 80;
|
||||
}
|
||||
/**
|
||||
* The last 5 seconds of nausea are useless, night vision flashes in the
|
||||
* last 10 seconds, blindness takes a few seconds to decay as well, and
|
||||
* there can be small server lags. It's best to apply a specific duration
|
||||
* for every type of permanent effect.
|
||||
*
|
||||
* @param type Potion effect type
|
||||
* @return The duration that MMOItems should be using to give player
|
||||
* "permanent" potion effects, depending on the potion effect type
|
||||
*/
|
||||
public static int getEffectDuration(PotionEffectType type) {
|
||||
return type.equals(PotionEffectType.NIGHT_VISION) || type.equals(PotionEffectType.CONFUSION) ? 260 : type.equals(PotionEffectType.BLINDNESS) ? 140 : 80;
|
||||
}
|
||||
|
||||
@NotNull public static String getDisplayName(@Nullable ItemStack item) {
|
||||
if (item == null) { return "null"; }
|
||||
return (item.hasItemMeta() && item.getItemMeta().hasDisplayName()) ?
|
||||
item.getItemMeta().getDisplayName() :
|
||||
caseOnWords(item.getType().name().toLowerCase().replace("_", " "));
|
||||
}
|
||||
@NotNull
|
||||
public static String getDisplayName(@Nullable ItemStack item) {
|
||||
if (item == null) {
|
||||
return "null";
|
||||
}
|
||||
return (item.hasItemMeta() && item.getItemMeta().hasDisplayName()) ?
|
||||
item.getItemMeta().getDisplayName() :
|
||||
caseOnWords(item.getType().name().toLowerCase().replace("_", " "));
|
||||
}
|
||||
|
||||
/**
|
||||
* Super useful to display enum names like DIAMOND_SWORD in chat
|
||||
*
|
||||
* @param s String with lower cases and spaces only
|
||||
* @return Same string with capital letters at the beginning of each word.
|
||||
*/
|
||||
public static String caseOnWords(String s) {
|
||||
StringBuilder builder = new StringBuilder(s);
|
||||
boolean isLastSpace = true;
|
||||
for (int i = 0; i < builder.length(); i++) {
|
||||
char ch = builder.charAt(i);
|
||||
if (isLastSpace && ch >= 'a' && ch <= 'z') {
|
||||
builder.setCharAt(i, (char) (ch + ('A' - 'a')));
|
||||
isLastSpace = false;
|
||||
} else isLastSpace = ch == ' ';
|
||||
}
|
||||
return builder.toString();
|
||||
}
|
||||
/**
|
||||
* Super useful to display enum names like DIAMOND_SWORD in chat
|
||||
*
|
||||
* @param s String with lower cases and spaces only
|
||||
* @return Same string with capital letters at the beginning of each word.
|
||||
*/
|
||||
public static String caseOnWords(String s) {
|
||||
StringBuilder builder = new StringBuilder(s);
|
||||
boolean isLastSpace = true;
|
||||
for (int i = 0; i < builder.length(); i++) {
|
||||
char ch = builder.charAt(i);
|
||||
if (isLastSpace && ch >= 'a' && ch <= 'z') {
|
||||
builder.setCharAt(i, (char) (ch + ('A' - 'a')));
|
||||
isLastSpace = false;
|
||||
} else isLastSpace = ch == ' ';
|
||||
}
|
||||
return builder.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param item The item to check
|
||||
* @param lore Whether or not MI should check for an item lore
|
||||
* @return If the item is not null, has an itemMeta and has a display name.
|
||||
* If 'lore' is true, also checks if the itemMeta has a lore.
|
||||
*/
|
||||
public static boolean isMetaItem(ItemStack item, boolean lore) {
|
||||
return item != null && item.getType() != Material.AIR && item.getItemMeta() != null && item.getItemMeta().getDisplayName() != null && (!lore || item.getItemMeta().getLore() != null);
|
||||
}
|
||||
/**
|
||||
* @param item The item to check
|
||||
* @param lore Whether or not MI should check for an item lore
|
||||
* @return If the item is not null, has an itemMeta and has a display name.
|
||||
* If 'lore' is true, also checks if the itemMeta has a lore.
|
||||
*/
|
||||
public static boolean isMetaItem(ItemStack item, boolean lore) {
|
||||
return item != null && item.getType() != Material.AIR && item.getItemMeta() != null && item.getItemMeta().getDisplayName() != null && (!lore || item.getItemMeta().getLore() != null);
|
||||
}
|
||||
|
||||
//region Restoration
|
||||
/**
|
||||
* @param player Player to heal
|
||||
* @param saturation Saturation amount
|
||||
* <br>
|
||||
* Negative values are just ignored
|
||||
*/
|
||||
public static void saturate(@NotNull Player player, double saturation) { saturate(player, saturation, false); }
|
||||
/**
|
||||
* @param player Player to heal
|
||||
* @param saturation Saturation amount
|
||||
* @param allowNegatives If passing a negative saturation value will desaturatie the entity x)
|
||||
* <br>
|
||||
* If <code>false</code>, negative values are just ignored
|
||||
*/
|
||||
public static void saturate(@NotNull Player player, double saturation, boolean allowNegatives) { if (saturation > 0 || allowNegatives) player.setSaturation(Math.min(0, Math.min(20, player.getSaturation() + (float) saturation))); }
|
||||
//region Restoration
|
||||
|
||||
/**
|
||||
* @param player Player to heal
|
||||
* @param feed Food amount
|
||||
* <br>
|
||||
* Negative values are just ignored
|
||||
*/
|
||||
public static void feed(@NotNull Player player, int feed) { feed(player, feed, false); }
|
||||
/**
|
||||
* @param player Player to heal
|
||||
* @param feed Food amount
|
||||
* @param allowNegatives If passing a negative feed value will hunger the entity x)
|
||||
* <br>
|
||||
* If <code>false</code>, negative values are just ignored
|
||||
*/
|
||||
public static void feed(@NotNull Player player, int feed, boolean allowNegatives) { if (feed > 0 || allowNegatives) player.setFoodLevel(Math.max(Math.min(20, player.getFoodLevel() + feed), 0)); }
|
||||
/**
|
||||
* @param player Player to heal
|
||||
* @param saturation Saturation amount
|
||||
* <br>
|
||||
* Negative values are just ignored
|
||||
*/
|
||||
public static void saturate(@NotNull Player player, double saturation) {
|
||||
saturate(player, saturation, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param player Player to heal
|
||||
* @param heal Heal amount
|
||||
* <br>
|
||||
* Negative values are just ignored
|
||||
*/
|
||||
public static void heal(@NotNull LivingEntity player, double heal) { heal(player, heal, false); }
|
||||
/**
|
||||
* @param player Player to heal
|
||||
* @param heal Heal amount
|
||||
* @param allowNegatives If passing a negative health value will damage the entity x)
|
||||
* <br>
|
||||
* If <code>false</code>, negative values are just ignored
|
||||
*/
|
||||
public static void heal(@NotNull LivingEntity player, double heal, boolean allowNegatives) { if (heal > 0 || allowNegatives) player.setHealth(Math.min(player.getAttribute(Attribute.GENERIC_MAX_HEALTH).getValue(), player.getHealth() + heal)); }
|
||||
//endregion
|
||||
/**
|
||||
* @param player Player to heal
|
||||
* @param saturation Saturation amount
|
||||
* @param allowNegatives If passing a negative saturation value will desaturatie the entity x)
|
||||
* <br>
|
||||
* If <code>false</code>, negative values are just ignored
|
||||
*/
|
||||
public static void saturate(@NotNull Player player, double saturation, boolean allowNegatives) {
|
||||
if (saturation > 0 || allowNegatives)
|
||||
player.setSaturation(Math.min(0, Math.min(20, player.getSaturation() + (float) saturation)));
|
||||
}
|
||||
|
||||
public static boolean canDamage(Player player, Entity target) {
|
||||
return canDamage(player, null, target);
|
||||
}
|
||||
/**
|
||||
* @param player Player to heal
|
||||
* @param feed Food amount
|
||||
* <br>
|
||||
* Negative values are just ignored
|
||||
*/
|
||||
public static void feed(@NotNull Player player, int feed) {
|
||||
feed(player, feed, false);
|
||||
}
|
||||
|
||||
public static boolean canDamage(Entity target) {
|
||||
return canDamage(null, null, target);
|
||||
}
|
||||
/**
|
||||
* @param player Player to heal
|
||||
* @param feed Food amount
|
||||
* @param allowNegatives If passing a negative feed value will hunger the entity x)
|
||||
* <br>
|
||||
* If <code>false</code>, negative values are just ignored
|
||||
*/
|
||||
public static void feed(@NotNull Player player, int feed, boolean allowNegatives) {
|
||||
if (feed > 0 || allowNegatives) player.setFoodLevel(Math.max(Math.min(20, player.getFoodLevel() + feed), 0));
|
||||
}
|
||||
|
||||
/**
|
||||
* @param player Player hitting the entity
|
||||
* @param loc If the given location is not null, this method checks if this
|
||||
* location is inside the bounding box of the entity hit
|
||||
* @param target The entity being hit
|
||||
* @return If the entity can be damaged, by a specific player, at a specific
|
||||
* spot
|
||||
*/
|
||||
public static boolean canDamage(@Nullable Player player, @Nullable Location loc, Entity target) {
|
||||
/**
|
||||
* @param player Player to heal
|
||||
* @param heal Heal amount
|
||||
* <br>
|
||||
* Negative values are just ignored
|
||||
*/
|
||||
public static void heal(@NotNull LivingEntity player, double heal) {
|
||||
heal(player, heal, false);
|
||||
}
|
||||
|
||||
/*
|
||||
* Cannot hit himself or non-living entities. Careful, some entities are
|
||||
* weirdly considered as livingEntities like the armor stand. Also check
|
||||
* if the entity is dead since a dying entity (dying effect takes some
|
||||
* time) can still be targeted but we dont want that
|
||||
*/
|
||||
if (target.equals(player) || target.isDead() || !(target instanceof LivingEntity) || target instanceof ArmorStand)
|
||||
return false;
|
||||
/**
|
||||
* @param player Player to heal
|
||||
* @param heal Heal amount
|
||||
* @param allowNegatives If passing a negative health value will damage the entity x)
|
||||
* <br>
|
||||
* If <code>false</code>, negative values are just ignored
|
||||
*/
|
||||
public static void heal(@NotNull LivingEntity player, double heal, boolean allowNegatives) {
|
||||
if (heal > 0 || allowNegatives)
|
||||
player.setHealth(Math.min(player.getAttribute(Attribute.GENERIC_MAX_HEALTH).getValue(), player.getHealth() + heal));
|
||||
}
|
||||
//endregion
|
||||
|
||||
/*
|
||||
* Extra plugin compatibility, everything is handled via MMOLib because
|
||||
* the same system is used by MMOCore
|
||||
*/
|
||||
if (MythicLib.plugin.getEntities().findCustom(target)) return false;
|
||||
/**
|
||||
* Interaction type is set to OFFENSE_SKILL by default. No bounding box checks
|
||||
*
|
||||
* @param source Player targeting the entity
|
||||
* @param target The entity being hit
|
||||
* @return If the entity can be damaged, by a specific player, at a specific spot
|
||||
*/
|
||||
public static boolean canTarget(Player source, Entity target) {
|
||||
return canTarget(source, null, target, InteractionType.OFFENSE_SKILL);
|
||||
}
|
||||
|
||||
/*
|
||||
* The ability player damage option is cached for quicker access in the
|
||||
* config manager instance since it is used in runnables
|
||||
*/
|
||||
if (target instanceof Player && (!MMOItems.plugin.getLanguage().abilityPlayerDamage || !MMOItems.plugin.getFlags().isPvpAllowed(target.getLocation())))
|
||||
return false;
|
||||
/**
|
||||
* Interaction type is set to OFFENSE_SKILL by default.
|
||||
*
|
||||
* @param source Player targeting the entity
|
||||
* @param loc If the given location is not null, this method checks if this
|
||||
* location is inside the bounding box of the entity hit
|
||||
* @param target The entity being hit
|
||||
* @return If the entity can be damaged, by a specific player, at a specific spot
|
||||
*/
|
||||
public static boolean canTarget(Player source, Location loc, Entity target) {
|
||||
return canTarget(source, loc, target, InteractionType.OFFENSE_SKILL);
|
||||
}
|
||||
|
||||
return loc == null || MythicLib.plugin.getVersion().getWrapper().isInBoundingBox(target, loc);
|
||||
}
|
||||
/**
|
||||
* No bounding box checks
|
||||
*
|
||||
* @param source Player targeting the entity
|
||||
* @param target The entity being hit
|
||||
* @param interaction Type of interaction
|
||||
* @return If the entity can be damaged, by a specific player, at a specific spot
|
||||
*/
|
||||
public static boolean canTarget(Player source, Entity target, InteractionType interaction) {
|
||||
return canTarget(source, null, target, interaction);
|
||||
}
|
||||
|
||||
private static final String[] romanChars = {"M", "CM", "D", "CD", "C", "XC", "L", "XL", "X", "IX", "V", "IV", "I"};
|
||||
private static final int[] romanValues = {1000, 900, 500, 400, 100, 90, 50, 40, 10, 9, 5, 4, 1};
|
||||
/**
|
||||
* @param source Player targeting the entity
|
||||
* @param loc If the given location is not null, this method checks if this
|
||||
* location is inside the bounding box of the entity hit
|
||||
* @param target The entity being hit
|
||||
* @param interaction Type of interaction
|
||||
* @return If the entity can be damaged, by a specific player, at a specific spot
|
||||
*/
|
||||
public static boolean canTarget(@Nullable Player source, @Nullable Location loc, Entity target, InteractionType interaction) {
|
||||
|
||||
/**
|
||||
* @param input Integer from 1 to 3999
|
||||
* @return Roman display of given int
|
||||
*/
|
||||
public static String intToRoman(int input) {
|
||||
if (input < 1 || input > 3999) throw new IllegalArgumentException("Input must be between 1 and 3999");
|
||||
// Check for easy checks and other as well
|
||||
if (!MythicLib.plugin.getEntities().canTarget(source, target, interaction))
|
||||
return false;
|
||||
|
||||
StringBuilder format = new StringBuilder();
|
||||
// Check for bounding box
|
||||
return loc == null || MythicLib.plugin.getVersion().getWrapper().isInBoundingBox(target, loc);
|
||||
}
|
||||
|
||||
for (int i = 0; i < romanChars.length; i++)
|
||||
while (input >= romanValues[i]) {
|
||||
format.append(romanChars[i]);
|
||||
input -= romanValues[i];
|
||||
}
|
||||
private static final String[] romanChars = {"M", "CM", "D", "CD", "C", "XC", "L", "XL", "X", "IX", "V", "IV", "I"};
|
||||
private static final int[] romanValues = {1000, 900, 500, 400, 100, 90, 50, 40, 10, 9, 5, 4, 1};
|
||||
|
||||
return format.toString();
|
||||
}
|
||||
/**
|
||||
* @param input Integer from 1 to 3999
|
||||
* @return Roman display of given int
|
||||
*/
|
||||
public static String intToRoman(int input) {
|
||||
if (input < 1 || input > 3999) throw new IllegalArgumentException("Input must be between 1 and 3999");
|
||||
|
||||
public static double truncation(double x, int n) {
|
||||
double pow = Math.pow(10.0, n);
|
||||
return Math.floor(x * pow) / pow;
|
||||
}
|
||||
StringBuilder format = new StringBuilder();
|
||||
|
||||
/**
|
||||
* @param v Vector to rotate
|
||||
* @param loc The position is not actually being used here, only the pitch and yaw
|
||||
* @return Vector facing direction given by location
|
||||
*/
|
||||
public static Vector rotateFunc(Vector v, Location loc) {
|
||||
double yaw = loc.getYaw() / 180 * Math.PI;
|
||||
double pitch = loc.getPitch() / 180 * Math.PI;
|
||||
v = rotAxisX(v, pitch);
|
||||
v = rotAxisY(v, -yaw);
|
||||
return v;
|
||||
}
|
||||
for (int i = 0; i < romanChars.length; i++)
|
||||
while (input >= romanValues[i]) {
|
||||
format.append(romanChars[i]);
|
||||
input -= romanValues[i];
|
||||
}
|
||||
|
||||
private static Vector rotAxisX(Vector v, double a) {
|
||||
double y = v.getY() * Math.cos(a) - v.getZ() * Math.sin(a);
|
||||
double z = v.getY() * Math.sin(a) + v.getZ() * Math.cos(a);
|
||||
return v.setY(y).setZ(z);
|
||||
}
|
||||
return format.toString();
|
||||
}
|
||||
|
||||
private static Vector rotAxisY(Vector v, double b) {
|
||||
double x = v.getX() * Math.cos(b) + v.getZ() * Math.sin(b);
|
||||
double z = v.getX() * -Math.sin(b) + v.getZ() * Math.cos(b);
|
||||
return v.setX(x).setZ(z);
|
||||
}
|
||||
public static double truncation(double x, int n) {
|
||||
double pow = Math.pow(10.0, n);
|
||||
return Math.floor(x * pow) / pow;
|
||||
}
|
||||
|
||||
private static Vector rotAxisZ(Vector v, double c) {
|
||||
double x = v.getX() * Math.cos(c) - v.getY() * Math.sin(c);
|
||||
double y = v.getX() * Math.sin(c) + v.getY() * Math.cos(c);
|
||||
return v.setX(x).setY(y);
|
||||
}
|
||||
/**
|
||||
* @param v Vector to rotate
|
||||
* @param loc The position is not actually being used here, only the pitch and yaw
|
||||
* @return Vector facing direction given by location
|
||||
*/
|
||||
public static Vector rotateFunc(Vector v, Location loc) {
|
||||
double yaw = loc.getYaw() / 180 * Math.PI;
|
||||
double pitch = loc.getPitch() / 180 * Math.PI;
|
||||
v = rotAxisX(v, pitch);
|
||||
v = rotAxisY(v, -yaw);
|
||||
return v;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param loc Where we are looking for nearby entities
|
||||
* @return List of all entities surrounding a location. This method loops
|
||||
* through the 9 surrounding chunks and collect all entities from
|
||||
* them. This list can be cached and used multiple times in the same
|
||||
* tick for projectile based spells which need to run entity
|
||||
* checkups
|
||||
*/
|
||||
public static List<Entity> getNearbyChunkEntities(Location loc) {
|
||||
List<Entity> entities = new ArrayList<>();
|
||||
private static Vector rotAxisX(Vector v, double a) {
|
||||
double y = v.getY() * Math.cos(a) - v.getZ() * Math.sin(a);
|
||||
double z = v.getY() * Math.sin(a) + v.getZ() * Math.cos(a);
|
||||
return v.setY(y).setZ(z);
|
||||
}
|
||||
|
||||
int cx = loc.getChunk().getX();
|
||||
int cz = loc.getChunk().getZ();
|
||||
private static Vector rotAxisY(Vector v, double b) {
|
||||
double x = v.getX() * Math.cos(b) + v.getZ() * Math.sin(b);
|
||||
double z = v.getX() * -Math.sin(b) + v.getZ() * Math.cos(b);
|
||||
return v.setX(x).setZ(z);
|
||||
}
|
||||
|
||||
for (int x = -1; x < 2; x++)
|
||||
for (int z = -1; z < 2; z++)
|
||||
entities.addAll(Arrays.asList(loc.getWorld().getChunkAt(cx + x, cz + z).getEntities()));
|
||||
private static Vector rotAxisZ(Vector v, double c) {
|
||||
double x = v.getX() * Math.cos(c) - v.getY() * Math.sin(c);
|
||||
double y = v.getX() * Math.sin(c) + v.getY() * Math.cos(c);
|
||||
return v.setX(x).setY(y);
|
||||
}
|
||||
|
||||
return entities;
|
||||
}
|
||||
/**
|
||||
* @param loc Where we are looking for nearby entities
|
||||
* @return List of all entities surrounding a location. This method loops
|
||||
* through the 9 surrounding chunks and collect all entities from
|
||||
* them. This list can be cached and used multiple times in the same
|
||||
* tick for projectile based spells which need to run entity
|
||||
* checkups
|
||||
*/
|
||||
public static List<Entity> getNearbyChunkEntities(Location loc) {
|
||||
List<Entity> entities = new ArrayList<>();
|
||||
|
||||
public static ItemStack readIcon(String string) throws IllegalArgumentException {
|
||||
String[] split = string.split(":");
|
||||
Material material = Material.valueOf(split[0].toUpperCase().replace("-", "_").replace(" ", "_"));
|
||||
return split.length > 1 ? MythicLib.plugin.getVersion().getWrapper().textureItem(material, Integer.parseInt(split[1])) : new ItemStack(material);
|
||||
}
|
||||
int cx = loc.getChunk().getX();
|
||||
int cz = loc.getChunk().getZ();
|
||||
|
||||
for (int x = -1; x < 2; x++)
|
||||
for (int z = -1; z < 2; z++)
|
||||
entities.addAll(Arrays.asList(loc.getWorld().getChunkAt(cx + x, cz + z).getEntities()));
|
||||
|
||||
return entities;
|
||||
}
|
||||
|
||||
public static ItemStack readIcon(String string) throws IllegalArgumentException {
|
||||
String[] split = string.split(":");
|
||||
Material material = Material.valueOf(split[0].toUpperCase().replace("-", "_").replace(" ", "_"));
|
||||
return split.length > 1 ? MythicLib.plugin.getVersion().getWrapper().textureItem(material, Integer.parseInt(split[1])) : new ItemStack(material);
|
||||
}
|
||||
}
|
||||
|
@ -49,7 +49,7 @@ public class Arcane_Hail extends LocationAbility {
|
||||
Location loc1 = loc.clone().add(randomCoordMultiplier() * radius, 0, randomCoordMultiplier() * radius);
|
||||
loc1.getWorld().playSound(loc1, VersionSound.ENTITY_ENDERMAN_HURT.toSound(), 1, 0);
|
||||
for (Entity entity : MMOUtils.getNearbyChunkEntities(loc1))
|
||||
if (MMOUtils.canDamage(attack.getDamager(), entity) && entity.getLocation().distanceSquared(loc1) <= 4)
|
||||
if (MMOUtils.canTarget(attack.getDamager(), entity) && entity.getLocation().distanceSquared(loc1) <= 4)
|
||||
new AttackMetadata(new DamageMetadata(damage, DamageType.SKILL, DamageType.MAGIC), attack.getStats()).damage((LivingEntity) entity);
|
||||
loc1.getWorld().spawnParticle(Particle.SPELL_WITCH, loc1, 12, 0, 0, 0, .1);
|
||||
loc1.getWorld().spawnParticle(Particle.SMOKE_NORMAL, loc1, 6, 0, 0, 0, .1);
|
||||
|
@ -52,7 +52,7 @@ public class Black_Hole extends LocationAbility {
|
||||
}
|
||||
|
||||
for (Entity entity : MMOUtils.getNearbyChunkEntities(loc))
|
||||
if (entity.getLocation().distanceSquared(loc) < Math.pow(radius, 2) && MMOUtils.canDamage(attack.getDamager(), entity))
|
||||
if (entity.getLocation().distanceSquared(loc) < Math.pow(radius, 2) && MMOUtils.canTarget(attack.getDamager(), entity))
|
||||
entity.setVelocity(MMOUtils.normalize(loc.clone().subtract(entity.getLocation()).toVector()).multiply(.5));
|
||||
}
|
||||
}.runTaskTimer(MMOItems.plugin, 0, 1);
|
||||
|
@ -57,7 +57,7 @@ public class Contamination extends LocationAbility {
|
||||
if (j % 10 == 0) {
|
||||
loc.getWorld().playSound(loc, VersionSound.ENTITY_ENDERMAN_HURT.toSound(), 2, 1);
|
||||
for (Entity entity : MMOUtils.getNearbyChunkEntities(loc))
|
||||
if (MMOUtils.canDamage(attack.getDamager(), entity) && entity.getLocation().distanceSquared(loc) <= 25)
|
||||
if (MMOUtils.canTarget(attack.getDamager(), entity) && entity.getLocation().distanceSquared(loc) <= 25)
|
||||
new AttackMetadata(new DamageMetadata(dps, DamageType.SKILL, DamageType.MAGIC), attack.getStats()).damage((LivingEntity) entity, false);
|
||||
}
|
||||
}
|
||||
|
@ -37,7 +37,7 @@ public class Corrosion extends LocationAbility {
|
||||
loc.getWorld().playSound(loc, Sound.BLOCK_BREWING_STAND_BREW, 2, 0);
|
||||
|
||||
for (Entity entity : MMOUtils.getNearbyChunkEntities(loc))
|
||||
if (entity.getLocation().distanceSquared(loc) < radiusSquared && MMOUtils.canDamage(attack.getDamager(), entity)) {
|
||||
if (entity.getLocation().distanceSquared(loc) < radiusSquared && MMOUtils.canTarget(attack.getDamager(), entity)) {
|
||||
((LivingEntity) entity).removePotionEffect(PotionEffectType.POISON);
|
||||
((LivingEntity) entity).addPotionEffect(new PotionEffect(PotionEffectType.POISON, duration, amplifier));
|
||||
}
|
||||
|
@ -48,7 +48,7 @@ public class Corrupt extends LocationAbility {
|
||||
}
|
||||
|
||||
for (Entity entity : MMOUtils.getNearbyChunkEntities(loc))
|
||||
if (MMOUtils.canDamage(attack.getDamager(), entity) && entity.getLocation().distanceSquared(loc) <= radius * radius) {
|
||||
if (MMOUtils.canTarget(attack.getDamager(), entity) && entity.getLocation().distanceSquared(loc) <= radius * radius) {
|
||||
new AttackMetadata(new DamageMetadata(damage, DamageType.SKILL, DamageType.MAGIC), attack.getStats()).damage((LivingEntity) entity);
|
||||
((LivingEntity) entity).removePotionEffect(PotionEffectType.WITHER);
|
||||
((LivingEntity) entity).addPotionEffect(new PotionEffect(PotionEffectType.WITHER, (int) (duration * 20), (int) amplifier));
|
||||
|
@ -44,7 +44,7 @@ public class Freeze extends LocationAbility {
|
||||
loc.getWorld().playSound(loc, VersionSound.ENTITY_FIREWORK_ROCKET_LARGE_BLAST.toSound(), 2, 1);
|
||||
|
||||
for (Entity entity : MMOUtils.getNearbyChunkEntities(loc))
|
||||
if (entity.getLocation().distanceSquared(loc) < radiusSquared && MMOUtils.canDamage(attack.getDamager(), entity)) {
|
||||
if (entity.getLocation().distanceSquared(loc) < radiusSquared && MMOUtils.canTarget(attack.getDamager(), entity)) {
|
||||
((LivingEntity) entity).removePotionEffect(PotionEffectType.SLOW);
|
||||
((LivingEntity) entity).addPotionEffect(new PotionEffect(PotionEffectType.SLOW, duration, amplifier));
|
||||
}
|
||||
|
@ -60,7 +60,7 @@ public class Freezing_Curse extends LocationAbility {
|
||||
double duration = ability.getModifier("duration");
|
||||
double damage = ability.getModifier("damage");
|
||||
for (Entity entity : MMOUtils.getNearbyChunkEntities(loc))
|
||||
if (entity.getLocation().distanceSquared(loc) < radius * radius && MMOUtils.canDamage(attack.getDamager(), entity)) {
|
||||
if (entity.getLocation().distanceSquared(loc) < radius * radius && MMOUtils.canTarget(attack.getDamager(), entity)) {
|
||||
new AttackMetadata(new DamageMetadata(damage, DamageType.SKILL, DamageType.MAGIC), attack.getStats()).damage((LivingEntity) entity);
|
||||
((LivingEntity) entity).removePotionEffect(PotionEffectType.SLOW);
|
||||
((LivingEntity) entity).addPotionEffect(new PotionEffect(PotionEffectType.SLOW, (int) (duration * 20), (int) amplifier));
|
||||
|
@ -35,7 +35,7 @@ public class Ignite extends LocationAbility {
|
||||
loc.getWorld().playSound(loc, VersionSound.ENTITY_FIREWORK_ROCKET_LARGE_BLAST.toSound(), 2, 1);
|
||||
|
||||
for (Entity entity : MMOUtils.getNearbyChunkEntities(loc))
|
||||
if (entity.getLocation().distanceSquared(loc) < radiusSquared && MMOUtils.canDamage(attack.getDamager(), entity))
|
||||
if (entity.getLocation().distanceSquared(loc) < radiusSquared && MMOUtils.canTarget(attack.getDamager(), entity))
|
||||
entity.setFireTicks(Math.min(entity.getFireTicks() + ignite, maxIgnite));
|
||||
}
|
||||
}
|
||||
|
@ -63,7 +63,7 @@ public class Life_Ender extends LocationAbility {
|
||||
source.getWorld().spawnParticle(Particle.SMOKE_LARGE, source, 0, Math.cos(j), 0, Math.sin(j), .5);
|
||||
|
||||
for (Entity entity : MMOUtils.getNearbyChunkEntities(source))
|
||||
if (entity.getLocation().distanceSquared(source) < radius * radius && MMOUtils.canDamage(attack.getDamager(), entity)) {
|
||||
if (entity.getLocation().distanceSquared(source) < radius * radius && MMOUtils.canTarget(attack.getDamager(), entity)) {
|
||||
new AttackMetadata(new DamageMetadata(damage, DamageType.SKILL, DamageType.MAGIC), attack.getStats()).damage((LivingEntity) entity);
|
||||
entity.setVelocity(entity.getLocation().subtract(source).toVector().setY(.75).normalize().multiply(knockback));
|
||||
}
|
||||
|
@ -32,7 +32,7 @@ public class Lightning_Beam extends LocationAbility {
|
||||
double radius = ability.getModifier("radius");
|
||||
|
||||
for (Entity entity : MMOUtils.getNearbyChunkEntities(loc))
|
||||
if (MMOUtils.canDamage(attack.getDamager(), entity) && entity.getLocation().distanceSquared(loc) <= radius * radius)
|
||||
if (MMOUtils.canTarget(attack.getDamager(), entity) && entity.getLocation().distanceSquared(loc) <= radius * radius)
|
||||
new AttackMetadata(new DamageMetadata(damage, DamageType.SKILL, DamageType.MAGIC), attack.getStats()).damage((LivingEntity) entity);
|
||||
|
||||
attack.getDamager().getWorld().playSound(attack.getDamager().getLocation(), VersionSound.ENTITY_FIREWORK_ROCKET_BLAST.toSound(), 1, 0);
|
||||
|
@ -38,7 +38,7 @@ public class Minor_Explosion extends LocationAbility {
|
||||
loc.getWorld().playSound(loc, Sound.ENTITY_GENERIC_EXPLODE, 2, 1);
|
||||
|
||||
for (Entity entity : MMOUtils.getNearbyChunkEntities(loc))
|
||||
if (entity.getLocation().distanceSquared(loc) < radiusSquared && MMOUtils.canDamage(attack.getDamager(), entity)) {
|
||||
if (entity.getLocation().distanceSquared(loc) < radiusSquared && MMOUtils.canTarget(attack.getDamager(), entity)) {
|
||||
new AttackMetadata(new DamageMetadata(damage, DamageType.SKILL, DamageType.MAGIC), attack.getStats()).damage((LivingEntity) entity);
|
||||
entity.setVelocity(MMOUtils.normalize(entity.getLocation().subtract(loc).toVector().setY(0)).setY(.2).multiply(2 * knockback));
|
||||
}
|
||||
|
@ -68,7 +68,7 @@ public class Snowman_Turret extends LocationAbility {
|
||||
|
||||
if (ti % 2 == 0)
|
||||
for (Entity entity : MMOUtils.getNearbyChunkEntities(snowman.getLocation()))
|
||||
if (!entity.equals(snowman) && MMOUtils.canDamage(attack.getDamager(), entity)
|
||||
if (!entity.equals(snowman) && MMOUtils.canTarget(attack.getDamager(), entity)
|
||||
&& entity.getLocation().distanceSquared(snowman.getLocation()) < radiusSquared) {
|
||||
snowman.getWorld().playSound(snowman.getLocation(), Sound.ENTITY_SNOWBALL_THROW, 1, 1.3f);
|
||||
Snowball snowball = snowman.launchProjectile(Snowball.class);
|
||||
|
@ -62,7 +62,7 @@ public class Arcane_Rift extends Ability<VectorAbilityMetadata> {
|
||||
loc.getWorld().spawnParticle(Particle.SPELL_WITCH, loc, 5, .5, 0, .5, 0);
|
||||
|
||||
for (Entity entity : MMOUtils.getNearbyChunkEntities(loc))
|
||||
if (MMOUtils.canDamage(attack.getDamager(), entity) && loc.distanceSquared(entity.getLocation()) < 2 && !hit.contains(entity.getEntityId())) {
|
||||
if (MMOUtils.canTarget(attack.getDamager(), entity) && loc.distanceSquared(entity.getLocation()) < 2 && !hit.contains(entity.getEntityId())) {
|
||||
hit.add(entity.getEntityId());
|
||||
new AttackMetadata(new DamageMetadata(damage, DamageType.SKILL, DamageType.MAGIC), attack.getStats()).damage((LivingEntity) entity);
|
||||
((LivingEntity) entity).addPotionEffect(new PotionEffect(PotionEffectType.SLOW, (int) (slowDuration * 20), (int) slowAmplifier));
|
||||
|
@ -61,7 +61,7 @@ public class Earthquake extends Ability<VectorAbilityMetadata> {
|
||||
loc.getWorld().playSound(loc, Sound.BLOCK_GRAVEL_BREAK, 2, 1);
|
||||
|
||||
for (Entity entity : MMOUtils.getNearbyChunkEntities(loc))
|
||||
if (MMOUtils.canDamage(attack.getDamager(), entity) && loc.distanceSquared(entity.getLocation()) < 2 && !hit.contains(entity.getEntityId())) {
|
||||
if (MMOUtils.canTarget(attack.getDamager(), entity) && loc.distanceSquared(entity.getLocation()) < 2 && !hit.contains(entity.getEntityId())) {
|
||||
hit.add(entity.getEntityId());
|
||||
new AttackMetadata(new DamageMetadata(damage, DamageType.SKILL, DamageType.MAGIC), attack.getStats()).damage((LivingEntity) entity);
|
||||
((LivingEntity) entity).addPotionEffect(new PotionEffect(PotionEffectType.SLOW, (int) (slowDuration * 20), (int) slowAmplifier));
|
||||
|
@ -51,7 +51,7 @@ public class Item_Bomb extends ItemAbility implements Listener {
|
||||
double slowAmplifier = ability.getModifier("slow-amplifier");
|
||||
|
||||
for (Entity entity : item.getEntity().getNearbyEntities(radius, radius, radius))
|
||||
if (MMOUtils.canDamage(attack.getDamager(), entity)) {
|
||||
if (MMOUtils.canTarget(attack.getDamager(), entity)) {
|
||||
new AttackMetadata(new DamageMetadata(damage, DamageType.SKILL, DamageType.PHYSICAL), attack.getStats()).damage((LivingEntity) entity);
|
||||
((LivingEntity) entity).removePotionEffect(PotionEffectType.SLOW);
|
||||
((LivingEntity) entity).addPotionEffect(new PotionEffect(PotionEffectType.SLOW, (int) (slowDuration * 20), (int) slowAmplifier));
|
||||
|
@ -62,7 +62,7 @@ public class Item_Throw extends ItemAbility implements Listener {
|
||||
|
||||
item.getEntity().getWorld().spawnParticle(Particle.CRIT, item.getEntity().getLocation(), 0);
|
||||
for (Entity target : item.getEntity().getNearbyEntities(1, 1, 1))
|
||||
if (MMOUtils.canDamage(attack.getDamager(), target)) {
|
||||
if (MMOUtils.canTarget(attack.getDamager(), target)) {
|
||||
new AttackMetadata(new DamageMetadata(ability.getModifier("damage"), DamageType.SKILL, DamageType.PHYSICAL, DamageType.PROJECTILE), attack.getStats()).damage((LivingEntity) target);
|
||||
item.close();
|
||||
cancel();
|
||||
|
@ -57,7 +57,7 @@ public class Burning_Hands extends SimpleAbility {
|
||||
if (entity.getLocation().distanceSquared(loc) < 60
|
||||
&& attack.getDamager().getEyeLocation().getDirection()
|
||||
.angle(entity.getLocation().toVector().subtract(attack.getDamager().getLocation().toVector())) < Math.PI / 6
|
||||
&& MMOUtils.canDamage(attack.getDamager(), entity))
|
||||
&& MMOUtils.canTarget(attack.getDamager(), entity))
|
||||
new AttackMetadata(new DamageMetadata(damage, DamageType.SKILL, DamageType.MAGIC), attack.getStats()).damage((LivingEntity) entity);
|
||||
|
||||
}
|
||||
|
@ -37,7 +37,7 @@ public class Circular_Slash extends SimpleAbility {
|
||||
attack.getDamager().getWorld().playSound(attack.getDamager().getLocation(), Sound.ENTITY_ZOMBIE_ATTACK_IRON_DOOR, 2, .5f);
|
||||
attack.getDamager().addPotionEffect(new PotionEffect(PotionEffectType.SLOW, 2, 254));
|
||||
for (Entity entity : attack.getDamager().getNearbyEntities(radius, radius, radius)) {
|
||||
if (MMOUtils.canDamage(attack.getDamager(), entity)) {
|
||||
if (MMOUtils.canTarget(attack.getDamager(), entity)) {
|
||||
new AttackMetadata(new DamageMetadata(damage, DamageType.SKILL, DamageType.PHYSICAL), attack.getStats()).damage((LivingEntity) entity);
|
||||
Vector v1 = entity.getLocation().toVector();
|
||||
Vector v2 = attack.getDamager().getLocation().toVector();
|
||||
|
@ -51,7 +51,7 @@ public class Firefly extends SimpleAbility {
|
||||
}
|
||||
|
||||
for (Entity entity : attack.getDamager().getNearbyEntities(1, 1, 1))
|
||||
if (MMOUtils.canDamage(attack.getDamager(), entity)) {
|
||||
if (MMOUtils.canTarget(attack.getDamager(), entity)) {
|
||||
double damage = ability.getModifier("damage");
|
||||
double knockback = ability.getModifier("knockback");
|
||||
|
||||
|
@ -49,7 +49,7 @@ public class Frozen_Aura extends SimpleAbility implements Listener {
|
||||
|
||||
if (ti % 7 == 0)
|
||||
for (Entity entity : MMOUtils.getNearbyChunkEntities(attack.getDamager().getLocation()))
|
||||
if (entity.getLocation().distanceSquared(attack.getDamager().getLocation()) < radiusSquared && MMOUtils.canDamage(attack.getDamager(), entity)) {
|
||||
if (entity.getLocation().distanceSquared(attack.getDamager().getLocation()) < radiusSquared && MMOUtils.canTarget(attack.getDamager(), entity)) {
|
||||
((LivingEntity) entity).removePotionEffect(PotionEffectType.SLOW);
|
||||
((LivingEntity) entity).addPotionEffect(new PotionEffect(PotionEffectType.SLOW, 40, (int) amplifier));
|
||||
}
|
||||
|
@ -47,7 +47,7 @@ public class Light_Dash extends SimpleAbility {
|
||||
attack.getDamager().getWorld().spawnParticle(Particle.SMOKE_LARGE, attack.getDamager().getLocation().add(0, 1, 0), 0);
|
||||
attack.getDamager().getWorld().playSound(attack.getDamager().getLocation(), VersionSound.ENTITY_ENDER_DRAGON_FLAP.toSound(), 1, 2);
|
||||
for (Entity entity : attack.getDamager().getNearbyEntities(1, 1, 1))
|
||||
if (!hit.contains(entity.getEntityId()) && MMOUtils.canDamage(attack.getDamager(), entity)) {
|
||||
if (!hit.contains(entity.getEntityId()) && MMOUtils.canTarget(attack.getDamager(), entity)) {
|
||||
hit.add(entity.getEntityId());
|
||||
new AttackMetadata(new DamageMetadata(damage, DamageType.SKILL, DamageType.PHYSICAL), attack.getStats()).damage((LivingEntity) entity);
|
||||
}
|
||||
|
@ -37,7 +37,7 @@ public class Overload extends SimpleAbility {
|
||||
attack.getDamager().addPotionEffect(new PotionEffect(PotionEffectType.SLOW, 2, 254));
|
||||
|
||||
for (Entity entity : attack.getDamager().getNearbyEntities(radius, radius, radius))
|
||||
if (MMOUtils.canDamage(attack.getDamager(), entity))
|
||||
if (MMOUtils.canTarget(attack.getDamager(), entity))
|
||||
new AttackMetadata(new DamageMetadata(damage, DamageType.SKILL, DamageType.MAGIC), attack.getStats()).damage((LivingEntity) entity);
|
||||
|
||||
double step = 12 + (radius * 2.5);
|
||||
|
@ -87,7 +87,7 @@ public class Present_Throw extends SimpleAbility {
|
||||
item.getEntity().getWorld().spawnParticle(Particle.FIREWORKS_SPARK, item.getEntity().getLocation().add(0, .1, 0), 128, 0, 0, 0, .25);
|
||||
item.getEntity().getWorld().playSound(item.getEntity().getLocation(), VersionSound.ENTITY_FIREWORK_ROCKET_TWINKLE.toSound(), 2, 1.5f);
|
||||
for (Entity entity : MMOUtils.getNearbyChunkEntities(item.getEntity().getLocation()))
|
||||
if (entity.getLocation().distanceSquared(item.getEntity().getLocation()) < radiusSquared && MMOUtils.canDamage(attack.getDamager(), entity))
|
||||
if (entity.getLocation().distanceSquared(item.getEntity().getLocation()) < radiusSquared && MMOUtils.canTarget(attack.getDamager(), entity))
|
||||
new AttackMetadata(new DamageMetadata(damage, DamageType.SKILL, DamageType.MAGIC, DamageType.PROJECTILE), attack.getStats()).damage((LivingEntity) entity);
|
||||
item.close();
|
||||
cancel();
|
||||
|
@ -38,7 +38,7 @@ public class Sky_Smash extends SimpleAbility {
|
||||
loc.getWorld().spawnParticle(Particle.SMOKE_LARGE, loc, 16, 0, 0, 0, .1);
|
||||
|
||||
for (Entity entity : MMOUtils.getNearbyChunkEntities(loc))
|
||||
if (MMOUtils.canDamage(attack.getDamager(), entity) && entity.getLocation().distanceSquared(loc) < 10) {
|
||||
if (MMOUtils.canTarget(attack.getDamager(), entity) && entity.getLocation().distanceSquared(loc) < 10) {
|
||||
new AttackMetadata(new DamageMetadata(damage, DamageType.SKILL, DamageType.PHYSICAL), attack.getStats()).damage((LivingEntity) entity);
|
||||
Location loc1 = attack.getDamager().getEyeLocation().clone();
|
||||
loc1.setPitch(-70);
|
||||
|
@ -46,7 +46,7 @@ public class Throw_Up extends SimpleAbility implements Listener {
|
||||
|
||||
if (j % 5 == 0)
|
||||
for (Entity entity : MMOUtils.getNearbyChunkEntities(loc))
|
||||
if (entity.getLocation().distanceSquared(loc) < 40 && attack.getDamager().getEyeLocation().getDirection().angle(entity.getLocation().toVector().subtract(attack.getDamager().getLocation().toVector())) < Math.PI / 6 && MMOUtils.canDamage(attack.getDamager(), entity))
|
||||
if (entity.getLocation().distanceSquared(loc) < 40 && attack.getDamager().getEyeLocation().getDirection().angle(entity.getLocation().toVector().subtract(attack.getDamager().getLocation().toVector())) < Math.PI / 6 && MMOUtils.canTarget(attack.getDamager(), entity))
|
||||
new AttackMetadata(new DamageMetadata(dps, DamageType.SKILL, DamageType.PHYSICAL, DamageType.PROJECTILE), attack.getStats()).damage((LivingEntity) entity);
|
||||
|
||||
loc.getWorld().playSound(loc, Sound.ENTITY_ZOMBIE_HURT, 1, 1);
|
||||
|
@ -59,7 +59,7 @@ public class Tactical_Grenade extends TargetAbility {
|
||||
loc.getWorld().playSound(loc, Sound.ENTITY_GENERIC_EXPLODE, 2, 1);
|
||||
|
||||
for (Entity entity : MMOUtils.getNearbyChunkEntities(loc))
|
||||
if (!hit.contains(entity.getEntityId()) && MMOUtils.canDamage(attack.getDamager(), entity) && entity.getLocation().distanceSquared(loc) < radius * radius) {
|
||||
if (!hit.contains(entity.getEntityId()) && MMOUtils.canTarget(attack.getDamager(), entity) && entity.getLocation().distanceSquared(loc) < radius * radius) {
|
||||
|
||||
/*
|
||||
* stop the runnable as soon as the grenade finally hits
|
||||
|
@ -72,7 +72,7 @@ public class Bouncy_Fireball extends VectorAbility {
|
||||
|
||||
for (Entity entity : MMOUtils.getNearbyChunkEntities(loc))
|
||||
if (entity.getLocation().distanceSquared(loc) < radius * radius)
|
||||
if (MMOUtils.canDamage(attack.getDamager(), entity)) {
|
||||
if (MMOUtils.canTarget(attack.getDamager(), entity)) {
|
||||
new AttackMetadata(new DamageMetadata(damage, DamageType.SKILL, DamageType.MAGIC, DamageType.PROJECTILE), attack.getStats()).damage((LivingEntity) entity);
|
||||
entity.setFireTicks((int) (ignite * 20));
|
||||
}
|
||||
|
@ -73,7 +73,7 @@ public class Corrupted_Fangs extends VectorAbility implements Listener {
|
||||
if (event.getDamager() instanceof EvokerFangs && entities.contains(event.getDamager().getEntityId())) {
|
||||
event.setCancelled(true);
|
||||
|
||||
if (MMOUtils.canDamage(attackMeta.getDamager(), event.getEntity()))
|
||||
if (MMOUtils.canTarget(attackMeta.getDamager(), event.getEntity()))
|
||||
attackMeta.damage((LivingEntity) event.getEntity());
|
||||
}
|
||||
}
|
||||
|
@ -59,13 +59,13 @@ public class Cursed_Beam extends VectorAbility {
|
||||
}
|
||||
|
||||
for (Entity target : entities)
|
||||
if (MMOUtils.canDamage(attack.getDamager(), loc, target)) {
|
||||
if (MMOUtils.canTarget(attack.getDamager(), loc, target)) {
|
||||
effect(target);
|
||||
double damage = ability.getModifier("damage");
|
||||
loc.getWorld().playSound(loc, VersionSound.ENTITY_ENDERMAN_TELEPORT.toSound(), 2, .7f);
|
||||
|
||||
for (Entity entity : entities)
|
||||
if (MMOUtils.canDamage(attack.getDamager(), entity) && loc.distanceSquared(entity.getLocation().add(0, 1, 0)) < 9) {
|
||||
if (MMOUtils.canTarget(attack.getDamager(), entity) && loc.distanceSquared(entity.getLocation().add(0, 1, 0)) < 9) {
|
||||
new AttackMetadata(new DamageMetadata(damage, DamageType.SKILL, DamageType.MAGIC, DamageType.PROJECTILE), attack.getStats()).damage((LivingEntity) entity);
|
||||
((LivingEntity) entity).addPotionEffect(new PotionEffect(PotionEffectType.BLINDNESS, (int) (duration * 20), 0));
|
||||
}
|
||||
|
@ -96,7 +96,7 @@ public class Explosive_Turkey extends VectorAbility implements Listener {
|
||||
chicken.getWorld().playSound(chicken.getLocation(), Sound.ENTITY_GENERIC_EXPLODE, 2, 1.5f);
|
||||
for (Entity entity : MMOUtils.getNearbyChunkEntities(chicken.getLocation()))
|
||||
if (!entity.isDead() && entity.getLocation().distanceSquared(chicken.getLocation()) < radiusSquared
|
||||
&& MMOUtils.canDamage(attack.getDamager(), entity)) {
|
||||
&& MMOUtils.canTarget(attack.getDamager(), entity)) {
|
||||
new AttackMetadata(new DamageMetadata(damage, DamageType.SKILL, DamageType.MAGIC, DamageType.PROJECTILE), attack.getStats()).damage((LivingEntity) entity);
|
||||
entity.setVelocity(entity.getLocation().toVector().subtract(chicken.getLocation().toVector()).multiply(.1 * knockback)
|
||||
.setY(.4 * knockback));
|
||||
|
@ -56,7 +56,7 @@ public class Fire_Meteor extends VectorAbility {
|
||||
double knockback = ability.getModifier("knockback");
|
||||
double radius = ability.getModifier("radius");
|
||||
for (Entity entity : MMOUtils.getNearbyChunkEntities(loc))
|
||||
if (MMOUtils.canDamage(attack.getDamager(), entity) && entity.getLocation().distanceSquared(loc) < radius * radius) {
|
||||
if (MMOUtils.canTarget(attack.getDamager(), entity) && entity.getLocation().distanceSquared(loc) < radius * radius) {
|
||||
new AttackMetadata(new DamageMetadata(damage, DamageType.SKILL, DamageType.MAGIC, DamageType.PROJECTILE), attack.getStats()).damage((LivingEntity) entity);
|
||||
entity.setVelocity(entity.getLocation().toVector().subtract(loc.toVector()).multiply(.1 * knockback).setY(.4 * knockback));
|
||||
}
|
||||
|
@ -54,7 +54,7 @@ public class Firebolt extends VectorAbility {
|
||||
if (random.nextDouble() < .3)
|
||||
loc.getWorld().spawnParticle(Particle.LAVA, loc, 0);
|
||||
for (Entity target : entities)
|
||||
if (MMOUtils.canDamage(attack.getDamager(), loc, target)) {
|
||||
if (MMOUtils.canTarget(attack.getDamager(), loc, target)) {
|
||||
loc.getWorld().spawnParticle(Particle.FLAME, loc, 32, 0, 0, 0, .1);
|
||||
loc.getWorld().spawnParticle(Particle.LAVA, loc, 8, 0, 0, 0, 0);
|
||||
loc.getWorld().spawnParticle(Particle.EXPLOSION_LARGE, loc, 0);
|
||||
|
@ -44,7 +44,7 @@ public class Heavy_Charge extends VectorAbility {
|
||||
}
|
||||
|
||||
for (Entity target : attack.getDamager().getNearbyEntities(1, 1, 1))
|
||||
if (MMOUtils.canDamage(attack.getDamager(), target)) {
|
||||
if (MMOUtils.canTarget(attack.getDamager(), target)) {
|
||||
attack.getDamager().getWorld().playSound(attack.getDamager().getLocation(), Sound.ENTITY_ZOMBIE_ATTACK_IRON_DOOR, 1, 1);
|
||||
attack.getDamager().getWorld().spawnParticle(Particle.EXPLOSION_LARGE, target.getLocation().add(0, 1, 0), 0);
|
||||
target.setVelocity(attack.getDamager().getVelocity().setY(0.3).multiply(1.7 * knockback));
|
||||
|
@ -59,7 +59,7 @@ public class Holy_Missile extends VectorAbility {
|
||||
}
|
||||
|
||||
for (Entity entity : entities)
|
||||
if (MMOUtils.canDamage(attack.getDamager(), loc, entity)) {
|
||||
if (MMOUtils.canTarget(attack.getDamager(), loc, entity)) {
|
||||
loc.getWorld().spawnParticle(Particle.EXPLOSION_LARGE, loc, 1);
|
||||
loc.getWorld().spawnParticle(Particle.FIREWORKS_SPARK, loc, 32, 0, 0, 0, .2);
|
||||
loc.getWorld().playSound(loc, Sound.ENTITY_GENERIC_EXPLODE, 2, 1);
|
||||
|
@ -69,7 +69,7 @@ public class Ice_Crystal extends VectorAbility {
|
||||
}
|
||||
|
||||
for (Entity entity : entities)
|
||||
if (MMOUtils.canDamage(attack.getDamager(), loc, entity)) {
|
||||
if (MMOUtils.canTarget(attack.getDamager(), loc, entity)) {
|
||||
loc.getWorld().spawnParticle(Particle.EXPLOSION_LARGE, loc, 0);
|
||||
loc.getWorld().spawnParticle(Particle.FIREWORKS_SPARK, loc, 48, 0, 0, 0, .2);
|
||||
loc.getWorld().playSound(loc, Sound.ENTITY_GENERIC_EXPLODE, 2, 1);
|
||||
|
@ -1,6 +1,7 @@
|
||||
package net.Indyuce.mmoitems.ability.list.vector;
|
||||
|
||||
import io.lumine.mythic.lib.api.item.NBTItem;
|
||||
import io.lumine.mythic.lib.comp.target.InteractionType;
|
||||
import io.lumine.mythic.lib.damage.DamageMetadata;
|
||||
import io.lumine.mythic.lib.damage.DamageType;
|
||||
import net.Indyuce.mmoitems.MMOItems;
|
||||
@ -37,7 +38,7 @@ public class Shulker_Missile extends VectorAbility implements Listener {
|
||||
addModifier("duration", 5);
|
||||
addModifier("mana", 0);
|
||||
addModifier("stamina", 0);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void whenCast(ItemAttackMetadata attack, VectorAbilityMetadata ability) {
|
||||
@ -70,27 +71,26 @@ public class Shulker_Missile extends VectorAbility implements Listener {
|
||||
cancel();
|
||||
} else
|
||||
shulkerBullet.setVelocity(vec);
|
||||
}
|
||||
}.runTaskTimer(MMOItems.plugin, 0, 1);
|
||||
}
|
||||
}.runTaskTimer(MMOItems.plugin, 0, 3);
|
||||
}
|
||||
}
|
||||
}.runTaskTimer(MMOItems.plugin, 0, 1);
|
||||
}
|
||||
}.runTaskTimer(MMOItems.plugin, 0, 3);
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void a(EntityDamageByEntityEvent event) {
|
||||
if (event.getDamager() instanceof ShulkerBullet && event.getEntity() instanceof LivingEntity) {
|
||||
ShulkerBullet damager = (ShulkerBullet) event.getDamager();
|
||||
LivingEntity entity = (LivingEntity) event.getEntity();
|
||||
if (!MMOItems.plugin.getEntities().isCustomEntity(damager))
|
||||
return;
|
||||
@EventHandler
|
||||
public void a(EntityDamageByEntityEvent event) {
|
||||
if (event.getDamager() instanceof ShulkerBullet && event.getEntity() instanceof LivingEntity) {
|
||||
ShulkerBullet damager = (ShulkerBullet) event.getDamager();
|
||||
LivingEntity entity = (LivingEntity) event.getEntity();
|
||||
if (!MMOItems.plugin.getEntities().isCustomEntity(damager))
|
||||
return;
|
||||
|
||||
if (!MMOUtils.canDamage(entity)) {
|
||||
ShulkerMissileEntityData data = (ShulkerMissileEntityData) MMOItems.plugin.getEntities().getEntityData(damager);
|
||||
if (!MMOUtils.canTarget(data.attackMeta.getDamager(), null, entity, data.isWeaponAttack() ? InteractionType.OFFENSE_ACTION : InteractionType.OFFENSE_SKILL)) {
|
||||
event.setCancelled(true);
|
||||
return;
|
||||
}
|
||||
|
||||
ShulkerMissileEntityData data = (ShulkerMissileEntityData) MMOItems.plugin.getEntities().getEntityData(damager);
|
||||
|
||||
// Void spirit
|
||||
if (data.isWeaponAttack())
|
||||
data.attackMeta.applyEffects(data.weapon, entity);
|
||||
@ -106,23 +106,23 @@ public class Shulker_Missile extends VectorAbility implements Listener {
|
||||
// Potion effect should apply right after the damage with a 1 tick delay.
|
||||
if (y == 0) {
|
||||
entity.removePotionEffect(PotionEffectType.LEVITATION);
|
||||
entity.addPotionEffect(new PotionEffect(PotionEffectType.LEVITATION, (int) (data.duration * 20), 0));
|
||||
}
|
||||
entity.addPotionEffect(new PotionEffect(PotionEffectType.LEVITATION, (int) (data.duration * 20), 0));
|
||||
}
|
||||
|
||||
for (int j1 = 0; j1 < 3; j1++) {
|
||||
y += .04;
|
||||
for (int j = 0; j < 2; j++) {
|
||||
double xz = y * Math.PI * 1.3 + (j * Math.PI);
|
||||
loc.getWorld().spawnParticle(Particle.REDSTONE, loc.clone().add(Math.cos(xz), y, Math.sin(xz)), 1,
|
||||
new Particle.DustOptions(Color.MAROON, 1));
|
||||
}
|
||||
}
|
||||
if (y >= 2)
|
||||
cancel();
|
||||
}
|
||||
}.runTaskTimer(MMOItems.plugin, 0, 1);
|
||||
}
|
||||
}
|
||||
for (int j1 = 0; j1 < 3; j1++) {
|
||||
y += .04;
|
||||
for (int j = 0; j < 2; j++) {
|
||||
double xz = y * Math.PI * 1.3 + (j * Math.PI);
|
||||
loc.getWorld().spawnParticle(Particle.REDSTONE, loc.clone().add(Math.cos(xz), y, Math.sin(xz)), 1,
|
||||
new Particle.DustOptions(Color.MAROON, 1));
|
||||
}
|
||||
}
|
||||
if (y >= 2)
|
||||
cancel();
|
||||
}
|
||||
}.runTaskTimer(MMOItems.plugin, 0, 1);
|
||||
}
|
||||
}
|
||||
|
||||
public static class ShulkerMissileEntityData implements EntityData {
|
||||
private final ItemAttackMetadata attackMeta;
|
||||
@ -159,6 +159,6 @@ public class Shulker_Missile extends VectorAbility implements Listener {
|
||||
|
||||
public boolean isWeaponAttack() {
|
||||
return attackMeta.getDamage().hasType(DamageType.WEAPON);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -56,7 +56,7 @@ public class TNT_Throw extends VectorAbility implements Listener {
|
||||
|
||||
@EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true)
|
||||
public void a(EntityDamageByEntityEvent event) {
|
||||
if (event.getDamager().equals(tnt) && !MMOUtils.canDamage(player, event.getEntity()))
|
||||
if (event.getDamager().equals(tnt) && !MMOUtils.canTarget(player, event.getEntity()))
|
||||
event.setCancelled(true);
|
||||
}
|
||||
}
|
||||
|
@ -38,7 +38,7 @@ public class Thrust extends VectorAbility {
|
||||
for (double j = 0; j < 7; j += .5) {
|
||||
loc.add(vec);
|
||||
for (Entity entity : MMOUtils.getNearbyChunkEntities(loc))
|
||||
if (MMOUtils.canDamage(attack.getDamager(), loc, entity))
|
||||
if (MMOUtils.canTarget(attack.getDamager(), loc, entity))
|
||||
new AttackMetadata(new DamageMetadata(damage, DamageType.SKILL, DamageType.PHYSICAL), attack.getStats()).damage((LivingEntity) entity);
|
||||
loc.getWorld().spawnParticle(Particle.SMOKE_LARGE, loc, 0);
|
||||
}
|
||||
|
@ -1,6 +1,7 @@
|
||||
package net.Indyuce.mmoitems.ability.metadata;
|
||||
|
||||
import io.lumine.mythic.lib.MythicLib;
|
||||
import io.lumine.mythic.lib.comp.target.InteractionType;
|
||||
import net.Indyuce.mmoitems.MMOUtils;
|
||||
import net.Indyuce.mmoitems.ability.AbilityMetadata;
|
||||
import net.Indyuce.mmoitems.stat.data.AbilityData;
|
||||
@ -13,7 +14,7 @@ public class FriendlyTargetAbilityMetadata extends AbilityMetadata {
|
||||
public FriendlyTargetAbilityMetadata(AbilityData ability, Player caster, LivingEntity target) {
|
||||
super(ability);
|
||||
|
||||
this.target = target != null ? target : MythicLib.plugin.getVersion().getWrapper().rayTrace(caster, 50, entity -> (entity instanceof Player && MMOUtils.canDamage(caster, entity))).getHit();
|
||||
this.target = target != null ? target : MythicLib.plugin.getVersion().getWrapper().rayTrace(caster, 50, entity -> entity instanceof Player && MMOUtils.canTarget(caster, entity, InteractionType.SUPPORT_SKILL)).getHit();
|
||||
}
|
||||
|
||||
public LivingEntity getTarget() {
|
||||
|
@ -1,6 +1,7 @@
|
||||
package net.Indyuce.mmoitems.ability.metadata;
|
||||
|
||||
import io.lumine.mythic.lib.MythicLib;
|
||||
import io.lumine.mythic.lib.comp.target.InteractionType;
|
||||
import net.Indyuce.mmoitems.MMOUtils;
|
||||
import net.Indyuce.mmoitems.ability.AbilityMetadata;
|
||||
import net.Indyuce.mmoitems.stat.data.AbilityData;
|
||||
@ -13,7 +14,7 @@ public class TargetAbilityMetadata extends AbilityMetadata {
|
||||
public TargetAbilityMetadata(AbilityData ability, Player caster, LivingEntity target) {
|
||||
super(ability);
|
||||
|
||||
this.target = target != null ? target : MythicLib.plugin.getVersion().getWrapper().rayTrace(caster, 50, entity -> MMOUtils.canDamage(caster, entity)).getHit();
|
||||
this.target = target != null ? target : MythicLib.plugin.getVersion().getWrapper().rayTrace(caster, 50, entity -> MMOUtils.canTarget(caster, entity, InteractionType.OFFENSE_SKILL)).getHit();
|
||||
}
|
||||
|
||||
public LivingEntity getTarget() {
|
||||
@ -21,7 +22,7 @@ public class TargetAbilityMetadata extends AbilityMetadata {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSuccessful() {
|
||||
return target != null;
|
||||
}
|
||||
public boolean isSuccessful() {
|
||||
return target != null;
|
||||
}
|
||||
}
|
||||
|
@ -1,6 +1,7 @@
|
||||
package net.Indyuce.mmoitems.api;
|
||||
|
||||
import io.lumine.mythic.lib.MythicLib;
|
||||
import io.lumine.mythic.lib.comp.target.InteractionType;
|
||||
import io.lumine.mythic.lib.damage.DamageMetadata;
|
||||
import io.lumine.mythic.lib.damage.DamageType;
|
||||
import io.lumine.mythic.lib.version.VersionMaterial;
|
||||
@ -52,7 +53,7 @@ public enum Element {
|
||||
Vector vec = target.getLocation().subtract(attack.getDamager().getLocation()).toVector().normalize().multiply(1.7).setY(.5);
|
||||
target.setVelocity(vec);
|
||||
for (Entity entity : target.getNearbyEntities(3, 1, 3))
|
||||
if (MMOUtils.canDamage(attack.getDamager(), entity)) {
|
||||
if (MMOUtils.canTarget(attack.getDamager(), entity, InteractionType.OFFENSE_ACTION)) {
|
||||
entity.playEffect(EntityEffect.HURT);
|
||||
entity.setVelocity(vec);
|
||||
}
|
||||
@ -71,14 +72,14 @@ public enum Element {
|
||||
|
||||
target.setVelocity(new Vector(0, 1, 0));
|
||||
for (Entity entity : target.getNearbyEntities(3, 1, 3))
|
||||
if (MMOUtils.canDamage(attack.getDamager(), entity))
|
||||
if (MMOUtils.canTarget(attack.getDamager(), entity, InteractionType.OFFENSE_ACTION))
|
||||
entity.setVelocity(new Vector(0, 1, 0));
|
||||
}, 29, 33),
|
||||
|
||||
THUNDER(VersionMaterial.GUNPOWDER.toMaterial(), ChatColor.YELLOW, new ElementParticle(Particle.FIREWORKS_SPARK, .05f, 8), (attack, target, damage, absolute) -> {
|
||||
target.getWorld().playSound(target.getLocation(), VersionSound.ENTITY_FIREWORK_ROCKET_LARGE_BLAST.toSound(), 2, 0);
|
||||
for (Entity entity : target.getNearbyEntities(3, 2, 3))
|
||||
if (MMOUtils.canDamage(attack.getDamager(), entity))
|
||||
if (MMOUtils.canTarget(attack.getDamager(), entity, InteractionType.OFFENSE_ACTION))
|
||||
MythicLib.plugin.getDamage().damage(new ItemAttackMetadata(new DamageMetadata(attack.getDamage().getDamage() * damage / 100, DamageType.WEAPON), attack.getStats()), (LivingEntity) entity);
|
||||
|
||||
attack.getDamage().add(absolute);
|
||||
|
@ -1,6 +1,7 @@
|
||||
package net.Indyuce.mmoitems.api;
|
||||
|
||||
import io.lumine.mythic.lib.api.stat.modifier.ModifierSource;
|
||||
import io.lumine.mythic.lib.comp.target.InteractionType;
|
||||
import io.lumine.mythic.lib.version.VersionSound;
|
||||
import net.Indyuce.mmoitems.MMOItems;
|
||||
import net.Indyuce.mmoitems.MMOUtils;
|
||||
@ -38,7 +39,7 @@ public enum TypeSet {
|
||||
if (entity.getLocation().distanceSquared(loc) < 40
|
||||
&& attack.getDamager().getEyeLocation().getDirection()
|
||||
.angle(entity.getLocation().subtract(attack.getDamager().getLocation()).toVector()) < Math.PI / 3
|
||||
&& MMOUtils.canDamage(attack.getDamager(), entity) && !entity.equals(target)) {
|
||||
&& MMOUtils.canTarget(attack.getDamager(), entity, InteractionType.OFFENSE_ACTION) && !entity.equals(target)) {
|
||||
ItemAttackMetadata subAttack = new ItemAttackMetadata(attack.getDamage().clone(), attack.getStats());
|
||||
subAttack.getDamage().multiply(.4);
|
||||
subAttack.applyEffectsAndDamage(weapon.getNBTItem(), (LivingEntity) entity);
|
||||
@ -67,7 +68,7 @@ public enum TypeSet {
|
||||
if (entity.getLocation().distanceSquared(attack.getDamager().getLocation()) < 40
|
||||
&& attack.getDamager().getEyeLocation().getDirection()
|
||||
.angle(entity.getLocation().toVector().subtract(attack.getDamager().getLocation().toVector())) < Math.PI / 18
|
||||
&& MMOUtils.canDamage(attack.getDamager(), entity) && !entity.equals(target)) {
|
||||
&& MMOUtils.canTarget(attack.getDamager(), entity, InteractionType.OFFENSE_ACTION) && !entity.equals(target)) {
|
||||
ItemAttackMetadata subAttack = new ItemAttackMetadata(attack.getDamage().clone(), attack.getStats());
|
||||
subAttack.getDamage().multiply(.4);
|
||||
subAttack.applyEffectsAndDamage(weapon.getNBTItem(), (LivingEntity) entity);
|
||||
@ -93,7 +94,7 @@ public enum TypeSet {
|
||||
double bluntRating = weapon.getValue(attack.getStats().getStat("BLUNT_RATING"),
|
||||
MMOItems.plugin.getConfig().getDouble("default.blunt-rating")) / 100;
|
||||
for (Entity entity : target.getNearbyEntities(bluntPower, bluntPower, bluntPower))
|
||||
if (MMOUtils.canDamage(attack.getDamager(), entity) && !entity.equals(target)) {
|
||||
if (MMOUtils.canTarget(attack.getDamager(), entity, InteractionType.OFFENSE_ACTION) && !entity.equals(target)) {
|
||||
ItemAttackMetadata subAttack = new ItemAttackMetadata(attack.getDamage().clone(), attack.getStats());
|
||||
subAttack.getDamage().multiply(bluntRating);
|
||||
subAttack.applyEffectsAndDamage(weapon.getNBTItem(), (LivingEntity) entity);
|
||||
|
@ -4,12 +4,12 @@ import io.lumine.mythic.lib.MythicLib;
|
||||
import io.lumine.mythic.lib.api.item.ItemTag;
|
||||
import io.lumine.mythic.lib.api.item.NBTItem;
|
||||
import io.lumine.mythic.lib.api.util.SmartGive;
|
||||
import io.lumine.mythic.lib.comp.flags.CustomFlag;
|
||||
import net.Indyuce.mmoitems.ItemStats;
|
||||
import net.Indyuce.mmoitems.MMOItems;
|
||||
import net.Indyuce.mmoitems.api.Type;
|
||||
import net.Indyuce.mmoitems.api.event.item.ConsumableConsumedEvent;
|
||||
import net.Indyuce.mmoitems.api.item.util.LoreUpdate;
|
||||
import net.Indyuce.mmoitems.comp.flags.FlagPlugin.CustomFlag;
|
||||
import net.Indyuce.mmoitems.stat.type.ConsumableItemInteraction;
|
||||
import net.Indyuce.mmoitems.stat.type.PlayerConsumable;
|
||||
import org.bukkit.Bukkit;
|
||||
@ -20,147 +20,147 @@ import org.bukkit.inventory.ItemStack;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
public class Consumable extends UseItem {
|
||||
public Consumable(Player player, NBTItem item) {
|
||||
super(player, item);
|
||||
}
|
||||
public Consumable(Player player, NBTItem item) {
|
||||
super(player, item);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean checkItemRequirements() {
|
||||
return MMOItems.plugin.getFlags().isFlagAllowed(player, CustomFlag.MI_CONSUMABLES) && playerData.getRPG().canUse(getNBTItem(), true);
|
||||
}
|
||||
@Override
|
||||
public boolean checkItemRequirements() {
|
||||
return MythicLib.plugin.getFlags().isFlagAllowed(player, CustomFlag.MI_CONSUMABLES) && playerData.getRPG().canUse(getNBTItem(), true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Applies a consumable onto an item
|
||||
*
|
||||
* @param event The click event
|
||||
* @param target The item on which the consumable is being applied
|
||||
* @return If the consumable was successfully applied on the item
|
||||
*/
|
||||
public boolean useOnItem(@NotNull InventoryClickEvent event, @NotNull NBTItem target) {
|
||||
if (event.getClickedInventory() != event.getWhoClicked().getInventory())
|
||||
return false;
|
||||
/**
|
||||
* Applies a consumable onto an item
|
||||
*
|
||||
* @param event The click event
|
||||
* @param target The item on which the consumable is being applied
|
||||
* @return If the consumable was successfully applied on the item
|
||||
*/
|
||||
public boolean useOnItem(@NotNull InventoryClickEvent event, @NotNull NBTItem target) {
|
||||
if (event.getClickedInventory() != event.getWhoClicked().getInventory())
|
||||
return false;
|
||||
|
||||
// Make sure it is an MMOItem
|
||||
Type targetType = MMOItems.getType(target);
|
||||
// Make sure it is an MMOItem
|
||||
Type targetType = MMOItems.getType(target);
|
||||
|
||||
for (ConsumableItemInteraction action : MMOItems.plugin.getStats().getConsumableActions())
|
||||
if (action.handleConsumableEffect(event, playerData, this, target, targetType))
|
||||
return true;
|
||||
for (ConsumableItemInteraction action : MMOItems.plugin.getStats().getConsumableActions())
|
||||
if (action.handleConsumableEffect(event, playerData, this, target, targetType))
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated Use {@link Consumable#useOnPlayer()}
|
||||
*/
|
||||
@Deprecated
|
||||
public boolean useWithoutItem() {
|
||||
return useOnPlayer() == ConsumableConsumeResult.CONSUME;
|
||||
}
|
||||
/**
|
||||
* @deprecated Use {@link Consumable#useOnPlayer()}
|
||||
*/
|
||||
@Deprecated
|
||||
public boolean useWithoutItem() {
|
||||
return useOnPlayer() == ConsumableConsumeResult.CONSUME;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return If the item should be consumed
|
||||
*/
|
||||
public ConsumableConsumeResult useOnPlayer() {
|
||||
NBTItem nbtItem = getNBTItem();
|
||||
/**
|
||||
* @return If the item should be consumed
|
||||
*/
|
||||
public ConsumableConsumeResult useOnPlayer() {
|
||||
NBTItem nbtItem = getNBTItem();
|
||||
|
||||
// Inedible stat cancels this operation from the beginning
|
||||
if (nbtItem.getBoolean(ItemStats.INEDIBLE.getNBTPath()))
|
||||
return ConsumableConsumeResult.CANCEL;
|
||||
// Inedible stat cancels this operation from the beginning
|
||||
if (nbtItem.getBoolean(ItemStats.INEDIBLE.getNBTPath()))
|
||||
return ConsumableConsumeResult.CANCEL;
|
||||
|
||||
// So a consumable is being consumed, eh
|
||||
ConsumableConsumedEvent event = new ConsumableConsumedEvent(playerData, mmoitem, this);
|
||||
Bukkit.getPluginManager().callEvent(event);
|
||||
if (event.isCancelled())
|
||||
return ConsumableConsumeResult.CANCEL;
|
||||
// So a consumable is being consumed, eh
|
||||
ConsumableConsumedEvent event = new ConsumableConsumedEvent(playerData, mmoitem, this);
|
||||
Bukkit.getPluginManager().callEvent(event);
|
||||
if (event.isCancelled())
|
||||
return ConsumableConsumeResult.CANCEL;
|
||||
|
||||
// Run through all
|
||||
for (PlayerConsumable sc : MMOItems.plugin.getStats().getPlayerConsumables())
|
||||
sc.onConsume(mmoitem, player);
|
||||
// Run through all
|
||||
for (PlayerConsumable sc : MMOItems.plugin.getStats().getPlayerConsumables())
|
||||
sc.onConsume(mmoitem, player);
|
||||
|
||||
/**
|
||||
* If the item does not have a maximum amount of uses, this will always
|
||||
* return 0 and that portion will just skip.
|
||||
*
|
||||
* If the item does have a max amount of uses but it's the last
|
||||
* use, this portion will skip and the item will be consumed anyways.
|
||||
*/
|
||||
int usesLeft = nbtItem.getInteger(ItemStats.MAX_CONSUME.getNBTPath());
|
||||
if (usesLeft > 1) {
|
||||
usesLeft -= 1;
|
||||
nbtItem.addTag(new ItemTag(ItemStats.MAX_CONSUME.getNBTPath(), usesLeft));
|
||||
/**
|
||||
* If the item does not have a maximum amount of uses, this will always
|
||||
* return 0 and that portion will just skip.
|
||||
*
|
||||
* If the item does have a max amount of uses but it's the last
|
||||
* use, this portion will skip and the item will be consumed anyways.
|
||||
*/
|
||||
int usesLeft = nbtItem.getInteger(ItemStats.MAX_CONSUME.getNBTPath());
|
||||
if (usesLeft > 1) {
|
||||
usesLeft -= 1;
|
||||
nbtItem.addTag(new ItemTag(ItemStats.MAX_CONSUME.getNBTPath(), usesLeft));
|
||||
|
||||
/**
|
||||
* This dynamically updates the item lore
|
||||
*/
|
||||
String format = MythicLib.inst().parseColors(MMOItems.plugin.getLanguage().getStatFormat("max-consume"));
|
||||
String old = format.replace("#", "" + (usesLeft + 1));
|
||||
String replaced = format.replace("#", "" + usesLeft);
|
||||
ItemStack newItem = new LoreUpdate(nbtItem.toItem(), old, replaced).updateLore();
|
||||
/**
|
||||
* This dynamically updates the item lore
|
||||
*/
|
||||
String format = MythicLib.inst().parseColors(MMOItems.plugin.getLanguage().getStatFormat("max-consume"));
|
||||
String old = format.replace("#", "" + (usesLeft + 1));
|
||||
String replaced = format.replace("#", "" + usesLeft);
|
||||
ItemStack newItem = new LoreUpdate(nbtItem.toItem(), old, replaced).updateLore();
|
||||
|
||||
/**
|
||||
* This fixes the issue when players right click stacked consumables
|
||||
*/
|
||||
ItemStack oldItem = nbtItem.getItem();
|
||||
if (oldItem.getAmount() > 1) {
|
||||
newItem.setAmount(1);
|
||||
/**
|
||||
* This fixes the issue when players right click stacked consumables
|
||||
*/
|
||||
ItemStack oldItem = nbtItem.getItem();
|
||||
if (oldItem.getAmount() > 1) {
|
||||
newItem.setAmount(1);
|
||||
|
||||
if (player.getInventory().getItemInMainHand().equals(oldItem))
|
||||
player.getInventory().setItemInMainHand(newItem);
|
||||
else if (player.getInventory().getItemInOffHand().equals(oldItem))
|
||||
player.getInventory().setItemInOffHand(newItem);
|
||||
if (player.getInventory().getItemInMainHand().equals(oldItem))
|
||||
player.getInventory().setItemInMainHand(newItem);
|
||||
else if (player.getInventory().getItemInOffHand().equals(oldItem))
|
||||
player.getInventory().setItemInOffHand(newItem);
|
||||
|
||||
oldItem.setAmount(oldItem.getAmount() - 1);
|
||||
new SmartGive(player).give(oldItem);
|
||||
oldItem.setAmount(oldItem.getAmount() - 1);
|
||||
new SmartGive(player).give(oldItem);
|
||||
|
||||
/**
|
||||
* Player just holding one item
|
||||
*/
|
||||
} else {
|
||||
if (player.getInventory().getItemInMainHand().equals(oldItem))
|
||||
player.getInventory().setItemInMainHand(newItem);
|
||||
else if (player.getInventory().getItemInOffHand().equals(oldItem))
|
||||
player.getInventory().setItemInOffHand(newItem);
|
||||
}
|
||||
/**
|
||||
* Player just holding one item
|
||||
*/
|
||||
} else {
|
||||
if (player.getInventory().getItemInMainHand().equals(oldItem))
|
||||
player.getInventory().setItemInMainHand(newItem);
|
||||
else if (player.getInventory().getItemInOffHand().equals(oldItem))
|
||||
player.getInventory().setItemInOffHand(newItem);
|
||||
}
|
||||
|
||||
return ConsumableConsumeResult.NOT_CONSUME;
|
||||
}
|
||||
return ConsumableConsumeResult.NOT_CONSUME;
|
||||
}
|
||||
|
||||
return !event.isConsumed() || nbtItem.getBoolean(ItemStats.DISABLE_RIGHT_CLICK_CONSUME.getNBTPath()) ? ConsumableConsumeResult.NOT_CONSUME : ConsumableConsumeResult.CONSUME;
|
||||
}
|
||||
return !event.isConsumed() || nbtItem.getBoolean(ItemStats.DISABLE_RIGHT_CLICK_CONSUME.getNBTPath()) ? ConsumableConsumeResult.NOT_CONSUME : ConsumableConsumeResult.CONSUME;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return If an item should be eaten not when right clicked, but after
|
||||
* the eating animation. This does check if the item is actually edible
|
||||
*/
|
||||
public boolean hasVanillaEating() {
|
||||
return (getItem().getType().isEdible() || getItem().getType() == Material.POTION || getItem().getType() == Material.MILK_BUCKET)
|
||||
&& getNBTItem().hasTag("MMOITEMS_VANILLA_EATING");
|
||||
}
|
||||
/**
|
||||
* @return If an item should be eaten not when right clicked, but after
|
||||
* the eating animation. This does check if the item is actually edible
|
||||
*/
|
||||
public boolean hasVanillaEating() {
|
||||
return (getItem().getType().isEdible() || getItem().getType() == Material.POTION || getItem().getType() == Material.MILK_BUCKET)
|
||||
&& getNBTItem().hasTag("MMOITEMS_VANILLA_EATING");
|
||||
}
|
||||
|
||||
public static enum ConsumableConsumeResult {
|
||||
public static enum ConsumableConsumeResult {
|
||||
|
||||
/**
|
||||
* No consumable effects or command or cooldowns are applied at all.
|
||||
* <p>
|
||||
* This is also used by non edible consumables.
|
||||
*/
|
||||
CANCEL,
|
||||
/**
|
||||
* No consumable effects or command or cooldowns are applied at all.
|
||||
* <p>
|
||||
* This is also used by non edible consumables.
|
||||
*/
|
||||
CANCEL,
|
||||
|
||||
/**
|
||||
* Consume was a success and the item needs to be removed
|
||||
* from the player's inventory.
|
||||
*/
|
||||
CONSUME,
|
||||
/**
|
||||
* Consume was a success and the item needs to be removed
|
||||
* from the player's inventory.
|
||||
*/
|
||||
CONSUME,
|
||||
|
||||
/**
|
||||
* Consume was a success but the item should not be consumed.
|
||||
* This is used to handle the 'Max Consumes' item stat.
|
||||
* consumables with "Disable right click consume' also use this.
|
||||
* <p>
|
||||
* Using {@link ConsumableConsumedEvent#setConsumed(boolean)}, external plugins can also make it
|
||||
* so the consumable is not consumed but its effects are applied.
|
||||
*/
|
||||
NOT_CONSUME;
|
||||
}
|
||||
/**
|
||||
* Consume was a success but the item should not be consumed.
|
||||
* This is used to handle the 'Max Consumes' item stat.
|
||||
* consumables with "Disable right click consume' also use this.
|
||||
* <p>
|
||||
* Using {@link ConsumableConsumedEvent#setConsumed(boolean)}, external plugins can also make it
|
||||
* so the consumable is not consumed but its effects are applied.
|
||||
*/
|
||||
NOT_CONSUME;
|
||||
}
|
||||
}
|
||||
|
@ -1,64 +1,64 @@
|
||||
package net.Indyuce.mmoitems.api.interaction;
|
||||
|
||||
|
||||
import io.lumine.mythic.lib.MythicLib;
|
||||
import io.lumine.mythic.lib.UtilityMethods;
|
||||
import io.lumine.mythic.lib.api.item.NBTItem;
|
||||
import io.lumine.mythic.lib.comp.flags.CustomFlag;
|
||||
import net.Indyuce.mmoitems.MMOItems;
|
||||
import net.Indyuce.mmoitems.comp.flags.FlagPlugin.CustomFlag;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.Particle;
|
||||
import org.bukkit.Sound;
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.block.BlockFace;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.scheduler.BukkitRunnable;
|
||||
import org.bukkit.util.Vector;
|
||||
|
||||
public class Tool extends UseItem {
|
||||
public Tool(Player player, NBTItem item) {
|
||||
super(player, item);
|
||||
}
|
||||
public Tool(Player player, NBTItem item) {
|
||||
super(player, item);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean checkItemRequirements() {
|
||||
return MMOItems.plugin.getFlags().isFlagAllowed(player, CustomFlag.MI_TOOLS) && playerData.getRPG().canUse(getNBTItem(), true);
|
||||
}
|
||||
@Override
|
||||
public boolean checkItemRequirements() {
|
||||
return MythicLib.plugin.getFlags().isFlagAllowed(player, CustomFlag.MI_TOOLS) && playerData.getRPG().canUse(getNBTItem(), true);
|
||||
}
|
||||
|
||||
public boolean miningEffects(Block block) {
|
||||
boolean cancel = false;
|
||||
|
||||
if (getNBTItem().getBoolean("MMOITEMS_AUTOSMELT"))
|
||||
if (block.getType() == Material.IRON_ORE || block.getType() == Material.GOLD_ORE) {
|
||||
ItemStack item = new ItemStack(Material.valueOf(block.getType().name().replace("_ORE", "_INGOT")));
|
||||
public boolean miningEffects(Block block) {
|
||||
boolean cancel = false;
|
||||
|
||||
UtilityMethods.dropItemNaturally(block.getLocation(), item);
|
||||
block.getWorld().spawnParticle(Particle.CLOUD, block.getLocation().add(.5, .5, .5), 0);
|
||||
block.setType(Material.AIR);
|
||||
cancel = true;
|
||||
}
|
||||
if (getNBTItem().getBoolean("MMOITEMS_AUTOSMELT"))
|
||||
if (block.getType() == Material.IRON_ORE || block.getType() == Material.GOLD_ORE) {
|
||||
ItemStack item = new ItemStack(Material.valueOf(block.getType().name().replace("_ORE", "_INGOT")));
|
||||
|
||||
if (getNBTItem().getBoolean("MMOITEMS_BOUNCING_CRACK"))
|
||||
new BukkitRunnable() {
|
||||
final Vector v = player.getEyeLocation().getDirection().multiply(.5);
|
||||
final Location loc = block.getLocation().clone().add(.5, .5, .5);
|
||||
int j = 0;
|
||||
UtilityMethods.dropItemNaturally(block.getLocation(), item);
|
||||
block.getWorld().spawnParticle(Particle.CLOUD, block.getLocation().add(.5, .5, .5), 0);
|
||||
block.setType(Material.AIR);
|
||||
cancel = true;
|
||||
}
|
||||
|
||||
public void run() {
|
||||
j++;
|
||||
if (j > 10)
|
||||
cancel();
|
||||
if (getNBTItem().getBoolean("MMOITEMS_BOUNCING_CRACK"))
|
||||
new BukkitRunnable() {
|
||||
final Vector v = player.getEyeLocation().getDirection().multiply(.5);
|
||||
final Location loc = block.getLocation().clone().add(.5, .5, .5);
|
||||
int j = 0;
|
||||
|
||||
loc.add(v);
|
||||
Block block = loc.getBlock();
|
||||
if (block.getType() == Material.AIR || MMOItems.plugin.getLanguage().isBlacklisted(block.getType()))
|
||||
return;
|
||||
public void run() {
|
||||
j++;
|
||||
if (j > 10)
|
||||
cancel();
|
||||
|
||||
block.breakNaturally(getItem());
|
||||
loc.getWorld().playSound(loc, Sound.BLOCK_GRAVEL_BREAK, 1, 1);
|
||||
}
|
||||
}.runTaskTimer(MMOItems.plugin, 0, 1);
|
||||
loc.add(v);
|
||||
Block block = loc.getBlock();
|
||||
if (block.getType() == Material.AIR || MMOItems.plugin.getLanguage().isBlacklisted(block.getType()))
|
||||
return;
|
||||
|
||||
block.breakNaturally(getItem());
|
||||
loc.getWorld().playSound(loc, Sound.BLOCK_GRAVEL_BREAK, 1, 1);
|
||||
}
|
||||
}.runTaskTimer(MMOItems.plugin, 0, 1);
|
||||
|
||||
/*if (getNBTItem().hasTag("MMOITEMS_BREAK_SIZE")) {
|
||||
int breakSize = getNBTItem().getInteger("MMOITEMS_BREAK_SIZE");
|
||||
@ -67,6 +67,6 @@ public class Tool extends UseItem {
|
||||
System.out.println("Debug: Facing - " + face);
|
||||
}
|
||||
}*/
|
||||
return cancel;
|
||||
}
|
||||
return cancel;
|
||||
}
|
||||
}
|
||||
|
@ -1,6 +1,8 @@
|
||||
package net.Indyuce.mmoitems.api.interaction;
|
||||
|
||||
import io.lumine.mythic.lib.MythicLib;
|
||||
import io.lumine.mythic.lib.api.item.NBTItem;
|
||||
import io.lumine.mythic.lib.comp.flags.CustomFlag;
|
||||
import net.Indyuce.mmoitems.ItemStats;
|
||||
import net.Indyuce.mmoitems.MMOItems;
|
||||
import net.Indyuce.mmoitems.api.Type;
|
||||
@ -9,7 +11,6 @@ import net.Indyuce.mmoitems.api.interaction.weapon.Weapon;
|
||||
import net.Indyuce.mmoitems.api.interaction.weapon.untargeted.*;
|
||||
import net.Indyuce.mmoitems.api.item.mmoitem.VolatileMMOItem;
|
||||
import net.Indyuce.mmoitems.api.player.PlayerData;
|
||||
import net.Indyuce.mmoitems.comp.flags.FlagPlugin.CustomFlag;
|
||||
import net.Indyuce.mmoitems.stat.data.CommandData;
|
||||
import net.Indyuce.mmoitems.stat.data.CommandListData;
|
||||
import org.bukkit.Bukkit;
|
||||
@ -20,128 +21,128 @@ import org.jetbrains.annotations.NotNull;
|
||||
import java.util.Random;
|
||||
|
||||
public class UseItem {
|
||||
protected final Player player;
|
||||
protected final PlayerData playerData;
|
||||
protected final VolatileMMOItem mmoitem;
|
||||
protected final Player player;
|
||||
protected final PlayerData playerData;
|
||||
protected final VolatileMMOItem mmoitem;
|
||||
|
||||
protected static final Random RANDOM = new Random();
|
||||
protected static final Random RANDOM = new Random();
|
||||
|
||||
public UseItem(Player player, NBTItem nbtItem) {
|
||||
this(PlayerData.get(player), nbtItem);
|
||||
}
|
||||
public UseItem(Player player, NBTItem nbtItem) {
|
||||
this(PlayerData.get(player), nbtItem);
|
||||
}
|
||||
|
||||
public UseItem(PlayerData playerData, NBTItem nbtItem) {
|
||||
this.player = playerData.getPlayer();
|
||||
this.playerData = playerData;
|
||||
this.mmoitem = new VolatileMMOItem(nbtItem);
|
||||
}
|
||||
public UseItem(PlayerData playerData, NBTItem nbtItem) {
|
||||
this.player = playerData.getPlayer();
|
||||
this.playerData = playerData;
|
||||
this.mmoitem = new VolatileMMOItem(nbtItem);
|
||||
}
|
||||
|
||||
public Player getPlayer() {
|
||||
return player;
|
||||
}
|
||||
public Player getPlayer() {
|
||||
return player;
|
||||
}
|
||||
|
||||
public PlayerData getPlayerData() {
|
||||
return playerData;
|
||||
}
|
||||
public PlayerData getPlayerData() {
|
||||
return playerData;
|
||||
}
|
||||
|
||||
public VolatileMMOItem getMMOItem() {
|
||||
return mmoitem;
|
||||
}
|
||||
public VolatileMMOItem getMMOItem() {
|
||||
return mmoitem;
|
||||
}
|
||||
|
||||
public NBTItem getNBTItem() {
|
||||
return mmoitem.getNBT();
|
||||
}
|
||||
public NBTItem getNBTItem() {
|
||||
return mmoitem.getNBT();
|
||||
}
|
||||
|
||||
public ItemStack getItem() {
|
||||
return mmoitem.getNBT().getItem();
|
||||
}
|
||||
public ItemStack getItem() {
|
||||
return mmoitem.getNBT().getItem();
|
||||
}
|
||||
|
||||
/**
|
||||
* Apply item costs and requirements. This method should be overriden to
|
||||
* check for WorldGuard flags as well as the two-handed restriction.
|
||||
*
|
||||
* @return If the item can be used
|
||||
*/
|
||||
public boolean checkItemRequirements() {
|
||||
return playerData.getRPG().canUse(mmoitem.getNBT(), true);
|
||||
}
|
||||
/**
|
||||
* Apply item costs and requirements. This method should be overriden to
|
||||
* check for WorldGuard flags as well as the two-handed restriction.
|
||||
*
|
||||
* @return If the item can be used
|
||||
*/
|
||||
public boolean checkItemRequirements() {
|
||||
return playerData.getRPG().canUse(mmoitem.getNBT(), true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute commands after checking for WG flags;
|
||||
* this does NOT check for the command cooldown.
|
||||
*/
|
||||
public void executeCommands() {
|
||||
if (MMOItems.plugin.getFlags().isFlagAllowed(player, CustomFlag.MI_COMMANDS) && mmoitem.hasData(ItemStats.COMMANDS))
|
||||
((CommandListData) mmoitem.getData(ItemStats.COMMANDS)).getCommands().forEach(this::scheduleCommandExecution);
|
||||
}
|
||||
/**
|
||||
* Execute commands after checking for WG flags;
|
||||
* this does NOT check for the command cooldown.
|
||||
*/
|
||||
public void executeCommands() {
|
||||
if (MythicLib.plugin.getFlags().isFlagAllowed(player, CustomFlag.MI_COMMANDS) && mmoitem.hasData(ItemStats.COMMANDS))
|
||||
((CommandListData) mmoitem.getData(ItemStats.COMMANDS)).getCommands().forEach(this::scheduleCommandExecution);
|
||||
}
|
||||
|
||||
/**
|
||||
* Instantly fires the command if it has no delay
|
||||
* or schedule its execution if it does have some
|
||||
*
|
||||
* @param command Command to execute
|
||||
*/
|
||||
private void scheduleCommandExecution(CommandData command) {
|
||||
String parsed = MMOItems.plugin.getPlaceholderParser().parse(player, command.getCommand());
|
||||
/**
|
||||
* Instantly fires the command if it has no delay
|
||||
* or schedule its execution if it does have some
|
||||
*
|
||||
* @param command Command to execute
|
||||
*/
|
||||
private void scheduleCommandExecution(CommandData command) {
|
||||
String parsed = MMOItems.plugin.getPlaceholderParser().parse(player, command.getCommand());
|
||||
|
||||
if (!command.hasDelay())
|
||||
dispatchCommand(parsed, command.isConsoleCommand(), command.hasOpPerms());
|
||||
else
|
||||
Bukkit.getScheduler().runTaskLater(MMOItems.plugin, () -> dispatchCommand(parsed, command.isConsoleCommand(), command.hasOpPerms()),
|
||||
(long) command.getDelay() * 20);
|
||||
}
|
||||
if (!command.hasDelay())
|
||||
dispatchCommand(parsed, command.isConsoleCommand(), command.hasOpPerms());
|
||||
else
|
||||
Bukkit.getScheduler().runTaskLater(MMOItems.plugin, () -> dispatchCommand(parsed, command.isConsoleCommand(), command.hasOpPerms()),
|
||||
(long) command.getDelay() * 20);
|
||||
}
|
||||
|
||||
/**
|
||||
* Dispatches a command
|
||||
*
|
||||
* @param parsed Command with placeholders already parsed
|
||||
* @param console If the console should dispatch the command, when
|
||||
* set to false the player dispatches it.
|
||||
* @param op Very dangerous option, dispatches the command
|
||||
* as a server administrator
|
||||
*/
|
||||
private void dispatchCommand(String parsed, boolean console, boolean op) {
|
||||
if (console) {
|
||||
Bukkit.dispatchCommand(Bukkit.getConsoleSender(), parsed);
|
||||
return;
|
||||
}
|
||||
/**
|
||||
* Dispatches a command
|
||||
*
|
||||
* @param parsed Command with placeholders already parsed
|
||||
* @param console If the console should dispatch the command, when
|
||||
* set to false the player dispatches it.
|
||||
* @param op Very dangerous option, dispatches the command
|
||||
* as a server administrator
|
||||
*/
|
||||
private void dispatchCommand(String parsed, boolean console, boolean op) {
|
||||
if (console) {
|
||||
Bukkit.dispatchCommand(Bukkit.getConsoleSender(), parsed);
|
||||
return;
|
||||
}
|
||||
|
||||
if (op && !player.isOp()) {
|
||||
player.setOp(true);
|
||||
try {
|
||||
Bukkit.dispatchCommand(player, parsed);
|
||||
} catch (Exception ignored) {
|
||||
player.setOp(false);
|
||||
} finally {
|
||||
player.setOp(false);
|
||||
}
|
||||
} else
|
||||
Bukkit.dispatchCommand(player, parsed);
|
||||
}
|
||||
if (op && !player.isOp()) {
|
||||
player.setOp(true);
|
||||
try {
|
||||
Bukkit.dispatchCommand(player, parsed);
|
||||
} catch (Exception ignored) {
|
||||
player.setOp(false);
|
||||
} finally {
|
||||
player.setOp(false);
|
||||
}
|
||||
} else
|
||||
Bukkit.dispatchCommand(player, parsed);
|
||||
}
|
||||
|
||||
public static UseItem getItem(Player player, NBTItem item, String type) {
|
||||
return getItem(player, item, Type.get(type));
|
||||
}
|
||||
public static UseItem getItem(Player player, NBTItem item, String type) {
|
||||
return getItem(player, item, Type.get(type));
|
||||
}
|
||||
|
||||
public static UseItem getItem(@NotNull Player player, @NotNull NBTItem item, @NotNull Type type) {
|
||||
if (type.corresponds(Type.CONSUMABLE))
|
||||
return new Consumable(player, item);
|
||||
if (type.corresponds(Type.SKIN))
|
||||
return new ItemSkin(player, item);
|
||||
if (type.corresponds(Type.GEM_STONE))
|
||||
return new GemStone(player, item);
|
||||
if (type.corresponds(Type.MUSKET))
|
||||
return new Musket(player, item);
|
||||
if (type.corresponds(Type.CROSSBOW))
|
||||
return new Crossbow(player, item);
|
||||
if (type.corresponds(Type.GAUNTLET))
|
||||
return new Gauntlet(player, item);
|
||||
if (type.corresponds(Type.WHIP))
|
||||
return new Whip(player, item);
|
||||
if (type.corresponds(Type.LUTE))
|
||||
return new Lute(player, item);
|
||||
if (type.corresponds(Type.STAFF))
|
||||
return new Staff(player, item);
|
||||
return type.isWeapon() ? new Weapon(player, item) : new UseItem(player, item);
|
||||
}
|
||||
public static UseItem getItem(@NotNull Player player, @NotNull NBTItem item, @NotNull Type type) {
|
||||
if (type.corresponds(Type.CONSUMABLE))
|
||||
return new Consumable(player, item);
|
||||
if (type.corresponds(Type.SKIN))
|
||||
return new ItemSkin(player, item);
|
||||
if (type.corresponds(Type.GEM_STONE))
|
||||
return new GemStone(player, item);
|
||||
if (type.corresponds(Type.MUSKET))
|
||||
return new Musket(player, item);
|
||||
if (type.corresponds(Type.CROSSBOW))
|
||||
return new Crossbow(player, item);
|
||||
if (type.corresponds(Type.GAUNTLET))
|
||||
return new Gauntlet(player, item);
|
||||
if (type.corresponds(Type.WHIP))
|
||||
return new Whip(player, item);
|
||||
if (type.corresponds(Type.LUTE))
|
||||
return new Lute(player, item);
|
||||
if (type.corresponds(Type.STAFF))
|
||||
return new Staff(player, item);
|
||||
return type.isWeapon() ? new Weapon(player, item) : new UseItem(player, item);
|
||||
}
|
||||
}
|
||||
|
@ -1,15 +1,14 @@
|
||||
package net.Indyuce.mmoitems.api.interaction.weapon;
|
||||
|
||||
import io.lumine.mythic.lib.MythicLib;
|
||||
import io.lumine.mythic.lib.api.item.NBTItem;
|
||||
import io.lumine.mythic.lib.comp.flags.CustomFlag;
|
||||
import net.Indyuce.mmoitems.ItemStats;
|
||||
import net.Indyuce.mmoitems.MMOItems;
|
||||
import net.Indyuce.mmoitems.api.ItemAttackMetadata;
|
||||
import net.Indyuce.mmoitems.api.interaction.UseItem;
|
||||
import net.Indyuce.mmoitems.api.player.PlayerData;
|
||||
import net.Indyuce.mmoitems.api.player.PlayerData.CooldownType;
|
||||
import net.Indyuce.mmoitems.api.util.message.Message;
|
||||
import net.Indyuce.mmoitems.comp.flags.FlagPlugin;
|
||||
import net.Indyuce.mmoitems.comp.flags.FlagPlugin.CustomFlag;
|
||||
import org.bukkit.ChatColor;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.entity.LivingEntity;
|
||||
@ -18,102 +17,96 @@ import org.bukkit.entity.Player;
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
public class Weapon extends UseItem {
|
||||
public Weapon(Player player, NBTItem item) {
|
||||
this(PlayerData.get(player), item);
|
||||
}
|
||||
public Weapon(Player player, NBTItem item) {
|
||||
this(PlayerData.get(player), item);
|
||||
}
|
||||
|
||||
public Weapon(PlayerData playerData, NBTItem item) {
|
||||
super(playerData, item);
|
||||
}
|
||||
public Weapon(PlayerData playerData, NBTItem item) {
|
||||
super(playerData, item);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean checkItemRequirements() {
|
||||
if (playerData.areHandsFull()) {
|
||||
Message.HANDS_TOO_CHARGED.format(ChatColor.RED).send(getPlayer());
|
||||
return false;
|
||||
}
|
||||
@Override
|
||||
public boolean checkItemRequirements() {
|
||||
if (playerData.areHandsFull()) {
|
||||
Message.HANDS_TOO_CHARGED.format(ChatColor.RED).send(getPlayer());
|
||||
return false;
|
||||
}
|
||||
|
||||
// Check for class, level...
|
||||
boolean asCanUse = playerData.getRPG().canUse(getNBTItem(), true);
|
||||
// Check for class, level... then flags
|
||||
return playerData.getRPG().canUse(getNBTItem(), true) && MythicLib.plugin.getFlags().isFlagAllowed(getPlayer(), CustomFlag.MI_WEAPONS);
|
||||
}
|
||||
|
||||
// Check for flags
|
||||
FlagPlugin flagPlugin = MMOItems.plugin.getFlags();
|
||||
boolean asFlagAllowed = flagPlugin == null || flagPlugin.isFlagAllowed(getPlayer(), CustomFlag.MI_WEAPONS);
|
||||
/**
|
||||
* Only applies mana and stamina weapon costs
|
||||
*
|
||||
* @return If the attack was cast successfully
|
||||
*/
|
||||
public boolean applyWeaponCosts() {
|
||||
return applyWeaponCosts(0, null);
|
||||
}
|
||||
|
||||
return asCanUse && asFlagAllowed;
|
||||
}
|
||||
/**
|
||||
* Applies cooldown, mana and stamina weapon costs
|
||||
*
|
||||
* @param attackSpeed The weapon attack speed
|
||||
* @param cooldown The weapon cooldown type. When set to null, no
|
||||
* cooldown will be applied. This is made to handle
|
||||
* @return If requirements were met ie the attack was cast successfully
|
||||
*/
|
||||
public boolean applyWeaponCosts(double attackSpeed, @Nullable CooldownType cooldown) {
|
||||
if (cooldown != null && getPlayerData().isOnCooldown(cooldown))
|
||||
return false;
|
||||
|
||||
/**
|
||||
* Only applies mana and stamina weapon costs
|
||||
*
|
||||
* @return If the attack was cast successfully
|
||||
*/
|
||||
public boolean applyWeaponCosts() {
|
||||
return applyWeaponCosts(0, null);
|
||||
}
|
||||
double manaCost = getNBTItem().getStat("MANA_COST");
|
||||
if (manaCost > 0 && playerData.getRPG().getMana() < manaCost) {
|
||||
Message.NOT_ENOUGH_MANA.format(ChatColor.RED).send(getPlayer());
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Applies cooldown, mana and stamina weapon costs
|
||||
*
|
||||
* @param attackSpeed The weapon attack speed
|
||||
* @param cooldown The weapon cooldown type. When set to null, no
|
||||
* cooldown will be applied. This is made to handle
|
||||
* @return If requirements were met ie the attack was cast successfully
|
||||
*/
|
||||
public boolean applyWeaponCosts(double attackSpeed, @Nullable CooldownType cooldown) {
|
||||
if (cooldown != null && getPlayerData().isOnCooldown(cooldown))
|
||||
return false;
|
||||
double staminaCost = getNBTItem().getStat("STAMINA_COST");
|
||||
if (staminaCost > 0 && playerData.getRPG().getStamina() < staminaCost) {
|
||||
Message.NOT_ENOUGH_STAMINA.format(ChatColor.RED).send(getPlayer());
|
||||
return false;
|
||||
}
|
||||
|
||||
double manaCost = getNBTItem().getStat("MANA_COST");
|
||||
if (manaCost > 0 && playerData.getRPG().getMana() < manaCost) {
|
||||
Message.NOT_ENOUGH_MANA.format(ChatColor.RED).send(getPlayer());
|
||||
return false;
|
||||
}
|
||||
if (manaCost > 0)
|
||||
playerData.getRPG().giveMana(-manaCost);
|
||||
|
||||
double staminaCost = getNBTItem().getStat("STAMINA_COST");
|
||||
if (staminaCost > 0 && playerData.getRPG().getStamina() < staminaCost) {
|
||||
Message.NOT_ENOUGH_STAMINA.format(ChatColor.RED).send(getPlayer());
|
||||
return false;
|
||||
}
|
||||
if (staminaCost > 0)
|
||||
playerData.getRPG().giveStamina(-staminaCost);
|
||||
|
||||
if (manaCost > 0)
|
||||
playerData.getRPG().giveMana(-manaCost);
|
||||
if (cooldown != null)
|
||||
getPlayerData().applyCooldown(cooldown, attackSpeed);
|
||||
|
||||
if (staminaCost > 0)
|
||||
playerData.getRPG().giveStamina(-staminaCost);
|
||||
return true;
|
||||
}
|
||||
|
||||
if (cooldown != null)
|
||||
getPlayerData().applyCooldown(cooldown, attackSpeed);
|
||||
public ItemAttackMetadata handleTargetedAttack(ItemAttackMetadata attackMeta, LivingEntity target) {
|
||||
|
||||
return true;
|
||||
}
|
||||
// Handle weapon cooldown, mana and stamina costs
|
||||
double attackSpeed = getNBTItem().getStat(ItemStats.ATTACK_SPEED.getId());
|
||||
attackSpeed = attackSpeed == 0 ? 1.493 : 1 / attackSpeed;
|
||||
if (!applyWeaponCosts())
|
||||
return attackMeta.setSuccessful(false);
|
||||
|
||||
public ItemAttackMetadata handleTargetedAttack(ItemAttackMetadata attackMeta, LivingEntity target) {
|
||||
// Handle item set attack effects
|
||||
if (getMMOItem().getType().getItemSet().hasAttackEffect() && !getNBTItem().getBoolean("MMOITEMS_DISABLE_ATTACK_PASSIVE"))
|
||||
getMMOItem().getType().getItemSet().applyAttackEffect(attackMeta, target, this);
|
||||
|
||||
// Handle weapon cooldown, mana and stamina costs
|
||||
double attackSpeed = getNBTItem().getStat(ItemStats.ATTACK_SPEED.getId());
|
||||
attackSpeed = attackSpeed == 0 ? 1.493 : 1 / attackSpeed;
|
||||
if (!applyWeaponCosts())
|
||||
return attackMeta.setSuccessful(false);
|
||||
return attackMeta;
|
||||
}
|
||||
|
||||
// Handle item set attack effects
|
||||
if (getMMOItem().getType().getItemSet().hasAttackEffect() && !getNBTItem().getBoolean("MMOITEMS_DISABLE_ATTACK_PASSIVE"))
|
||||
getMMOItem().getType().getItemSet().applyAttackEffect(attackMeta, target, this);
|
||||
protected Location getGround(Location loc) {
|
||||
for (int j = 0; j < 20; j++) {
|
||||
if (loc.getBlock().getType().isSolid())
|
||||
return loc;
|
||||
loc.add(0, -1, 0);
|
||||
}
|
||||
return loc;
|
||||
}
|
||||
|
||||
return attackMeta;
|
||||
}
|
||||
|
||||
protected Location getGround(Location loc) {
|
||||
for (int j = 0; j < 20; j++) {
|
||||
if (loc.getBlock().getType().isSolid())
|
||||
return loc;
|
||||
loc.add(0, -1, 0);
|
||||
}
|
||||
return loc;
|
||||
}
|
||||
|
||||
// returns default getValue if stat equals 0
|
||||
public double getValue(double a, double def) {
|
||||
return a <= 0 ? def : a;
|
||||
}
|
||||
// returns default getValue if stat equals 0
|
||||
public double getValue(double a, double def) {
|
||||
return a <= 0 ? def : a;
|
||||
}
|
||||
}
|
||||
|
@ -4,6 +4,7 @@ import com.google.gson.JsonObject;
|
||||
import io.lumine.mythic.lib.MythicLib;
|
||||
import io.lumine.mythic.lib.api.item.NBTItem;
|
||||
import io.lumine.mythic.lib.api.stat.StatMap;
|
||||
import io.lumine.mythic.lib.comp.target.InteractionType;
|
||||
import io.lumine.mythic.lib.damage.DamageMetadata;
|
||||
import io.lumine.mythic.lib.damage.DamageType;
|
||||
import io.lumine.mythic.lib.version.VersionSound;
|
||||
@ -101,7 +102,7 @@ public class Lute extends UntargetedWeapon {
|
||||
}
|
||||
|
||||
for (Entity target : entities)
|
||||
if (MMOUtils.canDamage(getPlayer(), loc, target)) {
|
||||
if (MMOUtils.canTarget(getPlayer(), loc, target, InteractionType.OFFENSE_ACTION)) {
|
||||
attackMeta.applyEffectsAndDamage(getNBTItem(), (LivingEntity) target);
|
||||
cancel();
|
||||
return;
|
||||
|
@ -4,6 +4,7 @@ import io.lumine.mythic.lib.MythicLib;
|
||||
import io.lumine.mythic.lib.api.MMORayTraceResult;
|
||||
import io.lumine.mythic.lib.api.item.NBTItem;
|
||||
import io.lumine.mythic.lib.api.stat.StatMap;
|
||||
import io.lumine.mythic.lib.comp.target.InteractionType;
|
||||
import io.lumine.mythic.lib.damage.DamageMetadata;
|
||||
import io.lumine.mythic.lib.damage.DamageType;
|
||||
import net.Indyuce.mmoitems.ItemStats;
|
||||
@ -57,7 +58,7 @@ public class Musket extends UntargetedWeapon {
|
||||
Vector vec = loc.getDirection();
|
||||
|
||||
MMORayTraceResult trace = MythicLib.plugin.getVersion().getWrapper().rayTrace(stats.getPlayer(), vec, range,
|
||||
entity -> MMOUtils.canDamage(stats.getPlayer(), entity));
|
||||
entity -> MMOUtils.canTarget(stats.getPlayer(), entity, InteractionType.OFFENSE_ACTION));
|
||||
if (trace.hasHit()) {
|
||||
ItemAttackMetadata attackMeta = new ItemAttackMetadata(new DamageMetadata(attackDamage, DamageType.WEAPON, DamageType.PROJECTILE, DamageType.PHYSICAL), stats);
|
||||
attackMeta.applyEffectsAndDamage(getNBTItem(), trace.getHit());
|
||||
|
@ -4,6 +4,7 @@ import io.lumine.mythic.lib.MythicLib;
|
||||
import io.lumine.mythic.lib.api.MMORayTraceResult;
|
||||
import io.lumine.mythic.lib.api.item.NBTItem;
|
||||
import io.lumine.mythic.lib.api.stat.StatMap;
|
||||
import io.lumine.mythic.lib.comp.target.InteractionType;
|
||||
import io.lumine.mythic.lib.damage.DamageMetadata;
|
||||
import io.lumine.mythic.lib.damage.DamageType;
|
||||
import io.lumine.mythic.lib.version.VersionSound;
|
||||
@ -59,7 +60,7 @@ public class Staff extends UntargetedWeapon {
|
||||
Location loc = getPlayer().getEyeLocation().add(new Vector(Math.cos(a), 0, Math.sin(a)).multiply(.5));
|
||||
|
||||
MMORayTraceResult trace = MythicLib.plugin.getVersion().getWrapper().rayTrace(stats.getPlayer(), range,
|
||||
entity -> MMOUtils.canDamage(stats.getPlayer(), entity));
|
||||
entity -> MMOUtils.canTarget(stats.getPlayer(), entity, InteractionType.OFFENSE_ACTION));
|
||||
if (trace.hasHit())
|
||||
attackMeta.applyEffectsAndDamage(getNBTItem(), trace.getHit());
|
||||
trace.draw(loc, getPlayer().getEyeLocation().getDirection(), 2,
|
||||
|
@ -4,6 +4,7 @@ import io.lumine.mythic.lib.MythicLib;
|
||||
import io.lumine.mythic.lib.api.MMORayTraceResult;
|
||||
import io.lumine.mythic.lib.api.item.NBTItem;
|
||||
import io.lumine.mythic.lib.api.stat.StatMap;
|
||||
import io.lumine.mythic.lib.comp.target.InteractionType;
|
||||
import io.lumine.mythic.lib.damage.DamageMetadata;
|
||||
import io.lumine.mythic.lib.damage.DamageType;
|
||||
import io.lumine.mythic.lib.version.VersionSound;
|
||||
@ -46,7 +47,7 @@ public class Whip extends UntargetedWeapon {
|
||||
Location loc = getPlayer().getEyeLocation().add(new Vector(Math.cos(a), 0, Math.sin(a)).multiply(.5));
|
||||
|
||||
MMORayTraceResult trace = MythicLib.plugin.getVersion().getWrapper().rayTrace(stats.getPlayer(), range,
|
||||
entity -> MMOUtils.canDamage(stats.getPlayer(), entity));
|
||||
entity -> MMOUtils.canTarget(stats.getPlayer(), entity, InteractionType.OFFENSE_ACTION));
|
||||
if (trace.hasHit())
|
||||
new ItemAttackMetadata(new DamageMetadata(attackDamage, DamageType.WEAPON, DamageType.PROJECTILE, DamageType.PHYSICAL), stats).applyEffects(getNBTItem(), trace.getHit());
|
||||
trace.draw(loc, getPlayer().getEyeLocation().getDirection(), 2,
|
||||
|
@ -3,6 +3,7 @@ package net.Indyuce.mmoitems.api.interaction.weapon.untargeted.lute;
|
||||
import com.google.gson.JsonObject;
|
||||
import io.lumine.mythic.lib.MythicLib;
|
||||
import io.lumine.mythic.lib.api.item.NBTItem;
|
||||
import io.lumine.mythic.lib.comp.target.InteractionType;
|
||||
import io.lumine.mythic.lib.damage.DamageMetadata;
|
||||
import io.lumine.mythic.lib.damage.DamageType;
|
||||
import net.Indyuce.mmoitems.MMOItems;
|
||||
@ -21,53 +22,53 @@ import java.util.List;
|
||||
|
||||
public class BruteLuteAttack implements LuteAttackHandler {
|
||||
|
||||
@Override
|
||||
public void handle(ItemAttackMetadata attack, NBTItem nbt, double attackDamage, double range, Vector weight, SoundReader sound) {
|
||||
new BukkitRunnable() {
|
||||
final Vector vec = attack.getDamager().getEyeLocation().getDirection().multiply(.4);
|
||||
final Location loc = attack.getDamager().getEyeLocation();
|
||||
int ti = 0;
|
||||
@Override
|
||||
public void handle(ItemAttackMetadata attack, NBTItem nbt, double attackDamage, double range, Vector weight, SoundReader sound) {
|
||||
new BukkitRunnable() {
|
||||
final Vector vec = attack.getDamager().getEyeLocation().getDirection().multiply(.4);
|
||||
final Location loc = attack.getDamager().getEyeLocation();
|
||||
int ti = 0;
|
||||
|
||||
public void run() {
|
||||
if (ti++ > range)
|
||||
cancel();
|
||||
public void run() {
|
||||
if (ti++ > range)
|
||||
cancel();
|
||||
|
||||
List<Entity> entities = MMOUtils.getNearbyChunkEntities(loc);
|
||||
for (int j = 0; j < 3; j++) {
|
||||
loc.add(vec.add(weight));
|
||||
if (loc.getBlock().getType().isSolid()) {
|
||||
cancel();
|
||||
break;
|
||||
}
|
||||
List<Entity> entities = MMOUtils.getNearbyChunkEntities(loc);
|
||||
for (int j = 0; j < 3; j++) {
|
||||
loc.add(vec.add(weight));
|
||||
if (loc.getBlock().getType().isSolid()) {
|
||||
cancel();
|
||||
break;
|
||||
}
|
||||
|
||||
if (nbt.hasTag("MMOITEMS_PROJECTILE_PARTICLES")) {
|
||||
JsonObject obj = MythicLib.plugin.getJson().parse(nbt.getString("MMOITEMS_PROJECTILE_PARTICLES"), JsonObject.class);
|
||||
Particle particle = Particle.valueOf(obj.get("Particle").getAsString());
|
||||
// If the selected particle is colored, use the provided color
|
||||
if (ProjectileParticlesData.isColorable(particle)) {
|
||||
double red = Double.parseDouble(String.valueOf(obj.get("Red")));
|
||||
double green = Double.parseDouble(String.valueOf(obj.get("Green")));
|
||||
double blue = Double.parseDouble(String.valueOf(obj.get("Blue")));
|
||||
ProjectileParticlesData.shootParticle(attack.getDamager(), particle, loc, red, green, blue);
|
||||
// If it's not colored, just shoot the particle
|
||||
} else {
|
||||
ProjectileParticlesData.shootParticle(attack.getDamager(), particle, loc, 0, 0, 0);
|
||||
}
|
||||
// If no particle has been provided via projectile particle attribute, default to this particle
|
||||
} else
|
||||
loc.getWorld().spawnParticle(Particle.NOTE, loc, 2, .1, .1, .1, 0);
|
||||
if (nbt.hasTag("MMOITEMS_PROJECTILE_PARTICLES")) {
|
||||
JsonObject obj = MythicLib.plugin.getJson().parse(nbt.getString("MMOITEMS_PROJECTILE_PARTICLES"), JsonObject.class);
|
||||
Particle particle = Particle.valueOf(obj.get("Particle").getAsString());
|
||||
// If the selected particle is colored, use the provided color
|
||||
if (ProjectileParticlesData.isColorable(particle)) {
|
||||
double red = Double.parseDouble(String.valueOf(obj.get("Red")));
|
||||
double green = Double.parseDouble(String.valueOf(obj.get("Green")));
|
||||
double blue = Double.parseDouble(String.valueOf(obj.get("Blue")));
|
||||
ProjectileParticlesData.shootParticle(attack.getDamager(), particle, loc, red, green, blue);
|
||||
// If it's not colored, just shoot the particle
|
||||
} else {
|
||||
ProjectileParticlesData.shootParticle(attack.getDamager(), particle, loc, 0, 0, 0);
|
||||
}
|
||||
// If no particle has been provided via projectile particle attribute, default to this particle
|
||||
} else
|
||||
loc.getWorld().spawnParticle(Particle.NOTE, loc, 2, .1, .1, .1, 0);
|
||||
|
||||
if (j == 0) sound.play(loc, 2, (float) (.5 + (double) ti / range));
|
||||
if (j == 0) sound.play(loc, 2, (float) (.5 + (double) ti / range));
|
||||
|
||||
for (Entity target : entities)
|
||||
if (MMOUtils.canDamage(attack.getDamager(), loc, target)) {
|
||||
new ItemAttackMetadata(new DamageMetadata(attackDamage, DamageType.WEAPON, DamageType.PHYSICAL, DamageType.PROJECTILE), attack.getStats()).applyEffectsAndDamage(nbt, (LivingEntity) target);
|
||||
cancel();
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}.runTaskTimer(MMOItems.plugin, 0, 1);
|
||||
}
|
||||
for (Entity target : entities)
|
||||
if (MMOUtils.canTarget(attack.getDamager(), loc, target, InteractionType.OFFENSE_ACTION)) {
|
||||
new ItemAttackMetadata(new DamageMetadata(attackDamage, DamageType.WEAPON, DamageType.PHYSICAL, DamageType.PROJECTILE), attack.getStats()).applyEffectsAndDamage(nbt, (LivingEntity) target);
|
||||
cancel();
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}.runTaskTimer(MMOItems.plugin, 0, 1);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -3,6 +3,7 @@ package net.Indyuce.mmoitems.api.interaction.weapon.untargeted.lute;
|
||||
import com.google.gson.JsonObject;
|
||||
import io.lumine.mythic.lib.MythicLib;
|
||||
import io.lumine.mythic.lib.api.item.NBTItem;
|
||||
import io.lumine.mythic.lib.comp.target.InteractionType;
|
||||
import io.lumine.mythic.lib.damage.DamageMetadata;
|
||||
import io.lumine.mythic.lib.damage.DamageType;
|
||||
import net.Indyuce.mmoitems.MMOItems;
|
||||
@ -67,7 +68,7 @@ public class CircularLuteAttack implements LuteAttackHandler {
|
||||
if (j == 0) sound.play(loc, 2, (float) (.5 + (double) ti / range));
|
||||
|
||||
for (Entity target : entities)
|
||||
if (MMOUtils.canDamage(attack.getDamager(), loc, target)) {
|
||||
if (MMOUtils.canTarget(attack.getDamager(), loc, target, InteractionType.OFFENSE_ACTION)) {
|
||||
new ItemAttackMetadata(new DamageMetadata(attackDamage, DamageType.WEAPON, DamageType.PROJECTILE), attack.getStats()).applyEffectsAndDamage(nbt, (LivingEntity) target);
|
||||
cancel();
|
||||
return;
|
||||
|
@ -3,6 +3,7 @@ package net.Indyuce.mmoitems.api.interaction.weapon.untargeted.lute;
|
||||
import com.google.gson.JsonObject;
|
||||
import io.lumine.mythic.lib.MythicLib;
|
||||
import io.lumine.mythic.lib.api.item.NBTItem;
|
||||
import io.lumine.mythic.lib.comp.target.InteractionType;
|
||||
import io.lumine.mythic.lib.damage.DamageMetadata;
|
||||
import io.lumine.mythic.lib.damage.DamageType;
|
||||
import net.Indyuce.mmoitems.MMOItems;
|
||||
@ -60,7 +61,7 @@ public class SimpleLuteAttack implements LuteAttackHandler {
|
||||
if (j == 0) sound.play(loc, 2, (float) (.5 + (double) ti / range));
|
||||
|
||||
for (Entity target : entities)
|
||||
if (MMOUtils.canDamage(attack.getDamager(), loc, target)) {
|
||||
if (MMOUtils.canTarget(attack.getDamager(), loc, target, InteractionType.OFFENSE_ACTION)) {
|
||||
new ItemAttackMetadata(new DamageMetadata(attackDamage, DamageType.WEAPON, DamageType.PROJECTILE), attack.getStats()).applyEffectsAndDamage(nbt, (LivingEntity) target);
|
||||
cancel();
|
||||
return;
|
||||
|
@ -3,6 +3,7 @@ package net.Indyuce.mmoitems.api.interaction.weapon.untargeted.lute;
|
||||
import com.google.gson.JsonObject;
|
||||
import io.lumine.mythic.lib.MythicLib;
|
||||
import io.lumine.mythic.lib.api.item.NBTItem;
|
||||
import io.lumine.mythic.lib.comp.target.InteractionType;
|
||||
import io.lumine.mythic.lib.damage.DamageMetadata;
|
||||
import io.lumine.mythic.lib.damage.DamageType;
|
||||
import net.Indyuce.mmoitems.MMOItems;
|
||||
@ -58,7 +59,7 @@ public class SlashLuteAttack implements LuteAttackHandler {
|
||||
}.runTaskTimer(MMOItems.plugin, 0, 1);
|
||||
|
||||
for (Entity entity : MMOUtils.getNearbyChunkEntities(attack.getDamager().getLocation()))
|
||||
if (entity.getLocation().distanceSquared(attack.getDamager().getLocation()) < 40 && attack.getDamager().getEyeLocation().getDirection().angle(entity.getLocation().toVector().subtract(attack.getDamager().getLocation().toVector())) < Math.PI / 6 && MMOUtils.canDamage(attack.getDamager(), entity))
|
||||
if (entity.getLocation().distanceSquared(attack.getDamager().getLocation()) < 40 && attack.getDamager().getEyeLocation().getDirection().angle(entity.getLocation().toVector().subtract(attack.getDamager().getLocation().toVector())) < Math.PI / 6 && MMOUtils.canTarget(attack.getDamager(), entity, InteractionType.OFFENSE_ACTION))
|
||||
new ItemAttackMetadata(new DamageMetadata(attackDamage, DamageType.WEAPON, DamageType.PROJECTILE), attack.getStats()).applyEffectsAndDamage(nbt, (LivingEntity) entity);
|
||||
}
|
||||
}
|
||||
|
@ -3,6 +3,7 @@ package net.Indyuce.mmoitems.api.interaction.weapon.untargeted.lute;
|
||||
import com.google.gson.JsonObject;
|
||||
import io.lumine.mythic.lib.MythicLib;
|
||||
import io.lumine.mythic.lib.api.item.NBTItem;
|
||||
import io.lumine.mythic.lib.comp.target.InteractionType;
|
||||
import io.lumine.mythic.lib.damage.DamageMetadata;
|
||||
import io.lumine.mythic.lib.damage.DamageType;
|
||||
import net.Indyuce.mmoitems.MMOItems;
|
||||
@ -65,7 +66,7 @@ public class WaveLuteAttack implements LuteAttackHandler {
|
||||
if (j == 0) sound.play(loc, 2, (float) (.5 + (double) ti / range));
|
||||
|
||||
for (Entity target : entities)
|
||||
if (MMOUtils.canDamage(attack.getDamager(), loc, target)) {
|
||||
if (MMOUtils.canTarget(attack.getDamager(), loc, target, InteractionType.OFFENSE_ACTION)) {
|
||||
new ItemAttackMetadata(new DamageMetadata(attackDamage, DamageType.WEAPON, DamageType.PROJECTILE), attack.getStats()).applyEffectsAndDamage(nbt, (LivingEntity) target);
|
||||
cancel();
|
||||
return;
|
||||
|
@ -3,6 +3,7 @@ package net.Indyuce.mmoitems.api.interaction.weapon.untargeted.staff;
|
||||
import io.lumine.mythic.lib.MythicLib;
|
||||
import io.lumine.mythic.lib.api.MMORayTraceResult;
|
||||
import io.lumine.mythic.lib.api.item.NBTItem;
|
||||
import io.lumine.mythic.lib.comp.target.InteractionType;
|
||||
import io.lumine.mythic.lib.version.VersionSound;
|
||||
import net.Indyuce.mmoitems.MMOUtils;
|
||||
import net.Indyuce.mmoitems.api.ItemAttackMetadata;
|
||||
@ -17,7 +18,7 @@ public class LightningSpirit implements StaffAttackHandler {
|
||||
|
||||
Location loc = attackMeta.getDamager().getEyeLocation();
|
||||
MMORayTraceResult trace = MythicLib.plugin.getVersion().getWrapper().rayTrace(attackMeta.getDamager(), range,
|
||||
entity -> MMOUtils.canDamage(attackMeta.getDamager(), entity));
|
||||
entity -> MMOUtils.canTarget(attackMeta.getDamager(), entity, InteractionType.OFFENSE_ACTION));
|
||||
if (trace.hasHit())
|
||||
attackMeta.applyEffects(nbt, trace.getHit());
|
||||
trace.draw(loc, attackMeta.getDamager().getEyeLocation().getDirection(), 2,
|
||||
|
@ -1,6 +1,7 @@
|
||||
package net.Indyuce.mmoitems.api.interaction.weapon.untargeted.staff;
|
||||
|
||||
import io.lumine.mythic.lib.api.item.NBTItem;
|
||||
import io.lumine.mythic.lib.comp.target.InteractionType;
|
||||
import net.Indyuce.mmoitems.MMOItems;
|
||||
import net.Indyuce.mmoitems.MMOUtils;
|
||||
import net.Indyuce.mmoitems.api.ItemAttackMetadata;
|
||||
@ -45,7 +46,7 @@ public class ManaSpirit implements StaffAttackHandler {
|
||||
loc.getWorld().spawnParticle(Particle.REDSTONE, loc.clone().add(vec), 1, new Particle.DustOptions(Color.AQUA, 1));
|
||||
}
|
||||
for (Entity target : targets)
|
||||
if (MMOUtils.canDamage(attackMeta.getDamager(), loc, target)) {
|
||||
if (MMOUtils.canTarget(attackMeta.getDamager(), loc, target, InteractionType.OFFENSE_ACTION)) {
|
||||
attackMeta.applyEffects(nbt, (LivingEntity) target);
|
||||
loc.getWorld().spawnParticle(Particle.EXPLOSION_LARGE, loc, 0);
|
||||
cancel();
|
||||
|
@ -1,6 +1,7 @@
|
||||
package net.Indyuce.mmoitems.api.interaction.weapon.untargeted.staff;
|
||||
|
||||
import io.lumine.mythic.lib.api.item.NBTItem;
|
||||
import io.lumine.mythic.lib.comp.target.InteractionType;
|
||||
import net.Indyuce.mmoitems.MMOItems;
|
||||
import net.Indyuce.mmoitems.MMOUtils;
|
||||
import net.Indyuce.mmoitems.api.ItemAttackMetadata;
|
||||
@ -16,37 +17,37 @@ import java.util.List;
|
||||
|
||||
public class NetherSpirit implements StaffAttackHandler {
|
||||
|
||||
@Override
|
||||
public void handle(ItemAttackMetadata attackMeta, NBTItem nbt, double attackDamage, double range) {
|
||||
new BukkitRunnable() {
|
||||
final Vector vec = attackMeta.getDamager().getEyeLocation().getDirection().multiply(.3);
|
||||
final Location loc = attackMeta.getDamager().getEyeLocation();
|
||||
int ti = 0;
|
||||
@Override
|
||||
public void handle(ItemAttackMetadata attackMeta, NBTItem nbt, double attackDamage, double range) {
|
||||
new BukkitRunnable() {
|
||||
final Vector vec = attackMeta.getDamager().getEyeLocation().getDirection().multiply(.3);
|
||||
final Location loc = attackMeta.getDamager().getEyeLocation();
|
||||
int ti = 0;
|
||||
|
||||
public void run() {
|
||||
if (ti++ % 2 == 0)
|
||||
loc.getWorld().playSound(loc, Sound.BLOCK_FIRE_AMBIENT, 2, 2);
|
||||
List<Entity> targets = MMOUtils.getNearbyChunkEntities(loc);
|
||||
for (int j = 0; j < 3; j++) {
|
||||
loc.add(vec);
|
||||
if (loc.getBlock().getType().isSolid()) {
|
||||
cancel();
|
||||
break;
|
||||
}
|
||||
public void run() {
|
||||
if (ti++ % 2 == 0)
|
||||
loc.getWorld().playSound(loc, Sound.BLOCK_FIRE_AMBIENT, 2, 2);
|
||||
List<Entity> targets = MMOUtils.getNearbyChunkEntities(loc);
|
||||
for (int j = 0; j < 3; j++) {
|
||||
loc.add(vec);
|
||||
if (loc.getBlock().getType().isSolid()) {
|
||||
cancel();
|
||||
break;
|
||||
}
|
||||
|
||||
loc.getWorld().spawnParticle(Particle.FLAME, loc, 2, .07, .07, .07, 0);
|
||||
loc.getWorld().spawnParticle(Particle.SMOKE_NORMAL, loc, 0);
|
||||
for (Entity target : targets)
|
||||
if (MMOUtils.canDamage(attackMeta.getDamager(), loc, target)) {
|
||||
attackMeta.applyEffects(nbt, (LivingEntity) target);
|
||||
loc.getWorld().spawnParticle(Particle.EXPLOSION_LARGE, loc, 0);
|
||||
cancel();
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (ti >= range)
|
||||
cancel();
|
||||
}
|
||||
}.runTaskTimer(MMOItems.plugin, 0, 1);
|
||||
}
|
||||
loc.getWorld().spawnParticle(Particle.FLAME, loc, 2, .07, .07, .07, 0);
|
||||
loc.getWorld().spawnParticle(Particle.SMOKE_NORMAL, loc, 0);
|
||||
for (Entity target : targets)
|
||||
if (MMOUtils.canTarget(attackMeta.getDamager(), loc, target, InteractionType.OFFENSE_ACTION)) {
|
||||
attackMeta.applyEffects(nbt, (LivingEntity) target);
|
||||
loc.getWorld().spawnParticle(Particle.EXPLOSION_LARGE, loc, 0);
|
||||
cancel();
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (ti >= range)
|
||||
cancel();
|
||||
}
|
||||
}.runTaskTimer(MMOItems.plugin, 0, 1);
|
||||
}
|
||||
}
|
||||
|
@ -1,6 +1,7 @@
|
||||
package net.Indyuce.mmoitems.api.interaction.weapon.untargeted.staff;
|
||||
|
||||
import io.lumine.mythic.lib.api.item.NBTItem;
|
||||
import io.lumine.mythic.lib.comp.target.InteractionType;
|
||||
import io.lumine.mythic.lib.version.VersionSound;
|
||||
import net.Indyuce.mmoitems.MMOItems;
|
||||
import net.Indyuce.mmoitems.MMOUtils;
|
||||
@ -37,7 +38,7 @@ public class SunfireSpirit implements StaffAttackHandler {
|
||||
loc.getWorld().spawnParticle(Particle.EXPLOSION_LARGE, loc, 0);
|
||||
loc.getWorld().playSound(loc, VersionSound.ENTITY_FIREWORK_ROCKET_BLAST.toSound(), 2, 2);
|
||||
for (Entity target : MMOUtils.getNearbyChunkEntities(loc))
|
||||
if (MMOUtils.canDamage(attackMeta.getDamager(), target) && target.getLocation().distanceSquared(loc) <= 9)
|
||||
if (MMOUtils.canTarget(attackMeta.getDamager(), target, InteractionType.OFFENSE_ACTION) && target.getLocation().distanceSquared(loc) <= 9)
|
||||
attackMeta.applyEffectsAndDamage(nbt, (LivingEntity) target);
|
||||
cancel();
|
||||
break;
|
||||
|
@ -1,6 +1,7 @@
|
||||
package net.Indyuce.mmoitems.api.interaction.weapon.untargeted.staff;
|
||||
|
||||
import io.lumine.mythic.lib.api.item.NBTItem;
|
||||
import io.lumine.mythic.lib.comp.target.InteractionType;
|
||||
import io.lumine.mythic.lib.version.VersionSound;
|
||||
import net.Indyuce.mmoitems.MMOItems;
|
||||
import net.Indyuce.mmoitems.MMOUtils;
|
||||
@ -35,7 +36,7 @@ public class ThunderSpirit implements StaffAttackHandler {
|
||||
loc.getWorld().spawnParticle(Particle.FIREWORKS_SPARK, loc, 24, 0, 0, 0, .12);
|
||||
loc.getWorld().playSound(loc, VersionSound.ENTITY_FIREWORK_ROCKET_BLAST.toSound(), 2, 2);
|
||||
for (Entity target : MMOUtils.getNearbyChunkEntities(loc))
|
||||
if (MMOUtils.canDamage(attackMeta.getDamager(), target) && target.getLocation().distanceSquared(loc) <= 9)
|
||||
if (MMOUtils.canTarget(attackMeta.getDamager(), target, InteractionType.OFFENSE_ACTION) && target.getLocation().distanceSquared(loc) <= 9)
|
||||
attackMeta.applyEffectsAndDamage(nbt, (LivingEntity) target);
|
||||
cancel();
|
||||
}
|
||||
|
@ -3,6 +3,7 @@ package net.Indyuce.mmoitems.api.interaction.weapon.untargeted.staff;
|
||||
import io.lumine.mythic.lib.MythicLib;
|
||||
import io.lumine.mythic.lib.api.MMORayTraceResult;
|
||||
import io.lumine.mythic.lib.api.item.NBTItem;
|
||||
import io.lumine.mythic.lib.comp.target.InteractionType;
|
||||
import net.Indyuce.mmoitems.MMOUtils;
|
||||
import net.Indyuce.mmoitems.api.ItemAttackMetadata;
|
||||
import org.bukkit.Color;
|
||||
@ -19,7 +20,7 @@ public class XRaySpirit implements StaffAttackHandler {
|
||||
double a = Math.toRadians(attackMeta.getDamager().getEyeLocation().getYaw() + 160);
|
||||
Location loc = attackMeta.getDamager().getEyeLocation().add(new Vector(Math.cos(a), 0, Math.sin(a)).multiply(.5));
|
||||
|
||||
MMORayTraceResult trace = MythicLib.plugin.getVersion().getWrapper().rayTrace(attackMeta.getDamager(), range, entity -> MMOUtils.canDamage(attackMeta.getDamager(), entity));
|
||||
MMORayTraceResult trace = MythicLib.plugin.getVersion().getWrapper().rayTrace(attackMeta.getDamager(), range, entity -> MMOUtils.canTarget(attackMeta.getDamager(), entity, InteractionType.OFFENSE_ACTION));
|
||||
if (trace.hasHit())
|
||||
attackMeta.applyEffectsAndDamage(nbt, trace.getHit());
|
||||
trace.draw(loc, attackMeta.getDamager().getEyeLocation().getDirection(), 2, Color.BLACK);
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -1,21 +0,0 @@
|
||||
package net.Indyuce.mmoitems.comp.flags;
|
||||
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
public class DefaultFlags implements FlagPlugin {
|
||||
@Override
|
||||
public boolean isPvpAllowed(Location loc) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isFlagAllowed(Player player, CustomFlag flag) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isFlagAllowed(Location loc, CustomFlag flag) {
|
||||
return true;
|
||||
}
|
||||
}
|
@ -1,24 +0,0 @@
|
||||
package net.Indyuce.mmoitems.comp.flags;
|
||||
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
public interface FlagPlugin {
|
||||
boolean isPvpAllowed(Location loc);
|
||||
|
||||
boolean isFlagAllowed(Player player, CustomFlag flag);
|
||||
|
||||
boolean isFlagAllowed(Location loc, CustomFlag flag);
|
||||
|
||||
enum CustomFlag {
|
||||
MI_ABILITIES,
|
||||
MI_WEAPONS,
|
||||
MI_COMMANDS,
|
||||
MI_CONSUMABLES,
|
||||
MI_TOOLS;
|
||||
|
||||
public String getPath() {
|
||||
return name().toLowerCase().replace("_", "-");
|
||||
}
|
||||
}
|
||||
}
|
@ -1,35 +0,0 @@
|
||||
package net.Indyuce.mmoitems.comp.flags;
|
||||
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import com.bekvon.bukkit.residence.Residence;
|
||||
import com.bekvon.bukkit.residence.containers.Flags;
|
||||
import com.bekvon.bukkit.residence.protection.ClaimedResidence;
|
||||
import com.bekvon.bukkit.residence.protection.FlagPermissions;
|
||||
|
||||
public class ResidenceFlags implements FlagPlugin {
|
||||
public ResidenceFlags() {
|
||||
for (CustomFlag flag : CustomFlag.values())
|
||||
FlagPermissions.addFlag(flag.getPath());
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isPvpAllowed(Location loc) {
|
||||
ClaimedResidence res = Residence.getInstance().getResidenceManager().getByLoc(loc);
|
||||
return res == null || res.getPermissions().has(Flags.pvp, true);
|
||||
}
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
@Override
|
||||
public boolean isFlagAllowed(Player player, CustomFlag flag) {
|
||||
ClaimedResidence res = Residence.getInstance().getResidenceManager().getByLoc(player);
|
||||
return res == null || res.getPermissions().playerHas(player, flag.getPath(), true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isFlagAllowed(Location loc, CustomFlag flag) {
|
||||
ClaimedResidence res = Residence.getInstance().getResidenceManager().getByLoc(loc);
|
||||
return res == null || res.getPermissions().has(flag.getPath(), true, true);
|
||||
}
|
||||
}
|
@ -1,58 +0,0 @@
|
||||
package net.Indyuce.mmoitems.comp.flags;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import com.sk89q.worldedit.bukkit.BukkitAdapter;
|
||||
import com.sk89q.worldguard.WorldGuard;
|
||||
import com.sk89q.worldguard.bukkit.WorldGuardPlugin;
|
||||
import com.sk89q.worldguard.protection.ApplicableRegionSet;
|
||||
import com.sk89q.worldguard.protection.flags.Flags;
|
||||
import com.sk89q.worldguard.protection.flags.StateFlag;
|
||||
import com.sk89q.worldguard.protection.flags.registry.FlagRegistry;
|
||||
|
||||
import net.Indyuce.mmoitems.MMOItems;
|
||||
|
||||
public class WorldGuardFlags implements FlagPlugin {
|
||||
private final WorldGuard worldguard;
|
||||
private final WorldGuardPlugin worldguardPlugin;
|
||||
private final Map<String, StateFlag> flags = new HashMap<>();
|
||||
|
||||
public WorldGuardFlags() {
|
||||
this.worldguard = WorldGuard.getInstance();
|
||||
this.worldguardPlugin = ((WorldGuardPlugin) MMOItems.plugin.getServer().getPluginManager().getPlugin("WorldGuard"));
|
||||
|
||||
FlagRegistry registry = worldguard.getFlagRegistry();
|
||||
for (CustomFlag customFlag : CustomFlag.values()) {
|
||||
StateFlag flag = new StateFlag(customFlag.getPath(), true);
|
||||
try {
|
||||
registry.register(flag);
|
||||
flags.put(customFlag.getPath(), flag);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isPvpAllowed(Location loc) {
|
||||
return getApplicableRegion(loc).queryState(null, Flags.PVP) != StateFlag.State.DENY;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isFlagAllowed(Location loc, CustomFlag customFlag) {
|
||||
return getApplicableRegion(loc).queryValue(null, flags.get(customFlag.getPath())) != StateFlag.State.DENY;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isFlagAllowed(Player player, CustomFlag customFlag) {
|
||||
return getApplicableRegion(player.getLocation()).queryValue(worldguardPlugin.wrapPlayer(player), flags.get(customFlag.getPath())) != StateFlag.State.DENY;
|
||||
}
|
||||
|
||||
private ApplicableRegionSet getApplicableRegion(Location loc) {
|
||||
return worldguard.getPlatform().getRegionContainer().createQuery().getApplicableRegions(BukkitAdapter.adapt(loc));
|
||||
}
|
||||
}
|
@ -5,14 +5,13 @@ import io.lumine.mythic.lib.api.util.AltChar;
|
||||
import io.lumine.mythic.lib.version.VersionMaterial;
|
||||
import net.Indyuce.mmocore.MMOCore;
|
||||
import net.Indyuce.mmocore.api.block.BlockType;
|
||||
import net.Indyuce.mmocore.api.droptable.condition.Condition;
|
||||
import net.Indyuce.mmocore.api.droptable.dropitem.DropItem;
|
||||
import net.Indyuce.mmocore.api.load.MMOLoader;
|
||||
import net.Indyuce.mmocore.api.quest.objective.Objective;
|
||||
import net.Indyuce.mmocore.api.quest.trigger.Trigger;
|
||||
import net.Indyuce.mmocore.experience.Profession;
|
||||
import net.Indyuce.mmocore.experience.provider.ExperienceDispenser;
|
||||
import net.Indyuce.mmocore.experience.source.type.ExperienceSource;
|
||||
import net.Indyuce.mmocore.loot.droptable.condition.Condition;
|
||||
import net.Indyuce.mmocore.loot.droptable.dropitem.DropItem;
|
||||
import net.Indyuce.mmoitems.MMOItems;
|
||||
import net.Indyuce.mmoitems.api.block.CustomBlock;
|
||||
import net.Indyuce.mmoitems.api.crafting.ConditionalDisplay;
|
||||
|
@ -3,7 +3,7 @@ package net.Indyuce.mmoitems.comp.mmocore.load;
|
||||
import org.apache.commons.lang.Validate;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
|
||||
import net.Indyuce.mmocore.api.droptable.dropitem.DropItem;
|
||||
import net.Indyuce.mmocore.loot.droptable.dropitem.DropItem;
|
||||
import net.Indyuce.mmoitems.MMOItems;
|
||||
import net.Indyuce.mmoitems.api.ItemTier;
|
||||
import net.Indyuce.mmoitems.api.item.build.MMOItemBuilder;
|
||||
|
@ -5,7 +5,7 @@ import net.Indyuce.mmoitems.api.player.PlayerData;
|
||||
import org.apache.commons.lang.Validate;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
|
||||
import net.Indyuce.mmocore.api.loot.LootBuilder;
|
||||
import net.Indyuce.mmocore.loot.LootBuilder;
|
||||
import net.Indyuce.mmoitems.MMOItems;
|
||||
import net.Indyuce.mmoitems.api.Type;
|
||||
import net.Indyuce.mmoitems.api.item.mmoitem.MMOItem;
|
||||
|
@ -7,7 +7,7 @@ import net.Indyuce.mmoitems.api.player.PlayerData;
|
||||
import org.apache.commons.lang.Validate;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
|
||||
import net.Indyuce.mmocore.api.loot.LootBuilder;
|
||||
import net.Indyuce.mmocore.loot.LootBuilder;
|
||||
import net.Indyuce.mmoitems.MMOItems;
|
||||
import net.Indyuce.mmoitems.api.Type;
|
||||
import net.Indyuce.mmoitems.api.item.mmoitem.MMOItem;
|
||||
|
@ -4,6 +4,7 @@ import io.lumine.mythic.lib.MythicLib;
|
||||
import io.lumine.mythic.lib.api.item.NBTItem;
|
||||
import io.lumine.mythic.lib.api.player.EquipmentSlot;
|
||||
import io.lumine.mythic.lib.api.stat.StatMap;
|
||||
import io.lumine.mythic.lib.comp.target.InteractionType;
|
||||
import io.lumine.mythic.lib.damage.DamageMetadata;
|
||||
import io.lumine.mythic.lib.damage.DamageType;
|
||||
import net.Indyuce.mmoitems.MMOItems;
|
||||
@ -194,7 +195,7 @@ public class ItemUse implements Listener {
|
||||
return;
|
||||
|
||||
LivingEntity target = (LivingEntity) event.getRightClicked();
|
||||
if (!MMOUtils.canDamage(player, target))
|
||||
if (!MMOUtils.canTarget(player, target, InteractionType.OFFENSE_ACTION))
|
||||
return;
|
||||
|
||||
UseItem weapon = UseItem.getItem(player, item, item.getType());
|
||||
|
@ -34,141 +34,141 @@ import java.util.Iterator;
|
||||
import java.util.Map;
|
||||
|
||||
public class PlayerListener implements Listener {
|
||||
private final Map<Player, ArrayList<ItemStack>> deathItems = new HashMap<>();
|
||||
private final Map<Player, ArrayList<ItemStack>> deathItems = new HashMap<>();
|
||||
|
||||
@EventHandler
|
||||
public void loadPlayerData(PlayerJoinEvent event) {
|
||||
MMOItems.plugin.getRecipes().refreshRecipeBook(event.getPlayer());
|
||||
PlayerData.load(event.getPlayer());
|
||||
}
|
||||
@EventHandler
|
||||
public void loadPlayerData(PlayerJoinEvent event) {
|
||||
MMOItems.plugin.getRecipes().refreshRecipeBook(event.getPlayer());
|
||||
PlayerData.load(event.getPlayer());
|
||||
}
|
||||
|
||||
@EventHandler(priority = EventPriority.HIGH)
|
||||
public void savePlayerData(PlayerQuitEvent event) {
|
||||
PlayerData.get(event.getPlayer()).save();
|
||||
}
|
||||
@EventHandler(priority = EventPriority.HIGH)
|
||||
public void savePlayerData(PlayerQuitEvent event) {
|
||||
PlayerData.get(event.getPlayer()).save();
|
||||
}
|
||||
|
||||
@EventHandler(priority = EventPriority.HIGH, ignoreCancelled = true)
|
||||
public void castWhenHitAbilities(EntityDamageByEntityEvent event) {
|
||||
if (!(event.getEntity() instanceof Player) || event.getEntity().hasMetadata("NPC"))
|
||||
return;
|
||||
@EventHandler(priority = EventPriority.HIGH, ignoreCancelled = true)
|
||||
public void castWhenHitAbilities(EntityDamageByEntityEvent event) {
|
||||
if (!(event.getEntity() instanceof Player) || event.getEntity().hasMetadata("NPC"))
|
||||
return;
|
||||
|
||||
LivingEntity damager = MMOUtils.getDamager(event);
|
||||
if (damager == null)
|
||||
return;
|
||||
LivingEntity damager = MMOUtils.getDamager(event);
|
||||
if (damager == null)
|
||||
return;
|
||||
|
||||
Player player = (Player) event.getEntity();
|
||||
PlayerData.get(player).castAbilities(damager, CastingMode.WHEN_HIT);
|
||||
}
|
||||
Player player = (Player) event.getEntity();
|
||||
PlayerData.get(player).castAbilities(damager, CastingMode.WHEN_HIT);
|
||||
}
|
||||
|
||||
@EventHandler(priority = EventPriority.LOW)
|
||||
public void castClickAbilities(PlayerInteractEvent event) {
|
||||
if (event.getAction() == Action.PHYSICAL)
|
||||
return;
|
||||
@EventHandler(priority = EventPriority.LOW)
|
||||
public void castClickAbilities(PlayerInteractEvent event) {
|
||||
if (event.getAction() == Action.PHYSICAL)
|
||||
return;
|
||||
|
||||
Player player = event.getPlayer();
|
||||
boolean left = event.getAction() == Action.LEFT_CLICK_AIR || event.getAction() == Action.LEFT_CLICK_BLOCK;
|
||||
CastingMode castMode = player.isSneaking() ? (left ? CastingMode.SHIFT_LEFT_CLICK : CastingMode.SHIFT_RIGHT_CLICK) : (left ? CastingMode.LEFT_CLICK : CastingMode.RIGHT_CLICK);
|
||||
PlayerData.get(player).castAbilities(null, castMode);
|
||||
}
|
||||
Player player = event.getPlayer();
|
||||
boolean left = event.getAction() == Action.LEFT_CLICK_AIR || event.getAction() == Action.LEFT_CLICK_BLOCK;
|
||||
CastingMode castMode = player.isSneaking() ? (left ? CastingMode.SHIFT_LEFT_CLICK : CastingMode.SHIFT_RIGHT_CLICK) : (left ? CastingMode.LEFT_CLICK : CastingMode.RIGHT_CLICK);
|
||||
PlayerData.get(player).castAbilities(null, castMode);
|
||||
}
|
||||
|
||||
/*
|
||||
* Prevent players from dropping items which are bound to them with a
|
||||
* soulbound. Items are cached inside a map waiting for the player to
|
||||
* respawn. If he does not respawn the items are dropped on the ground, this
|
||||
* way there don't get lost
|
||||
*/
|
||||
@EventHandler(priority = EventPriority.HIGH)
|
||||
public void onDeath(PlayerDeathEvent event) {
|
||||
if (event.getKeepInventory() || !MMOItems.plugin.getLanguage().keepSoulboundOnDeath)
|
||||
return;
|
||||
/*
|
||||
* Prevent players from dropping items which are bound to them with a
|
||||
* soulbound. Items are cached inside a map waiting for the player to
|
||||
* respawn. If he does not respawn the items are dropped on the ground, this
|
||||
* way there don't get lost
|
||||
*/
|
||||
@EventHandler(priority = EventPriority.HIGH)
|
||||
public void onDeath(PlayerDeathEvent event) {
|
||||
if (event.getKeepInventory() || !MMOItems.plugin.getLanguage().keepSoulboundOnDeath)
|
||||
return;
|
||||
|
||||
Player player = event.getEntity();
|
||||
SoulboundInfo soulboundInfo = new SoulboundInfo(player);
|
||||
Player player = event.getEntity();
|
||||
SoulboundInfo soulboundInfo = new SoulboundInfo(player);
|
||||
|
||||
Iterator<ItemStack> iterator = event.getDrops().iterator();
|
||||
while (iterator.hasNext()) {
|
||||
ItemStack item = iterator.next();
|
||||
NBTItem nbt = NBTItem.get(item);
|
||||
Iterator<ItemStack> iterator = event.getDrops().iterator();
|
||||
while (iterator.hasNext()) {
|
||||
ItemStack item = iterator.next();
|
||||
NBTItem nbt = NBTItem.get(item);
|
||||
|
||||
if (nbt.hasTag("MMOITEMS_DISABLE_DEATH_DROP") && nbt.getBoolean("MMOITEMS_DISABLE_DEATH_DROP")) {
|
||||
iterator.remove();
|
||||
if (!deathItems.containsKey(player))
|
||||
deathItems.put(player, new ArrayList<>());
|
||||
if (nbt.hasTag("MMOITEMS_DISABLE_DEATH_DROP") && nbt.getBoolean("MMOITEMS_DISABLE_DEATH_DROP")) {
|
||||
iterator.remove();
|
||||
if (!deathItems.containsKey(player))
|
||||
deathItems.put(player, new ArrayList<>());
|
||||
|
||||
deathItems.get(player).add(item);
|
||||
}
|
||||
deathItems.get(player).add(item);
|
||||
}
|
||||
|
||||
/*
|
||||
* not a perfect check but it's very sufficient and so we avoid
|
||||
* using a JsonParser followed by map checkups in the SoulboundData
|
||||
* constructor
|
||||
*/
|
||||
else if (nbt.hasTag("MMOITEMS_SOULBOUND") && nbt.getString("MMOITEMS_SOULBOUND").contains(player.getUniqueId().toString())) {
|
||||
iterator.remove();
|
||||
soulboundInfo.add(item);
|
||||
}
|
||||
}
|
||||
/*
|
||||
* not a perfect check but it's very sufficient and so we avoid
|
||||
* using a JsonParser followed by map checkups in the SoulboundData
|
||||
* constructor
|
||||
*/
|
||||
else if (nbt.hasTag("MMOITEMS_SOULBOUND") && nbt.getString("MMOITEMS_SOULBOUND").contains(player.getUniqueId().toString())) {
|
||||
iterator.remove();
|
||||
soulboundInfo.add(item);
|
||||
}
|
||||
}
|
||||
|
||||
if (soulboundInfo.hasItems())
|
||||
soulboundInfo.setup();
|
||||
}
|
||||
if (soulboundInfo.hasItems())
|
||||
soulboundInfo.setup();
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void onRespawn(PlayerRespawnEvent event) {
|
||||
Player player = event.getPlayer();
|
||||
@EventHandler
|
||||
public void onRespawn(PlayerRespawnEvent event) {
|
||||
Player player = event.getPlayer();
|
||||
|
||||
if (MMOItems.plugin.getLanguage().keepSoulboundOnDeath)
|
||||
SoulboundInfo.read(player);
|
||||
if (MMOItems.plugin.getLanguage().keepSoulboundOnDeath)
|
||||
SoulboundInfo.read(player);
|
||||
|
||||
if (deathItems.containsKey(player)) {
|
||||
Schedulers.sync().runLater( () -> {
|
||||
player.getInventory().addItem(deathItems.get(player).toArray(new ItemStack[0]));
|
||||
deathItems.remove(player);
|
||||
}, 10);
|
||||
}
|
||||
}
|
||||
if (deathItems.containsKey(player)) {
|
||||
Schedulers.sync().runLater(() -> {
|
||||
player.getInventory().addItem(deathItems.get(player).toArray(new ItemStack[0]));
|
||||
deathItems.remove(player);
|
||||
}, 10);
|
||||
}
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void onArmorEquip(ArmorEquipEvent event) {
|
||||
Player p = event.getPlayer();
|
||||
RPGPlayer rpgPlayer = PlayerData.get(p.getUniqueId()).getRPG();
|
||||
NBTItem item = NBTItem.get(event.getNewArmorPiece());
|
||||
@EventHandler
|
||||
public void onArmorEquip(ArmorEquipEvent event) {
|
||||
Player p = event.getPlayer();
|
||||
RPGPlayer rpgPlayer = PlayerData.get(p.getUniqueId()).getRPG();
|
||||
NBTItem item = NBTItem.get(event.getNewArmorPiece());
|
||||
|
||||
if (!rpgPlayer.canUse(item, true))
|
||||
event.setCancelled(true);
|
||||
}
|
||||
if (!rpgPlayer.canUse(item, true))
|
||||
event.setCancelled(true);
|
||||
}
|
||||
|
||||
@EventHandler(ignoreCancelled = true)
|
||||
public void registerTridents(ProjectileLaunchEvent event) {
|
||||
if (!(event.getEntity() instanceof Trident) || !(event.getEntity().getShooter() instanceof Player))
|
||||
return;
|
||||
@EventHandler(ignoreCancelled = true)
|
||||
public void registerTridents(ProjectileLaunchEvent event) {
|
||||
if (!(event.getEntity() instanceof Trident) || !(event.getEntity().getShooter() instanceof Player))
|
||||
return;
|
||||
|
||||
InteractItem item = new InteractItem((Player) event.getEntity().getShooter(), Material.TRIDENT);
|
||||
if (!item.hasItem())
|
||||
return;
|
||||
InteractItem item = new InteractItem((Player) event.getEntity().getShooter(), Material.TRIDENT);
|
||||
if (!item.hasItem())
|
||||
return;
|
||||
|
||||
NBTItem nbtItem = MythicLib.plugin.getVersion().getWrapper().getNBTItem(item.getItem());
|
||||
Type type = Type.get(nbtItem.getType());
|
||||
PlayerData playerData = PlayerData.get((Player) event.getEntity().getShooter());
|
||||
NBTItem nbtItem = MythicLib.plugin.getVersion().getWrapper().getNBTItem(item.getItem());
|
||||
Type type = Type.get(nbtItem.getType());
|
||||
PlayerData playerData = PlayerData.get((Player) event.getEntity().getShooter());
|
||||
|
||||
if (type != null) {
|
||||
Weapon weapon = new Weapon(playerData, nbtItem);
|
||||
if (!weapon.checkItemRequirements() || !weapon.applyWeaponCosts()) {
|
||||
event.setCancelled(true);
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (type != null) {
|
||||
Weapon weapon = new Weapon(playerData, nbtItem);
|
||||
if (!weapon.checkItemRequirements() || !weapon.applyWeaponCosts()) {
|
||||
event.setCancelled(true);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
MMOItems.plugin.getEntities().registerCustomProjectile(nbtItem, playerData.getStats().newTemporary(EquipmentSlot.fromBukkit(item.getSlot())), event.getEntity(), type != null);
|
||||
}
|
||||
MMOItems.plugin.getEntities().registerCustomProjectile(nbtItem, playerData.getStats().newTemporary(EquipmentSlot.fromBukkit(item.getSlot())), event.getEntity(), type != null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Fixes an issue where
|
||||
* @param event
|
||||
*/
|
||||
@EventHandler
|
||||
public void registerInventoryUpdates(PlayerSwapHandItemsEvent event) {
|
||||
PlayerData playerData = PlayerData.get(event.getPlayer());
|
||||
playerData.updateInventory();
|
||||
}
|
||||
/**
|
||||
* Fixes an issue where quickly swapping items in hand just
|
||||
* does not update the player's inventory which can make the
|
||||
* player cast abilities or attacks with not the correct stats
|
||||
*/
|
||||
@EventHandler
|
||||
public void registerInventoryUpdates(PlayerSwapHandItemsEvent event) {
|
||||
PlayerData.get(event.getPlayer()).updateInventory();
|
||||
}
|
||||
}
|
@ -194,9 +194,6 @@ two-handed-item-restriction: true
|
||||
# the item ability cooldown progress bar.
|
||||
cooldown-progress-bar-char: █
|
||||
|
||||
# When toggled off, players can't damage each other using item abilities.
|
||||
ability-player-damage: true
|
||||
|
||||
# Displays a message on the action bar instead of on the chat.
|
||||
# Can be used to reduce chat spam.
|
||||
# Might interfere with other action bar plugins.
|
||||
|
Loading…
Reference in New Issue
Block a user