Uses KnarLib to get rid of duplicate code
This commit is contained in:
parent
5b02a094e8
commit
c03e06b132
26
pom.xml
26
pom.xml
@ -13,7 +13,7 @@
|
||||
|
||||
<description>A plugin for displaying citizens on the dynmap map</description>
|
||||
<properties>
|
||||
<java.version>17</java.version>
|
||||
<java.version>16</java.version>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
</properties>
|
||||
|
||||
@ -24,8 +24,8 @@
|
||||
<artifactId>maven-compiler-plugin</artifactId>
|
||||
<version>3.8.1</version>
|
||||
<configuration>
|
||||
<source>17</source>
|
||||
<target>17</target>
|
||||
<source>${java.version}</source>
|
||||
<target>${java.version}</target>
|
||||
</configuration>
|
||||
</plugin>
|
||||
<plugin>
|
||||
@ -40,6 +40,20 @@
|
||||
</goals>
|
||||
<configuration>
|
||||
<createDependencyReducedPom>false</createDependencyReducedPom>
|
||||
<filters>
|
||||
<filter>
|
||||
<artifact>net.knarcraft:knarlib</artifact>
|
||||
<includes>
|
||||
<include>net/knarcraft/knarlib/**</include>
|
||||
</includes>
|
||||
</filter>
|
||||
<filter>
|
||||
<excludes>
|
||||
<exclude>*.MF</exclude>
|
||||
<exclude>*.yml</exclude>
|
||||
</excludes>
|
||||
</filter>
|
||||
</filters>
|
||||
</configuration>
|
||||
</execution>
|
||||
</executions>
|
||||
@ -136,6 +150,12 @@
|
||||
<version>1.7.3</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>net.knarcraft</groupId>
|
||||
<artifactId>knarlib</artifactId>
|
||||
<version>1.0-SNAPSHOT</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.mcmonkey</groupId>
|
||||
<artifactId>sentinel</artifactId>
|
||||
|
@ -1,6 +1,6 @@
|
||||
package net.knarcraft.dynmapcitizens;
|
||||
|
||||
import net.knarcraft.dynmapcitizens.formatting.Translator;
|
||||
import net.knarcraft.dynmapcitizens.formatting.DynmapCitizensTranslatableMessage;
|
||||
import net.knarcraft.dynmapcitizens.handler.VaultHandler;
|
||||
import net.knarcraft.dynmapcitizens.handler.trait.BlacksmithHandler;
|
||||
import net.knarcraft.dynmapcitizens.handler.trait.CitizensTraitHandler;
|
||||
@ -8,6 +8,9 @@ import net.knarcraft.dynmapcitizens.handler.trait.MinstrelHandler;
|
||||
import net.knarcraft.dynmapcitizens.handler.trait.SentinelHandler;
|
||||
import net.knarcraft.dynmapcitizens.handler.trait.quests.QuestsHandler;
|
||||
import net.knarcraft.dynmapcitizens.settings.GlobalSettings;
|
||||
import net.knarcraft.knarlib.KnarLib;
|
||||
import net.knarcraft.knarlib.formatting.TranslatableTimeUnit;
|
||||
import net.knarcraft.knarlib.formatting.Translator;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.configuration.file.FileConfiguration;
|
||||
import org.bukkit.plugin.Plugin;
|
||||
@ -31,6 +34,8 @@ public final class DynmapCitizens extends JavaPlugin {
|
||||
@Override
|
||||
public void onEnable() {
|
||||
DynmapCitizens.instance = this;
|
||||
KnarLib.setPlugin(this);
|
||||
|
||||
//Initialize quest and dynmap APIs
|
||||
PluginManager pluginManager = Bukkit.getPluginManager();
|
||||
Plugin dynmapPlugin = pluginManager.getPlugin("dynmap");
|
||||
@ -51,6 +56,8 @@ public final class DynmapCitizens extends JavaPlugin {
|
||||
this.globalSettings.load(configuration);
|
||||
|
||||
//Load all messages
|
||||
Translator.registerMessageCategory(TranslatableTimeUnit.UNIT_SECOND);
|
||||
Translator.registerMessageCategory(DynmapCitizensTranslatableMessage.SENTINEL_DESCRIPTION);
|
||||
Translator.loadLanguages("en");
|
||||
|
||||
//Initialize all enabled traits
|
||||
|
@ -0,0 +1,35 @@
|
||||
package net.knarcraft.dynmapcitizens.formatting;
|
||||
|
||||
import net.knarcraft.knarlib.formatting.TranslatableMessage;
|
||||
|
||||
/**
|
||||
* An enum describing all of DynmapCitizens' translatable messages
|
||||
*/
|
||||
public enum DynmapCitizensTranslatableMessage implements TranslatableMessage {
|
||||
|
||||
SENTINEL_DESCRIPTION,
|
||||
SENTINEL_DETAILS,
|
||||
QUESTS_PLANNER_DESCRIPTION,
|
||||
QUESTS_PLANNER_COOL_DOWN,
|
||||
QUESTS_PLANNER_UNREPEATABLE,
|
||||
QUESTS_PLANNER_FROM,
|
||||
QUESTS_PLANNER_UNTIL,
|
||||
QUEST_PLANNER_REPEAT,
|
||||
QUESTS_REQUIREMENTS_FORMAT,
|
||||
QUESTS_REQUIREMENTS_QUEST_POINTS,
|
||||
QUESTS_REQUIREMENTS_EXP,
|
||||
QUESTS_REQUIREMENTS_BLOCKED_BY_QUEST_FORMAT,
|
||||
QUESTS_REQUIREMENTS_BLOCKED_BY_QUEST_ITEM,
|
||||
QUESTS_REQUIREMENTS_REQUIRED_QUEST_FORMAT,
|
||||
QUESTS_REQUIREMENTS_REQUIRED_QUEST_ITEM,
|
||||
QUESTS_REQUIREMENTS_REQUIRED_ITEM_FORMAT,
|
||||
QUESTS_REQUIREMENTS_REQUIRED_ITEM_ITEM,
|
||||
QUESTS_REQUIREMENTS_MC_MMO_SKILL,
|
||||
QUESTS_REQUIREMENTS_REQUIRED_PERMISSION_FORMAT,
|
||||
QUESTS_REQUIREMENTS_REQUIRED_PERMISSION_ITEM;
|
||||
|
||||
@Override
|
||||
public TranslatableMessage[] getAllMessages() {
|
||||
return DynmapCitizensTranslatableMessage.values();
|
||||
}
|
||||
}
|
@ -1,114 +0,0 @@
|
||||
package net.knarcraft.dynmapcitizens.formatting;
|
||||
|
||||
import net.knarcraft.dynmapcitizens.DynmapCitizens;
|
||||
import net.md_5.bungee.api.ChatColor;
|
||||
import org.bukkit.command.CommandSender;
|
||||
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
/**
|
||||
* A formatter for formatting displayed messages
|
||||
*/
|
||||
public final class StringFormatter {
|
||||
|
||||
private final static String pluginName = DynmapCitizens.getInstance().getDescription().getName();
|
||||
|
||||
private StringFormatter() {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Displays a message signifying a successful action
|
||||
*
|
||||
* @param sender <p>The command sender to display the message to</p>
|
||||
* @param message <p>The translatable message to display</p>
|
||||
*/
|
||||
public static void displaySuccessMessage(CommandSender sender, TranslatableMessage message) {
|
||||
sender.sendMessage(ChatColor.GREEN + getFormattedMessage(Translator.getTranslatedMessage(message)));
|
||||
}
|
||||
|
||||
/**
|
||||
* Displays a message signifying a successful action
|
||||
*
|
||||
* @param sender <p>The command sender to display the message to</p>
|
||||
* @param message <p>The raw message to display</p>
|
||||
*/
|
||||
public static void displaySuccessMessage(CommandSender sender, String message) {
|
||||
sender.sendMessage(ChatColor.GREEN + getFormattedMessage(message));
|
||||
}
|
||||
|
||||
/**
|
||||
* Displays a message signifying an unsuccessful action
|
||||
*
|
||||
* @param sender <p>The command sender to display the message to</p>
|
||||
* @param message <p>The translatable message to display</p>
|
||||
*/
|
||||
public static void displayErrorMessage(CommandSender sender, TranslatableMessage message) {
|
||||
sender.sendMessage(ChatColor.DARK_RED + getFormattedMessage(Translator.getTranslatedMessage(message)));
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the formatted version of any chat message
|
||||
*
|
||||
* @param message <p>The message to format</p>
|
||||
* @return <p>The formatted message</p>
|
||||
*/
|
||||
private static String getFormattedMessage(String message) {
|
||||
return "[" + pluginName + "] " + ChatColor.RESET + translateColors(message);
|
||||
}
|
||||
|
||||
/**
|
||||
* Translates & color codes to proper colors
|
||||
*
|
||||
* @param input <p>The input string to translate colors for</p>
|
||||
* @return <p>The input with color codes translated</p>
|
||||
*/
|
||||
private static String translateColors(String input) {
|
||||
return ChatColor.translateAlternateColorCodes('&', input);
|
||||
}
|
||||
|
||||
/**
|
||||
* Replaces a placeholder in a string
|
||||
*
|
||||
* @param input <p>The input string to replace in</p>
|
||||
* @param placeholder <p>The placeholder to replace</p>
|
||||
* @param replacement <p>The replacement value</p>
|
||||
* @return <p>The input string with the placeholder replaced</p>
|
||||
*/
|
||||
public static String replacePlaceholder(String input, String placeholder, String replacement) {
|
||||
return input.replace(placeholder, replacement);
|
||||
}
|
||||
|
||||
/**
|
||||
* Replaces placeholders in a string
|
||||
*
|
||||
* @param input <p>The input string to replace in</p>
|
||||
* @param placeholders <p>The placeholders to replace</p>
|
||||
* @param replacements <p>The replacement values</p>
|
||||
* @return <p>The input string with placeholders replaced</p>
|
||||
*/
|
||||
public static String replacePlaceholders(String input, String[] placeholders, String[] replacements) {
|
||||
for (int i = 0; i < Math.min(placeholders.length, replacements.length); i++) {
|
||||
input = replacePlaceholder(input, placeholders[i], replacements[i]);
|
||||
}
|
||||
return input;
|
||||
}
|
||||
|
||||
/**
|
||||
* Translates all found color codes to formatting in a string
|
||||
*
|
||||
* @param message <p>The string to search for color codes</p>
|
||||
* @return <p>The message with color codes translated</p>
|
||||
*/
|
||||
public static String translateAllColorCodes(String message) {
|
||||
message = ChatColor.translateAlternateColorCodes('&', message);
|
||||
Pattern pattern = Pattern.compile("(#[a-fA-F0-9]{6})");
|
||||
Matcher matcher = pattern.matcher(message);
|
||||
while (matcher.find()) {
|
||||
message = message.replace(matcher.group(), "" + ChatColor.of(matcher.group()));
|
||||
}
|
||||
return message;
|
||||
}
|
||||
|
||||
}
|
@ -1,7 +0,0 @@
|
||||
package net.knarcraft.dynmapcitizens.formatting;
|
||||
|
||||
public enum TranslatableMessage {
|
||||
|
||||
SENTINEL_DETAILS
|
||||
|
||||
}
|
@ -1,120 +0,0 @@
|
||||
package net.knarcraft.dynmapcitizens.formatting;
|
||||
|
||||
import net.knarcraft.dynmapcitizens.DynmapCitizens;
|
||||
import net.knarcraft.dynmapcitizens.util.FileHelper;
|
||||
import org.bukkit.configuration.file.YamlConfiguration;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.InputStreamReader;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.logging.Level;
|
||||
|
||||
/**
|
||||
* A tool to get strings translated to the correct language
|
||||
*/
|
||||
public final class Translator {
|
||||
|
||||
private static Map<TranslatableMessage, String> translatedMessages;
|
||||
private static Map<TranslatableMessage, String> backupTranslatedMessages;
|
||||
|
||||
private Translator() {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads the languages used by this translator
|
||||
*/
|
||||
public static void loadLanguages(String selectedLanguage) {
|
||||
backupTranslatedMessages = loadTranslatedMessages("en");
|
||||
translatedMessages = loadCustomTranslatedMessages(selectedLanguage);
|
||||
if (translatedMessages == null) {
|
||||
translatedMessages = loadTranslatedMessages(selectedLanguage);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a translated version of the given translatable message
|
||||
*
|
||||
* @param translatableMessage <p>The message to translate</p>
|
||||
* @return <p>The translated message</p>
|
||||
*/
|
||||
public static String getTranslatedMessage(TranslatableMessage translatableMessage) {
|
||||
if (translatedMessages == null) {
|
||||
return "Translated strings not loaded";
|
||||
}
|
||||
String translatedMessage;
|
||||
if (translatedMessages.containsKey(translatableMessage)) {
|
||||
translatedMessage = translatedMessages.get(translatableMessage);
|
||||
} else if (backupTranslatedMessages.containsKey(translatableMessage)) {
|
||||
translatedMessage = backupTranslatedMessages.get(translatableMessage);
|
||||
} else {
|
||||
translatedMessage = translatableMessage.toString();
|
||||
}
|
||||
return StringFormatter.translateAllColorCodes(translatedMessage);
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads all translated messages for the given language
|
||||
*
|
||||
* @param language <p>The language chosen by the user</p>
|
||||
* @return <p>A mapping of all strings for the given language</p>
|
||||
*/
|
||||
public static Map<TranslatableMessage, String> loadTranslatedMessages(String language) {
|
||||
try {
|
||||
BufferedReader reader = FileHelper.getBufferedReaderForInternalFile("/strings.yml");
|
||||
return loadTranslatableMessages(language, reader);
|
||||
} catch (FileNotFoundException e) {
|
||||
DynmapCitizens.getInstance().getLogger().log(Level.SEVERE, "Unable to load translated messages");
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Tries to load translated messages from a custom strings.yml file
|
||||
*
|
||||
* @param language <p>The selected language</p>
|
||||
* @return <p>The loaded translated strings, or null if no custom language file exists</p>
|
||||
*/
|
||||
public static Map<TranslatableMessage, String> loadCustomTranslatedMessages(String language) {
|
||||
DynmapCitizens instance = DynmapCitizens.getInstance();
|
||||
|
||||
File strings = new File(instance.getDataFolder(), "strings.yml");
|
||||
if (!strings.exists()) {
|
||||
instance.getLogger().log(Level.FINEST, "Strings file not found");
|
||||
return null;
|
||||
}
|
||||
|
||||
try {
|
||||
instance.getLogger().log(Level.INFO, "Loading custom strings...");
|
||||
return loadTranslatableMessages(language, new BufferedReader(new InputStreamReader(new FileInputStream(strings))));
|
||||
} catch (FileNotFoundException e) {
|
||||
instance.getLogger().log(Level.WARNING, "Unable to load custom messages");
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads translatable messages from the given reader
|
||||
*
|
||||
* @param language <p>The selected language</p>
|
||||
* @param reader <p>The buffered reader to read from</p>
|
||||
* @return <p>The loaded translated strings</p>
|
||||
*/
|
||||
private static Map<TranslatableMessage, String> loadTranslatableMessages(String language, BufferedReader reader) {
|
||||
Map<TranslatableMessage, String> translatedMessages = new HashMap<>();
|
||||
YamlConfiguration configuration = YamlConfiguration.loadConfiguration(reader);
|
||||
|
||||
for (TranslatableMessage message : TranslatableMessage.values()) {
|
||||
String translated = configuration.getString(language + "." + message.toString());
|
||||
if (translated != null) {
|
||||
translatedMessages.put(message, translated);
|
||||
}
|
||||
}
|
||||
return translatedMessages;
|
||||
}
|
||||
|
||||
}
|
@ -2,7 +2,11 @@ package net.knarcraft.dynmapcitizens.handler.trait.quests;
|
||||
|
||||
import me.blackvein.quests.quests.IQuest;
|
||||
import me.blackvein.quests.quests.Planner;
|
||||
import net.knarcraft.dynmapcitizens.util.TimeFormatter;
|
||||
import net.knarcraft.knarlib.formatting.TimeFormatter;
|
||||
|
||||
import java.text.DateFormat;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
* A class to generate a string containing all information about a quest's planner info
|
||||
@ -42,13 +46,13 @@ public class QuestPlannerInfoGenerator {
|
||||
//Quest only becomes available after the start date
|
||||
if (planner.hasStart()) {
|
||||
plannerInfo.append("<li>Quest available from ");
|
||||
plannerInfo.append(TimeFormatter.formatTimestamp(planner.getStartInMillis())).append("</li>");
|
||||
plannerInfo.append(formatTimestamp(planner.getStartInMillis())).append("</li>");
|
||||
}
|
||||
|
||||
//Quest is only available until the end date
|
||||
if (planner.hasEnd()) {
|
||||
plannerInfo.append("<li>Quest available until ");
|
||||
plannerInfo.append(TimeFormatter.formatTimestamp(planner.getEndInMillis())).append("</li>");
|
||||
plannerInfo.append(formatTimestamp(planner.getEndInMillis())).append("</li>");
|
||||
}
|
||||
|
||||
//Quest availability repeats
|
||||
@ -61,4 +65,16 @@ public class QuestPlannerInfoGenerator {
|
||||
return plannerInfo.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a datetime string for the given timestamp
|
||||
*
|
||||
* @param timestamp <p>A timestamp in milliseconds</p>
|
||||
* @return <p>A datetime string</p>
|
||||
*/
|
||||
private String formatTimestamp(long timestamp) {
|
||||
DateFormat format = new SimpleDateFormat("dd MM yyyy HH:mm:ss");
|
||||
Date date = new Date(timestamp);
|
||||
return format.format(date);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -1,32 +0,0 @@
|
||||
package net.knarcraft.dynmapcitizens.util;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
|
||||
/**
|
||||
* A helper class for dealing with files
|
||||
*/
|
||||
public final class FileHelper {
|
||||
|
||||
private FileHelper() {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a buffered reader for
|
||||
*
|
||||
* @return <p>A buffered read for reading the file</p>
|
||||
* @throws FileNotFoundException <p>If unable to get an input stream for the given file</p>
|
||||
*/
|
||||
public static BufferedReader getBufferedReaderForInternalFile(String file) throws FileNotFoundException {
|
||||
InputStream inputStream = FileHelper.class.getResourceAsStream(file);
|
||||
if (inputStream == null) {
|
||||
throw new FileNotFoundException("Unable to read the given file");
|
||||
}
|
||||
return new BufferedReader(new InputStreamReader(inputStream, StandardCharsets.UTF_8));
|
||||
}
|
||||
|
||||
}
|
@ -1,98 +0,0 @@
|
||||
package net.knarcraft.dynmapcitizens.util;
|
||||
|
||||
import java.text.DateFormat;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.Date;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import static net.knarcraft.dynmapcitizens.formatting.StringFormatter.replacePlaceholder;
|
||||
|
||||
/**
|
||||
* A helper class for time formatting
|
||||
*/
|
||||
public class TimeFormatter {
|
||||
|
||||
/**
|
||||
* Gets a datetime string for the given timestamp
|
||||
*
|
||||
* @param timestamp <p>A timestamp in milliseconds</p>
|
||||
* @return <p>A datetime string</p>
|
||||
*/
|
||||
public static String formatTimestamp(long timestamp) {
|
||||
DateFormat format = new SimpleDateFormat("dd MM yyyy HH:mm:ss");
|
||||
Date date = new Date(timestamp);
|
||||
return format.format(date);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the string used for displaying this sign's duration
|
||||
*
|
||||
* @return <p>The string used for displaying this sign's duration</p>
|
||||
*/
|
||||
public static String getDurationString(long duration) {
|
||||
if (duration == 0) {
|
||||
return "immediately";
|
||||
} else {
|
||||
double minute = 60;
|
||||
double hour = minute * 60;
|
||||
double day = hour * 24;
|
||||
double week = day * 7;
|
||||
double month = day * 30;
|
||||
double year = day * 365;
|
||||
double decade = year * 10;
|
||||
|
||||
Map<Double, String[]> timeUnits = new HashMap<>();
|
||||
timeUnits.put(decade, new String[]{"decade", "decades"});
|
||||
timeUnits.put(year, new String[]{"year", "years"});
|
||||
timeUnits.put(month, new String[]{"month", "months"});
|
||||
timeUnits.put(week, new String[]{"week", "weeks"});
|
||||
timeUnits.put(day, new String[]{"day", "days"});
|
||||
timeUnits.put(hour, new String[]{"hour", "hours"});
|
||||
timeUnits.put(minute, new String[]{"minute", "minutes"});
|
||||
timeUnits.put(1D, new String[]{"second", "seconds"});
|
||||
|
||||
List<Double> sortedUnits = new ArrayList<>(timeUnits.keySet());
|
||||
Collections.sort(sortedUnits);
|
||||
Collections.reverse(sortedUnits);
|
||||
|
||||
for (Double unit : sortedUnits) {
|
||||
if (duration / unit >= 1) {
|
||||
double units = round(duration / unit);
|
||||
return formatDurationString(units, timeUnits.get(unit)[units == 1 ? 0 : 1],
|
||||
(units * 10) % 10 == 0);
|
||||
}
|
||||
}
|
||||
return formatDurationString(duration, "seconds", false);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Rounds a number to its last two digits
|
||||
*
|
||||
* @param number <p>The number to round</p>
|
||||
* @return <p>The rounded number</p>
|
||||
*/
|
||||
private static double round(double number) {
|
||||
return Math.round(number * 100.0) / 100.0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Formats a duration string
|
||||
*
|
||||
* @param duration <p>The duration to display</p>
|
||||
* @param translatableMessage <p>The time unit to display</p>
|
||||
* @param castToInt <p>Whether to cast the duration to an int</p>
|
||||
* @return <p>The formatted duration string</p>
|
||||
*/
|
||||
private static String formatDurationString(double duration, String translatableMessage, boolean castToInt) {
|
||||
String durationFormat = "{duration} {unit}";
|
||||
durationFormat = replacePlaceholder(durationFormat, "{unit}", translatableMessage);
|
||||
return replacePlaceholder(durationFormat, "{duration}", castToInt ? String.valueOf((int) duration) :
|
||||
String.valueOf(duration));
|
||||
}
|
||||
|
||||
}
|
@ -49,7 +49,24 @@ en:
|
||||
QUESTS_REQUIREMENTS_REQUIRED_QUEST_ITEM: "<li>{questName}</li>"
|
||||
QUESTS_REQUIREMENTS_REQUIRED_ITEM_FORMAT: "<li>Required items:<ul>{requiredItems}</ul></li>"
|
||||
QUESTS_REQUIREMENTS_REQUIRED_ITEM_ITEM: "<li>{itemName}</li>"
|
||||
QUESTS_REQUIREMENTS_MCMMO_SKILL: "<li>Requires mcMMO skill {skill} at level {level}</li>"
|
||||
QUESTS_REQUIREMENTS_MC_MMO_SKILL: "<li>Requires mcMMO skill {skill} at level {level}</li>"
|
||||
QUESTS_REQUIREMENTS_REQUIRED_PERMISSION_FORMAT: "<li>Required permissions:<ul>{permissions}</ul></li>"
|
||||
QUESTS_REQUIREMENTS_REQUIRED_PERMISSION_ITEM: "<li>{permission}</li>"
|
||||
|
||||
DURATION_FORMAT: "in {time} {unit}"
|
||||
UNIT_NOW: "imminently"
|
||||
UNIT_SECOND: "second"
|
||||
UNIT_SECONDS: "seconds"
|
||||
UNIT_MINUTE: "minute"
|
||||
UNIT_MINUTES: "minutes"
|
||||
UNIT_HOUR: "hour"
|
||||
UNIT_HOURS: "hours"
|
||||
UNIT_DAY: "day"
|
||||
UNIT_DAYS: "days"
|
||||
UNIT_WEEK: "week"
|
||||
UNIT_WEEKS: "weeks"
|
||||
UNIT_MONTH: "month"
|
||||
UNIT_MONTHS: "months"
|
||||
UNIT_YEAR: "year"
|
||||
UNIT_YEARS: "years"
|
||||
UNIT_DECADE: "decade"
|
||||
UNIT_DECADES: "decades"
|
Loading…
Reference in New Issue
Block a user