custom item move to mongodb

This commit is contained in:
NK 2022-11-30 11:21:47 +00:00
parent c286d631e9
commit 938aa316ec
12 changed files with 207 additions and 348 deletions

View file

@ -18,12 +18,10 @@ public final class Main extends JavaPlugin {
public static Dotenv env;
@Override
public void onEnable() {
getConfig().options().copyDefaults();
saveDefaultConfig();
EnchantmentManager.register();
new CustomItemManager(this);
new FileManager();
env = Dotenv.configure().directory("E:\\Files\\SB\\plugins\\NullValkyrie").filename(".env").load();
new DatabaseManager();
new FileManager();
new CommandManager();
Bukkit.getPluginManager().registerEvents(new ServerEvents(), this);
Bukkit.getPluginManager().registerEvents(new MenuListener(), this);
@ -32,7 +30,6 @@ public final class Main extends JavaPlugin {
Bukkit.getPluginManager().registerEvents(new DamageEffectEvents(this), this);
Bukkit.getPluginManager().registerEvents(new NPCEvents(), this);
new DiscordClientManager();
new DatabaseManager();
NPCDataManager.reloadNPC();
}
}

View file

@ -1,6 +1,5 @@
package me.night.nullvalkyrie.commands;
import me.night.nullvalkyrie.npc.NPCManager;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
@ -15,7 +14,6 @@ public class BetaCommand extends Command {
@Override
public void onCommand(CommandSender sender, String[] args) {
if (sender instanceof Player) {
NPCManager.createNPC((Player) sender, args[0]);
}
}
@Override

View file

@ -1,18 +1,14 @@
package me.night.nullvalkyrie.commands;
import me.night.nullvalkyrie.Main;
import me.night.nullvalkyrie.database.CustomWeaponsDataManager;
import me.night.nullvalkyrie.items.CustomItemManager;
import org.bukkit.ChatColor;
import org.bukkit.command.CommandSender;
import org.bukkit.configuration.file.FileConfiguration;
import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack;
import org.bukkit.util.StringUtil;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Objects;
import java.util.*;
public class UtilCommand extends Command {
@ -51,12 +47,12 @@ public class UtilCommand extends Command {
@Override
public List<String> onTabComplete(CommandSender sender, String[] args) {
if (args.length == 1) {
List<String> hh = CustomItemManager.getAllFilesFromDirectory("ItemData");
HashMap<String, Object> hh = CustomWeaponsDataManager.getWeapons();
ArrayList<String> cc = new ArrayList<>();
for (String s : hh) {
FileConfiguration c = CustomItemManager.loadConfig("ItemData\\" + s);
if (Objects.equals(c.getString("type"), "Util")) {
cc.add(c.getString("name"));
for (String s : hh.keySet()) {
HashMap<String, Object> item = (HashMap<String, Object>) hh.get(s);
if (Objects.equals(item.get("Type"), "Util")) {
cc.add((String) item.get("Name"));
}
}
return StringUtil.copyPartialMatches(args[0], cc, new ArrayList<>());

View file

@ -1,17 +1,14 @@
package me.night.nullvalkyrie.commands;
import me.night.nullvalkyrie.database.CustomWeaponsDataManager;
import me.night.nullvalkyrie.items.CustomItemManager;
import org.bukkit.ChatColor;
import org.bukkit.command.CommandSender;
import org.bukkit.configuration.file.FileConfiguration;
import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack;
import org.bukkit.util.StringUtil;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Objects;
import java.util.*;
public class WeaponCommand extends Command {
public WeaponCommand() {
@ -34,7 +31,7 @@ public class WeaponCommand extends Command {
builder.append(" ");
}
}
ItemStack item = CustomItemManager.getItem(builder.toString());
ItemStack item = CustomItemManager.produceItem(builder.toString());
if (item.hasItemMeta()) {
player.getInventory().addItem(item);
} else {
@ -46,12 +43,12 @@ public class WeaponCommand extends Command {
@Override
public List<String> onTabComplete(CommandSender sender, String[] args) {
if (args.length == 1) {
List<String> hh = CustomItemManager.getAllFilesFromDirectory("ItemData");
HashMap<String, Object> hh = CustomWeaponsDataManager.getWeapons();
ArrayList<String> cc = new ArrayList<>();
for (String s : hh) {
FileConfiguration c = CustomItemManager.loadConfig("ItemData/" + s);
if (Objects.equals(c.getString("type"), "Weapon")) {
cc.add(c.getString("name"));
for (String s : hh.keySet()) {
HashMap<String, Object> item = (HashMap<String, Object>) hh.get(s);
if (Objects.equals(item.get("Type"), "Weapon")) {
cc.add((String) item.get("Name"));
}
}
return StringUtil.copyPartialMatches(args[0], cc, new ArrayList<>());

View file

@ -1,4 +1,91 @@
package me.night.nullvalkyrie.database;
import com.mongodb.client.MongoCursor;
import com.mongodb.client.model.Filters;
import org.bson.Document;
import org.bukkit.Material;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
public class CustomWeaponsDataManager {
public static HashMap<String, Object> getWeapon(String itemName) {
HashMap<String, Object> item = new HashMap<>();
try (MongoCursor<Document> cursor = DatabaseManager.custom_weapons.find(Filters.eq("Name", itemName)).cursor()) {
while (cursor.hasNext()) {
Document doc = cursor.next();
String name = doc.getString("Name");
Document lore = (Document) doc.get("Lore");
Document ability = (Document) lore.get("Ability");
Document properties = (Document) lore.get("Properties");
HashMap<String, HashMap<String, Object>> lores = new HashMap<>();
HashMap<String, Object> abi = new HashMap<>();
HashMap<String, Object> prop = new HashMap<>();
abi.put("Name", ability.getString("Name"));
List<String> details = new ArrayList<>();
if (ability.get("Details") != null)
for (String s : (List<String>) ability.get("Details")) details.add(s);
abi.put("Details", details);
for (String a : properties.keySet()) prop.put(a, properties.get(a));
lores.put("Ability", abi);
lores.put("Properties", prop);
Document enchants = (Document) doc.get("Enchants");
Document attributes = (Document) doc.get("Attributes");
HashMap<String, Object> ench = new HashMap<>();
HashMap<String, Object> attr = new HashMap<>();
for (String a : enchants.keySet()) ench.put(a, enchants.get(a));
for (String a : attributes.keySet()) attr.put(a, attributes.get(a));
item.put("Name", name);
item.put("Material", Material.matchMaterial(doc.getString("Material")));
item.put("Type", doc.getString("Type"));
item.put("Rarity", doc.getString("Rarity"));
item.put("Lore", lores);
item.put("Enchants", ench);
item.put("Attributes", attr);
}
return item;
}
}
public static HashMap<String, Object> getWeapons() {
HashMap<String, Object> list = new HashMap<>();
try (MongoCursor<Document> cursor = DatabaseManager.custom_weapons.find().cursor()) {
while (cursor.hasNext()) {
Document doc = cursor.next();
HashMap<String, Object> item = new HashMap<>();
String name = doc.getString("Name");
Document lore = (Document) doc.get("Lore");
Document ability = (Document) lore.get("Ability");
Document properties = (Document) lore.get("Properties");
HashMap<String, HashMap<String, Object>> lores = new HashMap<>();
HashMap<String, Object> abi = new HashMap<>();
HashMap<String, Object> prop = new HashMap<>();
abi.put("Name", ability.getString("Name"));
List<String> details = new ArrayList<>();
if (ability.get("Details") != null)
for (String s : (List<String>) ability.get("Details")) details.add(s);
abi.put("Details", details);
for (String a : properties.keySet()) prop.put(a, properties.get(a));
lores.put("Ability", abi);
lores.put("Properties", prop);
Document enchants = (Document) doc.get("Enchants");
Document attributes = (Document) doc.get("Attributes");
HashMap<String, Object> ench = new HashMap<>();
HashMap<String, Object> attr = new HashMap<>();
for (String a : enchants.keySet()) ench.put(a, enchants.get(a));
for (String a : attributes.keySet()) attr.put(a, attributes.get(a));
item.put("Name", name);
item.put("Material", Material.matchMaterial(doc.getString("Material")));
item.put("Type", doc.getString("Type"));
item.put("Rarity", doc.getString("Rarity"));
item.put("Lore", lores);
item.put("Enchants", ench);
item.put("Attributes", attr);
list.put(name, item);
}
return list;
}
}
}

View file

@ -10,7 +10,7 @@ import java.util.HashMap;
public class DatabaseManager {
private static MongoCollection<Document> users;
private static MongoCollection<Document> custom_weapons;
public static MongoCollection<Document> custom_weapons;
public static MongoCollection<Document> ranks;
public static MongoCollection<Document> npcs;
public static MongoCollection<Document> miners;

View file

@ -47,7 +47,7 @@ public class MinerDataManager {
try (MongoCursor<Document> cursor = DatabaseManager.miners.find(Filters.eq("ID", id)).cursor()) {
while (cursor.hasNext()) {
Document doc = cursor.next();
return new CryptoMiner((String) doc.get("Name"), Material.matchMaterial((String) doc.get("Material")), (int) doc.get("Level"), (double) doc.get("Rate"), (long) doc.get("LastClaim"));
return new CryptoMiner(doc.getString("Name"), Material.matchMaterial(doc.getString("Material")), doc.getInteger("Level"), doc.getDouble("Rate"), doc.getLong("LastClaim"));
}
}
return null;
@ -58,7 +58,7 @@ public class MinerDataManager {
try (MongoCursor<Document> cursor = DatabaseManager.miners.find().cursor()) {
while (cursor.hasNext()) {
Document doc = cursor.next();
list.put((long) doc.get("ID"), new CryptoMiner((String) doc.get("Name"), Material.matchMaterial((String) doc.get("Material")), (int) doc.get("Level"), (double) doc.get("Rate"), (long) doc.get("LastClaim")));
list.put(doc.getLong("ID"), new CryptoMiner(doc.getString("Name"), Material.matchMaterial(doc.getString("Material")), doc.getInteger("Level"), doc.getDouble("Rate"), doc.getLong("LastClaim")));
}
return list;
}

View file

@ -42,15 +42,15 @@ public class NPCDataManager {
try (MongoCursor<Document> cursor = DatabaseManager.npcs.find().cursor()) {
while (cursor.hasNext()) {
Document document = cursor.next();
String name = (String) document.get("Name");
int x = (int) document.get("x");
int y = (int) document.get("y");
int z = (int) document.get("z");
int pitch = (int) document.get("pitch");
int yaw = (int) document.get("yaw");
String world = (String) document.get("world");
String texture = (String) document.get("texture");
String signature = (String) document.get("signature");
String name = document.getString("Name");
int x = document.getInteger("x");
int y = document.getInteger("y");
int z = document.getInteger("z");
int pitch = document.getInteger("pitch");
int yaw = document.getInteger("yaw");
String world = document.getString("world");
String texture = document.getString("texture");
String signature = document.getString("signature");
Location location = new Location(Bukkit.getWorld(world), x, y, z);
location.setPitch((float) pitch);
location.setYaw((float) yaw);

View file

@ -1,12 +1,12 @@
package me.night.nullvalkyrie.items;
import me.night.nullvalkyrie.Main;
import me.night.nullvalkyrie.util.Util;
import org.bukkit.ChatColor;
import org.bukkit.Material;
import org.bukkit.NamespacedKey;
import org.bukkit.attribute.Attribute;
import org.bukkit.attribute.AttributeModifier;
import org.bukkit.configuration.file.FileConfiguration;
import org.bukkit.configuration.file.YamlConfiguration;
import org.bukkit.enchantments.Enchantment;
import org.bukkit.inventory.EquipmentSlot;
@ -20,57 +20,41 @@ import java.io.File;
import java.io.IOException;
import java.util.*;
import static me.night.nullvalkyrie.database.CustomWeaponsDataManager.getWeapon;
public class CustomItemManager {
private static final HashMap<String, ItemStack> weapons = new HashMap<>();
public static HashMap<String, NamespacedKey> keys = new HashMap<>();
private static Main main;
public CustomItemManager(Main main) {
CustomItemManager.main = main;
main.getConfig().options().copyDefaults();
main.saveDefaultConfig();
if(!main.getDataFolder().exists()) main.getDataFolder().mkdir();
createDirectoryInPluginFolder("ItemData");
createFilesFromConfig(main.getConfig());
register();
}
public void register() {
List<String> files = getAllFilesFromDirectory("ItemData");
for (String file : files) {
FileConfiguration fileConfig = loadConfig("ItemData/" + file);
ItemStack item = new ItemStack(Material.matchMaterial(fileConfig.getString("material")));
public static ItemStack produceItem(String itemName) {
HashMap<String, Object> weapon = getWeapon(itemName);
ItemStack item = new ItemStack((Material) weapon.get("Material"));
List<String> properties = new ArrayList<>();
List<String> itemAbility = new ArrayList<>();
HashMap<String, Double> attributes = new HashMap<>();
for (String key : fileConfig.getKeys(true)) {
if (key.startsWith("enchants.")) {
item.addUnsafeEnchantment(Enchantment.getByKey(NamespacedKey.minecraft(Arrays.asList(key.split("\\.")).get(1))), fileConfig.getInt(key));
} else if (key.startsWith("lore.properties.")) {
String property = Arrays.asList(key.split("\\.")).get(2);
if (property.equals("damage") && fileConfig.getInt(key) > 0) {
properties.add(ChatColor.GRAY + "Damage: " + ChatColor.RED + "+" + fileConfig.getInt(key));
} else if (property.equals("speed") && fileConfig.getInt(key) > 0) {
properties.add(ChatColor.GRAY + "Speed: " + ChatColor.RED + "+" + fileConfig.getInt(key));
}
} else if (key.startsWith("lore.ability.")) {
String paths = Arrays.asList(key.split("\\.")).get(2);
if (paths.equals("name")) {
itemAbility.add(ChatColor.GOLD + "Item Ability: " + fileConfig.getString(key));
} else if (paths.equals("details")) {
for (Object line : fileConfig.getList(key)) {
itemAbility.add(ChatColor.GRAY.toString() + line);
}
}
} else if (key.startsWith("attributes.")) {
if (fileConfig.getDouble(key) > 0.0) {
attributes.put(Arrays.asList(key.split("\\.")).get(1), fileConfig.getDouble(key));
}
} else if (key.startsWith("recipe.")) {
}
HashMap<String, Object> enchants = (HashMap<String, Object>) weapon.get("Enchants");
HashMap<String, Object> attributes = (HashMap<String, Object>) weapon.get("Attributes");
for (String enchant : enchants.keySet()) {
item.addUnsafeEnchantment(Enchantment.getByKey(NamespacedKey.minecraft(enchant)), (Integer) enchants.get(enchant));
}
HashMap<String, Object> lo = (HashMap<String, Object>) weapon.get("Lore");
HashMap<String, Object> abi = (HashMap<String, Object>) lo.get("Ability");
HashMap<String, Object> prob = (HashMap<String, Object>) lo.get("Properties");
for (String p : prob.keySet())
if ((int) prob.get(p) > 0)
properties.add(ChatColor.GRAY + Util.capitalize(p) + ": " + ChatColor.RED + "+" + prob.get(p));
itemAbility.add(ChatColor.GOLD + "Item Ability: " + abi.get("Name"));
for (String line : (List<String>) abi.get("Details"))
itemAbility.add(ChatColor.GRAY + line);
//recipe
ItemMeta itemMeta = item.getItemMeta();
itemMeta.setDisplayName(Rarity.getRarity(fileConfig.getString("rarity")).getColor() + fileConfig.getString("name"));
itemMeta.setDisplayName(Rarity.getRarity((String) weapon.get("Rarity")).getColor() + weapon.get("Name"));
itemMeta.setUnbreakable(true);
ArrayList<String> lore = new ArrayList<>();
lore.addAll(properties);
@ -80,11 +64,10 @@ public class CustomItemManager {
List<String> splitted = Arrays.asList(Arrays.asList(enchantment.getKey().toString().split(":")).get(1).split("_"));
StringBuilder builder = new StringBuilder();
for (String strings : splitted) {
String formatted = strings.substring(0, 1).toUpperCase() + strings.substring(1);
String formatted = Util.capitalize(strings);
if (splitted.size() > 1) {
if (strings.equals(splitted.get(splitted.size() - 1))) {
builder.append(formatted);
} else {
if (strings.equals(splitted.get(splitted.size() - 1))) builder.append(formatted);
else {
builder.append(formatted);
builder.append(" ");
}
@ -96,38 +79,39 @@ public class CustomItemManager {
lore.add("");
lore.addAll(itemAbility);
lore.add("");
lore.add(Rarity.getRarity(fileConfig.getString("rarity")).getDisplay());
lore.add(Rarity.getRarity((String) weapon.get("Rarity")).getDisplay());
itemMeta.setLore(lore);
for (String attribute : attributes.keySet()) {
if (attribute.equals("damage")) {
AttributeModifier p = new AttributeModifier(UUID.randomUUID(), "generic.attackDamage", attributes.get(attribute), AttributeModifier.Operation.ADD_NUMBER, EquipmentSlot.HAND);
AttributeModifier p = new AttributeModifier(UUID.randomUUID(), "generic.attackDamage", (Double) attributes.get(attribute), AttributeModifier.Operation.ADD_NUMBER, EquipmentSlot.HAND);
itemMeta.addAttributeModifier(Attribute.GENERIC_ATTACK_DAMAGE, p);
} else if (attribute.equals("moveSpeed")) {
AttributeModifier s = new AttributeModifier(UUID.randomUUID(), "generic.movementSpeed", attributes.get(attribute), AttributeModifier.Operation.ADD_NUMBER, EquipmentSlot.HAND);
AttributeModifier s = new AttributeModifier(UUID.randomUUID(), "generic.movementSpeed", (Double) attributes.get(attribute), AttributeModifier.Operation.ADD_NUMBER, EquipmentSlot.HAND);
itemMeta.addAttributeModifier(Attribute.GENERIC_MOVEMENT_SPEED, s);
}
}
itemMeta.addItemFlags(ItemFlag.HIDE_ATTRIBUTES, ItemFlag.HIDE_UNBREAKABLE, ItemFlag.HIDE_ENCHANTS);
for (String key : fileConfig.getKeys(true)) {
if (key.startsWith("pdc.")) {
String property = Arrays.asList(key.split("\\.")).get(1);
if (property.equals("ammo")) {
PersistentDataContainer container = itemMeta.getPersistentDataContainer();
NamespacedKey key1 = new NamespacedKey(main, "ammo");
keys.put(Rarity.getRarity(fileConfig.getString("rarity")).getColor() + fileConfig.getString("name") + "." + property, key1);
container.set(key1, PersistentDataType.INTEGER, fileConfig.getInt(key));
} else if (property.equals("maxload")) {
PersistentDataContainer container = itemMeta.getPersistentDataContainer();
NamespacedKey key2 = new NamespacedKey(main, "maxload");
keys.put(Rarity.getRarity(fileConfig.getString("rarity")).getColor() + fileConfig.getString("name") + "." + property, key2);
container.set(key2, PersistentDataType.INTEGER, fileConfig.getInt(key));
}
}
}
// for (String key : fileConfig.getKeys(true)) {
// if (key.startsWith("pdc.")) {
// String property = Arrays.asList(key.split("\\.")).get(1);
// if (property.equals("ammo")) {
// PersistentDataContainer container = itemMeta.getPersistentDataContainer();
// NamespacedKey key1 = new NamespacedKey(main, "ammo");
// keys.put(Rarity.getRarity(fileConfig.getString("rarity")).getColor() + fileConfig.getString("name") + "." + property, key1);
// container.set(key1, PersistentDataType.INTEGER, fileConfig.getInt(key));
// } else if (property.equals("maxload")) {
// PersistentDataContainer container = itemMeta.getPersistentDataContainer();
// NamespacedKey key2 = new NamespacedKey(main, "maxload");
// keys.put(Rarity.getRarity(fileConfig.getString("rarity")).getColor() + fileConfig.getString("name") + "." + property, key2);
// container.set(key2, PersistentDataType.INTEGER, fileConfig.getInt(key));
// }
// }
// }
item.setItemMeta(itemMeta);
weapons.put(fileConfig.getString("name"), item);
}
return item;
}
public static void setItemRecipe(NamespacedKey key, ItemStack i, int ingredient, String shape1, String shape2, String shape3, List<Material> ingredients) {
// ShapedRecipe wither_sword_recipe = new ShapedRecipe(new NamespacedKey(main, "widow_sword"), widow_sword);
// wither_sword_recipe.shape(" A ", " A "," B ");
@ -135,6 +119,7 @@ public class CustomItemManager {
// wither_sword_recipe.setIngredient('B', Material.STICK);
// Bukkit.addRecipe(wither_sword_recipe);
}
public static YamlConfiguration loadConfig(String path) {
File f = new File(main.getDataFolder(), path);
if (!f.exists()) {
@ -147,73 +132,7 @@ public class CustomItemManager {
}
return YamlConfiguration.loadConfiguration(f);
}
public static File loadFile(String path) {
File file = new File(main.getDataFolder(), path);
if(!file.exists()) {
try {
file.createNewFile();
} catch (IOException e) {
e.printStackTrace();
}
}
return file;
}
public static void createDirectoryInPluginFolder(String path) {
File f = new File(main.getDataFolder(), path);
if(!f.exists()) {
try {
if(!f.mkdir()) {
try {
f.mkdir();
} catch (SecurityException e) {
e.printStackTrace();
}
}
} catch (SecurityException e) {
e.printStackTrace();
}
}
}
public static List<String> getAllFilesFromDirectory(String path) {
ArrayList<String> ns = new ArrayList<>();
try {
File f = new File(main.getDataFolder(), path);
File[] files = f.listFiles();
for (File file : files) {
ns.add(file.getName());
}
} catch (Exception e) {
e.printStackTrace();
}
return ns;
}
public void createFilesFromConfig(FileConfiguration config) {
for(String filename : config.getKeys(false)) {
FileConfiguration fileConfig = loadConfig("ItemData/" + filename + ".yml");
for(String key : config.getKeys(true)) {
if(key.startsWith(filename)) {
List<String> paths = new ArrayList<>(Arrays.asList(key.split("\\.")));
if(paths.size() != 1) {
paths.remove(0);
if(paths.size() == 1) {
fileConfig.set(paths.get(0), config.get(key));
} else {
fileConfig.set(String.join(".", paths), config.get(key));
}
try {
fileConfig.save(loadFile("ItemData/" + filename + ".yml"));
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
}
public static ItemStack getItem(String name) {
return weapons.get(name);
}

View file

@ -13,7 +13,13 @@ public class Util {
builder.append(repeat);
return builder.toString();
}
public static String color(String string) {
return ChatColor.translateAlternateColorCodes('&', string);
}
public static String capitalize(String str) {
if (str == null || str.length() == 0) return str;
return str.substring(0, 1).toUpperCase() + str.substring(1);
}
}

View file

@ -1,141 +0,0 @@
ExplosiveBow:
name: "Explosive Bow"
material: "BOW"
type: "Weapon"
rarity: "LEGENDARY"
lore:
properties:
damage: 50
ability:
name: Explosive Shot
details:
- Shoot a explosive arrow that causes lots of damage
- Arrow won't destroy blocks
enchants:
thunderbolt: 5
attributes:
damage: 50.0
FragGrenade:
name: "Frag Grenade"
material: "EGG"
type: "Weapon"
rarity: "LEGENDARY"
lore:
properties:
damage: 50
ability:
name: TNT Party
details:
- Throw a *large* TNT explode with tons of damage
enchants:
thunderbolt: 5
attributes:
damage: 50.0
GrapplingHook:
name: "Grappling Hook"
material: "FISHING_ROD"
type: "Util"
rarity: "RARE"
lore:
ability:
name: Hook
details:
- Using it will make you fly
enchants:
thunderbolt: 5
SnowGun:
name: "Snow Gun"
material: "DIAMOND_HOE"
type: "Weapon"
rarity: "ULTRA"
lore:
properties:
damage: 25
speed: 20
ability:
name: Let it go
details:
- Shoot Snowball that cause lots of damage
enchants:
thunderbolt: 5
attributes:
damage: 25.0
moveSpeed: 0.2
pdc:
ammo: 30
maxload: 121
TeleportDoor:
name: "Teleport Door"
material: "DIAMOND_SHOVEL"
type: "Weapon"
rarity: "GRAND"
lore:
properties:
damage: 75
speed: 20
ability:
name: Instant Teleport
details:
- Teleport to 12 blocks away from you
enchants:
thunderbolt: 5
attributes:
damage: 75.0
moveSpeed: 0.2
Terminator:
name: "Terminator"
material: "BOW"
type: "Weapon"
rarity: "MYTHIC"
lore:
properties:
damage: 50
speed: 10
ability:
name: Triple Shot
details:
- Shoot three arrow at one time
- Arrow deals 50% more damage
enchants:
sharpness: 20
looting: 10
thunderbolt: 5
attributes:
damage: 50.0
moveSpeed: 0.1
WidowSword:
name: "Widow Sword"
material: "STICK"
type: "Weapon"
rarity: "MYTHIC"
lore:
properties:
damage: 100
speed: 20
ability:
name: Damage Multiplier
details:
- Damage dealt to mobs will be multiplied
- Zombie + 100%
- Skeleton + 100%
- Spider + 100%
enchants:
sharpness: 20
looting: 10
thunderbolt: 5
attributes:
damage: 100.0
moveSpeed: 0.2
zombie: 100
skeleton: 100
spider: 100
InfiniteWaterBucket:
name: "Infinite Water Bucket"
material: "WATER_BUCKET"
type: "Util"
rarity: "EPIC"
InfiniteLavaBucket:
name: "Infinite Lava Bucket"
material: "LAVA_BUCKET"
type: "Util"
rarity: "EPIC"