1313import org .bukkit .configuration .ConfigurationSection ;
1414import org .bukkit .configuration .file .FileConfiguration ;
1515import org .bukkit .configuration .file .YamlConfiguration ;
16+ import org .bukkit .enchantments .Enchantment ;
1617import org .bukkit .entity .Player ;
18+ import org .bukkit .inventory .ItemFlag ;
1719import org .bukkit .inventory .ItemStack ;
20+ import org .bukkit .inventory .meta .Damageable ;
1821import org .bukkit .inventory .meta .ItemMeta ;
1922import org .bukkit .persistence .PersistentDataType ;
2023import org .bukkit .plugin .java .JavaPlugin ;
@@ -29,7 +32,8 @@ public final class ItemManager {
2932
3033 private ItemManager () {}
3134
32- private static final NamespacedKey namespace = new NamespacedKey (JavaPlugin .getPlugin (ItemsPlugin .class ), "itemid" );
35+ private static final NamespacedKey ID_KEY = new NamespacedKey (JavaPlugin .getPlugin (ItemsPlugin .class ), "itemid" );
36+ private static final NamespacedKey USES_KEY = new NamespacedKey (JavaPlugin .getPlugin (ItemsPlugin .class ), "itemuses" );
3337 private static final Map <String , BendingItem > NAME_CACHE = new HashMap <>();
3438 private static final Map <Integer , BendingItem > ID_CACHE = new HashMap <>();
3539 private static final Map <Player , BendingItem > EQUIPPED = new HashMap <>();
@@ -40,6 +44,10 @@ private ItemManager() {}
4044 private static final String DURABILITY_PATH = "Durability" ;
4145 private static final String USAGE_PATH = "Usage" ;
4246 private static final String ELEMENT_PATH = "Element" ;
47+ private static final String UNBREAKABLE_PATH = "Unbreakable" ;
48+ private static final String ENCHANTS_PATH = "Enchants" ;
49+ private static final String FLAGS_PATH = "Flags" ;
50+ private static final String USES_PATH = "Uses" ;
4351
4452 public static void equip (Player player , BendingItem item ) {
4553 EQUIPPED .put (player , item );
@@ -57,6 +65,34 @@ public static boolean matches(Player player, ItemStack item) {
5765 return EQUIPPED .containsKey (player ) && EQUIPPED .get (player ).isSimilar (item );
5866 }
5967
68+ public static void modify (CoreAbility ability ) {
69+ Player player = ability .getPlayer ();
70+
71+ BendingItem main = get (player .getInventory ().getItemInMainHand ()), off = get (player .getInventory ().getItemInOffHand ());
72+
73+ if (main != null && main .getUsage () == Usage .HOLDING ) {
74+ main .applyMods (ability , player .getInventory ().getItemInMainHand ());
75+ }
76+
77+ if (off != null && off .getUsage () == Usage .HOLDING ) {
78+ off .applyMods (ability , player .getInventory ().getItemInOffHand ());
79+ }
80+
81+ for (ItemStack is : player .getInventory ().getArmorContents ()) {
82+ BendingItem item = get (is );
83+ if (item != null && (item .getUsage () == Usage .WEARING || item .getUsage () == Usage .POSSESS )) {
84+ item .applyMods (ability , is );
85+ }
86+ }
87+
88+ for (ItemStack is : player .getInventory ().getStorageContents ()) {
89+ BendingItem item = get (is );
90+ if (item != null && item .getUsage () == Usage .POSSESS ) {
91+ item .applyMods (ability , is );
92+ }
93+ }
94+ }
95+
6096 public static List <BendingItem > listActive (Player player ) {
6197 List <BendingItem > actives = new ArrayList <>();
6298
@@ -96,16 +132,34 @@ public static BendingItem get(int id) {
96132 }
97133
98134 public static BendingItem get (ItemStack item ) {
99- BendingItem bItem = ID_CACHE .get (getID (item ));
135+ int id = getID (item );
136+ BendingItem bItem = ID_CACHE .get (id );
100137
101- if (bItem != null && !bItem .isSimilar (item )) {
138+ if (( bItem == null && id > - 1 ) || ( bItem != null && !bItem .isSimilar (item ) )) {
102139 removeID (item );
103140 return null ;
104141 }
105142
106143 return bItem ;
107144 }
108145
146+ public static void use (Player player , ItemStack item ) {
147+ if (!item .hasItemMeta () || !item .getItemMeta ().getPersistentDataContainer ().has (USES_KEY , PersistentDataType .INTEGER )) {
148+ return ;
149+ }
150+
151+ ItemMeta meta = item .getItemMeta ();
152+ int uses = meta .getPersistentDataContainer ().get (USES_KEY , PersistentDataType .INTEGER );
153+ if (uses == 1 ) {
154+ player .getInventory ().remove (item );
155+ } else {
156+ meta .getPersistentDataContainer ().set (USES_KEY , PersistentDataType .INTEGER , uses - 1 );
157+ item .setItemMeta (meta );
158+ }
159+
160+ player .updateInventory ();
161+ }
162+
109163 public static List <BendingItem > listItems () {
110164 return new ArrayList <>(ID_CACHE .values ());
111165 }
@@ -154,7 +208,7 @@ public static BendingItem register(File file) throws IllegalArgumentException {
154208 ItemStack item = new ItemStack (mat );
155209 ItemMeta meta = item .getItemMeta ();
156210 List <String > lore = new ArrayList <>();
157- lore .add (ChatColor .DARK_GRAY + "Usage: " + usage .toString ());
211+ lore .add (ChatColor .DARK_GRAY + ( ChatColor . ITALIC + "Usage: " ) + usage .toString ());
158212
159213 if (config .contains (DISPLAY_PATH )) {
160214 meta .setDisplayName (ChatColor .translateAlternateColorCodes ('&' , config .getString (DISPLAY_PATH )));
@@ -166,14 +220,47 @@ public static BendingItem register(File file) throws IllegalArgumentException {
166220 lore .addAll (config .getStringList (LORE_PATH ).stream ().map ((s ) -> ChatColor .translateAlternateColorCodes ('&' , s )).collect (Collectors .toList ()));
167221 }
168222
169- /*
223+ if (config .contains (UNBREAKABLE_PATH )) {
224+ meta .setUnbreakable (config .getBoolean (UNBREAKABLE_PATH ));
225+ }
226+
170227 if (config .contains (DURABILITY_PATH ) && meta instanceof Damageable ) {
171- ((Damageable) meta).setDamage(config.getInt(DURABILITY_PATH));
228+ ((Damageable ) meta ).setDamage (-(config .getInt (DURABILITY_PATH ) - mat .getMaxDurability ()));
229+ }
230+
231+ if (config .contains (USES_PATH )) {
232+ meta .getPersistentDataContainer ().set (USES_KEY , PersistentDataType .INTEGER , config .getInt (USES_PATH ));
233+ }
234+
235+ if (config .contains (ENCHANTS_PATH )) {
236+ for (String enchant : config .getStringList (ENCHANTS_PATH )) {
237+ String [] split = enchant .split (":" );
238+
239+ if (split .length != 2 ) {
240+ continue ;
241+ }
242+
243+ try {
244+ meta .addEnchant (Enchantment .getByKey (NamespacedKey .minecraft (split [0 ])), Integer .parseInt (split [1 ]), true );
245+ } catch (NumberFormatException e ) {
246+ JavaPlugin .getPlugin (ItemsPlugin .class ).getLogger ().warning ("Unable to parse integer from '" + enchant + "' in enchants on item '" + name + "', ignoring." );
247+ } catch (Exception e ) {
248+ JavaPlugin .getPlugin (ItemsPlugin .class ).getLogger ().warning ("Unable to parse enchant from '" + enchant + "' in enchants on item '" + name + "', ignoring." );
249+ }
250+ }
172251 }
173- */
252+
253+ if (config .contains (FLAGS_PATH )) {
254+ for (String flag : config .getStringList (FLAGS_PATH )) {
255+ try {
256+ meta .addItemFlags (ItemFlag .valueOf (flag .toUpperCase ()));
257+ } catch (Exception e ) {}
258+ }
259+ }
260+
174261 int id = name .hashCode ();
175262 meta .setLore (lore );
176- meta .getPersistentDataContainer ().set (namespace , PersistentDataType .INTEGER , id );
263+ meta .getPersistentDataContainer ().set (ID_KEY , PersistentDataType .INTEGER , id );
177264 item .setItemMeta (meta );
178265
179266 Map <CoreAbility , List <BendingModifier >> mods = null ;
@@ -214,23 +301,32 @@ private static List<BendingModifier> loadMods(ConfigurationSection section) {
214301 private static int getID (ItemStack item ) {
215302 int id = -1 ;
216303
217- if (item != null && item .hasItemMeta () && item .getItemMeta ().getPersistentDataContainer ().has (namespace , PersistentDataType .INTEGER )) {
218- id = item .getItemMeta ().getPersistentDataContainer ().get (namespace , PersistentDataType .INTEGER );
304+ if (item != null && item .hasItemMeta () && item .getItemMeta ().getPersistentDataContainer ().has (ID_KEY , PersistentDataType .INTEGER )) {
305+ id = item .getItemMeta ().getPersistentDataContainer ().get (ID_KEY , PersistentDataType .INTEGER );
219306 }
220307
221308 return id ;
222309 }
223310
224311 private static void removeID (ItemStack item ) {
225- if (item != null && item .hasItemMeta () && item . getItemMeta (). getPersistentDataContainer (). has ( namespace , PersistentDataType . INTEGER )) {
226- item . getItemMeta (). getPersistentDataContainer (). remove ( namespace ) ;
312+ if (item == null || ! item .hasItemMeta ()) {
313+ return ;
227314 }
315+
316+ ItemMeta meta = item .getItemMeta ();
317+
318+ if (meta .getPersistentDataContainer ().has (ID_KEY , PersistentDataType .INTEGER )) {
319+ meta .getPersistentDataContainer ().remove (ID_KEY );
320+ }
321+
322+ item .setItemMeta (meta );
228323 }
229324
230325 private static void configureDefaults (File folder ) {
231326 File example1 = new File (folder , "Raavaxe.yml" );
232327 File example2 = new File (folder , "Vaatuhelm.yml" );
233328 File example3 = new File (folder , "Meteorite.yml" );
329+ File example4 = new File (folder , "Timesword.yml" );
234330
235331 try {
236332 example1 .createNewFile ();
@@ -248,6 +344,7 @@ private static void configureDefaults(File folder) {
248344 config1 .addDefault (USAGE_PATH , Usage .HOLDING .toString ());
249345 config1 .addDefault (DURABILITY_PATH , 2000 );
250346 config1 .addDefault (LORE_PATH , Arrays .asList ("&dAn axe graced by Raava and" , "&dimbued with spiritual energy that" , "&dincreases bending damage!" ));
347+ config1 .addDefault (FLAGS_PATH , Arrays .asList (ItemFlag .HIDE_ATTRIBUTES .toString ()));
251348 config1 .addDefault ("Mods.Base.Damage" , "x2" );
252349
253350 FileConfiguration config2 = YamlConfiguration .loadConfiguration (example2 );
@@ -278,10 +375,27 @@ private static void configureDefaults(File folder) {
278375 config3 .addDefault ("Mods.EarthArmor.GoldHearts" , "+2" );
279376 config3 .addDefault ("Mods.EarthSmash.FlightDuration" , "+3000" );
280377
378+ FileConfiguration config4 = YamlConfiguration .loadConfiguration (example4 );
379+ config4 .options ().copyDefaults (true );
380+ config4 .addDefault (DISPLAY_PATH , "&6Sword of Time" );
381+ config4 .addDefault (MATERIAL_PATH , Material .WOODEN_SWORD .toString ());
382+ config4 .addDefault (ELEMENT_PATH , Element .AVATAR .getName ());
383+ config4 .addDefault (USAGE_PATH , Usage .HOLDING .toString ());
384+ config4 .addDefault (UNBREAKABLE_PATH , true );
385+ config4 .addDefault (LORE_PATH , Arrays .asList ("&7A sword crafted out of a" , "&7branch from the Tree of Time," , "&7it absorbed enough spiritual" , "&7energy to be indestructible" ));
386+ config4 .addDefault (FLAGS_PATH , Arrays .asList (ItemFlag .HIDE_ATTRIBUTES .toString (), ItemFlag .HIDE_ENCHANTS .toString ()));
387+ config4 .addDefault ("Mods.Base.Damage" , "x2" );
388+ config4 .addDefault ("Mods.Base.Speed" , "x1.4" );
389+ config4 .addDefault ("Mods.Base.Duration" , "x1.5" );
390+ config4 .addDefault ("Mods.Base.Cooldown" , "x0.5" );
391+ config4 .addDefault ("Mods.Base.ChargeTime" , "x0.5" );
392+ config4 .addDefault (ENCHANTS_PATH , Arrays .asList (Enchantment .SWEEPING_EDGE .getKey ().getKey () + ":4" ));
393+
281394 try {
282395 config1 .save (example1 );
283396 config2 .save (example2 );
284397 config3 .save (example3 );
398+ config4 .save (example4 );
285399 } catch (Exception e ) {
286400 e .printStackTrace ();
287401 }
0 commit comments