Created
March 30, 2019 04:28
-
-
Save aikar/766d5c3ac4afcdfdf60588da912b7747 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
* Copyright (c) 2016. Starlis LLC / dba Empire Minecraft | |
* | |
* This source code is proprietary software and must not be redistributed without Starlis LLC's approval | |
* | |
*/ | |
package com.empireminecraft.util; | |
import com.empireminecraft.api.meta.Meta; | |
import com.empireminecraft.api.meta.MetaKey.PersistentKey; | |
import com.empireminecraft.config.meta.ItemKeys; | |
import com.empireminecraft.features.items.FinalItems; | |
import com.empireminecraft.features.items.FragileItems; | |
import com.empireminecraft.features.items.GamesItems; | |
import com.empireminecraft.features.items.SoulboundItems; | |
import com.empireminecraft.features.items.TemporaryItems; | |
import com.empireminecraft.features.items.UnbreakableItems; | |
import com.empireminecraft.features.items.UnplaceableItem; | |
import com.empireminecraft.features.items.WearableItems; | |
import org.bukkit.ChatColor; | |
import org.bukkit.Material; | |
import org.bukkit.enchantments.Enchantment; | |
import org.bukkit.entity.HumanEntity; | |
import org.bukkit.inventory.ItemFlag; | |
import org.bukkit.inventory.ItemStack; | |
import org.bukkit.inventory.meta.ItemMeta; | |
import org.jetbrains.annotations.NotNull; | |
import java.util.ArrayList; | |
import java.util.HashMap; | |
import java.util.List; | |
import java.util.Map; | |
import java.util.UUID; | |
public class LoreBuilder { | |
private static final int LOREMETA_INDEX = 30; | |
private static final String LOREMETA_TAG = "&&::META"; | |
private final ItemStack item; | |
private final ItemMeta meta; | |
private final List<String> lore; | |
private int index = 0; | |
/** | |
* Initiates a builder and sets the index to the first empty line after the lore | |
* | |
* @param item | |
*/ | |
public LoreBuilder(@NotNull ItemStack item) { | |
if (item.getType() == Material.AIR || !item.getType().isItem()) { | |
throw new IllegalArgumentException("Can not pass AIR/Non-item types to LoreBuilder"); | |
} | |
this.item = item; | |
this.meta = item.getItemMeta(); | |
if (item.hasItemMeta() && meta.hasLore()) { | |
this.lore = meta.getLore(); | |
} else { | |
this.lore = new ArrayList<>(); | |
} | |
if (lore.size() <= LOREMETA_INDEX - 2) { | |
index = lore.size(); | |
} else { | |
for (int i = LOREMETA_INDEX - 2; i >= 0; i--) { | |
if (!lore.get(i).isEmpty()) { | |
index = i + 1; | |
break; | |
} | |
} | |
} | |
} | |
public Map<String, String> getMeta() { | |
Map<String, String> meta = new HashMap<>(); | |
if (LOREMETA_INDEX + 1 < lore.size()) { | |
for (int i = LOREMETA_INDEX + 1; i + 1 < lore.size(); i += 2) { | |
String key = lore.get(i); | |
String val = lore.get(i + 1); | |
meta.put(key, val); | |
} | |
} | |
return meta; | |
} | |
/** | |
* Clears all lore on this item, preserving metadata. | |
* | |
* @return | |
*/ | |
public LoreBuilder clear() { | |
index = 0; | |
if (lore.size() <= LOREMETA_INDEX) { | |
lore.clear(); | |
} else { | |
for (int i = 0; i < LOREMETA_INDEX; i++) { | |
lore.set(i, ""); | |
} | |
} | |
return this; | |
} | |
/** | |
* Clears all metadata on this item, preserving lore. | |
* | |
* @return | |
*/ | |
public LoreBuilder clearMeta() { | |
if (lore.size() > LOREMETA_INDEX) { | |
for (int i = LOREMETA_INDEX; i < lore.size(); i++) { | |
lore.set(i, ""); | |
} | |
for (int i = lore.size() - 1; i >= 0; i--) { | |
if (lore.get(i).isEmpty()) { | |
lore.remove(i); | |
} else { | |
break; | |
} | |
} | |
} | |
return this; | |
} | |
public LoreBuilder setName(String name) { | |
meta.setDisplayName(Util.color(name)); | |
return this; | |
} | |
public ItemStack getItemStack() { | |
return item; | |
} | |
public LoreBuilder makeShiny(boolean shiny) { | |
if (shiny) { | |
makeShiny(); | |
} | |
return this; | |
} | |
public LoreBuilder makeShiny() { | |
ensure(LOREMETA_INDEX - 1); | |
lore.set(LOREMETA_INDEX - 1, "&&::SHINY"); | |
return this; | |
} | |
public LoreBuilder makeWearable() { | |
int oldindex = index; | |
WearableItems.makeWearable(this); | |
index = oldindex + 1; | |
return this; | |
} | |
public LoreBuilder makeSoulbound() { | |
int oldindex = index; | |
SoulboundItems.makeSoulbound(this); | |
index = oldindex + 1; | |
return this; | |
} | |
public LoreBuilder makeFinal() { | |
int oldindex = index; | |
FinalItems.makeFinal(this); | |
index = oldindex + 1; | |
return this; | |
} | |
public LoreBuilder makeFragile() { | |
int oldindex = index; | |
FragileItems.makeFragile(this); | |
index = oldindex + 1; | |
return this; | |
} | |
public LoreBuilder makeUnplaceable() { | |
int oldindex = index; | |
UnplaceableItem.makeUnplaceable(this); | |
index = oldindex + 1; | |
return this; | |
} | |
public LoreBuilder makeUnbreakable() { | |
int oldindex = index; | |
UnbreakableItems.makeUnbreakable(this); | |
index = oldindex + 1; | |
return this; | |
} | |
public LoreBuilder makeTemporary() { | |
makeTemporary(0); | |
return this; | |
} | |
public LoreBuilder makeTemporary(int timeLimit) { | |
int oldindex = index; | |
TemporaryItems.makeTemporary(this, timeLimit); | |
index = oldindex + 1; | |
return this; | |
} | |
public LoreBuilder makeGamesItem() { | |
int oldindex = index; | |
GamesItems.makeGamesItem(this); | |
index = oldindex + 1; | |
return this; | |
} | |
public LoreBuilder makeUnclaimable() { | |
return this.setFlag(ItemKeys.UNCLAIMABLE); | |
} | |
public boolean hasFlag(PersistentKey key) { | |
return getIntMeta(key, 0) != 0; | |
} | |
public LoreBuilder setFlag(PersistentKey flag) { | |
return this.setMeta(flag, "1"); | |
} | |
public int getRepairCost(HumanEntity entity) { | |
String cost = getMeta(Meta.createPersistentKey("RepairCost_" + entity.getUniqueId())); | |
return Util.parseInt(cost, 0); | |
} | |
public LoreBuilder setRepairCost(HumanEntity entity, int cost) { | |
setMeta(Meta.createPersistentKey("RepairCost_" + entity.getUniqueId()), cost == 0 ? null : String.valueOf(cost)); | |
return this; | |
} | |
/** | |
* Changes the current index | |
* | |
* @param i | |
* @return | |
*/ | |
public LoreBuilder index(int i) { | |
index = i; | |
return this; | |
} | |
/** | |
* Shifts to the previous index | |
* | |
* @return | |
*/ | |
public LoreBuilder prev() { | |
index--; | |
return this; | |
} | |
/** | |
* Shifts to the next index | |
* | |
* @return | |
*/ | |
public LoreBuilder next() { | |
index++; | |
return this; | |
} | |
/** | |
* Sets the current index to an empty line | |
* | |
* @return | |
*/ | |
public LoreBuilder empty() { | |
return add(index, ""); | |
} | |
/** | |
* Inserts a line of lore after the last used index, shifting up any following lines if they existed. | |
* | |
* @param line | |
* @return | |
*/ | |
public LoreBuilder add(String line) { | |
return add(index, line); | |
} | |
/** | |
* Inserts the specified line at the index. If the line was already set, it will be shifted up 1. | |
* | |
* @param i | |
* @param line | |
* @return | |
*/ | |
public LoreBuilder add(int i, String line) { | |
if (line == null) { | |
return this; | |
} | |
ensure(i - 1); | |
String lastColor = ""; | |
for (String splitLine : Patterns.NEWLINE.split(Util.color(line))) { | |
splitLine = lastColor + splitLine; | |
lore.add(i, splitLine); | |
lastColor = ChatColor.getLastColors(splitLine); | |
index = ++i; | |
} | |
while (lore.size() > LOREMETA_INDEX && !lore.get(LOREMETA_INDEX).equals(LOREMETA_TAG)) { | |
lore.remove(LOREMETA_INDEX - 10); | |
} | |
return this; | |
} | |
/** | |
* Sets the line at the specified index, replacing it if already there. | |
* | |
* @param i | |
* @param line | |
* @return | |
*/ | |
public LoreBuilder set(int i, String line) { | |
ensure(i); | |
lore.set(i, Util.color(line)); | |
index = i + 1; | |
return this; | |
} | |
/** | |
* Stores meta data about this item in hidden lore fields | |
* | |
* @param key | |
* @param line | |
* @return | |
*/ | |
public LoreBuilder setMeta(PersistentKey key, String line) { | |
return setMeta(key.key(), line); | |
} | |
public LoreBuilder setMeta(PersistentKey key, UUID line) { | |
return setMeta(key.key(), line.toString()); | |
} | |
public LoreBuilder setMeta(PersistentKey key, Number line) { | |
return setMeta(key.key(), String.valueOf(line)); | |
} | |
/** | |
* @deprecated You should use PMeta Keys | |
*/ | |
@Deprecated | |
private LoreBuilder setMeta(String key, String line) { | |
ensure(LOREMETA_INDEX); | |
lore.set(LOREMETA_INDEX, LOREMETA_TAG); | |
for (int i = LOREMETA_INDEX + 1; i < lore.size(); i += 2) { | |
if (lore.get(i).equalsIgnoreCase(key)) { | |
if (i + 1 == lore.size()) { // Broken meta... | |
if (line == null) { | |
lore.remove(i); | |
} else { | |
lore.add(i + 1, line); | |
} | |
} else { | |
if (line == null) { | |
lore.remove(i+1); | |
lore.remove(i); | |
} else { | |
lore.set(i + 1, line); | |
} | |
} | |
return this; | |
} | |
} | |
// Add new | |
lore.add(key); | |
lore.add(line); | |
return this; | |
} | |
/** | |
* Gets the specified meta value out of the items lore, defaulting to null | |
* | |
* @param key | |
* @return | |
*/ | |
public String getMeta(PersistentKey key) { | |
return getMeta(key.key(), null); | |
} | |
/** | |
* Gets the specified meta value out of the items lore, with supplied default | |
* | |
* @param key | |
* @param def | |
* @return | |
*/ | |
public String getMeta(PersistentKey key, String def) { | |
return getMeta(key.key(), def); | |
} | |
/** | |
* @deprecated You should use PMeta Keys | |
*/ | |
@Deprecated | |
private String getMeta(String key, String def) { | |
if (LOREMETA_INDEX + 1 < lore.size()) { | |
for (int i = LOREMETA_INDEX + 1; i + 1 < lore.size(); i += 2) { | |
if (lore.get(i).equalsIgnoreCase(key)) { | |
return lore.get(i + 1); | |
} | |
} | |
} | |
return def; | |
} | |
public Integer getIntMeta(PersistentKey key) { | |
return getIntMeta(key, null); | |
} | |
public Integer getIntMeta(PersistentKey key, Integer def) { | |
String meta = getMeta(key); | |
if (meta == null) { | |
return def; | |
} | |
return Util.parseInt(meta, def); | |
} | |
public Long getLongMeta(PersistentKey key) { | |
return getLongMeta(key, null); | |
} | |
public Long getLongMeta(PersistentKey key, Long def) { | |
String meta = getMeta(key); | |
if (meta == null) { | |
return def; | |
} | |
return Util.parseLong(meta, def); | |
} | |
public boolean hasMeta(PersistentKey key) { | |
return getMeta(key) != null; | |
} | |
/** | |
* @param idx | |
*/ | |
private void ensure(int idx) { | |
// empty lines if they are not set. | |
for (int i = lore.size(); i <= idx; i++) { | |
lore.add(i, ""); | |
} | |
} | |
public ItemStack save() { | |
meta.setLore(lore); | |
item.setItemMeta(meta); | |
return item; | |
} | |
public LoreBuilder enchant(Enchantment enchantment, int level) { | |
meta.addEnchant(enchantment, level, true); | |
return this; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment