mirror of
https://github.com/songoda/EpicEnchants.git
synced 2024-11-14 22:56:20 +01:00
Progress
This commit is contained in:
parent
621b02fd15
commit
b5756c434c
94
core/pom.xml
94
core/pom.xml
@ -3,25 +3,113 @@
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<parent>
|
||||
<artifactId>epicenchants</artifactId>
|
||||
<artifactId>EpicEnchants-Parent</artifactId>
|
||||
<groupId>com.songoda</groupId>
|
||||
<version>1.0</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<artifactId>epicfurnaces</artifactId>
|
||||
<artifactId>EpicEnchants</artifactId>
|
||||
|
||||
<properties>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
</properties>
|
||||
|
||||
<repositories>
|
||||
<repository>
|
||||
<id>jitpack.io</id>
|
||||
<url>https://jitpack.io</url>
|
||||
</repository>
|
||||
<repository>
|
||||
<id>aikar</id>
|
||||
<url>https://repo.aikar.co/content/groups/aikar/</url>
|
||||
</repository>
|
||||
</repositories>
|
||||
|
||||
<build>
|
||||
<defaultGoal>clean package</defaultGoal>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-compiler-plugin</artifactId>
|
||||
<version>3.7.0</version>
|
||||
<configuration>
|
||||
<source>1.8</source>
|
||||
<target>1.8</target>
|
||||
</configuration>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-shade-plugin</artifactId>
|
||||
<version>3.1.0</version>
|
||||
<configuration>
|
||||
<dependencyReducedPomLocation>${project.build.directory}/dependency-reduced-pom.xml
|
||||
</dependencyReducedPomLocation>
|
||||
<relocations>
|
||||
<relocation>
|
||||
<pattern>co.aikar.commands</pattern>
|
||||
<shadedPattern>com.songoda.epicenchants.acf</shadedPattern> <!-- Replace this -->
|
||||
</relocation>
|
||||
</relocations>
|
||||
</configuration>
|
||||
<executions>
|
||||
<execution>
|
||||
<phase>package</phase>
|
||||
<goals>
|
||||
<goal>shade</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
</plugins>
|
||||
<resources>
|
||||
<resource>
|
||||
<directory>src/main/resources</directory>
|
||||
<filtering>true</filtering>
|
||||
</resource>
|
||||
</resources>
|
||||
</build>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.spigotmc</groupId>
|
||||
<artifactId>spigot</artifactId>
|
||||
<version>1.13.2</version>
|
||||
<version>1.8.8</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.projectlombok</groupId>
|
||||
<artifactId>lombok</artifactId>
|
||||
<version>1.18.4</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.github.tr7zw</groupId>
|
||||
<artifactId>Item-NBT-API</artifactId>
|
||||
<version>9c5f6575a8</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>co.aikar</groupId>
|
||||
<artifactId>acf-bukkit</artifactId>
|
||||
<version>0.5.0-SNAPSHOT</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>fr.minuskube.inv</groupId>
|
||||
<artifactId>smart-invs</artifactId>
|
||||
<version>1.2.6</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>net.milkbowl.vault</groupId>
|
||||
<artifactId>VaultAPI</artifactId>
|
||||
<version>1.7</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</project>
|
@ -1,38 +0,0 @@
|
||||
package com.songoda.epicenchants;
|
||||
|
||||
import com.songoda.epicenchants.objects.ActionClass;
|
||||
import com.songoda.epicenchants.wrappers.PotionEffectWrapper;
|
||||
import org.bukkit.configuration.ConfigurationSection;
|
||||
import org.bukkit.potion.PotionEffect;
|
||||
import org.bukkit.potion.PotionEffectType;
|
||||
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public class ConfigParser {
|
||||
public static PotionEffect parsePotionEffect(String input) {
|
||||
if (input.contains(":")) {
|
||||
return new PotionEffect(PotionEffectType.getByName(input.split(":")[0]), Integer.MAX_VALUE, Integer.valueOf(input.split(":")[1]));
|
||||
}
|
||||
|
||||
return new PotionEffect(PotionEffectType.getByName(input), Integer.MAX_VALUE, 0);
|
||||
}
|
||||
|
||||
public static ActionClass parseActionClass(ConfigurationSection section) {
|
||||
return ActionClass.builder()
|
||||
.modifyDamageGiven(section.getDouble("modify-damage-given"))
|
||||
.modifyDamageTaken(section.getDouble("modify-damage-taken"))
|
||||
.potionEffects(section.getConfigurationSection("potion-effects")
|
||||
.getKeys(false).stream()
|
||||
.map(section::getConfigurationSection)
|
||||
.map(ConfigParser::parsePotionEffect)
|
||||
.collect(Collectors.toSet()))
|
||||
.build();
|
||||
}
|
||||
|
||||
public static PotionEffectWrapper parsePotionEffect(ConfigurationSection section) {
|
||||
return new PotionEffectWrapper(new PotionEffect(
|
||||
PotionEffectType.getByName(section.getName()),
|
||||
section.getInt("duration"),
|
||||
section.getInt("amplifier")), section.getDouble("chance"));
|
||||
}
|
||||
}
|
@ -1,32 +1,77 @@
|
||||
package com.songoda.epicenchants;
|
||||
|
||||
import co.aikar.commands.BukkitCommandManager;
|
||||
import co.aikar.commands.InvalidCommandArgument;
|
||||
import com.songoda.epicenchants.commands.EnchantCommand;
|
||||
import com.songoda.epicenchants.managers.EnchantManager;
|
||||
import com.songoda.epicenchants.managers.FileManager;
|
||||
import com.songoda.epicenchants.objects.Enchant;
|
||||
import com.songoda.epicenchants.utils.InventoryParser;
|
||||
import fr.minuskube.inv.InventoryManager;
|
||||
import fr.minuskube.inv.SmartInventory;
|
||||
import lombok.Getter;
|
||||
import net.milkbowl.vault.economy.Economy;
|
||||
import org.bukkit.plugin.java.JavaPlugin;
|
||||
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import static com.songoda.epicenchants.utils.Chat.color;
|
||||
import static org.bukkit.Bukkit.getConsoleSender;
|
||||
|
||||
public class EpicEnchants extends JavaPlugin {
|
||||
|
||||
@Getter private FileManager fileManager;
|
||||
@Getter private EnchantManager enchantManager;
|
||||
|
||||
@Override
|
||||
public void onDisable() {
|
||||
this.fileManager = new FileManager(this);
|
||||
this.enchantManager = new EnchantManager();
|
||||
|
||||
saveDefaultConfig();
|
||||
|
||||
try {
|
||||
fileManager.loadEnchants();
|
||||
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
@Getter private BukkitCommandManager commandManager;
|
||||
@Getter private InventoryManager inventoryManager;
|
||||
@Getter private Economy economy;
|
||||
@Getter private Locale locale;
|
||||
@Getter private SmartInventory bookInventory;
|
||||
|
||||
@Override
|
||||
public void onEnable() {
|
||||
getConsoleSender().sendMessage(color("&a============================="));
|
||||
getConsoleSender().sendMessage(color("&7" + getDescription().getName() + " " + getDescription().getVersion() + " by &5Songoda <3&7!"));
|
||||
getConsoleSender().sendMessage(color("&7Action: &aEnabling&7..."));
|
||||
|
||||
this.fileManager = new FileManager(this);
|
||||
this.enchantManager = new EnchantManager();
|
||||
this.inventoryManager = new InventoryManager(this);
|
||||
this.locale = Locale.getLocale(getConfig().getString("System.Language Mode", getConfig().getString("language")));
|
||||
this.economy = getServer().getServicesManager().getRegistration(Economy.class).getProvider();
|
||||
|
||||
fileManager.createFiles();
|
||||
fileManager.loadEnchants();
|
||||
inventoryManager.init();
|
||||
|
||||
setupCommands();
|
||||
|
||||
if (!enchantManager.getEnchants().isEmpty()) {
|
||||
getLogger().info("Successfully loaded: " + enchantManager.getEnchants().stream().map(Enchant::getIdentifier).collect(Collectors.joining(",")));
|
||||
}
|
||||
|
||||
this.bookInventory = InventoryParser.parseBookMenu(this, fileManager.getConfiguration("bookMenu"));
|
||||
|
||||
getConsoleSender().sendMessage(color("&a============================="));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDisable() {
|
||||
getConsoleSender().sendMessage(color("&a============================="));
|
||||
getConsoleSender().sendMessage(color("&7" + getDescription().getName() + " " + getDescription().getVersion() + " by &5Songoda <3&7!"));
|
||||
getConsoleSender().sendMessage(color("&7Action: &cDisabling&7..."));
|
||||
getConsoleSender().sendMessage(color("&a============================="));
|
||||
}
|
||||
|
||||
private void setupCommands() {
|
||||
this.commandManager = new BukkitCommandManager(this);
|
||||
|
||||
commandManager.registerDependency(EpicEnchants.class, "instance", this);
|
||||
|
||||
commandManager.getCommandCompletions().registerCompletion("enchants", c -> enchantManager.getEnchants().stream().map(Enchant::getIdentifier).collect(Collectors.toList()));
|
||||
|
||||
commandManager.getCommandContexts().registerContext(Enchant.class, c -> enchantManager.getEnchant(c.getFirstArg()).orElseThrow(() -> new InvalidCommandArgument("Unknown enchant: " + c.getFirstArg())));
|
||||
|
||||
commandManager.registerCommand(new EnchantCommand());
|
||||
}
|
||||
}
|
||||
|
380
core/src/main/java/com/songoda/epicenchants/Locale.java
Normal file
380
core/src/main/java/com/songoda/epicenchants/Locale.java
Normal file
@ -0,0 +1,380 @@
|
||||
package com.songoda.epicenchants;
|
||||
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import com.google.common.collect.Lists;
|
||||
import org.bukkit.ChatColor;
|
||||
import org.bukkit.plugin.java.JavaPlugin;
|
||||
|
||||
import java.io.*;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* Assists in the creation of multiple localizations and languages,
|
||||
* as well as the generation of default .lang files
|
||||
*
|
||||
* @author Parker Hawke - 2008Choco
|
||||
*/
|
||||
public class Locale {
|
||||
|
||||
private static final List<Locale> LOCALES = Lists.newArrayList();
|
||||
private static final Pattern NODE_PATTERN = Pattern.compile("(\\w+(?:\\.{1}\\w+)*)\\s*=\\s*\"(.*)\"");
|
||||
private static final String FILE_EXTENSION = ".lang";
|
||||
private static JavaPlugin plugin;
|
||||
private static File localeFolder;
|
||||
|
||||
private static String defaultLocale;
|
||||
|
||||
private final Map<String, String> nodes = new HashMap<>();
|
||||
|
||||
private final File file;
|
||||
private final String name, region;
|
||||
|
||||
private Locale(String name, String region) {
|
||||
if (plugin == null)
|
||||
throw new IllegalStateException("Cannot generate locales without first initializing the class (Locale#init(JavaPlugin))");
|
||||
|
||||
this.name = name.toLowerCase();
|
||||
this.region = region.toUpperCase();
|
||||
|
||||
String fileName = name + "_" + region + FILE_EXTENSION;
|
||||
this.file = new File(localeFolder, fileName);
|
||||
|
||||
if (this.reloadMessages()) return;
|
||||
|
||||
plugin.getLogger().info("Loaded locale " + fileName);
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize the locale class to generate information and search for localizations.
|
||||
* This must be called before any other methods in the Locale class can be invoked.
|
||||
* Note that this will also call {@link #searchForLocales()}, so there is no need to
|
||||
* invoke it for yourself after the initialization
|
||||
*
|
||||
* @param plugin the plugin instance
|
||||
*/
|
||||
public static void init(JavaPlugin plugin) {
|
||||
Locale.plugin = plugin;
|
||||
|
||||
if (localeFolder == null) {
|
||||
localeFolder = new File(plugin.getDataFolder(), "locales/");
|
||||
}
|
||||
|
||||
localeFolder.mkdirs();
|
||||
Locale.searchForLocales();
|
||||
}
|
||||
|
||||
/**
|
||||
* Find all .lang file locales under the "locales" folder
|
||||
*/
|
||||
public static void searchForLocales() {
|
||||
if (!localeFolder.exists()) {
|
||||
localeFolder.mkdirs();
|
||||
}
|
||||
|
||||
for (File file : localeFolder.listFiles()) {
|
||||
String name = file.getName();
|
||||
if (!name.endsWith(".lang")) continue;
|
||||
|
||||
String fileName = name.substring(0, name.lastIndexOf('.'));
|
||||
String[] localeValues = fileName.split("_");
|
||||
|
||||
if (localeValues.length != 2) continue;
|
||||
if (localeExists(localeValues[0] + "_" + localeValues[1])) continue;
|
||||
|
||||
LOCALES.add(new Locale(localeValues[0], localeValues[1]));
|
||||
plugin.getLogger().info("Found and loaded locale \"" + fileName + "\"");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a locale by its entire proper name (i.e. "en_US")
|
||||
*
|
||||
* @param name the full name of the locale
|
||||
* @return locale of the specified name
|
||||
*/
|
||||
public static Locale getLocale(String name) {
|
||||
for (Locale locale : LOCALES)
|
||||
if (locale.getLanguageTag().equalsIgnoreCase(name)) return locale;
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a locale from the cache by its name (i.e. "en" from "en_US")
|
||||
*
|
||||
* @param name the name of the language
|
||||
* @return locale of the specified language. Null if not cached
|
||||
*/
|
||||
public static Locale getLocaleByName(String name) {
|
||||
for (Locale locale : LOCALES)
|
||||
if (locale.getName().equalsIgnoreCase(name)) return locale;
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a locale from the cache by its region (i.e. "US" from "en_US")
|
||||
*
|
||||
* @param region the name of the region
|
||||
* @return locale of the specified region. Null if not cached
|
||||
*/
|
||||
public static Locale getLocaleByRegion(String region) {
|
||||
for (Locale locale : LOCALES)
|
||||
if (locale.getRegion().equalsIgnoreCase(region)) return locale;
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check whether a locale exists and is registered or not
|
||||
*
|
||||
* @param name the whole language tag (i.e. "en_US")
|
||||
* @return true if it exists
|
||||
*/
|
||||
public static boolean localeExists(String name) {
|
||||
for (Locale locale : LOCALES)
|
||||
if (locale.getLanguageTag().equals(name)) return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Save a default locale file from the project source directory, to the locale folder
|
||||
*
|
||||
* @param in file to save
|
||||
* @param fileName the name of the file to save
|
||||
* @return true if the operation was successful, false otherwise
|
||||
*/
|
||||
public static boolean saveDefaultLocale(InputStream in, String fileName) {
|
||||
if (!localeFolder.exists()) localeFolder.mkdirs();
|
||||
|
||||
if (!fileName.endsWith(FILE_EXTENSION))
|
||||
fileName = (fileName.lastIndexOf(".") == -1 ? fileName : fileName.substring(0, fileName.lastIndexOf('.'))) + FILE_EXTENSION;
|
||||
|
||||
File destinationFile = new File(localeFolder, fileName);
|
||||
if (destinationFile.exists()) {
|
||||
return compareFiles(plugin.getResource(fileName), destinationFile);
|
||||
}
|
||||
|
||||
try (OutputStream outputStream = new FileOutputStream(destinationFile)) {
|
||||
copy(in == null ? plugin.getResource(fileName) : in, outputStream);
|
||||
|
||||
fileName = fileName.substring(0, fileName.lastIndexOf('.'));
|
||||
String[] localeValues = fileName.split("_");
|
||||
|
||||
if (localeValues.length != 2) return false;
|
||||
|
||||
LOCALES.add(new Locale(localeValues[0], localeValues[1]));
|
||||
if (defaultLocale == null) defaultLocale = fileName;
|
||||
|
||||
return true;
|
||||
} catch (IOException e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Save a default locale file from the project source directory, to the locale folder
|
||||
*
|
||||
* @param fileName the name of the file to save
|
||||
* @return true if the operation was successful, false otherwise
|
||||
*/
|
||||
public static boolean saveDefaultLocale(String fileName) {
|
||||
return saveDefaultLocale(null, fileName);
|
||||
}
|
||||
|
||||
/**
|
||||
* Clear all current locale data
|
||||
*/
|
||||
public static void clearLocaleData() {
|
||||
for (Locale locale : LOCALES)
|
||||
locale.nodes.clear();
|
||||
LOCALES.clear();
|
||||
}
|
||||
|
||||
// Write new changes to existing files, if any at all
|
||||
private static boolean compareFiles(InputStream defaultFile, File existingFile) {
|
||||
// Look for default
|
||||
if (defaultFile == null) {
|
||||
defaultFile = plugin.getResource(defaultLocale != null ? defaultLocale : "en_US");
|
||||
if (defaultFile == null) return false; // No default at all
|
||||
}
|
||||
|
||||
boolean changed = false;
|
||||
|
||||
List<String> defaultLines, existingLines;
|
||||
try (BufferedReader defaultReader = new BufferedReader(new InputStreamReader(defaultFile));
|
||||
BufferedReader existingReader = new BufferedReader(new FileReader(existingFile));
|
||||
BufferedWriter writer = new BufferedWriter(new FileWriter(existingFile, true))) {
|
||||
defaultLines = defaultReader.lines().collect(Collectors.toList());
|
||||
existingLines = existingReader.lines().map(s -> s.split("\\s*=")[0]).collect(Collectors.toList());
|
||||
|
||||
for (String defaultValue : defaultLines) {
|
||||
if (defaultValue.isEmpty() || defaultValue.startsWith("#")) continue;
|
||||
|
||||
String key = defaultValue.split("\\s*=")[0];
|
||||
|
||||
if (!existingLines.contains(key)) {
|
||||
if (!changed) {
|
||||
writer.newLine();
|
||||
writer.newLine();
|
||||
writer.write("# New messages for " + plugin.getName() + " v" + plugin.getDescription().getVersion());
|
||||
}
|
||||
|
||||
writer.newLine();
|
||||
writer.write(defaultValue);
|
||||
|
||||
changed = true;
|
||||
}
|
||||
}
|
||||
} catch (IOException e) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return changed;
|
||||
}
|
||||
|
||||
private static void copy(InputStream input, OutputStream output) {
|
||||
int n;
|
||||
byte[] buffer = new byte[1024 * 4];
|
||||
|
||||
try {
|
||||
while ((n = input.read(buffer)) != -1) {
|
||||
output.write(buffer, 0, n);
|
||||
}
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a message set for a specific node
|
||||
*
|
||||
* @param node the node to get
|
||||
* @return the message for the specified node
|
||||
*/
|
||||
public String getMessage(String node) {
|
||||
return ChatColor.translateAlternateColorCodes('&', this.getMessageOrDefault(node, node));
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a message set for a specific node and replace its params with a supplied arguments.
|
||||
*
|
||||
* @param node the node to get
|
||||
* @param args the replacement arguments
|
||||
* @return the message for the specified node
|
||||
*/
|
||||
public String getMessage(String node, Object... args) {
|
||||
String message = getMessage(node);
|
||||
for (Object arg : args) {
|
||||
message = message.replaceFirst("%.*?%", arg.toString());
|
||||
}
|
||||
return message;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a message set for a specific node
|
||||
*
|
||||
* @param node the node to get
|
||||
* @param defaultValue the default value given that a value for the node was not found
|
||||
* @return the message for the specified node. Default if none found
|
||||
*/
|
||||
public String getMessageOrDefault(String node, String defaultValue) {
|
||||
return this.nodes.getOrDefault(node, defaultValue);
|
||||
}
|
||||
|
||||
/**
|
||||
* Clear the previous message cache and load new messages directly from file
|
||||
*
|
||||
* @return reload messages from file
|
||||
*/
|
||||
public boolean reloadMessages() {
|
||||
if (!this.file.exists()) {
|
||||
plugin.getLogger().warning("Could not find file for locale " + this.name);
|
||||
return false;
|
||||
}
|
||||
|
||||
this.nodes.clear(); // Clear previous data (if any)
|
||||
|
||||
try (BufferedReader reader = new BufferedReader(new FileReader(file))) {
|
||||
String line;
|
||||
for (int lineNumber = 0; (line = reader.readLine()) != null; lineNumber++) {
|
||||
if (line.isEmpty() || line.startsWith("#") /* Comment */) continue;
|
||||
|
||||
Matcher matcher = NODE_PATTERN.matcher(line);
|
||||
if (!matcher.find()) {
|
||||
System.err.println("Invalid locale syntax at (line=" + lineNumber + ")");
|
||||
continue;
|
||||
}
|
||||
|
||||
nodes.put(matcher.group(1), matcher.group(2));
|
||||
}
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the file that represents this locale
|
||||
*
|
||||
* @return the locale file (.lang)
|
||||
*/
|
||||
public File getFile() {
|
||||
return file;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the entire locale tag (i.e. "en_US")
|
||||
*
|
||||
* @return the language tag
|
||||
*/
|
||||
public String getLanguageTag() {
|
||||
return name + "_" + region;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get an immutable list of all currently loaded locales
|
||||
*
|
||||
* @return list of all locales
|
||||
*/
|
||||
public static List<Locale> getLocales() {
|
||||
return ImmutableList.copyOf(LOCALES);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the key-value map of nodes to messages
|
||||
*
|
||||
* @return node-message map
|
||||
*/
|
||||
public Map<String, String> getMessageNodeMap() {
|
||||
return ImmutableMap.copyOf(nodes);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the name of the language that this locale is based on.
|
||||
* (i.e. "en" for English, or "fr" for French)
|
||||
*
|
||||
* @return the name of the language
|
||||
*/
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public String getPrefix() {
|
||||
return getMessage("general.nametag.prefix") + " ";
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the name of the region that this locale is from.
|
||||
* (i.e. "US" for United States or "CA" for Canada)
|
||||
*
|
||||
* @return the name of the region
|
||||
*/
|
||||
public String getRegion() {
|
||||
return region;
|
||||
}
|
||||
}
|
@ -0,0 +1,30 @@
|
||||
package com.songoda.epicenchants.commands;
|
||||
|
||||
import co.aikar.commands.BaseCommand;
|
||||
import co.aikar.commands.annotation.*;
|
||||
import com.songoda.epicenchants.EpicEnchants;
|
||||
import com.songoda.epicenchants.objects.Enchant;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
@CommandAlias("epicenchants|ee")
|
||||
public class EnchantCommand extends BaseCommand {
|
||||
|
||||
@Dependency("instance")
|
||||
private EpicEnchants instance;
|
||||
|
||||
//ee give {player} {enchant} {tier}
|
||||
@Subcommand("give")
|
||||
@CommandCompletion("@players @enchants")
|
||||
@Description("Give books to players")
|
||||
@CommandPermission("epicenchants.givebook")
|
||||
public void onGiveBook(@Flags("other") Player target, Enchant enchant, @Default("1") Integer tier, @Optional Double successRate, @Optional Double destroyRate) {
|
||||
target.getInventory().addItem(enchant.getBookItem().get(enchant, tier, successRate, destroyRate));
|
||||
}
|
||||
|
||||
@Default
|
||||
@Subcommand("gui")
|
||||
@Description("Opens the GUI for getting enchants")
|
||||
public void onGui(Player player) {
|
||||
instance.getBookInventory().open(player);
|
||||
}
|
||||
}
|
@ -2,9 +2,8 @@ package com.songoda.epicenchants.managers;
|
||||
|
||||
import com.songoda.epicenchants.objects.Enchant;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public class EnchantManager {
|
||||
private Map<String, Enchant> enchantMap;
|
||||
@ -20,4 +19,17 @@ public class EnchantManager {
|
||||
public void addEnchant(Enchant enchant) {
|
||||
enchantMap.put(enchant.getIdentifier(), enchant);
|
||||
}
|
||||
|
||||
public Collection<Enchant> getEnchants(int tier) {
|
||||
return Collections.unmodifiableCollection(enchantMap.values().stream().filter(s -> s.getTier() == tier).collect(Collectors.toList()));
|
||||
}
|
||||
|
||||
public Optional<Enchant> getRandomEnchant(int tier) {
|
||||
Collection<Enchant> tierList = getEnchants(tier);
|
||||
return tierList.stream().skip((int) (tierList.size() * Math.random())).findFirst();
|
||||
}
|
||||
|
||||
public Collection<Enchant> getEnchants() {
|
||||
return Collections.unmodifiableCollection(enchantMap.values());
|
||||
}
|
||||
}
|
||||
|
@ -1,39 +1,70 @@
|
||||
package com.songoda.epicenchants.managers;
|
||||
|
||||
import com.songoda.epicenchants.ConfigParser;
|
||||
import com.songoda.epicenchants.EpicEnchants;
|
||||
import com.songoda.epicenchants.objects.Enchant;
|
||||
import org.bukkit.ChatColor;
|
||||
import com.songoda.epicenchants.utils.ConfigParser;
|
||||
import org.apache.commons.io.FileUtils;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.configuration.InvalidConfigurationException;
|
||||
import org.bukkit.configuration.file.FileConfiguration;
|
||||
import org.bukkit.configuration.file.YamlConfiguration;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import static java.io.File.separator;
|
||||
import static java.util.Arrays.asList;
|
||||
|
||||
public class FileManager {
|
||||
private final EpicEnchants instance;
|
||||
private final Map<String, FileConfiguration> configurationMap;
|
||||
|
||||
public FileManager(EpicEnchants instance) {
|
||||
this.instance = instance;
|
||||
this.configurationMap = new HashMap<>();
|
||||
}
|
||||
|
||||
public void createFiles() {
|
||||
File dir = new File(instance.getDataFolder() + separator + "enchants" + separator);
|
||||
|
||||
if (!dir.exists()) {
|
||||
File def = new File(instance.getDataFolder() + separator + "enchants" + separator + "StrengthEnchant.yml");
|
||||
try {
|
||||
FileUtils.copyInputStreamToFile(instance.getResource("StrengthEnchant.yml"), def);
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
for (String name : asList("config", "bookMenu")) {
|
||||
File file = new File(instance.getDataFolder(), name + ".yml");
|
||||
if (!file.exists()) {
|
||||
file.getParentFile().mkdirs();
|
||||
instance.saveResource(file.getName(), false);
|
||||
}
|
||||
FileConfiguration configuration = new YamlConfiguration();
|
||||
try {
|
||||
configuration.load(file);
|
||||
} catch (IOException | InvalidConfigurationException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
configurationMap.put(name, configuration);
|
||||
}
|
||||
}
|
||||
|
||||
public void loadEnchants() {
|
||||
File dir = new File(instance.getDataFolder() + separator + "enchants" + separator);
|
||||
|
||||
if (!dir.exists()) {
|
||||
instance.saveResource("StrengthEnchant.yml", false);
|
||||
}
|
||||
|
||||
Arrays.stream(dir.listFiles((dir1, filename) -> filename.endsWith(".yml"))).forEach(file -> {
|
||||
try {
|
||||
instance.getEnchantManager().addEnchant(loadEnchant(YamlConfiguration.loadConfiguration(file)));
|
||||
} catch (Exception e) {
|
||||
instance.getLogger().severe(ChatColor.RED + "Something went wrong loading the enchant from file " + file.getName());
|
||||
instance.getLogger().severe(ChatColor.RED + "Please check to make sure there are no errors in the file.");
|
||||
Bukkit.getConsoleSender().sendMessage("Something went wrong loading the enchant from file " + file.getName());
|
||||
Bukkit.getConsoleSender().sendMessage("Please check to make sure there are no errors in the file.");
|
||||
e.printStackTrace();
|
||||
}
|
||||
});
|
||||
@ -42,11 +73,25 @@ public class FileManager {
|
||||
private Enchant loadEnchant(FileConfiguration config) {
|
||||
return Enchant.builder()
|
||||
.identifier(config.getString("identifier"))
|
||||
.maxTier(config.getInt("max-tier"))
|
||||
.tier(config.getInt("tier"))
|
||||
.maxLevel(config.getInt("max-tier"))
|
||||
.format(config.getString("applied-format"))
|
||||
.itemWhitelist(config.getStringList("item-whitelist").stream().map(Material::valueOf).collect(Collectors.toSet()))
|
||||
.potionEffects(config.getStringList("potion-effects").stream().map(ConfigParser::parsePotionEffect).collect(Collectors.toSet()))
|
||||
.action(ConfigParser.parseActionClass(config.getConfigurationSection("action")))
|
||||
.bookItem(ConfigParser.parseBookItem(config.getConfigurationSection("book-item")))
|
||||
.itemWhitelist(config.getStringList("item-whitelist").stream().map(Material::valueOf).collect(Collectors.toSet()))
|
||||
.potionEffects(config.getConfigurationSection("potion-effects").getKeys(false).stream()
|
||||
.map(s -> "potion-effects." + s)
|
||||
.map(config::getConfigurationSection)
|
||||
.map(ConfigParser::parsePotionEffect)
|
||||
.collect(Collectors.toSet()))
|
||||
.mobs(config.getConfigurationSection("mobs").getKeys(false).stream()
|
||||
.map(s -> "mobs." + s)
|
||||
.map(config::getConfigurationSection)
|
||||
.map(ConfigParser::parseMobWrapper).collect(Collectors.toSet()))
|
||||
.build();
|
||||
}
|
||||
|
||||
public FileConfiguration getConfiguration(String key) {
|
||||
return configurationMap.get(key);
|
||||
}
|
||||
}
|
||||
|
@ -1,13 +1,13 @@
|
||||
package com.songoda.epicenchants.objects;
|
||||
|
||||
import com.songoda.epicenchants.wrappers.PotionEffectWrapper;
|
||||
import com.songoda.epicenchants.wrappers.PotionChanceWrapper;
|
||||
import lombok.Builder;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
@Builder
|
||||
public class ActionClass {
|
||||
private Set<PotionEffectWrapper> potionEffects;
|
||||
private Set<PotionChanceWrapper> potionEffects;
|
||||
private double modifyDamageTaken;
|
||||
private double modifyDamageGiven;
|
||||
|
||||
|
@ -0,0 +1,46 @@
|
||||
package com.songoda.epicenchants.objects;
|
||||
|
||||
import co.aikar.commands.annotation.Optional;
|
||||
import com.songoda.epicenchants.utils.ItemBuilder;
|
||||
import de.tr7zw.itemnbtapi.NBTItem;
|
||||
import lombok.Builder;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import static java.util.concurrent.ThreadLocalRandom.current;
|
||||
|
||||
@Builder
|
||||
public class BookItem {
|
||||
private Material material;
|
||||
private String displayName;
|
||||
private List<String> lore;
|
||||
|
||||
public ItemStack get(Enchant enchant, int level) {
|
||||
return get(enchant, level, current().nextDouble(101), current().nextDouble(101));
|
||||
}
|
||||
|
||||
public ItemStack get(Enchant enchant, int level, @Optional Double successRate, @Optional Double destroyRate) {
|
||||
successRate = successRate == null ? current().nextInt(101) : successRate;
|
||||
destroyRate = destroyRate == null ? current().nextInt(101) : destroyRate;
|
||||
|
||||
double finalSuccessRate = successRate;
|
||||
double finalDestroyRate = destroyRate;
|
||||
ItemBuilder itemBuilder = new ItemBuilder(material)
|
||||
.name(displayName.replace("{level}", "" + level))
|
||||
.lore(lore.stream()
|
||||
.map(s -> s.replace("{level}", "" + level)
|
||||
.replace("{success_rate}", "" + finalSuccessRate)
|
||||
.replace("{destroy_rate}", "" + finalDestroyRate))
|
||||
.collect(Collectors.toList()));
|
||||
|
||||
NBTItem nbtItem = itemBuilder.nbt();
|
||||
nbtItem.setDouble("success-rate", successRate);
|
||||
nbtItem.setDouble("destroy-rate", destroyRate);
|
||||
nbtItem.setString("enchant", enchant.getIdentifier());
|
||||
|
||||
return nbtItem.getItem();
|
||||
}
|
||||
}
|
@ -1,21 +1,22 @@
|
||||
package com.songoda.epicenchants.objects;
|
||||
|
||||
import com.songoda.epicenchants.wrappers.MobWrapper;
|
||||
import com.songoda.epicenchants.wrappers.PotionEffectWrapper;
|
||||
import lombok.Builder;
|
||||
import lombok.Getter;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.potion.PotionEffect;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
@Builder
|
||||
public class Enchant {
|
||||
@Getter private String identifier;
|
||||
@Getter private int tier;
|
||||
private Set<MobWrapper> mobs;
|
||||
private Set<PotionEffect> potionEffects;
|
||||
private Set<PotionEffectWrapper> potionEffects;
|
||||
private Set<Material> itemWhitelist;
|
||||
private int maxTier;
|
||||
@Getter private int maxLevel;
|
||||
private String format;
|
||||
private ActionClass action;
|
||||
|
||||
@Getter private BookItem bookItem;
|
||||
}
|
||||
|
13
core/src/main/java/com/songoda/epicenchants/utils/Chat.java
Normal file
13
core/src/main/java/com/songoda/epicenchants/utils/Chat.java
Normal file
@ -0,0 +1,13 @@
|
||||
package com.songoda.epicenchants.utils;
|
||||
|
||||
import org.bukkit.ChatColor;
|
||||
|
||||
public class Chat {
|
||||
public static String color(String input) {
|
||||
return format(input, "", null);
|
||||
}
|
||||
|
||||
public static String format(String input, String placeholder, Object toReplace) {
|
||||
return ChatColor.translateAlternateColorCodes('&', input).replaceAll(placeholder, toReplace == null ? "" : toReplace.toString());
|
||||
}
|
||||
}
|
@ -0,0 +1,75 @@
|
||||
package com.songoda.epicenchants.utils;
|
||||
|
||||
import com.songoda.epicenchants.objects.ActionClass;
|
||||
import com.songoda.epicenchants.objects.BookItem;
|
||||
import com.songoda.epicenchants.wrappers.*;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.configuration.ConfigurationSection;
|
||||
import org.bukkit.enchantments.Enchantment;
|
||||
import org.bukkit.potion.PotionEffectType;
|
||||
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import static com.songoda.epicenchants.utils.Chat.color;
|
||||
|
||||
public class ConfigParser {
|
||||
public static ActionClass parseActionClass(ConfigurationSection section) {
|
||||
return ActionClass.builder()
|
||||
.modifyDamageGiven(section.getDouble("modify-damage-given"))
|
||||
.modifyDamageTaken(section.getDouble("modify-damage-taken"))
|
||||
.potionEffects(section.getConfigurationSection("potion-effects")
|
||||
.getKeys(false).stream()
|
||||
.map(s -> "potion-effects." + s)
|
||||
.map(section::getConfigurationSection)
|
||||
.map(ConfigParser::parsePotionChanceEffect)
|
||||
.collect(Collectors.toSet()))
|
||||
.build();
|
||||
}
|
||||
|
||||
public static PotionChanceWrapper parsePotionChanceEffect(ConfigurationSection section) {
|
||||
return PotionChanceWrapper.chanceBuilder()
|
||||
.type(PotionEffectType.getByName(section.getName()))
|
||||
.amplifier(section.getString("amplifier"))
|
||||
.duration(section.getString("duration"))
|
||||
.chance(section.getDouble("chance"))
|
||||
.build();
|
||||
}
|
||||
|
||||
public static PotionEffectWrapper parsePotionEffect(ConfigurationSection section) {
|
||||
return PotionEffectWrapper.builder()
|
||||
.type(PotionEffectType.getByName(section.getName()))
|
||||
.amplifier(section.getString("amplifier"))
|
||||
.duration(section.getString("duration"))
|
||||
.build();
|
||||
}
|
||||
|
||||
public static MobWrapper parseMobWrapper(ConfigurationSection section) {
|
||||
return MobWrapper.builder()
|
||||
.amount(section.getInt("amount"))
|
||||
.spawnPercentage(section.getDouble("spawn-percentage"))
|
||||
.health(section.getInt("health"))
|
||||
.attackDamage(section.getDouble("attack-damage"))
|
||||
.hostile(section.getBoolean("hostile"))
|
||||
.displayName(color(section.getString("display-name")))
|
||||
.helmet(new ItemBuilder(section.getConfigurationSection("armor.helmet")).build())
|
||||
.leggings(new ItemBuilder(section.getConfigurationSection("armor.chest-plate")).build())
|
||||
.chestPlate(new ItemBuilder(section.getConfigurationSection("armor.leggings")).build())
|
||||
.boots(new ItemBuilder(section.getConfigurationSection("armor.boots")).build())
|
||||
.build();
|
||||
}
|
||||
|
||||
public static EnchantmentWrapper parseEnchantmentWrapper(String key) {
|
||||
return EnchantmentWrapper.builder()
|
||||
.amplifier(key.contains(":") ? key.split(":")[1] : "")
|
||||
.enchantment(Enchantment.getByName(key.split(":")[0]))
|
||||
.build();
|
||||
}
|
||||
|
||||
public static BookItem parseBookItem(ConfigurationSection section) {
|
||||
return BookItem.builder()
|
||||
.material(Material.valueOf(section.getString("material")))
|
||||
.displayName(color(section.getString("display-name")))
|
||||
.lore(section.getStringList("lore").stream().map(Chat::color).collect(Collectors.toList()))
|
||||
.build();
|
||||
}
|
||||
}
|
@ -0,0 +1,9 @@
|
||||
package com.songoda.epicenchants.utils;
|
||||
|
||||
import java.util.concurrent.ThreadLocalRandom;
|
||||
|
||||
public class GeneralUtils {
|
||||
public static boolean chance(Double chance) {
|
||||
return ThreadLocalRandom.current().nextDouble(101) < chance;
|
||||
}
|
||||
}
|
@ -0,0 +1,72 @@
|
||||
package com.songoda.epicenchants.utils;
|
||||
|
||||
import com.songoda.epicenchants.EpicEnchants;
|
||||
import com.songoda.epicenchants.objects.Enchant;
|
||||
import fr.minuskube.inv.ClickableItem;
|
||||
import fr.minuskube.inv.SmartInventory;
|
||||
import fr.minuskube.inv.content.InventoryContents;
|
||||
import fr.minuskube.inv.content.InventoryProvider;
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
import org.bukkit.configuration.file.FileConfiguration;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import java.util.Optional;
|
||||
|
||||
import static com.songoda.epicenchants.utils.Chat.color;
|
||||
import static java.util.concurrent.ThreadLocalRandom.current;
|
||||
|
||||
public class InventoryParser {
|
||||
public static SmartInventory parseBookMenu(EpicEnchants instance, FileConfiguration config) {
|
||||
return SmartInventory.builder()
|
||||
.title(color(config.getString("title")))
|
||||
.size(config.getInt("rows"), 9)
|
||||
.provider(new InventoryProvider() {
|
||||
@Override
|
||||
public void init(Player opener, InventoryContents inventoryContents) {
|
||||
if (config.isConfigurationSection("fill")) {
|
||||
inventoryContents.fill(ClickableItem.empty(new ItemBuilder(config.getConfigurationSection("fill")).build()));
|
||||
}
|
||||
|
||||
config.getConfigurationSection("contents").getKeys(false)
|
||||
.stream()
|
||||
.filter(StringUtils::isNumeric)
|
||||
.map(s -> "contents." + s)
|
||||
.map(config::getConfigurationSection)
|
||||
.forEach(config -> {
|
||||
double expCost = config.getDouble("exp-cost");
|
||||
double ecoCost = config.getDouble("eco-cost");
|
||||
int tier = config.getInt("tier");
|
||||
inventoryContents.set(config.getInt("row"), config.getInt("column"), ClickableItem.of(new ItemBuilder(config).build(), event -> {
|
||||
Player player = ((Player) event.getWhoClicked());
|
||||
if (!instance.getEconomy().has((player), ecoCost) || (player).getLevel() < expCost) {
|
||||
player
|
||||
.sendMessage(instance
|
||||
.getLocale().getPrefix() + instance.getLocale()
|
||||
.getMessage("event.purchase.cannotafford"));
|
||||
return;
|
||||
}
|
||||
|
||||
Optional<Enchant> enchant = instance.getEnchantManager().getRandomEnchant(tier);
|
||||
|
||||
if (!enchant.isPresent()) {
|
||||
player.sendMessage(instance.getLocale().getPrefix() + instance.getLocale().getMessage("event.purchase.noenchant"));
|
||||
return;
|
||||
}
|
||||
|
||||
instance.getEconomy().withdrawPlayer(player, ecoCost);
|
||||
player.setLevel((int) (player.getLevel() - expCost));
|
||||
player.getInventory().addItem(enchant.get().getBookItem().get(enchant.get(), current().nextInt(enchant.get().getMaxLevel() + 1)));
|
||||
player.sendMessage(instance.getLocale().getPrefix() + instance.getLocale().getMessage("event.purchase.successful"));
|
||||
}));
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void update(Player player, InventoryContents inventoryContents) {
|
||||
|
||||
}
|
||||
})
|
||||
.manager(instance.getInventoryManager())
|
||||
.build();
|
||||
}
|
||||
}
|
@ -0,0 +1,218 @@
|
||||
package com.songoda.epicenchants.utils;
|
||||
|
||||
import com.songoda.epicenchants.wrappers.EnchantmentWrapper;
|
||||
import de.tr7zw.itemnbtapi.NBTItem;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.configuration.ConfigurationSection;
|
||||
import org.bukkit.enchantments.Enchantment;
|
||||
import org.bukkit.inventory.ItemFlag;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.inventory.meta.ItemMeta;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public class ItemBuilder {
|
||||
|
||||
private final ItemStack item;
|
||||
private ItemMeta meta;
|
||||
private Set<EnchantmentWrapper> enchantmentWrappers;
|
||||
|
||||
/*
|
||||
* Constructors:
|
||||
*/
|
||||
public ItemBuilder(Material material) {
|
||||
this(new ItemStack(material));
|
||||
}
|
||||
|
||||
public ItemBuilder(Material material, int amount) {
|
||||
this(new ItemStack(material, amount));
|
||||
}
|
||||
|
||||
public ItemBuilder(Material material, byte data) {
|
||||
this(new ItemStack(material, 1, data));
|
||||
}
|
||||
|
||||
public ItemBuilder(Material material, int amount, byte data) {
|
||||
this(new ItemStack(material, amount, data));
|
||||
}
|
||||
|
||||
public ItemBuilder(ConfigurationSection section) {
|
||||
this(Material.valueOf(section.getString("material")), (byte) (section.contains("data") ? section.getInt("data") : 0));
|
||||
|
||||
if (section.contains("enchants")) {
|
||||
section.getStringList("enchants").stream()
|
||||
.map(ConfigParser::parseEnchantmentWrapper)
|
||||
.forEach(this::addEnchantWrapper);
|
||||
}
|
||||
|
||||
if (section.contains("display-name")) {
|
||||
name(Chat.color(section.getString("display-name")));
|
||||
}
|
||||
|
||||
if (section.contains("lore")) {
|
||||
lore(section.getStringList("lore").stream().map(Chat::color).collect(Collectors.toList()));
|
||||
}
|
||||
}
|
||||
|
||||
public ItemBuilder(ItemStack item) {
|
||||
this.item = item;
|
||||
this.meta = item.getItemMeta();
|
||||
this.enchantmentWrappers = new HashSet<>();
|
||||
}
|
||||
|
||||
/*
|
||||
* Meta:
|
||||
*/
|
||||
public boolean hasMeta() {
|
||||
return getMeta() != null;
|
||||
}
|
||||
|
||||
public ItemBuilder meta(ItemMeta meta) {
|
||||
this.meta = meta;
|
||||
return this;
|
||||
}
|
||||
|
||||
/*
|
||||
* Name:
|
||||
*/
|
||||
public boolean hasName() {
|
||||
return meta.hasDisplayName();
|
||||
}
|
||||
|
||||
public ItemBuilder name(String name) {
|
||||
meta.setDisplayName(name);
|
||||
return this;
|
||||
}
|
||||
|
||||
/*
|
||||
* Lore:
|
||||
*/
|
||||
public boolean hasLore() {
|
||||
return meta.hasLore();
|
||||
}
|
||||
|
||||
public ItemBuilder lore(String... lore) {
|
||||
return lore(Arrays.asList(lore));
|
||||
}
|
||||
|
||||
public ItemBuilder lore(List<String> lore) {
|
||||
meta.setLore(lore);
|
||||
return this;
|
||||
}
|
||||
|
||||
public ItemBuilder addLore(List<String> lore) {
|
||||
if (!meta.hasLore()) {
|
||||
meta.setLore(lore);
|
||||
return this;
|
||||
}
|
||||
|
||||
List<String> toAdd = meta.getLore();
|
||||
toAdd.addAll(lore);
|
||||
meta.setLore(toAdd);
|
||||
return this;
|
||||
}
|
||||
|
||||
public ItemBuilder addLore(String... lore) {
|
||||
return addLore(Arrays.asList(lore));
|
||||
}
|
||||
|
||||
/*
|
||||
* Enchantments:
|
||||
*/
|
||||
public boolean hasEnchants() {
|
||||
return meta.hasEnchants();
|
||||
}
|
||||
|
||||
public boolean hasEnchant(Enchantment enchantment) {
|
||||
return meta.hasEnchant(enchantment);
|
||||
}
|
||||
|
||||
public boolean hasConflictingEnchant(Enchantment enchantment) {
|
||||
return meta.hasConflictingEnchant(enchantment);
|
||||
}
|
||||
|
||||
public ItemBuilder addEnchant(Enchantment enchantment, int level) {
|
||||
meta.addEnchant(enchantment, level, true);
|
||||
return this;
|
||||
}
|
||||
|
||||
public ItemBuilder removeEnchant(Enchantment enchantment) {
|
||||
meta.removeEnchant(enchantment);
|
||||
return this;
|
||||
}
|
||||
|
||||
public ItemBuilder addEnchantWrapper(EnchantmentWrapper enchantmentWrapper) {
|
||||
enchantmentWrappers.add(enchantmentWrapper);
|
||||
return this;
|
||||
}
|
||||
|
||||
/*
|
||||
* Flags:
|
||||
*/
|
||||
public boolean hasFlag(ItemFlag flag) {
|
||||
return meta.hasItemFlag(flag);
|
||||
}
|
||||
|
||||
public ItemBuilder addFlags(ItemFlag... flags) {
|
||||
meta.addItemFlags(flags);
|
||||
return this;
|
||||
}
|
||||
|
||||
public ItemBuilder removeFlags(ItemFlag... flags) {
|
||||
meta.removeItemFlags(flags);
|
||||
return this;
|
||||
}
|
||||
|
||||
public ItemBuilder unbreakable() {
|
||||
return unbreakable(true);
|
||||
}
|
||||
|
||||
public ItemBuilder unbreakable(boolean unbreakable) {
|
||||
meta.spigot().setUnbreakable(unbreakable);
|
||||
return this;
|
||||
}
|
||||
|
||||
public NBTItem nbt() {
|
||||
return new NBTItem(build());
|
||||
}
|
||||
|
||||
/*
|
||||
* Build the ItemStack.
|
||||
*/
|
||||
public ItemStack build() {
|
||||
item.setItemMeta(meta);
|
||||
return item;
|
||||
}
|
||||
|
||||
public Map<Enchantment, Integer> getEnchants() {
|
||||
return meta.getEnchants();
|
||||
}
|
||||
|
||||
public Set<ItemFlag> getFlags() {
|
||||
return meta.getItemFlags();
|
||||
}
|
||||
|
||||
public List<String> getLore() {
|
||||
return meta.getLore();
|
||||
}
|
||||
|
||||
public ItemMeta getMeta() {
|
||||
return meta;
|
||||
}
|
||||
|
||||
/*
|
||||
* NBT
|
||||
*/
|
||||
|
||||
public String getName() {
|
||||
return meta.getDisplayName();
|
||||
}
|
||||
|
||||
/*
|
||||
* Unbreakability:
|
||||
*/
|
||||
public boolean isUnbreakable() {
|
||||
return meta.spigot().isUnbreakable();
|
||||
}
|
||||
}
|
@ -0,0 +1,28 @@
|
||||
package com.songoda.epicenchants.utils;
|
||||
|
||||
import co.aikar.commands.*;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
public class ValidationUtils {
|
||||
@NotNull
|
||||
public static Number parseAndValidateNumber(CommandExecutionContext c, Number minValue, Number maxValue) throws InvalidCommandArgument {
|
||||
final Number val = ACFUtil.parseNumber(c.popFirstArg(), c.hasFlag("suffixes"));
|
||||
validateMinMax(c, val, minValue, maxValue);
|
||||
return val;
|
||||
}
|
||||
|
||||
private static void validateMinMax(CommandExecutionContext c, Number val) throws InvalidCommandArgument {
|
||||
validateMinMax(c, val, null, null);
|
||||
}
|
||||
|
||||
private static void validateMinMax(CommandExecutionContext c, Number val, Number minValue, Number maxValue) throws InvalidCommandArgument {
|
||||
minValue = c.getFlagValue("min", minValue);
|
||||
maxValue = c.getFlagValue("max", maxValue);
|
||||
if (maxValue != null && val.doubleValue() > maxValue.doubleValue()) {
|
||||
throw new InvalidCommandArgument(MessageKeys.PLEASE_SPECIFY_AT_MOST, "{max}", String.valueOf(maxValue));
|
||||
}
|
||||
if (minValue != null && val.doubleValue() < minValue.doubleValue()) {
|
||||
throw new InvalidCommandArgument(MessageKeys.PLEASE_SPECIFY_AT_LEAST, "{min}", String.valueOf(minValue));
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,18 @@
|
||||
package com.songoda.epicenchants.wrappers;
|
||||
|
||||
import lombok.Builder;
|
||||
import org.bukkit.enchantments.Enchantment;
|
||||
|
||||
@Builder
|
||||
public class EnchantmentWrapper {
|
||||
private String amplifier;
|
||||
private Enchantment enchantment;
|
||||
|
||||
public int getAmplifier(int tier) {
|
||||
return amplifier.isEmpty() ? 0 : Integer.parseInt(amplifier.replaceAll("\\{tier}", "" + tier));
|
||||
}
|
||||
|
||||
public Enchantment getEnchantment() {
|
||||
return enchantment;
|
||||
}
|
||||
}
|
@ -1,14 +1,49 @@
|
||||
package com.songoda.epicenchants.wrappers;
|
||||
|
||||
import com.songoda.epicenchants.utils.GeneralUtils;
|
||||
import lombok.Builder;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.entity.EntityType;
|
||||
import org.bukkit.entity.LivingEntity;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
|
||||
import static java.util.concurrent.ThreadLocalRandom.current;
|
||||
|
||||
@Builder
|
||||
public class MobWrapper {
|
||||
private String displayName;
|
||||
private int amount;
|
||||
private int health;
|
||||
private EntityType entityType;
|
||||
private double spawnPercentage;
|
||||
private double health;
|
||||
private double attackDamage;
|
||||
private boolean hostile;
|
||||
private ItemStack helmet, chestPlate, leggings, boots;
|
||||
|
||||
public boolean trySpawn(Location location) {
|
||||
if (!GeneralUtils.chance(spawnPercentage)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
for (int i = 0; i < current().nextInt(amount + 1); i++) {
|
||||
Location spawnLocation = location.clone().add(current().nextInt(-3, 3), 0, current().nextInt(-3, 3));
|
||||
int y = location.getWorld().getHighestBlockAt(spawnLocation).getY();
|
||||
|
||||
if (y < location.getY() - 10 || y > location.getY() + 10) {
|
||||
continue;
|
||||
}
|
||||
|
||||
LivingEntity entity = (LivingEntity) location.getWorld().spawn(spawnLocation, entityType.getEntityClass());
|
||||
|
||||
entity.setCustomName(displayName);
|
||||
entity.setCustomNameVisible(true);
|
||||
entity.setHealth(health);
|
||||
entity.getEquipment().setHelmet(helmet);
|
||||
entity.getEquipment().setChestplate(chestPlate);
|
||||
entity.getEquipment().setLeggings(leggings);
|
||||
entity.getEquipment().setBoots(boots);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,26 @@
|
||||
package com.songoda.epicenchants.wrappers;
|
||||
|
||||
import io.netty.util.internal.ThreadLocalRandom;
|
||||
import lombok.Builder;
|
||||
import lombok.Getter;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.potion.PotionEffectType;
|
||||
|
||||
@Getter
|
||||
public class PotionChanceWrapper extends PotionEffectWrapper {
|
||||
private double chance;
|
||||
|
||||
@Builder(builderMethodName = "chanceBuilder")
|
||||
PotionChanceWrapper(PotionEffectType type, String amplifier, String duration, double chance) {
|
||||
super(type, amplifier, duration);
|
||||
this.chance = chance;
|
||||
}
|
||||
|
||||
public boolean test() {
|
||||
return ThreadLocalRandom.current().nextDouble(101) < chance;
|
||||
}
|
||||
|
||||
public void perform(Player player, int tier) {
|
||||
player.addPotionEffect(get(tier));
|
||||
}
|
||||
}
|
@ -1,23 +1,23 @@
|
||||
package com.songoda.epicenchants.wrappers;
|
||||
|
||||
import io.netty.util.internal.ThreadLocalRandom;
|
||||
import org.bukkit.entity.Player;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Builder;
|
||||
import org.bukkit.potion.PotionEffect;
|
||||
import org.bukkit.potion.PotionEffectType;
|
||||
|
||||
import static java.lang.Integer.parseInt;
|
||||
import static java.lang.String.valueOf;
|
||||
|
||||
@Builder
|
||||
@AllArgsConstructor
|
||||
public class PotionEffectWrapper {
|
||||
private PotionEffect potionEffect;
|
||||
private double chance;
|
||||
private PotionEffectType type;
|
||||
private String amplifier;
|
||||
private String duration;
|
||||
|
||||
public PotionEffectWrapper(PotionEffect potionEffect, double chance) {
|
||||
this.potionEffect = potionEffect;
|
||||
this.chance = chance;
|
||||
}
|
||||
|
||||
public boolean test() {
|
||||
return ThreadLocalRandom.current().nextDouble(101) < chance;
|
||||
}
|
||||
|
||||
public void perform(Player player) {
|
||||
player.addPotionEffect(potionEffect);
|
||||
public PotionEffect get(int tier) {
|
||||
int tempAmplifier = amplifier.isEmpty() ? 0 : parseInt(amplifier.replace("{tier}", valueOf(tier)));
|
||||
int tempDuration = duration.isEmpty() ? 0 : parseInt(duration.replace("{tier}", valueOf(tier)));
|
||||
return new PotionEffect(type, tempDuration, tempAmplifier);
|
||||
}
|
||||
}
|
||||
|
@ -1,32 +1,39 @@
|
||||
enchant-id: Strength
|
||||
#The enchant identifier must be unique
|
||||
identifier: Strength
|
||||
|
||||
max-tier: 3
|
||||
#The max level for this enchant
|
||||
max-level: 3
|
||||
|
||||
#The tier of this enchant
|
||||
tier: 1
|
||||
|
||||
#The book item
|
||||
book-item:
|
||||
material: BOOK
|
||||
display-name: "&cStrength {tier}"
|
||||
display-name: "&cStrength {level}"
|
||||
lore:
|
||||
- "&7Drag on to enchant"
|
||||
- "&cDestroy Rate {destroy_rate}"
|
||||
- "&aSuccess Rate {success_rate}"
|
||||
|
||||
#Format as seen in the lore of the item
|
||||
applied-format: "&7Strength {tier}"
|
||||
applied-format: "&7Strength {level}"
|
||||
|
||||
#What items this enchant can be applied too
|
||||
item-whitelist:
|
||||
- "DIAMOND_HELMET"
|
||||
- "GOLD_HELMET"
|
||||
- "STONE_HELMET"
|
||||
- "IRON_HELMET"
|
||||
- "LEATHER_HELMET"
|
||||
|
||||
#Potion effects applied on equip
|
||||
potion-effects:
|
||||
- "STRENGTH:{tier}"
|
||||
INCREASE_DAMAGE:
|
||||
amplifier: {level}
|
||||
|
||||
#Spawned when hit or when you strike an enemy in case of tools
|
||||
mobs:
|
||||
IRON_GOLEM:
|
||||
amount: 3
|
||||
spawn-percentage: 20
|
||||
health: 80
|
||||
attack-damage: 2
|
||||
@ -36,22 +43,22 @@ mobs:
|
||||
helmet:
|
||||
material: DIAMOND_HELMET
|
||||
enchants:
|
||||
- "UNBREAKING:3"
|
||||
- "DURABILITY:3"
|
||||
- "THORNS:2"
|
||||
chest-plate:
|
||||
material: DIAMOND_CHESTPLATE
|
||||
enchants:
|
||||
- "UNBREAKING:3"
|
||||
- "DURABILITY:3"
|
||||
- "THORNS:2"
|
||||
leggings:
|
||||
material: DIAMOND_LEGGINGS
|
||||
enchants:
|
||||
- "UNBREAKING:3"
|
||||
- "DURABILITY:3"
|
||||
- "THORNS:2"
|
||||
boots:
|
||||
material: DIAMOND_BOOTS
|
||||
enchants:
|
||||
- "UNBREAKING:3"
|
||||
- "DURABILITY:3"
|
||||
- "THORNS:2"
|
||||
|
||||
#On hit or deal damage
|
||||
|
18
core/src/main/resources/bookMenu.yml
Normal file
18
core/src/main/resources/bookMenu.yml
Normal file
@ -0,0 +1,18 @@
|
||||
title: "Books"
|
||||
rows: 3
|
||||
|
||||
fill:
|
||||
material: "STAINED_GLASS_PANE"
|
||||
display-name: "&r"
|
||||
data: 7
|
||||
|
||||
contents:
|
||||
1:
|
||||
material: "BOOK"
|
||||
display-name: "&cClick to purchase random book"
|
||||
data: 7
|
||||
tier: 1
|
||||
exp-cost: 2000
|
||||
eco-cost: 2000
|
||||
row: 3
|
||||
column: 5
|
1
core/src/main/resources/config.yml
Normal file
1
core/src/main/resources/config.yml
Normal file
@ -0,0 +1 @@
|
||||
language: en_US
|
14
core/src/main/resources/en_US.lang
Normal file
14
core/src/main/resources/en_US.lang
Normal file
@ -0,0 +1,14 @@
|
||||
#General Messages
|
||||
|
||||
general.nametag.prefix= "&8[&6EpicEnchants&8]"
|
||||
|
||||
#Command Messages
|
||||
|
||||
command.give.success= "&7You have been given a &6tier {tier} &7Book."
|
||||
|
||||
#Event Messages
|
||||
|
||||
event.general.nopermission= "&cYou do not have permission to do that."
|
||||
event.purchase.noenchant= "&cThere is no enchant available for &6tier {tier}&7."
|
||||
event.purchase.cannotafford= "&cYou cannot afford this purchase."
|
||||
event.purchase.success= "&7You successfully purchased a &6tier {tier} &7Book."
|
@ -2,4 +2,5 @@ name: EpicEnchants
|
||||
version: ${project.version}
|
||||
main: com.songoda.epicenchants.EpicEnchants
|
||||
authors: [GB6]
|
||||
website: https://songoda.com/
|
||||
website: https://songoda.com/
|
||||
depend: [Vault]
|
9
pom.xml
9
pom.xml
@ -5,7 +5,7 @@
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<groupId>com.songoda</groupId>
|
||||
<artifactId>epicenchants</artifactId>
|
||||
<artifactId>EpicEnchants-Parent</artifactId>
|
||||
<packaging>pom</packaging>
|
||||
<version>1.0</version>
|
||||
<modules>
|
||||
@ -31,6 +31,13 @@
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
|
||||
<resources>
|
||||
<resource>
|
||||
<directory>src/main/resources</directory>
|
||||
<filtering>true</filtering>
|
||||
</resource>
|
||||
</resources>
|
||||
</build>
|
||||
|
||||
</project>
|
Loading…
Reference in New Issue
Block a user