Added 'SKIN' item type

Applies CMD and other cosmetic things when applied to another item.
Updated version number to 5.1.2
This commit is contained in:
Aria 2019-12-09 21:44:48 +01:00
parent 12d21d1b8b
commit 51e8979a3c
13 changed files with 284 additions and 14 deletions

View File

@ -4,7 +4,7 @@
<modelVersion>4.0.0</modelVersion>
<groupId>net.Indyuce</groupId>
<artifactId>MMOItems</artifactId>
<version>5.1.1-SNAPSHOT</version>
<version>5.1.2-SNAPSHOT</version>
<name>MMOItems</name>
<description>A great item solution for your RPG server.</description>

View File

@ -46,6 +46,7 @@ public class Type {
public static final Type CONSUMABLE = new Type(TypeSet.EXTRA, "CONSUMABLE", false, false, true, EquipmentSlot.MAIN_HAND);
public static final Type MISCELLANEOUS = new Type(TypeSet.EXTRA, "MISCELLANEOUS", false, false, true, EquipmentSlot.MAIN_HAND);
public static final Type GEM_STONE = new Type(TypeSet.EXTRA, "GEM_STONE", false, false, true, EquipmentSlot.OTHER);
public static final Type SKIN = new Type(TypeSet.EXTRA, "SKIN", false, false, true, EquipmentSlot.OTHER);
public static final Type ACCESSORY = new Type(TypeSet.EXTRA, "ACCESSORY", false, false, true, EquipmentSlot.ACCESSORY);
private final String id;

View File

@ -0,0 +1,120 @@
package net.Indyuce.mmoitems.api.interaction;
import java.lang.reflect.Field;
import org.bukkit.ChatColor;
import org.bukkit.Sound;
import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.ItemMeta;
import net.Indyuce.mmoitems.MMOItems;
import net.Indyuce.mmoitems.MMOUtils;
import net.Indyuce.mmoitems.api.Type;
import net.Indyuce.mmoitems.api.item.NBTItem;
import net.Indyuce.mmoitems.api.util.message.Message;
import net.Indyuce.mmoitems.stat.Skull_Texture.SkullTextureData;
import net.Indyuce.mmoitems.stat.data.StringListData;
import net.Indyuce.mmoitems.stat.type.ItemStat;
import net.Indyuce.mmoitems.version.VersionMaterial;
import net.Indyuce.mmoitems.version.nms.ItemTag;
public class ItemSkin extends UseItem {
public ItemSkin(Player player, NBTItem item, Type type) {
super(player, item, type);
}
public ApplyResult applyOntoItem(NBTItem target, Type targetType) {
if(targetType == Type.SKIN)
return new ApplyResult(ResultType.NONE);
if(MMOItems.plugin.getConfig().getBoolean("locked-skins") && target.getBoolean("MMOITEMS_HAS_SKIN")) {
player.playSound(player.getLocation(), Sound.ENTITY_PLAYER_LEVELUP, 1, 2);
Message.SKIN_REJECTED.format(ChatColor.RED, "#item#", MMOUtils.getDisplayName(target.getItem())).send(player);
return new ApplyResult(ResultType.NONE);
}
boolean compatible = false;
if(getMMOItem().hasData(ItemStat.COMPATIBLE_TYPES)) {
for(String type : ((StringListData) getMMOItem().getData(ItemStat.COMPATIBLE_TYPES)).getList()) {
if(type.equalsIgnoreCase(targetType.getId())) {
compatible = true;
break;
}
}
if(!compatible){
player.playSound(player.getLocation(), Sound.ENTITY_PLAYER_LEVELUP, 1, 2);
Message.SKIN_INCOMPATIBLE.format(ChatColor.RED, "#item#", MMOUtils.getDisplayName(target.getItem())).send(player);
return new ApplyResult(ResultType.NONE);
}
}
// check for success rate
double successRate = getNBTItem().getStat(ItemStat.SUCCESS_RATE);
if (successRate != 0)
if (random.nextDouble() < 1 - successRate / 100) {
player.playSound(player.getLocation(), Sound.ENTITY_ITEM_BREAK, 1, 1);
Message.SKIN_BROKE.format(ChatColor.RED, "#item#", MMOUtils.getDisplayName(target.getItem())).send(player);
return new ApplyResult(ResultType.FAILURE);
}
// Apply skin
target.addTag(new ItemTag("MMOITEMS_HAS_SKIN", true));
if(getNBTItem().getInteger("CustomModelData") != 0) target.addTag(new ItemTag("CustomModelData", getNBTItem().getInteger("CustomModelData")));
if(!getNBTItem().getString("MMOITEMS_ITEM_PARTICLES").isEmpty()) target.addTag(new ItemTag("MMOITEMS_ITEM_PARTICLES", getNBTItem().getString("MMOITEMS_ITEM_PARTICLES")));
ItemStack item = target.toItem();
if(item.getType() != getNBTItem().getItem().getType())
item.setType(getNBTItem().getItem().getType());
ItemMeta meta = item.getItemMeta();
if (getMMOItem().hasData(ItemStat.SKULL_TEXTURE) && item.getType() == VersionMaterial.PLAYER_HEAD.toMaterial() &&
getNBTItem().getItem().getType() == VersionMaterial.PLAYER_HEAD.toMaterial()) {
try {
Field profileField = meta.getClass().getDeclaredField("profile"); profileField.setAccessible(true);
profileField.set(meta, ((SkullTextureData) getMMOItem().getData(ItemStat.SKULL_TEXTURE)).getGameProfile());
} catch (NoSuchFieldException | IllegalArgumentException | IllegalAccessException e) {
MMOItems.plugin.getLogger().warning("Could not read skull texture");
}
}
item.setItemMeta(meta);
player.playSound(player.getLocation(), Sound.ENTITY_PLAYER_LEVELUP, 1, 2);
Message.SKIN_APPLIED.format(ChatColor.YELLOW, "#item#", MMOUtils.getDisplayName(target.getItem())).send(player);
return new ApplyResult(item);
}
public class ApplyResult {
private ResultType type;
private ItemStack result;
public ApplyResult(ResultType type) {
this(null, type);
}
public ApplyResult(ItemStack result) {
this(result, ResultType.SUCCESS);
}
public ApplyResult(ItemStack result, ResultType type) {
this.type = type;
this.result = result;
}
public ResultType getType() {
return type;
}
public ItemStack getResult() {
return result;
}
}
public enum ResultType {
FAILURE,
NONE,
SUCCESS;
}
}

View File

@ -100,6 +100,8 @@ public class UseItem {
public static UseItem getItem(Player player, NBTItem item, Type type) {
if (type.corresponds(Type.CONSUMABLE))
return new Consumable(player, item, type);
if (type.corresponds(Type.SKIN))
return new ItemSkin(player, item, type);
if (type.corresponds(Type.GEM_STONE))
return new GemStone(player, item, type);
if (type.corresponds(Type.MUSKET))

View File

@ -39,6 +39,10 @@ public enum Message {
GEM_STONE_APPLIED("You successfully applied &6#gem#&e onto your &6#item#&e."),
GEM_STONE_BROKE("Your gem stone &6#gem#&c broke while trying to apply it onto &6#item#&c."),
REPAIRED_ITEM("You successfully repaired &6#item#&e for &6#amount# &euses."),
SKIN_APPLIED("You successfully applied the skin onto your &6#item#&e!"),
SKIN_BROKE("Your skin broke while trying to apply it onto your &6#item#&c."),
SKIN_REJECTED("A skin has already been applied onto your &6#item#&c!"),
SKIN_INCOMPATIBLE("This skin is not compatible with your &6#item#&c!"),
// advanced workbennch
ADVANCED_WORKBENCH("Advanced Workbench"),

View File

@ -31,8 +31,7 @@ import net.Indyuce.mmoitems.api.Type;
import net.Indyuce.mmoitems.api.TypeSet;
import net.Indyuce.mmoitems.api.interaction.Consumable;
import net.Indyuce.mmoitems.api.interaction.GemStone;
import net.Indyuce.mmoitems.api.interaction.GemStone.ApplyResult;
import net.Indyuce.mmoitems.api.interaction.GemStone.ResultType;
import net.Indyuce.mmoitems.api.interaction.ItemSkin;
import net.Indyuce.mmoitems.api.interaction.Tool;
import net.Indyuce.mmoitems.api.interaction.UseItem;
import net.Indyuce.mmoitems.api.interaction.weapon.Gauntlet;
@ -232,19 +231,37 @@ public class ItemUse implements Listener {
if (!useItem.canBeUsed())
return;
if (useItem instanceof GemStone) {
if (useItem instanceof ItemSkin) {
NBTItem picked = MMOItems.plugin.getNMS().getNBTItem(event.getCurrentItem());
if (!picked.hasType())
return;
ApplyResult result = ((GemStone) useItem).applyOntoItem(picked, picked.getType());
if (result.getType() == ResultType.NONE)
ItemSkin.ApplyResult result = ((ItemSkin) useItem).applyOntoItem(picked, picked.getType());
if (result.getType() == ItemSkin.ResultType.NONE)
return;
event.setCancelled(true);
item.getItem().setAmount(item.getItem().getAmount() - 1);
if (result.getType() == ResultType.FAILURE)
if (result.getType() == ItemSkin.ResultType.FAILURE)
return;
event.setCurrentItem(result.getResult());
}
if (useItem instanceof GemStone) {
NBTItem picked = MMOItems.plugin.getNMS().getNBTItem(event.getCurrentItem());
if (!picked.hasType())
return;
GemStone.ApplyResult result = ((GemStone) useItem).applyOntoItem(picked, picked.getType());
if (result.getType() == GemStone.ResultType.NONE)
return;
event.setCancelled(true);
item.getItem().setAmount(item.getItem().getAmount() - 1);
if (result.getType() == GemStone.ResultType.FAILURE)
return;
event.setCurrentItem(result.getResult());

View File

@ -22,7 +22,7 @@ public class TypeManager {
public void reload() {
map.clear();
addAll(Type.ACCESSORY, Type.ARMOR, Type.BOW, Type.CATALYST, Type.CONSUMABLE, Type.CROSSBOW, Type.DAGGER,
Type.GAUNTLET,Type.GEM_STONE, Type.HAMMER, Type.LUTE, Type.MISCELLANEOUS, Type.MUSKET, Type.OFF_CATALYST,
Type.GAUNTLET,Type.GEM_STONE, Type.SKIN, Type.HAMMER, Type.LUTE, Type.MISCELLANEOUS, Type.MUSKET, Type.OFF_CATALYST,
Type.ORNAMENT, Type.SPEAR, Type.STAFF, Type.SWORD, Type.TOOL, Type.WHIP);
/*

View File

@ -0,0 +1,110 @@
package net.Indyuce.mmoitems.stat;
import java.util.ArrayList;
import java.util.List;
import org.bukkit.ChatColor;
import org.bukkit.Material;
import org.bukkit.configuration.ConfigurationSection;
import org.bukkit.configuration.file.FileConfiguration;
import org.bukkit.event.inventory.InventoryAction;
import org.bukkit.event.inventory.InventoryClickEvent;
import org.bukkit.inventory.ItemStack;
import com.google.gson.JsonArray;
import com.google.gson.JsonParser;
import net.Indyuce.mmoitems.MMOItems;
import net.Indyuce.mmoitems.api.ConfigFile;
import net.Indyuce.mmoitems.api.edition.StatEdition;
import net.Indyuce.mmoitems.api.item.MMOItem;
import net.Indyuce.mmoitems.api.item.NBTItem;
import net.Indyuce.mmoitems.api.item.build.MMOItemBuilder;
import net.Indyuce.mmoitems.api.util.AltChar;
import net.Indyuce.mmoitems.gui.edition.EditionInventory;
import net.Indyuce.mmoitems.stat.data.StatData;
import net.Indyuce.mmoitems.stat.data.StringListData;
import net.Indyuce.mmoitems.stat.type.ItemStat;
import net.Indyuce.mmoitems.stat.type.StringStat;
import net.Indyuce.mmoitems.version.nms.ItemTag;
public class Compatible_Types extends StringStat {
public Compatible_Types() {
super(new ItemStack(Material.COMMAND_BLOCK), "Compatible Types", new String[] { "The item types this skin is", "compatible with." }, "compatible-types", new String[] { "skin" });
}
@Override
public boolean whenClicked(EditionInventory inv, InventoryClickEvent event) {
ConfigFile config = inv.getItemType().getConfigFile();
if (event.getAction() == InventoryAction.PICKUP_ALL)
new StatEdition(inv, ItemStat.COMPATIBLE_TYPES).enable("Write in the chat the name of the type you want to add.");
if (event.getAction() == InventoryAction.PICKUP_HALF) {
if (config.getConfig().getConfigurationSection(inv.getItemId()).contains("compatible-types")) {
List<String> lore = config.getConfig().getStringList(inv.getItemId() + ".compatible-types");
if (lore.size() < 1)
return true;
String last = lore.get(lore.size() - 1);
lore.remove(last);
config.getConfig().set(inv.getItemId() + ".compatible-types", lore);
inv.registerItemEdition(config);
inv.open();
inv.getPlayer().sendMessage(MMOItems.plugin.getPrefix() + "Successfully removed '" + ChatColor.translateAlternateColorCodes('&', last) + ChatColor.GRAY + "'.");
}
}
return true;
}
@Override
public boolean whenInput(EditionInventory inv, ConfigFile config, String message, Object... info) {
List<String> lore = config.getConfig().getConfigurationSection(inv.getItemId()).contains("compatible-types") ? config.getConfig().getStringList(inv.getItemId() + ".compatible-types") : new ArrayList<>();
lore.add(message.toUpperCase());
config.getConfig().set(inv.getItemId() + ".compatible-types", lore);
inv.registerItemEdition(config);
inv.open();
inv.getPlayer().sendMessage(MMOItems.plugin.getPrefix() + "Compatible Types successfully added.");
return true;
}
@Override
public void whenDisplayed(List<String> lore, FileConfiguration config, String path) {
lore.add("");
lore.add(ChatColor.GRAY + "Current Value:");
if (!config.getConfigurationSection(path).contains("compatible-types"))
lore.add(ChatColor.RED + "No compatible types.");
else if (config.getStringList(path + ".compatible-types").isEmpty())
lore.add(ChatColor.RED + "No compatible types.");
else
config.getStringList(path + ".compatible-types").forEach(str -> lore.add(ChatColor.GRAY + ChatColor.translateAlternateColorCodes('&', str)));
lore.add("");
lore.add(ChatColor.YELLOW + AltChar.listDash + " Click to add a new type.");
lore.add(ChatColor.YELLOW + AltChar.listDash + " Right click to remove the last type.");
}
@Override
public boolean whenLoaded(MMOItem item, ConfigurationSection config) {
item.setData(ItemStat.COMPATIBLE_TYPES, new StringListData(config.getStringList("compatible-types")));
return true;
}
@Override
public boolean whenApplied(MMOItemBuilder item, StatData data) {
List<String> compatibleTypes = new ArrayList<>();
JsonArray array = new JsonArray();
((StringListData) data).getList().forEach(line -> {
line = ChatColor.translateAlternateColorCodes('&', line);
array.add(line);
compatibleTypes.add(line);
});
item.getLore().insert("compatible-types", compatibleTypes);
item.addItemTag(new ItemTag("MMOITEMS_COMPATIBLE_TYPES", array.toString()));
return true;
}
@Override
public void whenLoaded(MMOItem mmoitem, NBTItem item) {
if (item.hasTag("MMOITEMS_COMPATIBLE_TYPES"))
mmoitem.setData(ItemStat.COMPATIBLE_TYPES, new StringListData(new JsonParser().parse(item.getString("MMOITEMS_COMPATIBLE_TYPES")).getAsJsonArray()));
}
}

View File

@ -13,7 +13,7 @@ import net.Indyuce.mmoitems.stat.type.ItemStat;
public class Hide_Potion_Effects extends BooleanStat {
public Hide_Potion_Effects() {
super(new ItemStack(Material.POTION), "Hide Potion Effects", new String[] { "Hides potion effects & 'No Effects'", "from your item lore." }, "hide-potion-effects", new String[] { "all" }, Material.POTION, Material.SPLASH_POTION, Material.LINGERING_POTION);
super(new ItemStack(Material.POTION), "Hide Potion Effects", new String[] { "Hides potion effects & 'No Effects'", "from your item lore." }, "hide-potion-effects", new String[] { "all" }, Material.POTION, Material.SPLASH_POTION, Material.LINGERING_POTION, Material.TIPPED_ARROW);
}
@Override

View File

@ -185,10 +185,8 @@ public class Potion_Effects extends StringStat {
@Override
public boolean whenApplied(MMOItemBuilder item, StatData data) {
if (item.getMaterial().name().contains("POTION") || item.getMaterial() == Material.TIPPED_ARROW)
((EffectListData) data).getEffects().forEach(effect -> {
((PotionMeta) item.getMeta()).clearCustomEffects();
for(PotionEffectData effect : ((EffectListData) data).getEffects())
((PotionMeta) item.getMeta()).addCustomEffect(effect.toEffect(), false);
});
return true;
}
}

View File

@ -25,6 +25,7 @@ import net.Indyuce.mmoitems.stat.Arrow_Particles;
import net.Indyuce.mmoitems.stat.Attack_Damage;
import net.Indyuce.mmoitems.stat.Attack_Speed;
import net.Indyuce.mmoitems.stat.Commands;
import net.Indyuce.mmoitems.stat.Compatible_Types;
import net.Indyuce.mmoitems.stat.Crafting_Recipe;
import net.Indyuce.mmoitems.stat.CustomSounds;
import net.Indyuce.mmoitems.stat.Custom_Model_Data;
@ -138,8 +139,9 @@ public abstract class ItemStat {
public static final ItemStat DISABLE_RIGHT_CLICK_CONSUME = new DisableStat(Material.BARRIER, "right-click-consume", "Disable Right Click Consume", new String[] { "consumable" }, "This item will not be consumed", "when eaten by players.");
public static final ItemStat VANILLA_EATING_ANIMATION = new Vanilla_Eating_Animation(), INEDIBLE = new Inedible(), GEM_COLOR = new Gem_Color(), ITEM_TYPE_RESTRICTION = new Item_Type_Restriction();
public static final ItemStat SUCCESS_RATE = new DoubleStat(new ItemStack(Material.EMERALD), "Success Rate", new String[] { "The chance of your gem to successfully", "apply onto an item. This value is 100%", "by default. If it is not successfully", "applied, the gem stone will be lost." }, "success-rate", new String[] { "gem_stone" });
public static final ItemStat SUCCESS_RATE = new DoubleStat(new ItemStack(Material.EMERALD), "Success Rate", new String[] { "The chance of your gem to successfully", "apply onto an item. This value is 100%", "by default. If it is not successfully", "applied, the gem stone will be lost." }, "success-rate", new String[] { "gem_stone", "skin" });
public static final ItemStat COMPATIBLE_TYPES = new Compatible_Types();
public static final ItemStat CRAFTING_RECIPE = new Crafting_Recipe(), FURNACE_RECIPE = new Furnace_Recipe(), SHAPELESS_RECIPE = new Shapeless_Recipe(), ADVANCED_CRAFTING_RECIPE = new Advanced_Crafting_Recipe(), ADVANCED_CRAFTING_RECIPE_PERMISSION = new Advanced_Crafting_Recipe_Permission();
public static final ItemStat AUTOSMELT = new BooleanStat(new ItemStack(Material.COAL), "Autosmelt", new String[] { "If set to true, your tool will", "automaticaly smelt mined ores." }, "autosmelt", new String[] { "tool" });
public static final ItemStat BOUNCING_CRACK = new BooleanStat(new ItemStack(VersionMaterial.COBBLESTONE_WALL.toMaterial()), "Bouncing Crack", new String[] { "If set to true, your tool will", "also break nearby blocks." }, "bouncing-crack", new String[] { "tool" });

View File

@ -25,6 +25,9 @@ use-item-caching: true
# it CAN cause lag and/or take a lot of memory.
iterate-whole-inventory: false
# When this is set to true, skins can only be applied to an item ONCE.
locked-skins: true
# Enable/Disable abilities in the players offhand, stops
# players using abilities when interacting with chests, mining etc.
# Very useful if your have a lot of items that your players use in their

View File

@ -265,6 +265,19 @@ MISCELLANEOUS:
- '{range}&8- &7Lvl Range: &e#range#'
- '{tier}&8- &7Item Tier: #prefix##tier#'
SKIN:
display: LEATHER
name: 'Skin'
unident-item:
name: '&f#prefix#Unidentified Skin Item'
lore:
- '&7This item is unidentified. I must'
- '&7find a way to identify it!'
- '{tier}'
- '{tier}&8Item Info:'
- '{range}&8- &7Lvl Range: &e#range#'
- '{tier}&8- &7Item Tier: #prefix##tier#'
GEM_STONE:
display: EMERALD
name: 'Gem Stone'