Custom item types commit 3

This commit is contained in:
Jules 2024-01-29 03:06:07 +01:00
parent eba4b3ff80
commit d9b2f2ab43
20 changed files with 192 additions and 447 deletions

View File

@ -51,10 +51,14 @@ public class ItemStats {
DISABLE_ENCHANTING = new DisableStat("ENCHANTING", VersionMaterial.ENCHANTING_TABLE.toMaterial(), "Disable Enchanting", new String[]{"!block", "all"}, "Players can't enchant this item."),
DISABLE_REPAIRING = new DisableStat("REPAIRING", Material.ANVIL, "Disable Repairing", new String[]{"!block", "all"}, "Players can't use this item in anvils."),
DISABLE_ARROW_SHOOTING = new DisableStat("ARROW_SHOOTING", Material.ARROW, "Disable Arrow Shooting", new Material[]{Material.ARROW}, "Players can't shoot this", "item using a bow."),
DISABLE_ATTACK_PASSIVE = new DisableStat("ATTACK_PASSIVE", Material.BARRIER, "Disable Attack Passive", new String[]{"piercing", "slashing", "blunt"}, "Disables the blunt/slashing/piercing", "passive effects on attacks."),
DISABLE_DROP = new DisableStat("DROPING", Material.LAVA_BUCKET, "Disable Item Dropping", new String[]{"all"}, "Disables the dropping of this item!"),
DISABLE_ARROW_CONSUMPTION = new DisableStat("ARROW_CONSUMPTION", Material.ARROW, "Disable Arrow Consumption", new String[]{"crossbow"}, "Disable arrow requirement and consumption."),
// Special item interactions/skills
LEFT_CLICK_SCRIPT = new ActionLeftClick(),
RIGHT_CLICK_SCRIPT = new ActionRightClick(),
DISABLE_ATTACK_PASSIVE = new DisableStat("ATTACK_PASSIVE", Material.BARRIER, "Disable On-Hit Effect", new String[]{"weapon"}, "Disables on-hit effects granted by the item type."),
// RPG Stats
REQUIRED_LEVEL = new RequiredLevel(),
REQUIRED_CLASS = new RequiredClass(),
@ -74,11 +78,11 @@ public class ItemStats {
COOLDOWN_REDUCTION = new DoubleStat("COOLDOWN_REDUCTION", Material.BOOK, "Cooldown Reduction", new String[]{"Reduces cooldowns of item and player skills (%)."}),
RANGE = new DoubleStat("RANGE", Material.STICK, "Range", new String[]{"The range of your item attacks."}, new String[]{"staff", "whip", "wand", "musket", "gem_stone"}),
MANA_COST = new ManaCost(),
STAMINA_COST = new DoubleStat("STAMINA_COST", VersionMaterial.LIGHT_GRAY_DYE.toMaterial(), "Stamina Cost", new String[]{"Stamina spent by your weapon to be used."}, new String[]{"piercing", "slashing", "blunt", "range"}),
STAMINA_COST = new DoubleStat("STAMINA_COST", VersionMaterial.LIGHT_GRAY_DYE.toMaterial(), "Stamina Cost", new String[]{"Stamina spent by your weapon to be used."}, new String[]{"weapon"}),
ARROW_VELOCITY = new DoubleStat("ARROW_VELOCITY", Material.ARROW, "Arrow Velocity", new String[]{"Determines how far your", "weapon can shoot.", "Default: 1.0"}, new String[]{"gem_stone", "bow", "crossbow"}),
ARROW_POTION_EFFECTS = new ArrowPotionEffects(),
PVE_DAMAGE = new DoubleStat("PVE_DAMAGE", VersionMaterial.PORKCHOP.toMaterial(), "PvE Damage", new String[]{"Additional damage against", "non human entities in %."}, new String[]{"piercing", "slashing", "blunt", "catalyst", "range", "tool", "armor", "gem_stone", "accessory"}),
PVP_DAMAGE = new DoubleStat("PVP_DAMAGE", VersionMaterial.SKELETON_SKULL.toMaterial(), "PvP Damage", new String[]{"Additional damage", "against players in %."}, new String[]{"piercing", "slashing", "blunt", "catalyst", "range", "tool", "armor", "gem_stone", "accessory"}),
PVE_DAMAGE = new DoubleStat("PVE_DAMAGE", VersionMaterial.PORKCHOP.toMaterial(), "PvE Damage", new String[]{"Additional damage against", "non human entities in %."}, new String[]{"weapon", "catalyst", "tool", "armor", "gem_stone", "accessory"}),
PVP_DAMAGE = new DoubleStat("PVP_DAMAGE", VersionMaterial.SKELETON_SKULL.toMaterial(), "PvP Damage", new String[]{"Additional damage", "against players in %."}, new String[]{"weapon", "catalyst", "tool", "armor", "gem_stone", "accessory"}),
BLUNT_POWER = new DoubleStat("BLUNT_POWER", Material.IRON_AXE, "Blunt Power", new String[]{"The radius of the AoE attack.", "If set to 2.0, enemies within 2 blocks", "around your target will take damage."}, new String[]{"blunt", "gem_stone"}),
BLUNT_RATING = new DoubleStat("BLUNT_RATING", Material.BRICK, "Blunt Rating", new String[]{"The force of the blunt attack.", "If set to 50%, enemies hit by the attack", "will take 50% of the initial damage."}, new String[]{"blunt", "gem_stone"}),
WEAPON_DAMAGE = new DoubleStat("WEAPON_DAMAGE", Material.IRON_SWORD, "Weapon Damage", new String[]{"Additional on-hit weapon damage in %."}),
@ -110,7 +114,7 @@ public class ItemStats {
MAX_MANA = new DoubleStat("MAX_MANA", VersionMaterial.LAPIS_LAZULI.toMaterial(), "Max Mana", new String[]{"Adds mana to your max mana bar."}),
KNOCKBACK_RESISTANCE = new KnockbackResistance(),
MOVEMENT_SPEED = new MovementSpeed(),
TWO_HANDED = new BooleanStat("TWO_HANDED", Material.IRON_INGOT, "Two Handed", new String[]{"If set to true, a player will be", "significantly slower if holding two", "items, one being Two Handed."}, new String[]{"piercing", "slashing", "blunt", "catalyst", "range", "tool"}),
TWO_HANDED = new BooleanStat("TWO_HANDED", Material.IRON_INGOT, "Two Handed", new String[]{"If set to true, a player will be", "significantly slower if holding two", "items, one being Two Handed."}, new String[]{"weapon", "catalyst", "tool"}),
REQUIRED_BIOMES = new RequiredBiomes(),
DROP_ON_DEATH = new DisableDeathDrop(),
DURABILITY_BAR = new DurabilityBar(),
@ -154,8 +158,8 @@ public class ItemStats {
CUSTOM_SOUNDS = new CustomSounds(),
ELEMENTS = new Elements(),
COMMANDS = new Commands(),
// STAFF_SPIRIT = new StaffSpiritStat(),
LUTE_ATTACK_SOUND = new LuteAttackSoundStat(),
// STAFF_SPIRIT = new StaffSpiritStat(),
LUTE_ATTACK_SOUND = new LuteAttackSoundStat(),
LUTE_ATTACK_EFFECT = new LuteAttackEffectStat(),
NOTE_WEIGHT = new DoubleStat("NOTE_WEIGHT", VersionMaterial.MUSIC_DISC_MALL.toMaterial(), "Note Weight", new String[]{"Defines how the projectile cast", "by your lute tilts downwards."}, new String[]{"lute"}),
REMOVE_ON_CRAFT = new BooleanStat("REMOVE_ON_CRAFT", Material.GLASS_BOTTLE, "Remove on Craft", new String[]{"If the item should be completely", "removed when used in a recipe,", "or if it should become an", "empty bottle or bucket."}, new String[]{"all"}, Material.POTION, Material.SPLASH_POTION, Material.LINGERING_POTION, Material.MILK_BUCKET, Material.LAVA_BUCKET, Material.WATER_BUCKET),
@ -178,8 +182,8 @@ public class ItemStats {
// Abilities & Upgrading
ABILITIES = new Abilities(),
UPGRADE = new UpgradeStat(),
DOWNGRADE_ON_BREAK = new BooleanStat("BREAK_DOWNGRADE", Material.DAMAGED_ANVIL, "Downgrade when Broken", new String[]{"If this item's durability reaches 0,", "it will be fully repaired but also", "downgraded by one level.", "", "&cIt will only break if it cannot be", "&cdowngraded further", "", "Requires to define an &6Upgrade Template", "Required to define &6Custom Durability"}, new String[]{"piercing", "slashing", "blunt", "catalyst", "range", "tool", "armor", "consumable", "accessory"}),
DOWNGRADE_ON_DEATH = new BooleanStat("DEATH_DOWNGRADE", Material.DAMAGED_ANVIL, "Downgrade on Death", new String[]{"If the wearer of this item dies, it may", "downgrade (based on &6Death Downgrade", "&6Chance &7stat)", "", "Required to define an &6Upgrade Template", "Requires keep-inventory gamerule. "}, new String[]{"piercing", "slashing", "blunt", "catalyst", "range", "tool", "armor", "consumable", "accessory"}),
DOWNGRADE_ON_BREAK = new BooleanStat("BREAK_DOWNGRADE", Material.DAMAGED_ANVIL, "Downgrade when Broken", new String[]{"If this item's durability reaches 0,", "it will be fully repaired but also", "downgraded by one level.", "", "&cIt will only break if it cannot be", "&cdowngraded further", "", "Requires to define an &6Upgrade Template", "Required to define &6Custom Durability"}, new String[]{"weapon", "catalyst", "tool", "armor", "consumable", "accessory"}),
DOWNGRADE_ON_DEATH = new BooleanStat("DEATH_DOWNGRADE", Material.DAMAGED_ANVIL, "Downgrade on Death", new String[]{"If the wearer of this item dies, it may", "downgrade (based on &6Death Downgrade", "&6Chance &7stat)", "", "Required to define an &6Upgrade Template", "Requires keep-inventory gamerule. "}, new String[]{"weapon", "catalyst", "tool", "armor", "consumable", "accessory"}),
DOWNGRADE_ON_DEATH_CHANCE = new DoubleStat("DEATH_DOWNGRADE_CHANCE", Material.SKELETON_SKULL, "Death Downgrade Chance", new String[]{"Probability that an item with &cDowngrade ", "&con Death&7 will be downgraded when the", "player dies. ", "", "Exceeding 100% will for sure downgrade", "one item, and roll again to downgrade", "another (with the excess probability).", "&6The same item wont be downgraded twice."}, new String[]{"!miscellaneous", "!block", "all"}, false),
// Unique Item Stats
@ -203,7 +207,7 @@ public class ItemStats {
/**
* @deprecated Item damage is now {@link ItemDamage} and
* custom durability is now {@link CustomDurability}
* custom durability is now {@link CustomDurability}
*/
@Deprecated
public static final ItemStat DURABILITY = ITEM_DAMAGE;

View File

@ -5,15 +5,12 @@ import io.lumine.mythic.lib.UtilityMethods;
import io.lumine.mythic.lib.api.item.NBTItem;
import io.lumine.mythic.lib.player.cooldown.CooldownObject;
import io.lumine.mythic.lib.player.modifier.ModifierSource;
import io.lumine.mythic.lib.skill.SimpleSkill;
import io.lumine.mythic.lib.skill.Skill;
import io.lumine.mythic.lib.skill.trigger.TriggerType;
import io.lumine.mythic.lib.skill.handler.SkillHandler;
import net.Indyuce.mmoitems.MMOItems;
import net.Indyuce.mmoitems.api.item.util.identify.UnidentifiedItem;
import net.Indyuce.mmoitems.manager.TypeManager;
import net.Indyuce.mmoitems.stat.type.ItemStat;
import org.apache.commons.lang.Validate;
import org.apache.maven.model.ConfigurationContainer;
import org.bukkit.Material;
import org.bukkit.configuration.ConfigurationSection;
import org.bukkit.inventory.ItemStack;
@ -87,13 +84,14 @@ public class Type implements CooldownObject {
* The parent item type determines:
* - the item options compatible with this new item type
* - if this item type is a weapon or not
* - types of modifiers an item of this type would give
* - the lore format
*/
private Type parent;
private UnidentifiedItem unidentifiedTemplate;
private Skill onLeftClick, onRightClick, onAttack, onEntityInteract;
private SkillHandler onLeftClick, onRightClick, onAttack, onEntityInteract;
private boolean meleeAttacks;
@ -103,11 +101,6 @@ public class Type implements CooldownObject {
*/
private final List<ItemStat> available = new ArrayList<>();
@Deprecated
public Type(TypeSet set, String id, boolean weapon, ModifierSource modSource, boolean fourGUIMode) {
this(id, weapon, modSource);
}
public Type(String id, boolean weapon, ModifierSource modSource) {
this.id = id.toUpperCase().replace("-", "_").replace(" ", "_");
this.modifierSource = modSource;
@ -138,19 +131,19 @@ public class Type implements CooldownObject {
attackCooldownKey = config.getString("attack-cooldown-key", "default");
meleeAttacks = !config.getBoolean("cancel-melee-attacks");
meleeAttacks = !config.getBoolean("disable-melee-attacks");
}
public void postload(ConfigurationSection config) {
onLeftClick = config.contains("on-left-click") ? new SimpleSkill(MythicLib.plugin.getSkills().loadSkillHandler(config.get("on-left-click"))) : null;
onRightClick = config.contains("on-right-click") ? new SimpleSkill(MythicLib.plugin.getSkills().loadSkillHandler(config.get("on-right-click"))) : null;
onAttack = config.contains("on-attack") ? new SimpleSkill(MythicLib.plugin.getSkills().loadSkillHandler(config.get("on-attack"))) : null;
onEntityInteract = config.contains("on-entity-interact") ? new SimpleSkill(MythicLib.plugin.getSkills().loadSkillHandler(config.get("on-entity-interact"))) : null;
onLeftClick = config.contains("on-left-click") ? MythicLib.plugin.getSkills().loadSkillHandler(config.get("on-left-click")) : null;
onRightClick = config.contains("on-right-click") ? MythicLib.plugin.getSkills().loadSkillHandler(config.get("on-right-click")) : null;
onAttack = config.contains("on-attack") ? MythicLib.plugin.getSkills().loadSkillHandler(config.get("on-attack")) : null;
onEntityInteract = config.contains("on-entity-interact") ? MythicLib.plugin.getSkills().loadSkillHandler(config.get("on-entity-interact")) : null;
}
/**
* @deprecated Type is no longer an enum so that external plugins
* can register their own types. Use getId() instead
* can register their own types. Use getId() instead
*/
@Deprecated
public String name() {
@ -188,7 +181,7 @@ public class Type implements CooldownObject {
}
@Nullable
public Skill onLeftClick() {
public SkillHandler onLeftClick() {
return onLeftClick;
}
@ -198,17 +191,17 @@ public class Type implements CooldownObject {
}
@Nullable
public Skill onRightClick() {
public SkillHandler onRightClick() {
return onRightClick;
}
@Nullable
public Skill onAttack() {
public SkillHandler onAttack() {
return onAttack;
}
@Nullable
public Skill onEntityInteract() {
public SkillHandler onEntityInteract() {
return onEntityInteract;
}
@ -255,7 +248,7 @@ public class Type implements CooldownObject {
/**
* @return Either if the two types are the same,
* or if this type is a subtype of the given type.
* or if this type is a subtype of the given type.
*/
public boolean corresponds(Type type) {
return getSupertype().equals(type);
@ -263,8 +256,8 @@ public class Type implements CooldownObject {
/**
* @return The collection of all stats which can be applied onto this
* specific item type. This list is cached when types are being
* loaded and is a PRETTY GOOD performance improvement.
* specific item type. This list is cached when types are being
* loaded and is a PRETTY GOOD performance improvement.
*/
public List<ItemStat> getAvailableStats() {
return available;
@ -272,7 +265,7 @@ public class Type implements CooldownObject {
/**
* @return Finds the /item config file corresponding to the item type and
* loads it
* loads it
*/
public ConfigFile getConfigFile() {
return new ConfigFile("/item", getId().toLowerCase());

View File

@ -1,159 +0,0 @@
package net.Indyuce.mmoitems.api;
import io.lumine.mythic.lib.UtilityMethods;
import io.lumine.mythic.lib.damage.AttackMetadata;
import io.lumine.mythic.lib.player.PlayerMetadata;
import net.Indyuce.mmoitems.api.interaction.weapon.Weapon;
import net.Indyuce.mmoitems.api.player.PlayerData;
import org.bukkit.entity.LivingEntity;
import org.jetbrains.annotations.NotNull;
@Deprecated
public enum TypeSet {
/**
* Slashing weapons deal damage in a cone behind the player's initial
* target, which makes it a deadly AoE weapon for warriors
*/
@Deprecated
SLASHING((attack, attacker, attackerData, target, weapon) -> {
/*if (!MMOItems.plugin.getConfig().getBoolean("item-ability.slashing.enabled")
|| attackerData.isOnCooldown(CooldownType.SET_TYPE_ATTACK))
return;
attackerData.applyCooldown(CooldownType.SET_TYPE_ATTACK, MMOItems.plugin.getConfig().getDouble("item-ability.slashing.cooldown"));
Location loc = attacker.getPlayer().getLocation().clone().add(0, 1.3, 0);
final double a1 = (loc.getYaw() + 90) / 180 * Math.PI, p = -loc.getPitch() / 180 * Math.PI;
for (double r = 1; r < 5; r += .3)
for (double a = -Math.PI / 6; a < Math.PI / 6; a += Math.PI / 8 / r)
loc.getWorld().spawnParticle(Particle.CRIT, loc.clone().add(Math.cos(a + a1) * r, Math.sin(p) * r, Math.sin(a + a1) * r), 0);
for (Entity entity : MMOUtils.getNearbyChunkEntities(loc))
if (entity.getLocation().distanceSquared(loc) < 40
&& attacker.getPlayer().getEyeLocation().getDirection()
.angle(entity.getLocation().subtract(attacker.getPlayer().getLocation()).toVector()) < Math.PI / 3
&& UtilityMethods.canTarget(attacker.getPlayer(), entity, InteractionType.OFFENSE_ACTION) && !entity.equals(target))
attacker.attack((LivingEntity) entity, attack.getDamage().getDamage() * .4, DamageType.WEAPON, DamageType.PHYSICAL);*/
}),
/**
* Piercing weapons deal damage in a line behind the initial target, which
* is harder to land than a slashing weapon but the AoE damage ratio is
* increased which makes it a perfect 'double or nothing' weapon for
* assassins
*/
@Deprecated
PIERCING((attack, attacker, attackerData, target, weapon) -> {
/* if (!MMOItems.plugin.getConfig().getBoolean("item-ability.piercing.enabled")
|| attackerData.isOnCooldown(CooldownType.SET_TYPE_ATTACK))
return;
attackerData.applyCooldown(CooldownType.SET_TYPE_ATTACK, MMOItems.plugin.getConfig().getDouble("item-ability.piercing.cooldown"));
Location loc = attacker.getPlayer().getLocation().clone().add(0, 1.3, 0);
final double a1 = (loc.getYaw() + 90) / 180 * Math.PI, p = -loc.getPitch() / 180 * Math.PI;
for (double r = 1; r < 5; r += .3)
for (double a = -Math.PI / 12; a < Math.PI / 12; a += Math.PI / 16 / r)
loc.getWorld().spawnParticle(Particle.CRIT, loc.clone().add(Math.cos(a + a1) * r, Math.sin(p) * r, Math.sin(a + a1) * r), 0);
for (Entity entity : MMOUtils.getNearbyChunkEntities(loc))
if (!entity.equals(target) && entity.getLocation().distanceSquared(attacker.getPlayer().getLocation()) < 40
&& attacker.getPlayer().getEyeLocation().getDirection()
.angle(entity.getLocation().toVector().subtract(attacker.getPlayer().getLocation().toVector())) < Math.PI / 12
&& UtilityMethods.canTarget(attacker.getPlayer(), entity, InteractionType.OFFENSE_ACTION))
attacker.attack((LivingEntity) entity, attack.getDamage().getDamage() * .6, DamageType.WEAPON, DamageType.PHYSICAL);*/
}),
/**
* Blunt weapons are like 1.9 sweep attacks. They damage
* all enemies nearby and apply a slight knockback
*/
@Deprecated
BLUNT((attack, attacker, attackerData, target, weapon) -> {
/* final Random random = new Random();
float pitchRange = 0.7f + random.nextFloat() * (0.9f - 0.7f);
final double bluntPower;
if (MMOItems.plugin.getConfig().getBoolean("item-ability.blunt.aoe.enabled")
&& !attackerData.isOnCooldown(CooldownType.SPECIAL_ATTACK)
&& (bluntPower = attacker.getStat("BLUNT_POWER")) > 0) {
attackerData.applyCooldown(CooldownType.SPECIAL_ATTACK, MMOItems.plugin.getConfig().getDouble("item-ability.blunt.aoe.cooldown"));
target.getWorld().playSound(target.getLocation(), Sound.BLOCK_ANVIL_LAND, 0.6f, pitchRange);
target.getWorld().spawnParticle(Particle.EXPLOSION_LARGE, target.getLocation().add(0, 1, 0), 0);
final double bluntRating = weapon.requireNonZero(attacker.getStat("BLUNT_RATING"),
MMOItems.plugin.getConfig().getDouble("default.blunt-rating")) / 100;
for (Entity entity : target.getNearbyEntities(bluntPower, bluntPower, bluntPower))
if (UtilityMethods.canTarget(attacker.getPlayer(), entity, InteractionType.OFFENSE_ACTION) && !entity.equals(target))
attacker.attack((LivingEntity) entity, attack.getDamage().getDamage() * bluntRating, DamageType.WEAPON, DamageType.PHYSICAL);
}
if (MMOItems.plugin.getConfig().getBoolean("item-ability.blunt.stun.enabled")
&& !attackerData.isOnCooldown(CooldownType.SPECIAL_ATTACK)
&& random.nextDouble() < MMOItems.plugin.getConfig().getDouble("item-ability.blunt.stun.chance") / 100) {
attackerData.applyCooldown(CooldownType.SPECIAL_ATTACK, MMOItems.plugin.getConfig().getDouble("item-ability.blunt.stun.cooldown"));
target.getWorld().playSound(target.getLocation(), VersionSound.ENTITY_ZOMBIE_ATTACK_WOODEN_DOOR.toSound(), 1, 2);
target.removePotionEffect(PotionEffectType.SLOW);
target.removePotionEffect(PotionEffectType.BLINDNESS);
target.addPotionEffect(new PotionEffect(PotionEffectType.BLINDNESS, 20, 0));
target.addPotionEffect(
new PotionEffect(PotionEffectType.SLOW, (int) (30 * MMOItems.plugin.getConfig().getDouble("item-ability.blunt.stun.power")), 1));
Location loc = target.getLocation();
loc.setYaw((float) (loc.getYaw() + 2 * (random.nextDouble() - .5) * 90));
loc.setPitch((float) (loc.getPitch() + 2 * (random.nextDouble() - .5) * 30));
}*/
}),
/**
* Ranged attacks based weapons. when the player is too squishy to fight in
* the middle of the battle-field, these weapons allow him to take some
* distance and still deal some good damage
*/
@Deprecated
RANGE,
/**
* Hand/Mainhand/Offhand catalysts
*/
@Deprecated
CATALYST,
/**
* Any other item type, like armor, consumables, etc. They all have their
* very specific passive depending on their item type
*/
@Deprecated
EXTRA;
private final SetAttackHandler attackHandler;
private final String name;
private TypeSet() {
this(null);
}
private TypeSet(SetAttackHandler attackHandler) {
this.attackHandler = attackHandler;
this.name = UtilityMethods.caseOnWords(name().toLowerCase());
}
public boolean hasAttackEffect() {
return attackHandler != null;
}
public void applyAttackEffect(AttackMetadata attackMeta, PlayerMetadata attacker, PlayerData attackerData, LivingEntity target, Weapon weapon) {
attackHandler.apply(attackMeta, attacker, attackerData, target, weapon);
}
public String getName() {
return name;
}
@FunctionalInterface
interface SetAttackHandler {
void apply(@NotNull AttackMetadata attack, @NotNull PlayerMetadata attacker, @NotNull PlayerData attackerData, @NotNull LivingEntity target, @NotNull Weapon weapon);
}
}

View File

@ -6,12 +6,14 @@ import io.lumine.mythic.lib.api.player.EquipmentSlot;
import io.lumine.mythic.lib.comp.flags.CustomFlag;
import io.lumine.mythic.lib.damage.AttackMetadata;
import io.lumine.mythic.lib.player.PlayerMetadata;
import io.lumine.mythic.lib.skill.SimpleSkill;
import io.lumine.mythic.lib.skill.Skill;
import io.lumine.mythic.lib.skill.SkillMetadata;
import io.lumine.mythic.lib.skill.handler.SkillHandler;
import io.lumine.mythic.lib.skill.result.SkillResult;
import io.lumine.mythic.lib.skill.trigger.TriggerMetadata;
import io.lumine.mythic.lib.skill.trigger.TriggerType;
import net.Indyuce.mmoitems.ItemStats;
import net.Indyuce.mmoitems.MMOItems;
import net.Indyuce.mmoitems.api.Type;
import net.Indyuce.mmoitems.api.event.item.UntargetedWeaponUseEvent;
@ -123,13 +125,27 @@ public class Weapon extends UseItem {
if (!checkAndApplyWeaponCosts()) return false;
// Handle on-hit attack effects
final Skill onHitScript = mmoitem.getType().onAttack();
if (onHitScript != null && !getNBTItem().getBoolean("MMOITEMS_DISABLE_ATTACK_PASSIVE"))
onHitScript.cast(new TriggerMetadata(attacker, TriggerType.API, target, attackMeta));
final SkillHandler onHitSkill = mmoitem.getType().onAttack();
if (onHitSkill != null && !getNBTItem().getBoolean("MMOITEMS_DISABLE_ATTACK_PASSIVE"))
new SimpleSkill(onHitSkill).cast(new TriggerMetadata(attacker, TriggerType.API, target, attackMeta));
return true;
}
@Nullable
private SkillHandler findClickSkill(boolean rightClick) {
final String skillId = getNBTItem().getString((rightClick ? ItemStats.RIGHT_CLICK_SCRIPT : ItemStats.LEFT_CLICK_SCRIPT).getNBTPath());
if (skillId == null || skillId.isEmpty()) {
// Find item type action
final Type itemType = mmoitem.getType();
return rightClick ? itemType.onRightClick() : itemType.onLeftClick();
}
// Override item type with custom action
return MythicLib.plugin.getSkills().getHandler(skillId);
}
/**
* Called when the player interacts with the item. This method is used to
* apply durability and cast the weapon attack
@ -138,20 +154,18 @@ public class Weapon extends UseItem {
* @param actionHand Slot being interacted with
* @return Null if there are no attack detected
* @implNote Since MI 6.7.3 this method handles custom durability, cooldown
* checks and player stat snapshots.
* checks and player stat snapshots.
*/
@Nullable
public WeaponAttackResult handleUntargetedAttack(boolean rightClick, @NotNull EquipmentSlot actionHand) {
if (this instanceof LegacyWeapon) return legacyHandleUntargetedAttack(rightClick, actionHand);
// Check for item type attack effect
final Type itemType = mmoitem.getType();
final Skill attackEffect = rightClick ? itemType.onRightClick() : itemType.onLeftClick();
if (attackEffect == null) return WeaponAttackResult.NO_ATTACK;
final SkillHandler handler = findClickSkill(rightClick);
if (handler == null) return WeaponAttackResult.NO_ATTACK;
// Check for attack effect conditions
final SkillHandler handler = attackEffect.getHandler();
final SkillMetadata meta = new TriggerMetadata(getPlayerData().getMMOPlayerData(), TriggerType.API).toSkillMetadata(attackEffect);
final SkillMetadata meta = new TriggerMetadata(getPlayerData().getMMOPlayerData(), TriggerType.API).toSkillMetadata(new SimpleSkill(handler));
final SkillResult result = handler.getResult(meta);
if (!result.isSuccessful(meta)) return WeaponAttackResult.NO_ATTACK;

View File

@ -1,62 +0,0 @@
package net.Indyuce.mmoitems.api.interaction.weapon.untargeted.staff;
import io.lumine.mythic.lib.UtilityMethods;
import io.lumine.mythic.lib.api.item.NBTItem;
import io.lumine.mythic.lib.api.player.EquipmentSlot;
import io.lumine.mythic.lib.comp.interaction.InteractionType;
import io.lumine.mythic.lib.damage.DamageType;
import io.lumine.mythic.lib.player.PlayerMetadata;
import io.lumine.mythic.lib.version.VersionSound;
import net.Indyuce.mmoitems.MMOItems;
import net.Indyuce.mmoitems.util.MMOUtils;
import org.bukkit.Location;
import org.bukkit.Particle;
import org.bukkit.Sound;
import org.bukkit.entity.Entity;
import org.bukkit.entity.LivingEntity;
import org.bukkit.scheduler.BukkitRunnable;
import org.bukkit.util.Vector;
/*
@Deprecated
public class SunfireSpirit implements StaffAttackHandler {
@Override
public void handle(PlayerMetadata caster, double damage, NBTItem nbt, EquipmentSlot slot, double range) {
caster.getPlayer().getWorld().playSound(caster.getPlayer().getLocation(), Sound.ENTITY_WITHER_SHOOT, 2, 2);
new BukkitRunnable() {
final Location target = getGround(caster.getPlayer().getTargetBlock(null, (int) range * 2).getLocation()).add(0, 1.2, 0);
final double a = RANDOM.nextDouble() * Math.PI * 2;
final double dt = .02;
final Location loc = target.clone().add(Math.cos(a) * 4, 10, Math.sin(a) * 4);
final Vector vec = target.toVector().subtract(loc.toVector()).multiply(dt);
double ti = 0;
int counter;
public void run() {
if (counter++ % 2 == 0)
loc.getWorld().playSound(loc, Sound.BLOCK_FIRE_AMBIENT, 2, 2);
for (int j = 0; j < 3; j++) {
ti += dt;
loc.add(vec);
loc.getWorld().spawnParticle(Particle.FLAME, loc, 0, .03, 0, .03, 0);
// Projectile explode
if (ti >= 1) {
loc.getWorld().spawnParticle(Particle.FLAME, loc, 24, 0, 0, 0, .12);
loc.getWorld().spawnParticle(Particle.SMOKE_NORMAL, loc, 24, 0, 0, 0, .12);
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 (UtilityMethods.canTarget(caster.getPlayer(), target, InteractionType.OFFENSE_ACTION) && target.getLocation().distanceSquared(loc) <= 9)
caster.attack((LivingEntity) target, damage, DamageType.WEAPON, DamageType.MAGIC, DamageType.PROJECTILE);
cancel();
return;
}
}
}
}.runTaskTimer(MMOItems.plugin, 0, 1);
}
}
*/

View File

@ -1,60 +0,0 @@
package net.Indyuce.mmoitems.api.interaction.weapon.untargeted.staff;
import io.lumine.mythic.lib.UtilityMethods;
import io.lumine.mythic.lib.api.item.NBTItem;
import io.lumine.mythic.lib.api.player.EquipmentSlot;
import io.lumine.mythic.lib.comp.interaction.InteractionType;
import io.lumine.mythic.lib.damage.DamageType;
import io.lumine.mythic.lib.player.PlayerMetadata;
import io.lumine.mythic.lib.version.VersionSound;
import net.Indyuce.mmoitems.MMOItems;
import net.Indyuce.mmoitems.util.MMOUtils;
import org.bukkit.Location;
import org.bukkit.Particle;
import org.bukkit.Sound;
import org.bukkit.entity.Entity;
import org.bukkit.entity.LivingEntity;
import org.bukkit.scheduler.BukkitRunnable;
import org.bukkit.util.Vector;
/*
@Deprecated
public class ThunderSpirit implements StaffAttackHandler {
@Override
public void handle(PlayerMetadata caster, double damage, NBTItem nbt, EquipmentSlot slot, double range) {
caster.getPlayer().getWorld().playSound(caster.getPlayer().getLocation(), Sound.ENTITY_WITHER_SHOOT, 2, 2);
new BukkitRunnable() {
final Location target = getGround(caster.getPlayer().getTargetBlock(null, (int) range * 2).getLocation()).add(0, 1.2, 0);
final double a = RANDOM.nextDouble() * Math.PI * 2;
final double dt = .02;
double ti = 0;
final Location loc = target.clone().add(Math.cos(a) * 4, 10, Math.sin(a) * 4);
final Vector vec = target.toVector().subtract(loc.toVector()).multiply(dt);
int counter;
public void run() {
if (counter++ % 2 == 0)
loc.getWorld().playSound(loc, VersionSound.BLOCK_NOTE_BLOCK_HAT.toSound(), 2, 2);
for (int j = 0; j < 3; j++) {
ti += dt;
loc.add(vec);
loc.getWorld().spawnParticle(Particle.FIREWORKS_SPARK, loc, 0, .03, 0, .03, 0);
// Projectile explode
if (ti >= 1) {
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 (UtilityMethods.canTarget(caster.getPlayer(), target, InteractionType.OFFENSE_ACTION) && target.getLocation().distanceSquared(loc) <= 9)
caster.attack((LivingEntity) target, damage, DamageType.WEAPON, DamageType.MAGIC, DamageType.PROJECTILE);
cancel();
return;
}
}
}
}.runTaskTimer(MMOItems.plugin, 0, 1);
}
}
*/

View File

@ -13,7 +13,6 @@ import org.bukkit.Material;
import org.bukkit.entity.Player;
import org.bukkit.event.inventory.InventoryAction;
import org.bukkit.event.inventory.InventoryClickEvent;
import org.bukkit.inventory.Inventory;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.ItemMeta;
import org.jetbrains.annotations.NotNull;

View File

@ -9,7 +9,9 @@ import io.lumine.mythic.lib.comp.interaction.InteractionType;
import io.lumine.mythic.lib.damage.MeleeAttackMetadata;
import io.lumine.mythic.lib.entity.ProjectileMetadata;
import io.lumine.mythic.lib.entity.ProjectileType;
import io.lumine.mythic.lib.skill.SimpleSkill;
import io.lumine.mythic.lib.skill.Skill;
import io.lumine.mythic.lib.skill.handler.SkillHandler;
import io.lumine.mythic.lib.skill.trigger.TriggerMetadata;
import io.lumine.mythic.lib.skill.trigger.TriggerType;
import net.Indyuce.mmoitems.api.Type;
@ -163,12 +165,12 @@ public class ItemUse implements Listener {
if (!usableItem.checkItemRequirements()) return;
// Apply type-specific entity interactions
final Skill onEntityInteract = usableItem.getMMOItem().getType().onEntityInteract();
final SkillHandler onEntityInteract = usableItem.getMMOItem().getType().onEntityInteract();
if (onEntityInteract != null) {
SpecialWeaponAttackEvent called = new SpecialWeaponAttackEvent(usableItem.getPlayerData(), (Weapon) usableItem, target);
Bukkit.getPluginManager().callEvent(called);
if (!called.isCancelled())
onEntityInteract.cast(new TriggerMetadata(usableItem.getPlayerData().getMMOPlayerData(), TriggerType.API));
new SimpleSkill(onEntityInteract).cast(new TriggerMetadata(usableItem.getPlayerData().getMMOPlayerData(), TriggerType.API));
}
}

View File

@ -0,0 +1,33 @@
package net.Indyuce.mmoitems.stat;
import io.lumine.mythic.lib.MythicLib;
import io.lumine.mythic.lib.api.item.ItemTag;
import io.lumine.mythic.lib.skill.handler.SkillHandler;
import net.Indyuce.mmoitems.MMOItems;
import net.Indyuce.mmoitems.api.item.build.ItemStackBuilder;
import net.Indyuce.mmoitems.gui.edition.EditionInventory;
import net.Indyuce.mmoitems.stat.data.StringData;
import net.Indyuce.mmoitems.stat.type.StringStat;
import org.bukkit.Material;
import org.jetbrains.annotations.NotNull;
public class ActionLeftClick extends StringStat {
public ActionLeftClick() {
super("ON_LEFT_CLICK", Material.COMMAND_BLOCK_MINECART, "Left Click Script", new String[]{"Name of script ran when left clicking. When used,", "The item will naturally apply item costs like", "mana, stamina, cooldown. This option overrides the", "script provided by the item type."}, new String[]{"weapon"});
}
@Override
public void whenInput(@NotNull EditionInventory inv, @NotNull String message, Object... info) {
final SkillHandler<?> script = MythicLib.plugin.getSkills().getHandlerOrThrow(message);
inv.getEditedSection().set(getPath(), script.getId());
inv.registerTemplateEdition();
inv.getPlayer().sendMessage(MMOItems.plugin.getPrefix() + getName() + " successfully changed to '" + script.getId() + "'");
}
@Override
public void whenApplied(@NotNull ItemStackBuilder item, @NotNull StringData data) {
item.addItemTag(new ItemTag(getNBTPath(), data.toString()));
// No lore insertion
}
}

View File

@ -0,0 +1,33 @@
package net.Indyuce.mmoitems.stat;
import io.lumine.mythic.lib.MythicLib;
import io.lumine.mythic.lib.api.item.ItemTag;
import io.lumine.mythic.lib.skill.handler.SkillHandler;
import net.Indyuce.mmoitems.MMOItems;
import net.Indyuce.mmoitems.api.item.build.ItemStackBuilder;
import net.Indyuce.mmoitems.gui.edition.EditionInventory;
import net.Indyuce.mmoitems.stat.data.StringData;
import net.Indyuce.mmoitems.stat.type.StringStat;
import org.bukkit.Material;
import org.jetbrains.annotations.NotNull;
public class ActionRightClick extends StringStat {
public ActionRightClick() {
super("ON_RIGHT_CLICK", Material.COMMAND_BLOCK_MINECART, "Right Click Script", new String[]{"Name of script ran when right clicking. When used,", "The item will naturally apply item costs like", "mana, stamina, cooldown. This option overrides the", "script provided by the item type."}, new String[]{"weapon"});
}
@Override
public void whenInput(@NotNull EditionInventory inv, @NotNull String message, Object... info) {
final SkillHandler<?> script = MythicLib.plugin.getSkills().getHandlerOrThrow(message);
inv.getEditedSection().set(getPath(), script.getId());
inv.registerTemplateEdition();
inv.getPlayer().sendMessage(MMOItems.plugin.getPrefix() + getName() + " successfully changed to '" + script.getId() + "'");
}
@Override
public void whenApplied(@NotNull ItemStackBuilder item, @NotNull StringData data) {
item.addItemTag(new ItemTag(getNBTPath(), data.toString()));
// No lore insertion
}
}

View File

@ -36,7 +36,7 @@ import java.util.*;
public class Elements extends ItemStat<RandomElementListData, ElementListData> implements Previewable<RandomElementListData, ElementListData> {
public Elements() {
super("ELEMENT", Material.SLIME_BALL, "Elements", new String[]{"The elements of your item."},
new String[]{"slashing", "piercing", "blunt", "catalyst", "range", "tool", "armor", "gem_stone"});
new String[]{"weapon", "catalyst", "tool", "armor", "gem_stone"});
}
@Override

View File

@ -33,7 +33,7 @@ import java.util.Optional;
public class GemSockets extends ItemStat<GemSocketsData, GemSocketsData> {
public GemSockets() {
super("GEM_SOCKETS", Material.EMERALD, "Gem Sockets", new String[]{"The amount of gem", "sockets your weapon has."},
new String[]{"piercing", "slashing", "blunt", "catalyst", "range", "tool", "armor", "accessory", "!gem_stone"});
new String[]{"weapon", "catalyst", "tool", "armor", "accessory", "!gem_stone"});
}
@Override

View File

@ -18,7 +18,6 @@ import org.bukkit.event.inventory.InventoryClickEvent;
import net.Indyuce.mmoitems.ItemStats;
import net.Indyuce.mmoitems.MMOItems;
import net.Indyuce.mmoitems.api.Type;
import net.Indyuce.mmoitems.api.TypeSet;
import net.Indyuce.mmoitems.api.edition.StatEdition;
import net.Indyuce.mmoitems.api.item.build.ItemStackBuilder;
import net.Indyuce.mmoitems.gui.edition.EditionInventory;
@ -195,10 +194,6 @@ public class ItemTypeRestriction extends ItemStat<StringListData, StringListData
if (type.getId().equals(format))
return true;
for (TypeSet set : TypeSet.values())
if (set.name().equals(format))
return true;
return false;
}

View File

@ -24,7 +24,7 @@ import org.jetbrains.annotations.NotNull;
public class ManaCost extends DoubleStat implements ItemRestriction, PlayerConsumable {
public ManaCost() {
super("MANA_COST", VersionMaterial.LAPIS_LAZULI.toMaterial(), "Mana Cost", new String[]{"Mana spent by your weapon to be used."}, new String[]{"piercing", "slashing", "blunt", "range"});
super("MANA_COST", VersionMaterial.LAPIS_LAZULI.toMaterial(), "Mana Cost", new String[]{"Mana spent by your weapon to be used."}, new String[]{"weapon"});
}

View File

@ -1,96 +0,0 @@
package net.Indyuce.mmoitems.stat;
import io.lumine.mythic.lib.UtilityMethods;
import io.lumine.mythic.lib.api.item.ItemTag;
import io.lumine.mythic.lib.api.item.NBTItem;
import io.lumine.mythic.lib.version.VersionMaterial;
import net.Indyuce.mmoitems.MMOItems;
import net.Indyuce.mmoitems.api.interaction.weapon.untargeted.staff.*;
import net.Indyuce.mmoitems.api.item.build.ItemStackBuilder;
import net.Indyuce.mmoitems.gui.edition.EditionInventory;
import net.Indyuce.mmoitems.stat.data.StringData;
import net.Indyuce.mmoitems.stat.type.StringStat;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
/*
public class StaffSpiritStat extends StringStat {
public StaffSpiritStat() {
super("STAFF_SPIRIT", VersionMaterial.BONE_MEAL.toMaterial(), "Staff Spirit",
new String[]{"Spirit changes the texture", "of the magic attack.", "&9Tip: /mi list spirit"}, new String[]{"staff", "wand"});
}
@Override
public void whenInput(@NotNull EditionInventory inv, @NotNull String message, Object... info) {
try {
StaffSpirit spirit = StaffSpirit.valueOf(message.toUpperCase().replace(" ", "_").replace("-", "_"));
inv.getEditedSection().set("staff-spirit", spirit.name());
inv.registerTemplateEdition();
inv.getPlayer().sendMessage(MMOItems.plugin.getPrefix() + "Staff Spirit successfully changed to " + spirit.getName() + ".");
} catch (IllegalArgumentException exception) {
throw new IllegalArgumentException(exception.getMessage() + " (See all Staff Spirits here: /mi list spirit).");
}
}
@Override
public void whenApplied(@NotNull ItemStackBuilder item, @NotNull StringData data) {
StaffSpirit staffSpirit = StaffSpirit.valueOf(data.toString().toUpperCase().replace(" ", "_").replace("-", "_"));
item.addItemTag(new ItemTag("MMOITEMS_STAFF_SPIRIT", staffSpirit.name()));
item.getLore().insert("staff-spirit", staffSpirit.getName());
}
public enum StaffSpirit {
NETHER_SPIRIT("Shoots fire beams.", new NetherSpirit()),
VOID_SPIRIT("Shoots shulker missiles.", new VoidSpirit()),
MANA_SPIRIT("Summons mana bolts.", new ManaSpirit()),
LIGHTNING_SPIRIT("Summons lightning bolts.", new LightningSpirit()),
XRAY_SPIRIT("Fires piercing & powerful X-rays.", new XRaySpirit()),
THUNDER_SPIRIT("Fires AoE damaging thunder strikes.", new ThunderSpirit()),
SUNFIRE_SPIRIT("Fires AoE damaging fire comets.", new SunfireSpirit()),
// CURSED_SPIRIT(ChatColor.DARK_PURPLE, "Cursed Spirit", "Fires a
// targeted cursed projectile."), new CursedSpirit()),
;
private final String defaultLore;
private final StaffAttackHandler handler;
@NotNull
private String name = UtilityMethods.caseOnWords(name().toLowerCase().replace("_", " "));
StaffSpirit(String description, StaffAttackHandler handler) {
this.defaultLore = description;
this.handler = handler;
}
@Nullable
public static StaffSpirit get(NBTItem item) {
try {
return StaffSpirit.valueOf(item.getString("MMOITEMS_STAFF_SPIRIT"));
} catch (Exception e) {
return null;
}
}
public String getName() {
return name;
}
public boolean hasLore() {
return defaultLore != null;
}
public String getDefaultLore() {
return defaultLore;
}
public StaffAttackHandler getAttack() {
return handler;
}
public void setName(String str) {
this.name = str;
}
}
}
*/

View File

@ -49,7 +49,7 @@ public class UpgradeStat extends ItemStat<UpgradeData, UpgradeData> implements C
super("UPGRADE", Material.FLINT, "Item Upgrading",
new String[] { "Upgrading your item improves its", "current stats. It requires either a", "consumable or a specific crafting ",
"station. Upgrading may sometimes &cfail&7..." },
new String[] { "piercing", "slashing", "blunt", "catalyst", "range", "tool", "armor", "consumable", "accessory" });
new String[] { "weapon", "catalyst", "tool", "armor", "consumable", "accessory" });
}
@Override

View File

@ -196,7 +196,7 @@ public abstract class ItemStat<R extends RandomStatData<S>, S extends StatData>
/**
* @return The stat ID
* @deprecated Use getId() instead. Type is no longer an util since they can
* now be registered from external plugins
* now be registered from external plugins
*/
@Deprecated
@NotNull
@ -214,8 +214,8 @@ public abstract class ItemStat<R extends RandomStatData<S>, S extends StatData>
/**
* @return The NBT path used by the stat to save data in an item's NBTTags.
* The format is 'MMOITEMS_' followed by the stat name in capital
* letters only using _
* The format is 'MMOITEMS_' followed by the stat name in capital
* letters only using _
*/
@NotNull
public String getNBTPath() {
@ -243,12 +243,15 @@ public abstract class ItemStat<R extends RandomStatData<S>, S extends StatData>
* @param type The item type to check
* @return If a certain item type is compatible with this item stat
*/
public boolean isCompatible(Type type) {
public boolean isCompatible(@NotNull Type type) {
// Special rule for weapons
if (type.isWeapon() && compatibleTypes.contains("weapon")) return true;
// Recursive call with root types
if (type.isSubtype()) return isCompatible(type.getParent());
// Root item types
// Parent item types
final String lower = type.getId().toLowerCase();
return !compatibleTypes.contains("!" + lower) && (compatibleTypes.contains("all") || compatibleTypes.contains(lower));
}

View File

@ -31,6 +31,9 @@ SWORD:
- '{range}&8- &7Lvl Range: &e#range#'
- '{tier}&8- &7Item Tier: #prefix##tier#'
# What the item type does
on-attack: slashing_attack_effect
DAGGER:
display: STONE_SWORD
name: 'Dagger'
@ -44,6 +47,8 @@ DAGGER:
- '{range}&8- &7Lvl Range: &e#range#'
- '{tier}&8- &7Item Tier: #prefix##tier#'
on-attack: piercing_attack_effect
SPEAR:
display: TRIDENT
name: 'Spear'
@ -57,6 +62,8 @@ SPEAR:
- '{range}&8- &7Lvl Range: &e#range#'
- '{tier}&8- &7Item Tier: #prefix##tier#'
on-attack: piercing_attack_effect
HAMMER:
display: IRON_AXE
name: 'Hammer'
@ -70,6 +77,8 @@ HAMMER:
- '{range}&8- &7Lvl Range: &e#range#'
- '{tier}&8- &7Item Tier: #prefix##tier#'
on-attack: blunt_attack_effect
GAUNTLET:
display: IRON_HORSE_ARMOR
name: 'Gauntlet'
@ -83,6 +92,8 @@ GAUNTLET:
- '{range}&8- &7Lvl Range: &e#range#'
- '{tier}&8- &7Item Tier: #prefix##tier#'
on-attack: blunt_attack_effect
WHIP:
display: LEAD
name: 'Whip'
@ -109,6 +120,10 @@ STAFF:
- '{range}&8- &7Lvl Range: &e#range#'
- '{tier}&8- &7Item Tier: #prefix##tier#'
disable-melee-attacks: true
on-left-click: staff_default
attack-cooldown-key: "staff"
BOW:
display: BOW
name: 'Bow'
@ -122,6 +137,8 @@ BOW:
- '{range}&8- &7Lvl Range: &e#range#'
- '{tier}&8- &7Item Tier: #prefix##tier#'
disable-melee-attacks: true
CROSSBOW:
display: WOODEN_PICKAXE
name: 'Crossbow'
@ -135,6 +152,9 @@ CROSSBOW:
- '{range}&8- &7Lvl Range: &e#range#'
- '{tier}&8- &7Item Tier: #prefix##tier#'
disable-melee-attacks: true
on-right-click: crossbow_attack
MUSKET:
display: IRON_HORSE_ARMOR
name: 'Musket'
@ -148,6 +168,10 @@ MUSKET:
- '{range}&8- &7Lvl Range: &e#range#'
- '{tier}&8- &7Item Tier: #prefix##tier#'
disable-melee-attacks: true
# Lutes and muskets attack effects are hardcoded as
# of MI 6.10 and cannot be modified at the moment.
LUTE:
display: NAME_TAG
name: 'Lute'
@ -161,6 +185,10 @@ LUTE:
- '{range}&8- &7Lvl Range: &e#range#'
- '{tier}&8- &7Item Tier: #prefix##tier#'
disable-melee-attacks: true
# Lutes and muskets attack effects are hardcoded as
# of MI 6.10 and cannot be modified at the moment.
# Applies stats in both hands
CATALYST:
display: PRISMARINE_SHARD
@ -320,7 +348,6 @@ BLOCK:
- '{range}&8- &7Lvl Range: &e#range#'
- '{tier}&8- &7Item Tier: #prefix##tier#'
# Default subtypes
GREATSWORD:
display: DIAMOND_SWORD
@ -336,6 +363,8 @@ GREATSWORD:
- '{range}&8- &7Lvl Range: &e#range#'
- '{tier}&8- &7Item Tier: #prefix##tier#'
on-attack: slashing_attack_effect
LONG_SWORD:
display: STONE_SWORD
name: 'Long Sword'
@ -350,6 +379,8 @@ LONG_SWORD:
- '{range}&8- &7Lvl Range: &e#range#'
- '{tier}&8- &7Item Tier: #prefix##tier#'
on-attack: slashing_attack_effect
KATANA:
display: IRON_SWORD
name: 'Katana'
@ -364,6 +395,8 @@ KATANA:
- '{range}&8- &7Lvl Range: &e#range#'
- '{tier}&8- &7Item Tier: #prefix##tier#'
on-attack: slashing_attack_effect
THRUSTING_SWORD:
display: GOLDEN_SWORD
name: 'Thrusting Sword'
@ -378,6 +411,8 @@ THRUSTING_SWORD:
- '{range}&8- &7Lvl Range: &e#range#'
- '{tier}&8- &7Item Tier: #prefix##tier#'
on-attack: piercing_attack_effect
AXE:
display: STONE_AXE
name: 'Axe'
@ -392,6 +427,8 @@ AXE:
- '{range}&8- &7Lvl Range: &e#range#'
- '{tier}&8- &7Item Tier: #prefix##tier#'
on-attack: slashing_attack_effect
GREATAXE:
display: DIAMOND_AXE
name: 'Greataxe'
@ -406,6 +443,8 @@ GREATAXE:
- '{range}&8- &7Lvl Range: &e#range#'
- '{tier}&8- &7Item Tier: #prefix##tier#'
on-attack: slashing_attack_effect
HALBERD:
display: IRON_AXE
name: 'Halberd'
@ -420,6 +459,8 @@ HALBERD:
- '{range}&8- &7Lvl Range: &e#range#'
- '{tier}&8- &7Item Tier: #prefix##tier#'
on-attack: blunt_attack_effect
LANCE:
display: STICK
name: 'Lance'
@ -434,6 +475,8 @@ LANCE:
- '{range}&8- &7Lvl Range: &e#range#'
- '{tier}&8- &7Item Tier: #prefix##tier#'
on-attack: piercing_attack_effect
GREATHAMMER:
display: DIAMOND_AXE
name: 'Greathammer'
@ -448,6 +491,8 @@ GREATHAMMER:
- '{range}&8- &7Lvl Range: &e#range#'
- '{tier}&8- &7Item Tier: #prefix##tier#'
on-attack: blunt_attack_effect
GREATSTAFF:
display: DIAMOND_HOE
name: 'Greatstaff'
@ -462,6 +507,8 @@ GREATSTAFF:
- '{range}&8- &7Lvl Range: &e#range#'
- '{tier}&8- &7Item Tier: #prefix##tier#'
on-attack: blunt_attack_effect
STAVE:
display: IRON_HOE
name: 'Stave'
@ -476,6 +523,8 @@ STAVE:
- '{range}&8- &7Lvl Range: &e#range#'
- '{tier}&8- &7Item Tier: #prefix##tier#'
on-attack: blunt_attack_effect
TOME:
display: BOOK
name: 'Tome'
@ -518,6 +567,10 @@ WAND:
- '{range}&8- &7Lvl Range: &e#range#'
- '{tier}&8- &7Item Tier: #prefix##tier#'
disable-melee-attacks: true
on-left-click: staff_default
attack-cooldown-key: "staff"
GREATBOW:
display: BOW
name: 'Greatbow'
@ -532,6 +585,8 @@ GREATBOW:
- '{range}&8- &7Lvl Range: &e#range#'
- '{tier}&8- &7Item Tier: #prefix##tier#'
disable-melee-attacks: true
SHIELD:
display: SHIELD
name: 'Shield'

View File

@ -1,11 +1,3 @@
staff-spirit:
nether-spirit: '&3 &7■ Nether Spirit'
void-spirit: '&3 &7■ Void Spirit'
mana-spirit: '&3 &7■ Mana Spirit'
lightning-spirit: '&3 &7■ Lightning Spirit'
xray-spirit: '&3 &7■ X-Ray Spirit'
thunder-spirit: '&3 &7■ Thunder Spirit'
sunfire-spirit: '&3 &7■ Sunfire Spirit'
lute-attack:
wave: '&3 &7■ Wave Melody'
circular: '&3 &7■ Circular Melody'

View File

@ -82,7 +82,6 @@ lore-format:
- '#mana-regeneration#'
- '#stamina-regeneration#'
- '#movement-speed#'
- '#staff-spirit#'
- '#lute-attack-effect#'
- '#two-handed#'
- '#handworn#'