Merge pull request #54 from BONNe/rework

Challenges Addon Rework
This commit is contained in:
tastybento 2019-01-26 22:18:42 -08:00 committed by GitHub
commit 4ee610e407
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
55 changed files with 11106 additions and 2157 deletions

29
pom.xml
View File

@ -6,7 +6,7 @@
<groupId>world.bentobox</groupId>
<artifactId>challenges</artifactId>
<version>0.3.1-SNAPSHOT</version>
<version>0.5.0-SNAPSHOT</version>
<name>Challenges</name>
<description>Challenges is an add-on for BentoBox, an expandable Minecraft Bukkit plugin for island-type games like ASkyBlock or AcidIsland.</description>
@ -60,6 +60,10 @@
<id>vault-repo</id>
<url>http://nexus.hc.to/content/repositories/pub_releases</url>
</repository>
<repository>
<id>wesjd-repo</id>
<url>https://nexus.wesjd.net/repository/thirdparty/</url>
</repository>
</repositories>
<dependencies>
@ -69,6 +73,12 @@
<version>1.13.2-R0.1-SNAPSHOT</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.spigotmc</groupId>
<artifactId>spigot</artifactId>
<version>1.13.2-R0.1-SNAPSHOT</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-all</artifactId>
@ -90,7 +100,7 @@
<dependency>
<groupId>world.bentobox</groupId>
<artifactId>bentobox</artifactId>
<version>1.1-SNAPSHOT</version>
<version>1.1</version>
<scope>provided</scope>
</dependency>
<dependency>
@ -111,6 +121,11 @@
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>net.wesjd</groupId>
<artifactId>anvilgui</artifactId>
<version>1.2.1-SNAPSHOT</version>
</dependency>
</dependencies>
<build>
@ -195,8 +210,16 @@
<artifactId>maven-shade-plugin</artifactId>
<version>3.1.1</version>
<configuration>
<minimizeJar>false</minimizeJar>
<minimizeJar>true</minimizeJar>
</configuration>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>

View File

@ -1,13 +1,18 @@
package world.bentobox.challenges;
import org.bukkit.Bukkit;
import org.bukkit.Bukkit;
import java.util.Optional;
import world.bentobox.bentobox.api.addons.Addon;
import world.bentobox.bentobox.api.configuration.Config;
import world.bentobox.bentobox.hooks.VaultHook;
import world.bentobox.challenges.commands.ChallengesCommand;
import world.bentobox.challenges.commands.admin.Challenges;
import world.bentobox.challenges.listeners.ResetListener;
import world.bentobox.challenges.listeners.SaveListener;
import world.bentobox.bentobox.api.addons.Addon;
import world.bentobox.bentobox.api.commands.CompositeCommand;
import world.bentobox.level.Level;
/**
* Add-on to BSkyBlock that enables challenges
@ -16,90 +21,269 @@ import world.bentobox.bentobox.api.commands.CompositeCommand;
*/
public class ChallengesAddon extends Addon {
// ---------------------------------------------------------------------
// Section: Variables
// ---------------------------------------------------------------------
private ChallengesManager challengesManager;
private String permissionPrefix = "addon";
private FreshSqueezedChallenges importManager;
private ChallengesImportManager importManager;
private Settings settings;
private boolean hooked;
/**
* This boolean indicate if economy is enabled.
*/
private boolean economyProvided;
/**
* VaultHook that process economy.
* todo: because of BentoBox limitations.
*/
private Optional<VaultHook> vaultHook = null;
/**
* Level addon.
*/
private Level levelAddon;
/**
* This indicate if level addon exists.
*/
private boolean levelProvided;
// ---------------------------------------------------------------------
// Section: Constants
// ---------------------------------------------------------------------
/**
* Permission prefix for addon.
*/
private static final String PERMISSION_PREFIX = "addon";
// ---------------------------------------------------------------------
// Section: Methods
// ---------------------------------------------------------------------
/**
* {@inheritDoc}
*/
@Override
public void onLoad() {
// Save default config.yml
saveDefaultConfig();
this.saveDefaultConfig();
// Load the plugin's config
this.loadSettings();
}
/**
* {@inheritDoc}
*/
@Override
public void onEnable() {
// Check if it is enabled - it might be loaded, but not enabled.
if (getPlugin() == null || !getPlugin().isEnabled()) {
if (this.getPlugin() == null || !this.getPlugin().isEnabled()) {
Bukkit.getLogger().severe("BentoBox is not available or disabled!");
this.setState(State.DISABLED);
return;
}
// Challenges Manager
challengesManager = new ChallengesManager(this);
this.challengesManager = new ChallengesManager(this);
// Challenge import setup
importManager = new FreshSqueezedChallenges(this);
this.importManager = new ChallengesImportManager(this);
// Register commands - run one tick later to allow all addons to load
// AcidIsland hook in
getPlugin().getAddonsManager().getAddonByName("AcidIsland").ifPresent(a -> {
CompositeCommand acidIslandCmd = getPlugin().getCommandsManager().getCommand("ai");
if (acidIslandCmd != null) {
new ChallengesCommand(this, acidIslandCmd);
CompositeCommand acidCmd = getPlugin().getCommandsManager().getCommand("acid");
new Challenges(this, acidCmd);
hooked = true;
this.getPlugin().getAddonsManager().getGameModeAddons().forEach(gameModeAddon -> {
if (!this.settings.getDisabledGameModes().contains(gameModeAddon.getDescription().getName()))
{
if (gameModeAddon.getPlayerCommand().isPresent())
{
new ChallengesCommand(this, gameModeAddon.getPlayerCommand().get());
this.hooked = true;
}
if (gameModeAddon.getAdminCommand().isPresent())
{
new Challenges(this, gameModeAddon.getAdminCommand().get());
this.hooked = true;
}
}
});
getPlugin().getAddonsManager().getAddonByName("BSkyBlock").ifPresent(a -> {
// BSkyBlock hook in
CompositeCommand bsbIslandCmd = getPlugin().getCommandsManager().getCommand("island");
if (bsbIslandCmd != null) {
new ChallengesCommand(this, bsbIslandCmd);
CompositeCommand bsbAdminCmd = getPlugin().getCommandsManager().getCommand("bsbadmin");
new Challenges(this, bsbAdminCmd);
hooked = true;
}
});
// If the add-on never hooks in, then it is useless
if (!hooked) {
logError("Challenges could not hook into AcidIsland or BSkyBlock so will not do anything!");
this.setState(State.DISABLED);
return;
}
if (this.hooked) {
// Try to find Level addon and if it does not exist, display a warning
if (!getAddonByName("Level").isPresent()) {
logWarning("Level add-on not found so level challenges will not work!");
Optional<Addon> level = this.getAddonByName("Level");
if (!level.isPresent())
{
this.logWarning("Level add-on not found so level challenges will not work!");
this.levelAddon = null;
}
else
{
this.levelProvided = true;
this.levelAddon = (Level) level.get();
}
// BentoBox limitation. Cannot check hooks, as HookManager is created after loading addons.
// Optional<VaultHook> vault = this.getPlugin().getVault();
//
// if (!vault.isPresent() || !vault.get().hook())
// {
// this.vaultHook = null;
// this.logWarning("Economy plugin not found so money options will not work!");
// }
// else
// {
// this.economyProvided = true;
// this.vaultHook = vault.get();
// }
// Register the reset listener
this.registerListener(new ResetListener(this));
// Register the autosave listener.
this.registerListener(new SaveListener(this));
// Done
} else {
this.logError("Challenges could not hook into AcidIsland or BSkyBlock so will not do anything!");
this.setState(State.DISABLED);
}
}
/**
* {@inheritDoc}
*/
@Override
public void onReload()
{
if (this.hooked) {
this.challengesManager.save();
this.loadSettings();
this.getLogger().info("Challenges addon reloaded.");
}
}
/**
* {@inheritDoc}
*/
@Override
public void onDisable() {
if (challengesManager != null) {
challengesManager.save();
if (this.hooked) {
this.challengesManager.save();
}
if (this.settings != null)
{
new Config<>(this, Settings.class).saveConfigObject(this.settings);
}
}
/**
* This method loads addon configuration settings in memory.
*/
private void loadSettings() {
this.settings = new Config<>(this, Settings.class).loadConfigObject();
if (this.settings == null) {
// Disable
this.logError("Challenges settings could not load! Addon disabled.");
this.setState(State.DISABLED);
}
}
// ---------------------------------------------------------------------
// Section: Getters
// ---------------------------------------------------------------------
/**
* @return challengesManager
*/
public ChallengesManager getChallengesManager() {
return challengesManager;
return this.challengesManager;
}
/**
* @return Permission Prefix.
*/
@Override
public String getPermissionPrefix() {
return permissionPrefix ;
return PERMISSION_PREFIX;
}
/**
* @return the importManager
*/
public FreshSqueezedChallenges getImportManager() {
return importManager;
public ChallengesImportManager getImportManager() {
return this.importManager;
}
/**
* @return the challenge settings.
*/
public Settings getChallengesSettings()
{
return this.settings;
}
/**
*
* @return economyProvided variable.
*/
public boolean isEconomyProvided()
{
if (!this.economyProvided && this.getPlugin().getVault().isPresent() && this.vaultHook == null)
{
this.vaultHook = this.getPlugin().getVault();
this.economyProvided = this.vaultHook.get().hook();
}
return this.economyProvided;
}
/**
* Returns VaultHook. Used to get easier access to Economy. NEVER USE WITHOUT isEconomyProvided or null
* check.
* @return VaultHook or null.
*/
public VaultHook getEconomyProvider()
{
return vaultHook.orElseGet(null);
}
/**
*
* @return levelProvided variable.
*/
public boolean isLevelProvided()
{
return levelProvided;
}
/**
* This method returns Level addon. Used to easier access to Level. NEVER USE WITHOUT isLevelProvided or null
* @return LevelAddon or null.
*/
public Level getLevelAddon()
{
return levelAddon;
}
}

View File

@ -16,17 +16,21 @@ import org.bukkit.configuration.file.YamlConfiguration;
import org.bukkit.entity.EntityType;
import org.bukkit.inventory.ItemStack;
import world.bentobox.challenges.database.object.ChallengeLevels;
import world.bentobox.challenges.database.object.Challenges;
import world.bentobox.bentobox.util.ItemParser;
import world.bentobox.challenges.database.object.ChallengeLevel;
import world.bentobox.challenges.database.object.Challenge;
import world.bentobox.bentobox.api.user.User;
import world.bentobox.bentobox.util.Util;
import world.bentobox.challenges.utils.GuiUtils;
/**
* Imports challenges
* @author tastybento
*
*/
public class FreshSqueezedChallenges {
public class ChallengesImportManager
{
private ChallengesAddon addon;
private YamlConfiguration chal;
@ -35,7 +39,7 @@ public class FreshSqueezedChallenges {
* Import challenges from challenges.yml
* @param challengesAddon
*/
public FreshSqueezedChallenges(ChallengesAddon challengesAddon) {
public ChallengesImportManager(ChallengesAddon challengesAddon) {
this.addon = challengesAddon;
File challengeFile = new File(addon.getDataFolder(), "challenges.yml");
if (!challengeFile.exists()) {
@ -63,13 +67,13 @@ public class FreshSqueezedChallenges {
user.sendMessage("challenges.admin.import.no-load","[message]", e.getMessage());
return false;
}
makeLevels(user);
makeLevels(user, world, overwrite);
makeChallenges(user, world, overwrite);
addon.getChallengesManager().save();
return true;
}
private void makeLevels(User user) {
private void makeLevels(User user, World world, boolean overwrite) {
// Parse the levels
String levels = chal.getString("challenges.levels", "");
if (!levels.isEmpty()) {
@ -77,22 +81,23 @@ public class FreshSqueezedChallenges {
String[] lvs = levels.split(" ");
int order = 0;
for (String level : lvs) {
ChallengeLevels challengeLevel = new ChallengeLevels();
ChallengeLevel challengeLevel = new ChallengeLevel();
challengeLevel.setFriendlyName(level);
challengeLevel.setUniqueId(level);
challengeLevel.setUniqueId(Util.getWorld(world).getName() + "_" + level);
challengeLevel.setOrder(order++);
challengeLevel.setWaiveramount(chal.getInt("challenges.waiveramount"));
challengeLevel.setWorld(Util.getWorld(world).getName());
challengeLevel.setWaiverAmount(chal.getInt("challenges.waiveramount"));
// Check if there is a level reward
ConfigurationSection unlock = chal.getConfigurationSection("challenges.levelUnlock." + level);
if (unlock != null) {
challengeLevel.setUnlockMessage(unlock.getString("message"));
challengeLevel.setRewardDescription(unlock.getString("rewardDesc",""));
challengeLevel.setRewardText(unlock.getString("rewardDesc",""));
challengeLevel.setRewardItems(parseItems(unlock.getString("itemReward","")));
challengeLevel.setMoneyReward(unlock.getInt("moneyReward"));
challengeLevel.setExpReward(unlock.getInt("expReward"));
challengeLevel.setRewardMoney(unlock.getInt("moneyReward"));
challengeLevel.setRewardExperience(unlock.getInt("expReward"));
challengeLevel.setRewardCommands(unlock.getStringList("commands"));
}
addon.getChallengesManager().storeLevel(challengeLevel);
addon.getChallengesManager().loadLevel(challengeLevel, overwrite, user, false);
}
} else {
user.sendMessage("challenges.admin.import.no-levels");
@ -102,53 +107,63 @@ public class FreshSqueezedChallenges {
/**
* Imports challenges
* @param overwrite
* @param args
*/
private void makeChallenges(User user, World world, boolean overwrite) {
int size = 0;
// Parse the challenge file
ConfigurationSection chals = chal.getConfigurationSection("challenges.challengeList");
for (String challenge : chals.getKeys(false)) {
Challenges newChallenge = new Challenges();
Challenge newChallenge = new Challenge();
newChallenge.setUniqueId(Util.getWorld(world).getName() + "_" + challenge);
newChallenge.setDeployed(true);
ConfigurationSection details = chals.getConfigurationSection(challenge);
newChallenge.setFriendlyName(details.getString("friendlyname", challenge));
newChallenge.setWorld(Util.getWorld(world).getName());
newChallenge.setDescription(addon.getChallengesManager().stringSplit(details.getString("description", "")));
newChallenge.setIcon(new ParseItem(addon, details.getString("icon") + ":1").getItem());
newChallenge.setLevel(details.getString("level", ChallengesManager.FREE));
newChallenge.setChallengeType(Challenges.ChallengeType.valueOf(details.getString("type","INVENTORY").toUpperCase()));
newChallenge.setDescription(GuiUtils.stringSplit(details.getString("description", "")));
newChallenge.setIcon(ItemParser.parse(details.getString("icon") + ":1"));
if (details.getString("type").equalsIgnoreCase("level"))
{
// Fix for older version config
newChallenge.setChallengeType(Challenge.ChallengeType.OTHER);
}
else
{
newChallenge.setChallengeType(Challenge.ChallengeType.valueOf(details.getString("type","INVENTORY").toUpperCase()));
}
newChallenge.setTakeItems(details.getBoolean("takeItems",true));
newChallenge.setRewardText(details.getString("rewardText", ""));
newChallenge.setRewardCommands(details.getStringList("rewardcommands"));
newChallenge.setRewardMoney(details.getInt("moneyReward",0));
newChallenge.setRewardExp(details.getInt("expReward"));
newChallenge.setRewardExperience(details.getInt("expReward"));
newChallenge.setRepeatable(details.getBoolean("repeatable"));
newChallenge.setRepeatRewardText(details.getString("repeatRewardText",""));
newChallenge.setRepeatMoneyReward(details.getInt("repearMoneyReward"));
newChallenge.setRepeatExpReward(details.getInt("repeatExpReward"));
newChallenge.setRepeatExperienceReward(details.getInt("repeatExpReward"));
newChallenge.setRepeatRewardCommands(details.getStringList("repeatrewardcommands"));
newChallenge.setMaxTimes(details.getInt("maxtimes"));
// TODO reset allowed
newChallenge.setReqMoney(details.getInt("requiredMoney"));
newChallenge.setReqExp(details.getInt("requiredExp"));
newChallenge.setRequiredMoney(details.getInt("requiredMoney"));
newChallenge.setRequiredExperience(details.getInt("requiredExp"));
String reqItems = details.getString("requiredItems","");
if (newChallenge.getChallengeType().equals(Challenges.ChallengeType.INVENTORY)) {
if (newChallenge.getChallengeType().equals(Challenge.ChallengeType.INVENTORY)) {
newChallenge.setRequiredItems(parseItems(reqItems));
} else if (newChallenge.getChallengeType().equals(Challenges.ChallengeType.LEVEL)) {
newChallenge.setReqIslandlevel(Long.parseLong(reqItems));
} else if (newChallenge.getChallengeType().equals(Challenges.ChallengeType.ISLAND)) {
} else if (newChallenge.getChallengeType().equals(Challenge.ChallengeType.OTHER)) {
newChallenge.setRequiredIslandLevel(Long.parseLong(reqItems));
} else if (newChallenge.getChallengeType().equals(Challenge.ChallengeType.ISLAND)) {
parseEntities(newChallenge, reqItems);
}
newChallenge.setRewardItems(parseItems(details.getString("itemReward")));
newChallenge.setRepeatItemReward(parseItems(details.getString("repeatItemReward")));
// Save
if (addon.getChallengesManager().storeChallenge(newChallenge, overwrite, user, false)) {
this.addon.getChallengesManager().addChallengeToLevel(newChallenge,
addon.getChallengesManager().getLevel(Util.getWorld(world).getName() + "_" + details.getString("level")));
if (addon.getChallengesManager().loadChallenge(newChallenge, overwrite, user, false)) {
size++;
}
}
addon.getChallengesManager().sortChallenges();
user.sendMessage("challenges.admin.import.number", "[number]", String.valueOf(size));
}
@ -157,7 +172,7 @@ public class FreshSqueezedChallenges {
* @param challenge - challenge to be adjusted
* @param string - string from YAML file
*/
private void parseEntities(Challenges challenge, String string) {
private void parseEntities(Challenge challenge, String string) {
Map<EntityType, Integer> req = new EnumMap<>(EntityType.class);
Map<Material, Integer> blocks = new EnumMap<>(Material.class);
if (!string.isEmpty()) {
@ -179,7 +194,7 @@ public class FreshSqueezedChallenges {
List<ItemStack> result = new ArrayList<>();
if (!reqList.isEmpty()) {
for (String s : reqList.split(" ")) {
ItemStack item = new ParseItem(addon,s).getItem();
ItemStack item = ItemParser.parse(s);
if (item != null) {
result.add(item);
}
@ -187,7 +202,4 @@ public class FreshSqueezedChallenges {
}
return result;
}
}

File diff suppressed because it is too large Load Diff

View File

@ -11,7 +11,10 @@ import org.bukkit.potion.PotionType;
* Used for converting config file entries to objects
* @author tastybento
*
* @deprecated
* @see world.bentobox.bentobox.util.ItemParser#parse(String)
*/
@Deprecated
public class ParseItem {
private final ItemStack item;

View File

@ -0,0 +1,184 @@
package world.bentobox.challenges;
import java.util.HashSet;
import java.util.Set;
import world.bentobox.bentobox.api.configuration.ConfigComment;
import world.bentobox.bentobox.api.configuration.ConfigEntry;
import world.bentobox.bentobox.api.configuration.StoreAt;
import world.bentobox.bentobox.database.objects.DataObject;
@StoreAt(filename="config.yml", path="addons/Challenges")
@ConfigComment("Challenges Configuration [version]")
@ConfigComment("This config file is dynamic and saved when the server is shutdown.")
@ConfigComment("You cannot edit it while the server is running because changes will")
@ConfigComment("be lost! Use in-game settings GUI or edit when server is offline.")
@ConfigComment("")
public class Settings implements DataObject
{
@ConfigComment("")
@ConfigComment("Reset Challenges - if this is true, player's challenges will reset when they")
@ConfigComment("reset an island or if they are kicked or leave a team. Prevents exploiting the")
@ConfigComment("challenges by doing them repeatedly.")
private boolean resetChallenges = true;
@ConfigComment("")
@ConfigComment("Broadcast 1st time challenge completion messages to all players.")
@ConfigComment("Change to false if the spam becomes too much.")
private boolean broadcastMessages = true;
@ConfigComment("")
@ConfigComment("Remove non-repeatable challenges from the challenge GUI when complete.")
private boolean removeCompleteOneTimeChallenges = false;
@ConfigComment("")
@ConfigComment("Add enchanted glow to completed challenges")
private boolean addCompletedGlow = true;
@ConfigComment("")
@ConfigComment("This indicate if free challenges must be at the start (true) or at the end (false) of list.")
private boolean freeChallengesFirst = true;
@ConfigComment("")
@ConfigComment("This list stores GameModes in which Challenges addon should not work.")
@ConfigComment("To disable addon it is necessary to write its name in new line that starts with -. Example:")
@ConfigComment("disabled-gamemodes:")
@ConfigComment(" - BSkyBlock")
@ConfigEntry(path = "disabled-gamemodes")
private Set<String> disabledGameModes = new HashSet<>();
/**
* Default variable.
*/
@ConfigComment("")
private String uniqueId = "config";
// ---------------------------------------------------------------------
// Section: Methods
// ---------------------------------------------------------------------
@Override
public String getUniqueId()
{
return this.uniqueId;
}
/**
* @return resetChallenges value.
*/
public boolean isResetChallenges()
{
return this.resetChallenges;
}
/**
* @return broadcastMessages value.
*/
public boolean isBroadcastMessages()
{
return this.broadcastMessages;
}
/**
* @return removeCompleteOneTimeChallenges value.
*/
public boolean isRemoveCompleteOneTimeChallenges()
{
return this.removeCompleteOneTimeChallenges;
}
/**
* @return addCompletedGlow value.
*/
public boolean isAddCompletedGlow()
{
return this.addCompletedGlow;
}
/**
* @return disabledGameModes value.
*/
public Set<String> getDisabledGameModes()
{
return this.disabledGameModes;
}
/**
* @return freeChallengesFirst value.
*/
public boolean isFreeChallengesFirst()
{
return this.freeChallengesFirst;
}
@Override
public void setUniqueId(String uniqueId)
{
this.uniqueId = uniqueId;
}
/**
* @param resetChallenges new resetChallenges value.
*/
public void setResetChallenges(boolean resetChallenges)
{
this.resetChallenges = resetChallenges;
}
/**
* @param broadcastMessages new broadcastMessages value.
*/
public void setBroadcastMessages(boolean broadcastMessages)
{
this.broadcastMessages = broadcastMessages;
}
/**
* @param removeCompleteOneTimeChallenges new removeCompleteOneTimeChallenges value.
*/
public void setRemoveCompleteOneTimeChallenges(boolean removeCompleteOneTimeChallenges)
{
this.removeCompleteOneTimeChallenges = removeCompleteOneTimeChallenges;
}
/**
* @param addCompletedGlow new addCompletedGlow value.
*/
public void setAddCompletedGlow(boolean addCompletedGlow)
{
this.addCompletedGlow = addCompletedGlow;
}
/**
* @param disabledGameModes new disabledGameModes value.
*/
public void setDisabledGameModes(Set<String> disabledGameModes)
{
this.disabledGameModes = disabledGameModes;
}
/**
* @param freeChallengesFirst new freeChallengesFirst value.
*/
public void setFreeChallengesFirst(boolean freeChallengesFirst)
{
this.freeChallengesFirst = freeChallengesFirst;
}
}

View File

@ -3,10 +3,10 @@ package world.bentobox.challenges.commands;
import java.util.List;
import world.bentobox.challenges.ChallengesAddon;
import world.bentobox.challenges.panel.ChallengesPanels2;
import world.bentobox.challenges.panel.ChallengesPanels2.Mode;
import world.bentobox.bentobox.api.commands.CompositeCommand;
import world.bentobox.bentobox.api.user.User;
import world.bentobox.challenges.panel.user.ChallengesGUI;
public class ChallengesCommand extends CompositeCommand {
public static final String CHALLENGE_COMMAND = "challenges";
@ -19,7 +19,11 @@ public class ChallengesCommand extends CompositeCommand {
public boolean execute(User user, String label, List<String> args) {
// Open up the challenges GUI
if (user.isPlayer()) {
new ChallengesPanels2((ChallengesAddon) getAddon(), user, user, args.isEmpty() ? "" : args.get(0), getWorld(), getPermissionPrefix(), getTopLabel(), Mode.PLAYER);
new ChallengesGUI((ChallengesAddon) this.getAddon(),
this.getWorld(),
user,
this.getTopLabel(),
this.getPermissionPrefix()).build();
return true;
}
// Show help

View File

@ -3,10 +3,10 @@ package world.bentobox.challenges.commands.admin;
import java.util.List;
import world.bentobox.challenges.ChallengesAddon;
import world.bentobox.challenges.panel.ChallengesPanels2;
import world.bentobox.challenges.panel.ChallengesPanels2.Mode;
import world.bentobox.bentobox.api.commands.CompositeCommand;
import world.bentobox.bentobox.api.user.User;
import world.bentobox.challenges.panel.admin.AdminGUI;
public class Challenges extends CompositeCommand {
@ -25,7 +25,7 @@ public class Challenges extends CompositeCommand {
this.setDescription("challenges.admin.description");
// Register sub commands
new ImportCommand(getAddon(), this);
new CompleteChallenge(getAddon(), this);
// new CompleteChallenge(getAddon(), this);
new ReloadChallenges(getAddon(), this);
new ResetChallenge(getAddon(), this);
//new ShowChallenges(getAddon(), this);
@ -37,7 +37,12 @@ public class Challenges extends CompositeCommand {
public boolean execute(User user, String label, List<String> args) {
// Open up the admin challenges GUI
if (user.isPlayer()) {
new ChallengesPanels2((ChallengesAddon) getAddon(), user, user, args.isEmpty() ? "" : args.get(0), getWorld(), getPermissionPrefix(), getTopLabel(), Mode.ADMIN);
new AdminGUI((ChallengesAddon) this.getAddon(),
this.getWorld(),
user,
this.getTopLabel(),
this.getPermissionPrefix()).build();
return true;
}
return false;

View File

@ -51,13 +51,13 @@ public class CompleteChallenge extends CompositeCommand {
return false;
}
// Check for valid challenge name
if (!manager.isChallenge(getWorld(), args.get(1))) {
if (!manager.containsChallenge(args.get(1))) {
user.sendMessage("challenges.admin.complete.unknown-challenge");
return false;
}
// Complete challenge
User target = User.getInstance(targetUUID);
manager.setChallengeComplete(target, args.get(1), getWorld());
manager.setChallengeComplete(target, this.manager.getChallenge(args.get(1)));
user.sendMessage("general.success");
return true;
}
@ -70,7 +70,7 @@ public class CompleteChallenge extends CompositeCommand {
return Optional.of(Util.tabLimit(new ArrayList<>(Util.getOnlinePlayerList(user)), lastArg));
} else if (args.size() == 4) {
// Challenges in this world
return Optional.of(Util.tabLimit(manager.getAllChallengesList(getWorld()), lastArg));
return Optional.of(Util.tabLimit(manager.getAllChallengesNames(getWorld()), lastArg));
}
return Optional.empty();
}

View File

@ -9,6 +9,11 @@ import world.bentobox.bentobox.api.commands.CompositeCommand;
import world.bentobox.bentobox.api.panels.builders.PanelBuilder;
import world.bentobox.bentobox.api.user.User;
/**
* @deprecated Challenges can be creaded via GUI.
*/
@Deprecated
public class CreateChallenge extends CompositeCommand {
/**

View File

@ -25,8 +25,9 @@ import world.bentobox.bentobox.util.Util;
/**
* Command to create a surrounding type challenge
* @author tastybento
*
* @deprecated Required blocks can be added via GUI. Not necessary.
*/
@Deprecated
public class CreateSurrounding extends CompositeCommand implements Listener {
HashMap<UUID,SurroundChallengeBuilder> inProgress = new HashMap<>();

View File

@ -13,6 +13,11 @@ import world.bentobox.bentobox.api.localization.TextVariables;
import world.bentobox.bentobox.api.user.User;
import world.bentobox.bentobox.util.Util;
/**
* @deprecated Challenges can be reset via GUI.
*/
@Deprecated
public class ResetChallenge extends CompositeCommand {
private ChallengesManager manager;
@ -51,13 +56,13 @@ public class ResetChallenge extends CompositeCommand {
return false;
}
// Check for valid challenge name
if (!manager.isChallenge(getWorld(), args.get(1))) {
if (!manager.containsChallenge(args.get(1))) {
user.sendMessage("challenges.admin.complete.unknown-challenge");
return false;
}
// Complete challenge
User target = User.getInstance(targetUUID);
manager.setResetChallenge(target, args.get(1), getWorld());
manager.resetChallenge(target, manager.getChallenge(args.get(1)));
user.sendMessage("general.success");
return true;
}
@ -70,7 +75,7 @@ public class ResetChallenge extends CompositeCommand {
return Optional.of(Util.tabLimit(new ArrayList<>(Util.getOnlinePlayerList(user)), lastArg));
} else if (args.size() == 4) {
// Challenges in this world
return Optional.of(Util.tabLimit(manager.getAllChallengesList(getWorld()), lastArg));
return Optional.of(Util.tabLimit(manager.getAllChallengesNames(getWorld()), lastArg));
}
return Optional.empty();
}

View File

@ -28,7 +28,7 @@ public class ShowChallenges extends CompositeCommand {
@Override
public boolean execute(User user, String label, List<String> args) {
((ChallengesAddon)getAddon()).getChallengesManager().getAllChallengesList().forEach(user::sendRawMessage);
((ChallengesAddon)getAddon()).getChallengesManager().getAllChallengesNames(this.getWorld()).forEach(user::sendRawMessage);
return true;
}

View File

@ -12,8 +12,9 @@ import world.bentobox.bentobox.api.user.User;
/**
* Enables the state of a Surrounding Challenge to be stored as it is built
* @author tastybento
*
* @deprecated Levels and challenges can be created via GUI. Not necessary command.
*/
@Deprecated
public class SurroundChallengeBuilder {
private ChallengesAddon addon;
private String name;
@ -76,7 +77,7 @@ public class SurroundChallengeBuilder {
}
public boolean build() {
return addon.getChallengesManager().createSurroundingChallenge(this);
return false; //addon.getChallengesManager().createSurroundingChallenge(this);
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,472 @@
package world.bentobox.challenges.database.object;
import com.google.gson.annotations.Expose;
import org.bukkit.Material;
import org.bukkit.inventory.ItemStack;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import world.bentobox.bentobox.api.configuration.ConfigComment;
import world.bentobox.bentobox.database.objects.DataObject;
import world.bentobox.challenges.ChallengesManager;
/**
* Represent a challenge level
* @author tastybento
*
*/
public class ChallengeLevel implements DataObject, Comparable<ChallengeLevel>
{
/**
* Constructor ChallengeLevel creates a new ChallengeLevel instance.
*/
public ChallengeLevel()
{
}
// ---------------------------------------------------------------------
// Section: Variables
// ---------------------------------------------------------------------
@ConfigComment("")
@ConfigComment("Level name")
@Expose
private String uniqueId = ChallengesManager.FREE;
@ConfigComment("")
@ConfigComment("A friendly name for the level. If blank, level name is used.")
@Expose
private String friendlyName = "";
@ConfigComment("")
@ConfigComment("ItemStack that represents current level. Will be used as icon in GUIs.")
@Expose
private ItemStack icon = new ItemStack(Material.BOOK);
@ConfigComment("")
@ConfigComment("World that this level applies in. String.")
@Expose
private String world = "";
@ConfigComment("")
@ConfigComment("The ordering of the level, lowest to highest")
@Expose
private int order;
@ConfigComment("")
@ConfigComment("The number of undone challenges that can be left on this level before")
@ConfigComment("unlocking next level.")
@Expose
private int waiverAmount = 1;
@ConfigComment("")
@ConfigComment("The message shown when unlocking this level. Single line string.")
@Expose
private String unlockMessage = "";
@ConfigComment("")
@ConfigComment("")
@ConfigComment("If this is blank, the reward text will be auto-generated, otherwise")
@ConfigComment("this will be used.")
@Expose
private String rewardText = "";
@ConfigComment("")
@ConfigComment("List of items the player will receive on completing level.")
@ConfigComment("ItemStack List.")
@Expose
private List<ItemStack> rewardItems = new ArrayList<>();
@ConfigComment("")
@ConfigComment("Experience point reward on completing level.")
@Expose
private int rewardExperience = 0;
@ConfigComment("")
@ConfigComment("Money reward. Economy plugin or addon required for this option.")
@Expose
private int rewardMoney = 0;
@ConfigComment("")
@ConfigComment("Commands to run when the player completes all challenges in current")
@ConfigComment("level. String List")
@Expose
private List<String> rewardCommands = new ArrayList<>();
@ConfigComment("")
@ConfigComment("Set of all challenges that is linked with current level.")
@ConfigComment("String Set")
@Expose
private Set<String> challenges = new HashSet<>();
// ---------------------------------------------------------------------
// Section: Getters
// ---------------------------------------------------------------------
/**
* This method returns the uniqueId value.
* @return the value of uniqueId.
* @see DataObject#getUniqueId()
*/
@Override
public String getUniqueId()
{
return uniqueId;
}
/**
* This method returns the friendlyName value.
* @return the value of friendlyName.
*/
public String getFriendlyName()
{
return friendlyName;
}
/**
* This method returns the icon value.
* @return the value of icon.
*/
public ItemStack getIcon()
{
return icon.clone();
}
/**
* This method returns the world value.
* @return the value of world.
*/
public String getWorld()
{
return world;
}
/**
* This method returns the order value.
* @return the value of order.
*/
public int getOrder()
{
return order;
}
/**
* This method returns the waiverAmount value.
* @return the value of waiverAmount.
*/
public int getWaiverAmount()
{
return waiverAmount;
}
/**
* This method returns the unlockMessage value.
* @return the value of unlockMessage.
*/
public String getUnlockMessage()
{
return unlockMessage;
}
/**
* This method returns the rewardText value.
* @return the value of rewardText.
*/
public String getRewardText()
{
return rewardText;
}
/**
* This method returns the rewardItems value.
* @return the value of rewardItems.
*/
public List<ItemStack> getRewardItems()
{
return rewardItems;
}
/**
* This method returns the rewardExperience value.
* @return the value of rewardExperience.
*/
public int getRewardExperience()
{
return rewardExperience;
}
/**
* This method returns the rewardMoney value.
* @return the value of rewardMoney.
*/
public int getRewardMoney()
{
return rewardMoney;
}
/**
* This method returns the rewardCommands value.
* @return the value of rewardCommands.
*/
public List<String> getRewardCommands()
{
return rewardCommands;
}
/**
* This method returns the challenges value.
* @return the value of challenges.
*/
public Set<String> getChallenges()
{
return challenges;
}
// ---------------------------------------------------------------------
// Section: Setters
// ---------------------------------------------------------------------
/**
* This method sets the uniqueId value.
* @param uniqueId the uniqueId new value.
*
* @see DataObject#setUniqueId(String)
*/
@Override
public void setUniqueId(String uniqueId)
{
this.uniqueId = uniqueId;
}
/**
* This method sets the friendlyName value.
* @param friendlyName the friendlyName new value.
*
*/
public void setFriendlyName(String friendlyName)
{
this.friendlyName = friendlyName;
}
/**
* This method sets the icon value.
* @param icon the icon new value.
*
*/
public void setIcon(ItemStack icon)
{
this.icon = icon;
}
/**
* This method sets the world value.
* @param world the world new value.
*
*/
public void setWorld(String world)
{
this.world = world;
}
/**
* This method sets the order value.
* @param order the order new value.
*
*/
public void setOrder(int order)
{
this.order = order;
}
/**
* This method sets the waiverAmount value.
* @param waiverAmount the waiverAmount new value.
*
*/
public void setWaiverAmount(int waiverAmount)
{
this.waiverAmount = waiverAmount;
}
/**
* This method sets the unlockMessage value.
* @param unlockMessage the unlockMessage new value.
*
*/
public void setUnlockMessage(String unlockMessage)
{
this.unlockMessage = unlockMessage;
}
/**
* This method sets the rewardText value.
* @param rewardText the rewardText new value.
*
*/
public void setRewardText(String rewardText)
{
this.rewardText = rewardText;
}
/**
* This method sets the rewardItems value.
* @param rewardItems the rewardItems new value.
*
*/
public void setRewardItems(List<ItemStack> rewardItems)
{
this.rewardItems = rewardItems;
}
/**
* This method sets the rewardExperience value.
* @param rewardExperience the rewardExperience new value.
*
*/
public void setRewardExperience(int rewardExperience)
{
this.rewardExperience = rewardExperience;
}
/**
* This method sets the rewardMoney value.
* @param rewardMoney the rewardMoney new value.
*
*/
public void setRewardMoney(int rewardMoney)
{
this.rewardMoney = rewardMoney;
}
/**
* This method sets the rewardCommands value.
* @param rewardCommands the rewardCommands new value.
*
*/
public void setRewardCommands(List<String> rewardCommands)
{
this.rewardCommands = rewardCommands;
}
/**
* This method sets the challenges value.
* @param challenges the challenges new value.
*
*/
public void setChallenges(Set<String> challenges)
{
this.challenges = challenges;
}
// ---------------------------------------------------------------------
// Section: Other methods
// ---------------------------------------------------------------------
/**
* {@inheritDoc}
*/
@Override
public int compareTo(ChallengeLevel o)
{
if (this.equals(o))
{
return 0;
}
else
{
if (this.getWorld().equals(o.getWorld()))
{
if (this.order == o.getOrder())
{
return this.getUniqueId().compareTo(o.getUniqueId());
}
else
{
return Integer.compare(this.order, o.getOrder());
}
}
else
{
return this.getWorld().compareTo(o.getWorld());
}
}
}
/**
* {@inheritDoc}
*/
@Override
public int hashCode()
{
final int prime = 31;
int result = 1;
result = prime * result + ((uniqueId == null) ? 0 : uniqueId.hashCode());
return result;
}
/**
* {@inheritDoc}
*/
@Override
public boolean equals(Object obj)
{
if (this == obj)
{
return true;
}
if (!(obj instanceof ChallengeLevel))
{
return false;
}
ChallengeLevel other = (ChallengeLevel) obj;
if (uniqueId == null)
{
return other.uniqueId == null;
}
else
{
return uniqueId.equals(other.uniqueId);
}
}
}

View File

@ -1,225 +0,0 @@
package world.bentobox.challenges.database.object;
import java.util.ArrayList;
import java.util.List;
import org.bukkit.inventory.ItemStack;
import world.bentobox.challenges.ChallengesManager;
import world.bentobox.bentobox.api.configuration.ConfigComment;
import world.bentobox.bentobox.database.objects.DataObject;
/**
* Represent a challenge level
* @author tastybento
*
*/
public class ChallengeLevels implements DataObject, Comparable<ChallengeLevels> {
public ChallengeLevels() {}
@ConfigComment("A friendly name for the level. If blank, level name is used.")
private String friendlyName = "";
@ConfigComment("Worlds that this level applies in. String list.")
private List<String> worlds = new ArrayList<>();
@ConfigComment("Commands to run when this level is completed")
private List<String> rewardCommands = new ArrayList<>();
@ConfigComment("Level name")
private String uniqueId = ChallengesManager.FREE;
@ConfigComment("The number of undone challenges that can be left on this level before unlocking next level")
private int waiveramount = 1;
@ConfigComment("The ordering of the levels, lowest to highest")
private int order = 0;
@ConfigComment("The message shown when unlocking this level")
private String unlockMessage = "";
@ConfigComment("Unlock reward description")
private String rewardDescription = "";
@ConfigComment("List of reward itemstacks")
private List<ItemStack> rewardItems;
@ConfigComment("Unlock experience reward")
private int expReward;
@ConfigComment("Unlock money reward")
private int moneyReward;
public String getFriendlyName() {
return friendlyName;
}
public List<String> getRewardCommands() {
return rewardCommands = new ArrayList<>();
}
@Override
public String getUniqueId() {
return uniqueId;
}
/**
* Get the number of undone tasks that can be left on a level before unlocking next level
* @return
*/
public int getWaiveramount() {
return waiveramount;
}
public void setFriendlyName(String friendlyName) {
this.friendlyName = friendlyName;
}
public void setRewardCommands(List<String> rewardCommands) {
this.rewardCommands = rewardCommands;
}
@Override
public void setUniqueId(String uniqueId) {
this.uniqueId = uniqueId;
}
public void setWaiveramount(int waiveramount) {
this.waiveramount = waiveramount;
}
public int getOrder() {
return order;
}
public void setOrder(int order) {
this.order = order;
}
@Override
public int compareTo(ChallengeLevels o) {
return Integer.compare(this.order, o.order);
}
/**
* @return the rewardDescription
*/
public String getRewardDescription() {
return rewardDescription;
}
/**
* @param rewardDescription the rewardDescription to set
*/
public void setRewardDescription(String rewardDescription) {
this.rewardDescription = rewardDescription;
}
/**
* @return the rewardItems
*/
public List<ItemStack> getRewardItems() {
return rewardItems;
}
/**
* @param rewardItems the rewardItems to set
*/
public void setRewardItems(List<ItemStack> rewardItems) {
this.rewardItems = rewardItems;
}
/**
* @return the expReward
*/
public int getExpReward() {
return expReward;
}
/**
* @param expReward the expReward to set
*/
public void setExpReward(int expReward) {
this.expReward = expReward;
}
/**
* @return the moneyReward
*/
public int getMoneyReward() {
return moneyReward;
}
/**
* @param moneyReward the moneyReward to set
*/
public void setMoneyReward(int moneyReward) {
this.moneyReward = moneyReward;
}
/**
* @return the unlockMessage
*/
public String getUnlockMessage() {
return unlockMessage;
}
/**
* @param unlockMessage the unlockMessage to set
*/
public void setUnlockMessage(String unlockMessage) {
this.unlockMessage = unlockMessage;
}
/**
* @return the worlds
*/
public List<String> getWorlds() {
return worlds;
}
/**
* @param worlds the worlds to set
*/
public void setWorlds(List<String> worlds) {
this.worlds = worlds;
}
/* (non-Javadoc)
* @see java.lang.Object#hashCode()
*/
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((uniqueId == null) ? 0 : uniqueId.hashCode());
return result;
}
/* (non-Javadoc)
* @see java.lang.Object#equals(java.lang.Object)
*/
@Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (obj == null) {
return false;
}
if (!(obj instanceof ChallengeLevels)) {
return false;
}
ChallengeLevels other = (ChallengeLevels) obj;
if (uniqueId == null) {
if (other.uniqueId != null) {
return false;
}
} else if (!uniqueId.equals(other.uniqueId)) {
return false;
}
return true;
}
}

View File

@ -1,633 +0,0 @@
package world.bentobox.challenges.database.object;
import java.util.ArrayList;
import java.util.EnumMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.bukkit.Material;
import org.bukkit.World;
import org.bukkit.entity.EntityType;
import org.bukkit.inventory.ItemStack;
import world.bentobox.challenges.ChallengesManager;
import world.bentobox.bentobox.api.configuration.ConfigComment;
import world.bentobox.bentobox.database.objects.DataObject;
/**
* Data object for challenges
* @author tastybento
*
*/
public class Challenges implements DataObject {
public Challenges() {}
public enum ChallengeType {
/**
* This challenge only shows and icon in the GUI and doesn't do anything.
*/
ICON,
/**
* The player must have the items on them.
*/
INVENTORY,
/**
* The island level has to be equal or over this amount. Only works if there's an island level plugin installed.
*/
LEVEL,
/**
* Items or required entities have to be within x blocks of the player.
*/
ISLAND
}
// The order of the fields is the order shown in the YML files
@ConfigComment("Whether this challenge is deployed or not")
private boolean deployed;
// Description
@ConfigComment("Name of the icon and challenge. May include color codes. Single line.")
private String friendlyName = "";
@ConfigComment("Description of the challenge. Will become the lore on the icon. Can include & color codes. String List.")
private List<String> description = new ArrayList<>();
@ConfigComment("The icon in the GUI for this challenge. ItemStack.")
private ItemStack icon = new ItemStack(Material.PAPER);
@ConfigComment("Icon slot where this challenge should be placed. 0 to 49. A negative value means any slot")
private int slot = -1;
// Definition
@ConfigComment("Challenge level. Default is Free")
private String level = ChallengesManager.FREE;
@ConfigComment("Challenge type can be ICON, INVENTORY, LEVEL or ISLAND.")
private ChallengeType challengeType = ChallengeType.INVENTORY;
@ConfigComment("World where this challenge operates. List only overworld. Nether and end are automatically covered.")
private String world = "";
@ConfigComment("List of environments where this challenge will occur: NETHER, NORMAL, THE_END. Leave blank for all.")
private List<World.Environment> environment = new ArrayList<>();
@ConfigComment("The required permissions to see this challenge. String list.")
private Set<String> reqPerms = new HashSet<>();
@ConfigComment("The number of blocks around the player to search for items on an island")
private int searchRadius = 10;
@ConfigComment("If true, the challenge will disappear from the GUI when completed")
private boolean removeWhenCompleted;
@ConfigComment("Take the required items from the player")
private boolean takeItems = true;
@ConfigComment("Take the money from the player")
private boolean takeMoney = false;
// Requirements
@ConfigComment("This is a map of the blocks required in a ISLAND challenge. Material, Integer")
private Map<Material, Integer> requiredBlocks = new EnumMap<>(Material.class);
@ConfigComment("The items that must be in the inventory to complete the challenge. ItemStack List.")
private List<ItemStack> requiredItems = new ArrayList<>();
@ConfigComment("Any entities that must be in the area for ISLAND type challenges. Map EntityType, Number")
private Map<EntityType, Integer> requiredEntities = new EnumMap<>(EntityType.class);
@ConfigComment("Required experience")
private int reqExp;
@ConfigComment("Required island level for this challenge. Only works if Level Addon is being used.")
private long reqIslandlevel;
@ConfigComment("Required money")
private int reqMoney;
// Rewards
@ConfigComment("List of items the player will receive first time. ItemStack List.")
private List<ItemStack> rewardItems = new ArrayList<>();
@ConfigComment("If this is blank, the reward text will be auto-generated, otherwise this will be used.")
private String rewardText = "";
@ConfigComment("Experience point reward")
private int rewardExp;
@ConfigComment("Money reward")
private int rewardMoney;
@ConfigComment("Commands to run when the player completes the challenge for the first time. String List")
private List<String> rewardCommands = new ArrayList<>();
// Repeatable
@ConfigComment("True if the challenge is repeatable")
private boolean repeatable;
@ConfigComment("Maximum number of times the challenge can be repeated")
private int maxTimes = 1;
@ConfigComment("Repeat exp award")
private int repeatExpReward;
@ConfigComment("Reward items for repeating the challenge. List of ItemStacks.")
private List<ItemStack> repeatItemReward = new ArrayList<>();
@ConfigComment("Repeat money award")
private int repeatMoneyReward;
@ConfigComment("Commands to run when challenge is repeated. String List.")
private List<String> repeatRewardCommands = new ArrayList<>();
@ConfigComment("Description of the repeat rewards. If blank, it will be autogenerated.")
private String repeatRewardText = "";
@ConfigComment("Unique name of the challenge")
private String uniqueId = "";
/*
* END OF SETTINGS
*/
/**
* @return the challengeType
*/
public ChallengeType getChallengeType() {
return challengeType;
}
/**
* @param challengeType the challengeType to set
*/
public void setChallengeType(ChallengeType challengeType) {
this.challengeType = challengeType;
}
/**
* @return the deployed
*/
public boolean isDeployed() {
return deployed;
}
/**
* @param deployed the deployed to set
*/
public void setDeployed(boolean deployed) {
this.deployed = deployed;
}
/**
* @return the description
*/
public List<String> getDescription() {
return description;
}
/**
* @param description the description to set
*/
public void setDescription(List<String> description) {
this.description = description;
}
/**
* @return the expReward
*/
public int getRewardExp() {
return rewardExp;
}
/**
* @param expReward the expReward to set
*/
public void setRewardExp(int expReward) {
this.rewardExp = expReward;
}
/**
* @return the friendlyName
*/
public String getFriendlyName() {
return friendlyName;
}
/**
* @param friendlyName the friendlyName to set
*/
public void setFriendlyName(String friendlyName) {
this.friendlyName = friendlyName;
}
/**
* @return the icon
*/
public ItemStack getIcon() {
return icon != null ? icon.clone() : new ItemStack(Material.MAP);
}
/**
* @param icon the icon to set
*/
public void setIcon(ItemStack icon) {
this.icon = icon;
}
/**
* @return the level
*/
public String getLevel() {
return level;
}
/**
* @param level the level to set
*/
public void setLevel(String level) {
if (level.isEmpty()) {
level = ChallengesManager.FREE;
}
this.level = level;
}
/**
* @return the maxTimes
*/
public int getMaxTimes() {
return maxTimes;
}
/**
* @param maxTimes the maxTimes to set
*/
public void setMaxTimes(int maxTimes) {
this.maxTimes = maxTimes;
}
/**
* @return the moneyReward
*/
public int getRewardMoney() {
return rewardMoney;
}
/**
* @param moneyReward the moneyReward to set
*/
public void setRewardMoney(int moneyReward) {
this.rewardMoney = moneyReward;
}
/**
* @return the removeWhenCompleted
*/
public boolean isRemoveWhenCompleted() {
return removeWhenCompleted;
}
/**
* @param removeWhenCompleted the removeWhenCompleted to set
*/
public void setRemoveWhenCompleted(boolean removeWhenCompleted) {
this.removeWhenCompleted = removeWhenCompleted;
}
/**
* @return the repeatable
*/
public boolean isRepeatable() {
return repeatable;
}
/**
* @param repeatable the repeatable to set
*/
public void setRepeatable(boolean repeatable) {
this.repeatable = repeatable;
}
/**
* @return the repeatExpReward
*/
public int getRepeatExpReward() {
return repeatExpReward;
}
/**
* @param repeatExpReward the repeatExpReward to set
*/
public void setRepeatExpReward(int repeatExpReward) {
this.repeatExpReward = repeatExpReward;
}
/**
* @return the repeatItemReward
*/
public List<ItemStack> getRepeatItemReward() {
return repeatItemReward;
}
/**
* @param repeatItemReward the repeatItemReward to set
*/
public void setRepeatItemReward(List<ItemStack> repeatItemReward) {
this.repeatItemReward = repeatItemReward;
}
/**
* @return the repeatMoneyReward
*/
public int getRepeatMoneyReward() {
return repeatMoneyReward;
}
/**
* @param repeatMoneyReward the repeatMoneyReward to set
*/
public void setRepeatMoneyReward(int repeatMoneyReward) {
this.repeatMoneyReward = repeatMoneyReward;
}
/**
* @return the repeatRewardCommands
*/
public List<String> getRepeatRewardCommands() {
return repeatRewardCommands;
}
/**
* @param repeatRewardCommands the repeatRewardCommands to set
*/
public void setRepeatRewardCommands(List<String> repeatRewardCommands) {
this.repeatRewardCommands = repeatRewardCommands;
}
/**
* @return the repeatRewardText
*/
public String getRepeatRewardText() {
return repeatRewardText;
}
/**
* @param repeatRewardText the repeatRewardText to set
*/
public void setRepeatRewardText(String repeatRewardText) {
this.repeatRewardText = repeatRewardText;
}
/**
* @return the reqExp
*/
public int getReqExp() {
return reqExp;
}
/**
* @param reqExp the reqExp to set
*/
public void setReqExp(int reqExp) {
this.reqExp = reqExp;
}
/**
* @return the reqIslandlevel
*/
public long getReqIslandlevel() {
return reqIslandlevel;
}
/**
* @param reqIslandlevel the reqIslandlevel to set
*/
public void setReqIslandlevel(long reqIslandlevel) {
this.reqIslandlevel = reqIslandlevel;
}
/**
* @return the reqMoney
*/
public int getReqMoney() {
return reqMoney;
}
/**
* @param reqMoney the reqMoney to set
*/
public void setReqMoney(int reqMoney) {
this.reqMoney = reqMoney;
}
/**
* @return the reqPerms
*/
public Set<String> getReqPerms() {
return reqPerms;
}
/**
* @param reqPerms the reqPerms to set
*/
public void setReqPerms(Set<String> reqPerms) {
this.reqPerms = reqPerms;
}
/**
* @return the requiredItems
*/
public List<ItemStack> getRequiredItems() {
return requiredItems;
}
/**
* @param requiredItems the requiredItems to set
*/
public void setRequiredItems(List<ItemStack> requiredItems) {
this.requiredItems = requiredItems;
}
/**
* @return requiredEntities
*/
public Map<EntityType, Integer> getRequiredEntities() {
return requiredEntities;
}
/**
* @param requiredEntities the requiredEntities to set
*/
public void setRequiredEntities(Map<EntityType, Integer> requiredEntities) {
this.requiredEntities = requiredEntities;
}
/**
* @return the requiredBlocks
*/
public Map<Material, Integer> getRequiredBlocks() {
return requiredBlocks;
}
/**
* @param map the requiredBlocks to set
*/
public void setRequiredBlocks(Map<Material, Integer> map) {
this.requiredBlocks = map;
}
/**
* @return the rewardCommands
*/
public List<String> getRewardCommands() {
return rewardCommands;
}
/**
* @param rewardCommands the rewardCommands to set
*/
public void setRewardCommands(List<String> rewardCommands) {
this.rewardCommands = rewardCommands;
}
/**
* @return the itemReward
*/
public List<ItemStack> getRewardItems() {
return rewardItems;
}
/**
* @param itemReward the itemReward to set
*/
public void setRewardItems(List<ItemStack> itemReward) {
this.rewardItems = itemReward;
}
/**
* @return the rewardText
*/
public String getRewardText() {
return rewardText;
}
/**
* @param rewardText the rewardText to set
*/
public void setRewardText(String rewardText) {
this.rewardText = rewardText;
}
/**
* @return the searchRadius
*/
public int getSearchRadius() {
return searchRadius;
}
/**
* @param searchRadius the searchRadius to set
*/
public void setSearchRadius(int searchRadius) {
this.searchRadius = searchRadius;
}
/**
* @return the slot
*/
public int getSlot() {
return slot;
}
/**
* @param slot the slot to set
*/
public void setSlot(int slot) {
this.slot = slot;
}
/**
* @return the takeItems
*/
public boolean isTakeItems() {
return takeItems;
}
/**
* @param takeItems the takeItems to set
*/
public void setTakeItems(boolean takeItems) {
this.takeItems = takeItems;
}
/**
* @return the takeMoney
*/
public boolean isTakeMoney() {
return takeMoney;
}
/**
* @param takeMoney the takeMoney to set
*/
public void setTakeMoney(boolean takeMoney) {
this.takeMoney = takeMoney;
}
/**
* @return the environment
*/
public List<World.Environment> getEnvironment() {
return environment;
}
/**
* @param environment the environment to set
*/
public void setEnvironment(List<World.Environment> environment) {
this.environment = environment;
}
/**
* @return the worlds
*/
public String getWorld() {
return world;
}
/**
* @param worlds the worlds to set
*/
public void setWorld(String world) {
this.world = world;
}
/**
* @return the uniqueId
*/
@Override
public String getUniqueId() {
return uniqueId;
}
/**
* @param uniqueId the uniqueId to set
*/
@Override
public void setUniqueId(String uniqueId) {
this.uniqueId = uniqueId;
}
/* (non-Javadoc)
* @see java.lang.Object#hashCode()
*/
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((uniqueId == null) ? 0 : uniqueId.hashCode());
return result;
}
/* (non-Javadoc)
* @see java.lang.Object#equals(java.lang.Object)
*/
@Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (obj == null) {
return false;
}
if (!(obj instanceof Challenges)) {
return false;
}
Challenges other = (Challenges) obj;
if (uniqueId == null) {
if (other.uniqueId != null) {
return false;
}
} else if (!uniqueId.equals(other.uniqueId)) {
return false;
}
return true;
}
}

View File

@ -1,17 +1,13 @@
/**
*
*/
package world.bentobox.challenges.database.object;
import com.google.gson.annotations.Expose;
import org.bukkit.World;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import org.bukkit.World;
import com.google.gson.annotations.Expose;
import world.bentobox.bentobox.database.objects.DataObject;
import world.bentobox.bentobox.util.Util;
@ -20,173 +16,286 @@ import world.bentobox.bentobox.util.Util;
* @author tastybento
*
*/
public class ChallengesPlayerData implements DataObject {
@Expose
private String uniqueId = "";
public class ChallengesPlayerData implements DataObject
{
/**
* Challenge map, where key = unique challenge name and Value = number of times completed
* Constructor ChallengesPlayerData creates a new ChallengesPlayerData instance.
*/
@Expose
private Map<String, Integer> challengeStatus = new HashMap<>();
@Expose
private Map<String, Long> challengesTimestamp = new HashMap<>();
@Expose
private Set<String> levelsDone = new HashSet<>();
// Required for bean instantiation
public ChallengesPlayerData() {}
/**
* Mark a challenge as having been completed. Will increment the number of times and timestamp
* @param world - world of challenge
* @param challengeName - unique challenge name
*/
public void setChallengeDone(World world, String challengeName) {
String name = Util.getWorld(world).getName() + challengeName;
int times = challengeStatus.getOrDefault(name, 0) + 1;
challengeStatus.put(name, times);
challengesTimestamp.put(name, System.currentTimeMillis());
public ChallengesPlayerData()
{
}
/**
* Set the number of times a challenge has been done
* @param world - world of challenge
* @param challengeName - unique challenge name
* @param times - the number of times to set
*
*/
public void setChallengeTimes(World world, String challengeName, int times) {
String name = Util.getWorld(world).getName() + challengeName;
challengeStatus.put(name, times);
challengesTimestamp.put(name, System.currentTimeMillis());
}
/**
* Check if a challenge has been done
* @param challengeName - unique challenge name
* @return true if done at least once
*/
public boolean isChallengeDone(World world, String challengeName) {
return getTimes(world, challengeName) > 0;
}
/**
* Check how many times a challenge has been done
* @param challengeName - unique challenge name
* @return - number of times
*/
public int getTimes(World world, String challengeName) {
return challengeStatus.getOrDefault(Util.getWorld(world).getName() + challengeName, 0);
}
/**
* Creates a player data entry
*
* @param uniqueId - the player's UUID in string format
*/
public ChallengesPlayerData(String uniqueId) {
public ChallengesPlayerData(String uniqueId)
{
this.uniqueId = uniqueId;
}
/* (non-Javadoc)
* @see world.bentobox.bbox.database.objects.DataObject#getUniqueId()
// ---------------------------------------------------------------------
// Section: Variables
// ---------------------------------------------------------------------
/**
* This variable stores each player UUID as string.
*/
@Expose
private String uniqueId = "";
/**
* Challenge map, where key = unique challenge name and Value = number of times
* completed
*/
@Expose
private Map<String, Integer> challengeStatus = new HashMap<>();
/**
* Map of challenges completion time where key is challenges unique id and value is
* timestamp when challenge was completed last time.
*/
@Expose
private Map<String, Long> challengesTimestamp = new HashMap<>();
/**
* Set of Strings that contains all challenge levels that are completed.
*/
@Expose
private Set<String> levelsDone = new HashSet<>();
// ---------------------------------------------------------------------
// Section: Getters
// ---------------------------------------------------------------------
/**
* @return uniqueID
* @see DataObject#getUniqueId()
*/
@Override
public String getUniqueId() {
public String getUniqueId()
{
return uniqueId;
}
/* (non-Javadoc)
* @see world.bentobox.bbox.database.objects.DataObject#setUniqueId(java.lang.String)
*/
@Override
public void setUniqueId(String uniqueId) {
this.uniqueId = uniqueId;
}
/**
* @return the challengeStatus
* This method returns the challengeStatus value.
* @return the value of challengeStatus.
*/
public Map<String, Integer> getChallengeStatus() {
public Map<String, Integer> getChallengeStatus()
{
return challengeStatus;
}
/**
* @param challengeStatus the challengeStatus to set
* This method returns the challengesTimestamp value.
* @return the value of challengesTimestamp.
*/
public void setChallengeStatus(Map<String, Integer> challengeStatus) {
this.challengeStatus = challengeStatus;
}
/**
* @return the challengesTimestamp
*/
public Map<String, Long> getChallengesTimestamp() {
public Map<String, Long> getChallengesTimestamp()
{
return challengesTimestamp;
}
/**
* @param challengesTimestamp the challengesTimestamp to set
* This method returns the levelsDone value.
* @return the value of levelsDone.
*/
public void setChallengesTimestamp(Map<String, Long> challengesTimestamp) {
this.challengesTimestamp = challengesTimestamp;
}
/**
* @return the levelsDone
*/
public Set<String> getLevelsDone() {
public Set<String> getLevelsDone()
{
return levelsDone;
}
// ---------------------------------------------------------------------
// Section: Setters
// ---------------------------------------------------------------------
/**
* @param levelsDone the levelsDone to set
* @param uniqueId - unique ID the uniqueId to set
* @see DataObject#setUniqueId(String)
*/
public void setLevelsDone(Set<String> levelsDone) {
@Override
public void setUniqueId(String uniqueId)
{
this.uniqueId = uniqueId;
}
/**
* This method sets the challengeStatus value.
* @param challengeStatus the challengeStatus new value.
*
*/
public void setChallengeStatus(Map<String, Integer> challengeStatus)
{
this.challengeStatus = challengeStatus;
}
/**
* This method sets the challengesTimestamp value.
* @param challengesTimestamp the challengesTimestamp new value.
*
*/
public void setChallengesTimestamp(Map<String, Long> challengesTimestamp)
{
this.challengesTimestamp = challengesTimestamp;
}
/**
* This method sets the levelsDone value.
* @param levelsDone the levelsDone new value.
*
*/
public void setLevelsDone(Set<String> levelsDone)
{
this.levelsDone = levelsDone;
}
/* (non-Javadoc)
* @see java.lang.Object#hashCode()
*/
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((uniqueId == null) ? 0 : uniqueId.hashCode());
return result;
}
/* (non-Javadoc)
* @see java.lang.Object#equals(java.lang.Object)
*/
@Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (obj == null) {
return false;
}
if (!(obj instanceof ChallengesPlayerData)) {
return false;
}
ChallengesPlayerData other = (ChallengesPlayerData) obj;
if (uniqueId == null) {
if (other.uniqueId != null) {
return false;
}
} else if (!uniqueId.equals(other.uniqueId)) {
return false;
}
return true;
}
// ---------------------------------------------------------------------
// Section: Other Methods
// ---------------------------------------------------------------------
/**
* Resets all challenges and levels in world for this player
* @param world
*
* @param world world which challenges must be reset.
*/
public void reset(World world) {
public void reset(World world)
{
String worldName = Util.getWorld(world).getName();
challengeStatus.keySet().removeIf(n -> n.startsWith(worldName));
challengesTimestamp.keySet().removeIf(n -> n.startsWith(worldName));
levelsDone.removeIf(n -> n.startsWith(worldName));
}
/**
* Mark a challenge as having been completed. Will increment the number of times and
* timestamp
*
* @param challengeName - unique challenge name
*/
public void setChallengeDone(String challengeName)
{
int times = challengeStatus.getOrDefault(challengeName, 0) + 1;
challengeStatus.put(challengeName, times);
challengesTimestamp.put(challengeName, System.currentTimeMillis());
}
/**
* Set the number of times a challenge has been done
*
* @param challengeName - unique challenge name
* @param times - the number of times to set
*/
public void setChallengeTimes(String challengeName, int times)
{
challengeStatus.put(challengeName, times);
challengesTimestamp.put(challengeName, System.currentTimeMillis());
}
/**
* Check if a challenge has been done
*
* @param challengeName - unique challenge name
* @return true if done at least once
*/
public boolean isChallengeDone(String challengeName)
{
return this.getTimes(challengeName) > 0;
}
/**
* Check how many times a challenge has been done
*
* @param challengeName - unique challenge name
* @return - number of times
*/
public int getTimes(String challengeName)
{
return challengeStatus.getOrDefault(challengeName, 0);
}
/**
* This method adds given level id to completed level set.
* @param uniqueId from ChallengeLevel object.
*/
public void addCompletedLevel(String uniqueId)
{
this.levelsDone.add(uniqueId);
}
/**
* This method returns if given level is done.
* @param uniqueId of ChallengeLevel object.
* @return <code>true</code> if level is completed, otherwise <code>false</code>
*/
public boolean isLevelDone(String uniqueId)
{
return !this.levelsDone.isEmpty() && this.levelsDone.contains(uniqueId);
}
/**
* @see Object#hashCode()
* @return object hashCode value.
*/
@Override
public int hashCode()
{
final int prime = 31;
int result = 1;
result = prime * result + ((uniqueId == null) ? 0 : uniqueId.hashCode());
return result;
}
/**
* @see java.lang.Object#equals(java.lang.Object)
* @param obj Other object.
* @return boolean that indicate if objects are equals.
*/
@Override
public boolean equals(Object obj)
{
if (this == obj)
{
return true;
}
if (!(obj instanceof ChallengesPlayerData))
{
return false;
}
ChallengesPlayerData other = (ChallengesPlayerData) obj;
if (uniqueId == null)
{
return other.uniqueId == null;
}
else
{
return uniqueId.equals(other.uniqueId);
}
}
}

View File

@ -7,6 +7,7 @@ import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.Listener;
import world.bentobox.bentobox.api.user.User;
import world.bentobox.challenges.ChallengesAddon;
import world.bentobox.bentobox.api.events.island.IslandEvent;
import world.bentobox.bentobox.api.events.island.IslandEvent.Reason;
@ -26,8 +27,8 @@ public class ResetListener implements Listener {
@EventHandler(priority = EventPriority.LOW, ignoreCancelled = true)
public void onIslandReset(IslandEvent e) {
if (e.getReason().equals(Reason.CREATED) || (addon.getConfig().getBoolean("resetchallenges") && e.getReason().equals(Reason.RESETTED))) {
addon.getChallengesManager().resetAllChallenges(e.getOwner(), e.getLocation().getWorld());
if (e.getReason().equals(Reason.CREATED) || (addon.getChallengesSettings().isResetChallenges() && e.getReason().equals(Reason.RESETTED))) {
addon.getChallengesManager().resetAllChallenges(User.getInstance(e.getOwner()), e.getLocation().getWorld());
}
}
}

View File

@ -23,7 +23,7 @@ public class SaveListener implements Listener
@EventHandler(priority = EventPriority.LOW, ignoreCancelled = true)
public void onWorldSave(WorldSaveEvent e)
{
if (!this.addon.getChallengesManager().getAllChallengesList(e.getWorld()).isEmpty())
if (!this.addon.getChallengesManager().getAllChallenges(e.getWorld()).isEmpty())
{
this.addon.getChallengesManager().save();
}

View File

@ -6,18 +6,23 @@ import org.bukkit.event.inventory.ClickType;
import org.bukkit.inventory.ItemStack;
import world.bentobox.challenges.ChallengesAddon;
import world.bentobox.challenges.database.object.Challenges;
import world.bentobox.challenges.database.object.Challenge;
import world.bentobox.bentobox.api.panels.Panel;
import world.bentobox.bentobox.api.panels.PanelItem.ClickHandler;
import world.bentobox.bentobox.api.panels.builders.PanelBuilder;
import world.bentobox.bentobox.api.panels.builders.PanelItemBuilder;
import world.bentobox.bentobox.api.user.User;
/**
* @deprecated All panels are reworked.
*/
@Deprecated
public class AdminEditGUI implements ClickHandler {
private ChallengesAddon addon;
private User requester;
private Challenges challenge;
private Challenge challenge;
private World world;
private String permPrefix;
private String label;
@ -33,7 +38,7 @@ public class AdminEditGUI implements ClickHandler {
* @param permPrefix permission prefix for world
* @param label command label
*/
public AdminEditGUI(ChallengesAddon addon, User requester, User target, Challenges challenge, World world,
public AdminEditGUI(ChallengesAddon addon, User requester, User target, Challenge challenge, World world,
String permPrefix, String label) {
super();
this.addon = addon;

View File

@ -6,18 +6,23 @@ import org.bukkit.event.inventory.ClickType;
import org.bukkit.inventory.ItemStack;
import world.bentobox.challenges.ChallengesAddon;
import world.bentobox.challenges.database.object.Challenges;
import world.bentobox.challenges.database.object.Challenge;
import world.bentobox.bentobox.api.panels.Panel;
import world.bentobox.bentobox.api.panels.PanelItem.ClickHandler;
import world.bentobox.bentobox.api.panels.builders.PanelBuilder;
import world.bentobox.bentobox.api.panels.builders.PanelItemBuilder;
import world.bentobox.bentobox.api.user.User;
/**
* @deprecated All panels are reworked.
*/
@Deprecated
public class AdminGUI implements ClickHandler {
private ChallengesAddon addon;
private User player;
private Challenges challenge;
private Challenge challenge;
private World world;
private String permPrefix;
private String label;
@ -31,7 +36,7 @@ public class AdminGUI implements ClickHandler {
* @param permPrefix
* @param label
*/
public AdminGUI(ChallengesAddon addon, User player, Challenges challenge, World world,
public AdminGUI(ChallengesAddon addon, User player, Challenge challenge, World world,
String permPrefix, String label) {
super();
this.addon = addon;

View File

@ -11,10 +11,12 @@ import org.bukkit.inventory.ItemStack;
import world.bentobox.challenges.ChallengesAddon;
import world.bentobox.challenges.ChallengesManager;
import world.bentobox.challenges.LevelStatus;
import world.bentobox.challenges.database.object.ChallengeLevel;
import world.bentobox.challenges.utils.GuiUtils;
import world.bentobox.challenges.utils.LevelStatus;
import world.bentobox.challenges.commands.ChallengesCommand;
import world.bentobox.challenges.database.object.Challenges;
import world.bentobox.challenges.database.object.Challenges.ChallengeType;
import world.bentobox.challenges.database.object.Challenge;
import world.bentobox.challenges.database.object.Challenge.ChallengeType;
import world.bentobox.bentobox.api.panels.Panel;
import world.bentobox.bentobox.api.panels.PanelItem;
import world.bentobox.bentobox.api.panels.builders.PanelBuilder;
@ -22,11 +24,15 @@ import world.bentobox.bentobox.api.panels.builders.PanelItemBuilder;
import world.bentobox.bentobox.api.user.User;
/**
* @deprecated All panels are reworked.
*/
@Deprecated
public class ChallengesPanels {
private ChallengesAddon addon;
private ChallengesManager manager;
private User user;
private String level;
private ChallengeLevel level;
private World world;
private String permPrefix;
private String label;
@ -39,17 +45,17 @@ public class ChallengesPanels {
this.permPrefix = permPrefix;
this.label = label;
if (manager.getChallengeList().isEmpty()) {
if (manager.getAllChallenges(world).isEmpty()) {
addon.getLogger().severe("There are no challenges set up!");
user.sendMessage("general.errors.general");
return;
}
if (level.isEmpty()) {
level = manager.getChallengeList().keySet().iterator().next().getUniqueId();
level = manager.getLevels(world).iterator().next().getUniqueId();
}
this.level = level;
this.level = this.manager.getLevel(level);
// Check if level is valid
if (!manager.isLevelUnlocked(user, level, world)) {
if (!manager.isLevelUnlocked(user, world, this.level)) {
return;
}
PanelBuilder panelBuilder = new PanelBuilder()
@ -65,15 +71,15 @@ public class ChallengesPanels {
}
private void addChallengeItems(PanelBuilder panelBuilder) {
Set<Challenges> levelChallenges = manager.getChallenges(level, world);
List<Challenge> levelChallenges = manager.getLevelChallenges(level);
// Only show a control panel for the level requested.
for (Challenges challenge : levelChallenges) {
for (Challenge challenge : levelChallenges) {
createItem(panelBuilder, challenge);
}
}
private void addFreeChallanges(PanelBuilder panelBuilder) {
manager.getChallenges(ChallengesManager.FREE, world).forEach(challenge -> createItem(panelBuilder, challenge));
manager.getFreeChallenges(world).forEach(challenge -> createItem(panelBuilder, challenge));
}
@ -81,11 +87,10 @@ public class ChallengesPanels {
* Creates a panel item for challenge if appropriate and adds it to panelBuilder
* @param panelBuilder
* @param challenge
* @param user
*/
private void createItem(PanelBuilder panelBuilder, Challenges challenge) {
private void createItem(PanelBuilder panelBuilder, Challenge challenge) {
// Check completion
boolean completed = manager.isChallengeComplete(user, challenge.getUniqueId(), world);
boolean completed = manager.isChallengeComplete(user, challenge);
// If challenge is removed after completion, remove it
if (completed && challenge.isRemoveWhenCompleted()) {
return;
@ -96,16 +101,13 @@ public class ChallengesPanels {
.description(challengeDescription(challenge))
.glow(completed)
.clickHandler((panel, player, c, s) -> {
if (!challenge.getChallengeType().equals(ChallengeType.ICON)) {
new TryToComplete(addon).user(player).manager(manager).challenge(challenge)
.world(world).permPrefix(permPrefix).label(label).build();
//new TryToComplete(addon, player, manager, challenge, world, permPrefix, label);
}
return true;
})
.build();
if (challenge.getSlot() >= 0) {
panelBuilder.item(challenge.getSlot(),item);
if (challenge.getOrder() >= 0) {
panelBuilder.item(challenge.getOrder(),item);
} else {
panelBuilder.item(item);
}
@ -130,7 +132,7 @@ public class ChallengesPanels {
PanelItem item = new PanelItemBuilder()
.icon(new ItemStack(Material.ENCHANTED_BOOK))
.name(name)
.description(manager.stringSplit(user.getTranslation("challenges.navigation","[level]",name)))
.description(GuiUtils.stringSplit(user.getTranslation("challenges.navigation","[level]",name)))
.clickHandler((p, u, c, s) -> {
u.closeInventory();
u.performCommand(label + " " + ChallengesCommand.CHALLENGE_COMMAND + " " + status.getLevel().getUniqueId());
@ -144,7 +146,7 @@ public class ChallengesPanels {
PanelItem item = new PanelItemBuilder()
.icon(new ItemStack(Material.BOOK))
.name(name)
.description(manager.stringSplit(user.getTranslation("challenges.to-complete", "[challengesToDo]",String.valueOf(previousStatus != null ? previousStatus.getNumberOfChallengesStillToDo() : ""), "[thisLevel]", previousLevelName)))
.description(GuiUtils.stringSplit(user.getTranslation("challenges.to-complete", "[challengesToDo]",String.valueOf(previousStatus != null ? previousStatus.getNumberOfChallengesStillToDo() : ""), "[thisLevel]", previousLevelName)))
.build();
panelBuilder.item(item);
}
@ -157,10 +159,9 @@ public class ChallengesPanels {
* Creates the challenge description for the "item" in the inventory
*
* @param challenge
* @param player
* @return List of strings splitting challenge string into 25 chars long
*/
private List<String> challengeDescription(Challenges challenge) {
private List<String> challengeDescription(Challenge challenge) {
List<String> result = new ArrayList<String>();
String level = challenge.getLevel();
if (!level.isEmpty()) {
@ -168,9 +169,9 @@ public class ChallengesPanels {
}
// Check if completed or not
boolean complete = addon.getChallengesManager().isChallengeComplete(user, challenge.getUniqueId(), world);
boolean complete = addon.getChallengesManager().isChallengeComplete(user, challenge);
int maxTimes = challenge.getMaxTimes();
long doneTimes = addon.getChallengesManager().checkChallengeTimes(user, challenge, world);
long doneTimes = addon.getChallengesManager().getChallengeTimes(user, challenge);
if (complete) {
result.add(user.getTranslation("challenges.complete"));
}
@ -206,7 +207,7 @@ public class ChallengesPanels {
// First time
moneyReward = challenge.getRewardMoney();
rewardText = challenge.getRewardText();
expReward = challenge.getRewardExp();
expReward = challenge.getRewardExperience();
if (!rewardText.isEmpty()) {
result.addAll(splitTrans(user, "challenges.first-time-rewards"));
}
@ -214,7 +215,7 @@ public class ChallengesPanels {
// Repeat challenge
moneyReward = challenge.getRepeatMoneyReward();
rewardText = challenge.getRepeatRewardText();
expReward = challenge.getRepeatExpReward();
expReward = challenge.getRepeatExperienceReward();
if (!rewardText.isEmpty()) {
result.addAll(splitTrans(user, "challenges.repeat-rewards"));
}
@ -235,6 +236,6 @@ public class ChallengesPanels {
}
private Collection<? extends String> splitTrans(User user, String string, String...strings) {
return addon.getChallengesManager().stringSplit(user.getTranslation(string, strings));
return GuiUtils.stringSplit(user.getTranslation(string, strings));
}
}

View File

@ -1,26 +1,32 @@
package world.bentobox.challenges.panel;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import org.bukkit.Material;
import org.bukkit.World;
import org.bukkit.inventory.ItemStack;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import world.bentobox.challenges.ChallengesAddon;
import world.bentobox.challenges.ChallengesManager;
import world.bentobox.challenges.LevelStatus;
import world.bentobox.challenges.commands.ChallengesCommand;
import world.bentobox.challenges.database.object.Challenges;
import world.bentobox.challenges.database.object.Challenges.ChallengeType;
import world.bentobox.bentobox.api.panels.Panel;
import world.bentobox.bentobox.api.panels.PanelItem;
import world.bentobox.bentobox.api.panels.builders.PanelBuilder;
import world.bentobox.bentobox.api.panels.builders.PanelItemBuilder;
import world.bentobox.bentobox.api.user.User;
import world.bentobox.challenges.ChallengesAddon;
import world.bentobox.challenges.ChallengesManager;
import world.bentobox.challenges.commands.ChallengesCommand;
import world.bentobox.challenges.database.object.Challenge;
import world.bentobox.challenges.database.object.Challenge.ChallengeType;
import world.bentobox.challenges.database.object.ChallengeLevel;
import world.bentobox.challenges.utils.GuiUtils;
import world.bentobox.challenges.utils.LevelStatus;
/**
* @deprecated All panels are reworked.
*/
@Deprecated
public class ChallengesPanels2 {
public enum Mode {
@ -31,7 +37,7 @@ public class ChallengesPanels2 {
private ChallengesAddon addon;
private ChallengesManager manager;
private User requester;
private String level;
private ChallengeLevel level;
private World world;
private String permPrefix;
private String label;
@ -48,18 +54,18 @@ public class ChallengesPanels2 {
this.label = label;
this.mode = mode;
if (manager.getChallengeList().isEmpty()) {
if (manager.getAllChallenges(world).isEmpty()) {
addon.getLogger().severe("There are no challenges set up!");
requester.sendMessage("general.errors.general");
return;
}
if (level.isEmpty()) {
// TODO: open the farthest challenge panel
level = manager.getChallengeList().keySet().iterator().next().getUniqueId();
level = manager.getLevels(world).iterator().next().getUniqueId();
}
this.level = level;
this.level = manager.getLevel(level);
// Check if level is valid
if (mode.equals(Mode.PLAYER) && !manager.isLevelUnlocked(requester, level, world)) {
if (mode.equals(Mode.PLAYER) && !manager.isLevelUnlocked(requester, world, this.level)) {
return;
}
PanelBuilder panelBuilder = new PanelBuilder();
@ -89,13 +95,13 @@ public class ChallengesPanels2 {
private void addChallengeItems(PanelBuilder panelBuilder) {
// Only show a control panel for the level requested.
for (Challenges challenge : manager.getChallenges(level, world)) {
for (Challenge challenge : manager.getLevelChallenges(level)) {
createItem(panelBuilder, challenge);
}
}
private void addFreeChallanges(PanelBuilder panelBuilder) {
manager.getChallenges(ChallengesManager.FREE, world).forEach(challenge -> createItem(panelBuilder, challenge));
manager.getFreeChallenges(world).forEach(challenge -> createItem(panelBuilder, challenge));
}
@ -103,9 +109,8 @@ public class ChallengesPanels2 {
* Creates a panel item for challenge if appropriate and adds it to panelBuilder
* @param panelBuilder
* @param challenge
* @param requester
*/
private void createItem(PanelBuilder panelBuilder, Challenges challenge) {
private void createItem(PanelBuilder panelBuilder, Challenge challenge) {
// For admin, glow means activated. For user, glow means done
boolean glow = false;
switch (mode) {
@ -113,10 +118,10 @@ public class ChallengesPanels2 {
glow = challenge.isDeployed();
break;
case EDIT:
glow = manager.isChallengeComplete(requester, challenge.getUniqueId(), world);
glow = manager.isChallengeComplete(requester, challenge);
break;
case PLAYER:
glow = manager.isChallengeComplete(requester, challenge.getUniqueId(), world);
glow = manager.isChallengeComplete(requester, challenge);
break;
default:
break;
@ -134,33 +139,27 @@ public class ChallengesPanels2 {
if (mode.equals(Mode.ADMIN)) {
// Admin click
itemBuilder.clickHandler((panel, player, c, s) -> {
if (!challenge.getChallengeType().equals(ChallengeType.ICON)) {
new AdminGUI(addon, player, challenge, world, permPrefix, label);
}
return true;
});
} else if (mode.equals(Mode.EDIT)) {
// Admin edit click
itemBuilder.clickHandler((panel, player, c, s) -> {
if (!challenge.getChallengeType().equals(ChallengeType.ICON)) {
new AdminEditGUI(addon, player, target, challenge, world, permPrefix, label);
}
return true;
});
} else {
// Player click
itemBuilder.clickHandler((panel, player, c, s) -> {
if (!challenge.getChallengeType().equals(ChallengeType.ICON)) {
new TryToComplete(addon, player, manager, challenge, world, permPrefix, label);
}
new TryToComplete(addon, player, challenge, world, label, permPrefix);
return true;
});
}
// If the challenge has a specific slot allocated, use it
if (challenge.getSlot() >= 0) {
panelBuilder.item(challenge.getSlot(),itemBuilder.build());
if (challenge.getOrder() >= 0) {
panelBuilder.item(challenge.getOrder(),itemBuilder.build());
} else {
panelBuilder.item(itemBuilder.build());
}
@ -172,7 +171,7 @@ public class ChallengesPanels2 {
// Add navigation to other levels
for (LevelStatus status: manager.getChallengeLevelStatus(requester, world)) {
if (status.getLevel().getUniqueId().equalsIgnoreCase(level)) {
if (status.getLevel().getUniqueId().equalsIgnoreCase(level.getUniqueId())) {
// Skip if this is the current level
previousStatus = status;
continue;
@ -185,7 +184,7 @@ public class ChallengesPanels2 {
PanelItem item = new PanelItemBuilder()
.icon(new ItemStack(Material.ENCHANTED_BOOK))
.name(name)
.description(manager.stringSplit(requester.getTranslation("challenges.navigation","[level]",name)))
.description(GuiUtils.stringSplit(requester.getTranslation("challenges.navigation","[level]",name)))
.clickHandler((p, u, c, s) -> {
u.closeInventory();
u.performCommand(label + " " + ChallengesCommand.CHALLENGE_COMMAND + " " + status.getLevel().getUniqueId());
@ -199,7 +198,7 @@ public class ChallengesPanels2 {
PanelItem item = new PanelItemBuilder()
.icon(new ItemStack(Material.BOOK))
.name(name)
.description(manager.stringSplit(requester.getTranslation("challenges.to-complete", "[challengesToDo]",String.valueOf(previousStatus != null ? previousStatus.getNumberOfChallengesStillToDo() : ""), "[thisLevel]", previousLevelName)))
.description(GuiUtils.stringSplit(requester.getTranslation("challenges.to-complete", "[challengesToDo]",String.valueOf(previousStatus != null ? previousStatus.getNumberOfChallengesStillToDo() : ""), "[thisLevel]", previousLevelName)))
.build();
panelBuilder.item(item);
}
@ -212,10 +211,9 @@ public class ChallengesPanels2 {
* Creates the challenge description for the "item" in the inventory
*
* @param challenge
* @param player
* @return List of strings splitting challenge string into 25 chars long
*/
private List<String> challengeDescription(Challenges challenge) {
private List<String> challengeDescription(Challenge challenge) {
List<String> result = new ArrayList<String>();
String level = challenge.getLevel();
if (!level.isEmpty()) {
@ -234,9 +232,9 @@ public class ChallengesPanels2 {
result.addAll(addRewards(challenge, true, true));
} else {
// Check if completed or not
boolean complete = addon.getChallengesManager().isChallengeComplete(requester, challenge.getUniqueId(), world);
boolean complete = addon.getChallengesManager().isChallengeComplete(requester, challenge);
int maxTimes = challenge.getMaxTimes();
long doneTimes = addon.getChallengesManager().checkChallengeTimes(requester, challenge, world);
long doneTimes = addon.getChallengesManager().getChallengeTimes(requester, challenge);
if (complete) {
result.add(requester.getTranslation("challenges.complete"));
}
@ -274,7 +272,7 @@ public class ChallengesPanels2 {
return result;
}
private List<String> addRewards(Challenges challenge, boolean complete, boolean admin) {
private List<String> addRewards(Challenge challenge, boolean complete, boolean admin) {
List<String> result = new ArrayList<>();
double moneyReward = 0;
int expReward = 0;
@ -283,7 +281,7 @@ public class ChallengesPanels2 {
// First time
moneyReward = challenge.getRewardMoney();
rewardText = challenge.getRewardText();
expReward = challenge.getRewardExp();
expReward = challenge.getRewardExperience();
if (!rewardText.isEmpty()) {
result.addAll(splitTrans(requester, "challenges.first-time-rewards"));
}
@ -292,7 +290,7 @@ public class ChallengesPanels2 {
// Repeat challenge
moneyReward = challenge.getRepeatMoneyReward();
rewardText = challenge.getRepeatRewardText();
expReward = challenge.getRepeatExpReward();
expReward = challenge.getRepeatExperienceReward();
if (!rewardText.isEmpty()) {
result.addAll(splitTrans(requester, "challenges.repeat-rewards"));
}
@ -311,6 +309,6 @@ public class ChallengesPanels2 {
}
private Collection<? extends String> splitTrans(User user, String string, String...strings) {
return addon.getChallengesManager().stringSplit(user.getTranslation(string, strings));
return GuiUtils.stringSplit(user.getTranslation(string, strings));
}
}

View File

@ -0,0 +1,245 @@
package world.bentobox.challenges.panel;
import org.bukkit.Material;
import org.bukkit.World;
import org.bukkit.inventory.ItemStack;
import java.util.Collections;
import java.util.List;
import world.bentobox.bentobox.api.panels.PanelItem;
import world.bentobox.bentobox.api.panels.builders.PanelItemBuilder;
import world.bentobox.bentobox.api.user.User;
import world.bentobox.challenges.ChallengesAddon;
/**
* This class contains common methods that will be used over all GUIs. It also allows
* easier navigation between different GUIs.
*/
public abstract class CommonGUI
{
// ---------------------------------------------------------------------
// Section: Variables
// ---------------------------------------------------------------------
/**
* This variable stores parent gui.
*/
private CommonGUI parentGUI;
/**
* Variable stores Challenges addon.
*/
protected ChallengesAddon addon;
/**
* Variable stores world in which panel is referred to.
*/
protected World world;
/**
* Variable stores user who created this panel.
*/
protected User user;
/**
* Variable stores top label of command from which panel was called.
*/
protected String topLabel;
/**
* Variable stores permission prefix of command from which panel was called.
*/
protected String permissionPrefix;
/**
* Variable stores any value.
*/
protected Object valueObject;
/**
* This object holds current page index.
*/
protected int pageIndex;
/**
* This object holds PanelItem that allows to return to previous panel.
*/
protected PanelItem returnButton;
/**
* This enum contains buttons that is offten used in multiple GUIs.
*/
protected enum CommonButtons
{
NEXT,
PREVIOUS,
RETURN
}
// ---------------------------------------------------------------------
// Section: Constants
// ---------------------------------------------------------------------
protected static final String ADMIN = "admin";
protected static final String CHALLENGES = "challenges";
protected static final String IMPORT = "import";
protected static final String SETTINGS = "settings";
protected static final String DELETE = "delete";
protected static final String EDIT = "edit";
protected static final String ADD = "add";
protected static final String RESET = "reset";
protected static final String COMPLETE = "complete";
// ---------------------------------------------------------------------
// Section: Constructors
// ---------------------------------------------------------------------
/**
* Default constructor that inits panels with minimal requirements, without parent panel.
*
* @param addon Addon where panel operates.
* @param world World from which panel was created.
* @param user User who created panel.
* @param topLabel Command top label which creates panel (f.e. island or ai)
* @param permissionPrefix Command permission prefix (f.e. bskyblock.)
*/
public CommonGUI(ChallengesAddon addon,
World world,
User user,
String topLabel,
String permissionPrefix)
{
this(addon, world, user, topLabel, permissionPrefix, null);
}
/**
* Default constructor that inits panels with minimal requirements.
*
* @param addon Addon where panel operates.
* @param world World from which panel was created.
* @param user User who created panel.
* @param topLabel Command top label which creates panel (f.e. island or ai)
* @param permissionPrefix Command permission prefix (f.e. bskyblock.)
* @param parentGUI Parent panel for current panel.
*/
public CommonGUI(ChallengesAddon addon,
World world,
User user,
String topLabel,
String permissionPrefix,
CommonGUI parentGUI)
{
this.addon = addon;
this.world = world;
this.user = user;
this.topLabel = topLabel;
this.permissionPrefix = permissionPrefix;
this.parentGUI = parentGUI;
this.pageIndex = 0;
this.returnButton = new PanelItemBuilder().
name(this.user.getTranslation("challenges.gui.buttons.back")).
icon(Material.OAK_DOOR).
clickHandler((panel, user1, clickType, i) -> {
if (this.parentGUI == null)
{
this.user.closeInventory();
return true;
}
this.parentGUI.build();
return true;
}).build();
}
// ---------------------------------------------------------------------
// Section: Common methods
// ---------------------------------------------------------------------
/**
* This method builds all necessary elements in GUI panel.
*/
public abstract void build();
/**
* This method returns PanelItem that represents given Button.
* @param button Button that must be returned.
* @return PanelItem with requested functionality.
*/
protected PanelItem getButton(CommonButtons button)
{
ItemStack icon;
String name;
List<String> description;
PanelItem.ClickHandler clickHandler;
switch (button)
{
case NEXT:
{
name = this.user.getTranslation("challenges.gui.buttons.next");
description = Collections.emptyList();
icon = new ItemStack(Material.SIGN);
clickHandler = (panel, user, clickType, slot) -> {
this.pageIndex++;
this.build();
return true;
};
break;
}
case PREVIOUS:
{
name = this.user.getTranslation("challenges.gui.buttons.previous");
description = Collections.emptyList();
icon = new ItemStack(Material.SIGN);
clickHandler = (panel, user, clickType, slot) -> {
this.pageIndex--;
this.build();
return true;
};
break;
}
case RETURN:
return this.returnButton;
default:
return null;
}
return new PanelItem(icon, name, description, false, clickHandler, false);
}
/**
* This method sets new value to ValueObject variable.
* @param value new Value of valueObject.
*/
public void setValue(Object value)
{
this.valueObject = value;
}
}

View File

@ -7,6 +7,11 @@ import world.bentobox.challenges.ChallengesAddon;
import world.bentobox.bentobox.api.panels.PanelListener;
import world.bentobox.bentobox.api.user.User;
/**
* @deprecated All panels are reworked.
*/
@Deprecated
public class CreateChallengeListener implements PanelListener {
private ChallengesAddon addon;
@ -24,7 +29,7 @@ public class CreateChallengeListener implements PanelListener {
@Override
public void onInventoryClose(InventoryCloseEvent event) {
addon.getChallengesManager().createInvChallenge(user, event.getInventory());
addon.getChallengesManager().createChallenge("uniqueID");
}
@Override

View File

@ -4,6 +4,11 @@ import world.bentobox.challenges.ChallengesAddon;
import world.bentobox.bentobox.api.panels.builders.PanelBuilder;
import world.bentobox.bentobox.api.user.User;
/**
* @deprecated All panels are reworked.
*/
@Deprecated
public class CreateChallengePanel {
public CreateChallengePanel(ChallengesAddon addon, User user) {

View File

@ -12,7 +12,7 @@ import org.bukkit.event.inventory.InventoryClickEvent;
import org.bukkit.event.inventory.InventoryCloseEvent;
import org.bukkit.inventory.ItemStack;
import world.bentobox.challenges.database.object.Challenges;
import world.bentobox.challenges.database.object.Challenge;
import world.bentobox.bentobox.api.panels.Panel;
import world.bentobox.bentobox.api.panels.PanelItem.ClickHandler;
import world.bentobox.bentobox.api.panels.PanelListener;
@ -25,11 +25,12 @@ import world.bentobox.bentobox.util.Util;
* Handles the requirements for a challenge
* Items, blocks, entities
* @author tastybento
*
* @deprecated All panels are reworked.
*/
@Deprecated
public class RequiredPanel implements ClickHandler, PanelListener {
private static final int CONTROL_NUMBER = 4;
private Challenges challenge;
private Challenge challenge;
private User user;
private Panel panel;
private Panel referringPanel;
@ -38,7 +39,7 @@ public class RequiredPanel implements ClickHandler, PanelListener {
* @param challenge
* @param user
*/
public RequiredPanel(Challenges challenge, User user, Panel referringPanel) {
public RequiredPanel(Challenge challenge, User user, Panel referringPanel) {
this.challenge = challenge;
this.user = user;
this.panel = openPanel();
@ -72,7 +73,7 @@ public class RequiredPanel implements ClickHandler, PanelListener {
.clickHandler(this)
.build()).forEach(pb::item);
return pb.user(user).build();
case LEVEL:
case OTHER:
break;
default:
@ -136,8 +137,6 @@ public class RequiredPanel implements ClickHandler, PanelListener {
}
// Save changes
switch (challenge.getChallengeType()) {
case ICON:
break;
case INVENTORY:
List<ItemStack> reqItems = new ArrayList<>();
// Skip first item
@ -153,7 +152,7 @@ public class RequiredPanel implements ClickHandler, PanelListener {
break;
case ISLAND:
break;
case LEVEL:
case OTHER:
break;
default:
break;

View File

@ -0,0 +1,414 @@
package world.bentobox.challenges.panel.admin;
import org.bukkit.Material;
import org.bukkit.World;
import org.bukkit.inventory.ItemStack;
import java.util.Collections;
import java.util.List;
import net.wesjd.anvilgui.AnvilGUI;
import world.bentobox.bentobox.api.panels.PanelItem;
import world.bentobox.bentobox.api.panels.builders.PanelBuilder;
import world.bentobox.bentobox.api.user.User;
import world.bentobox.bentobox.util.Util;
import world.bentobox.challenges.ChallengesAddon;
import world.bentobox.challenges.panel.CommonGUI;
import world.bentobox.challenges.utils.GuiUtils;
/**
* This class contains Main
*/
public class AdminGUI extends CommonGUI
{
// ---------------------------------------------------------------------
// Section: Variables
// ---------------------------------------------------------------------
/**
* This boolean holds if import should overwrite existing challenges.
*/
private boolean overwriteMode;
/**
* This indicate if Reset Challenges must work as reset all.
*/
private boolean resetAllMode;
// ---------------------------------------------------------------------
// Section: Enums
// ---------------------------------------------------------------------
/**
* This enum contains all button variations. Just for cleaner code.
*/
private enum Button
{
COMPLETE_USER_CHALLENGES,
RESET_USER_CHALLENGES,
ADD_CHALLENGE,
ADD_LEVEL,
EDIT_CHALLENGE,
EDIT_LEVEL,
DELETE_CHALLENGE,
DELETE_LEVEL,
IMPORT_CHALLENGES,
EDIT_SETTINGS
}
// ---------------------------------------------------------------------
// Section: Constructor
// ---------------------------------------------------------------------
/**
* {@inheritDoc}
*/
public AdminGUI(ChallengesAddon addon,
World world,
User user,
String topLabel,
String permissionPrefix)
{
super(addon, world, user, topLabel, permissionPrefix);
}
// ---------------------------------------------------------------------
// Section: Methods
// ---------------------------------------------------------------------
/**
* {@inheritDoc}
*/
public void build()
{
PanelBuilder panelBuilder = new PanelBuilder().user(this.user).name(
this.user.getTranslation("challenges.admin.gui-title"));
GuiUtils.fillBorder(panelBuilder);
panelBuilder.item(10, this.createButton(Button.COMPLETE_USER_CHALLENGES));
panelBuilder.item(19, this.createButton(Button.RESET_USER_CHALLENGES));
// Add Challenges
panelBuilder.item(12, this.createButton(Button.ADD_CHALLENGE));
panelBuilder.item(13, this.createButton(Button.ADD_LEVEL));
// Edit Challenges
panelBuilder.item(21, this.createButton(Button.EDIT_CHALLENGE));
panelBuilder.item(22, this.createButton(Button.EDIT_LEVEL));
// Remove Challenges
panelBuilder.item(30, this.createButton(Button.DELETE_CHALLENGE));
panelBuilder.item(31, this.createButton(Button.DELETE_LEVEL));
// Import Challenges
panelBuilder.item(15, this.createButton(Button.IMPORT_CHALLENGES));
// Edit Addon Settings
panelBuilder.item(16, this.createButton(Button.EDIT_SETTINGS));
panelBuilder.item(44, this.returnButton);
panelBuilder.build();
}
/**
* This method is used to create PanelItem for each button type.
* @param button Button which must be created.
* @return PanelItem with necessary functionality.
*/
private PanelItem createButton(Button button)
{
ItemStack icon;
String name;
List<String> description;
boolean glow;
PanelItem.ClickHandler clickHandler;
String permissionSuffix;
switch (button)
{
case COMPLETE_USER_CHALLENGES:
permissionSuffix = COMPLETE;
name = this.user.getTranslation("challenges.gui.admin.buttons.complete");
description = Collections.emptyList();
icon = new ItemStack(Material.WRITTEN_BOOK);
clickHandler = (panel, user, clickType, slot) -> {
new ListUsersGUI(this.addon,
this.world,
this.user,
ListUsersGUI.Mode.COMPLETE,
this.topLabel,
this.permissionPrefix,
this).build();
return true;
};
glow = false;
break;
case RESET_USER_CHALLENGES:
permissionSuffix = RESET;
name = this.user.getTranslation("challenges.gui.admin.buttons.reset");
description = Collections.emptyList();
icon = new ItemStack(Material.WRITABLE_BOOK);
glow = this.resetAllMode;
clickHandler = (panel, user, clickType, slot) -> {
if (clickType.isRightClick())
{
this.resetAllMode = !this.resetAllMode;
this.build();
}
else
{
new ListUsersGUI(this.addon,
this.world,
this.user,
this.resetAllMode ? ListUsersGUI.Mode.RESET_ALL : ListUsersGUI.Mode.RESET,
this.topLabel,
this.permissionPrefix,
this).build();
}
return true;
};
break;
case ADD_CHALLENGE:
permissionSuffix = ADD;
name = this.user.getTranslation("challenges.gui.admin.buttons.add-challenge");
description = Collections.emptyList();
icon = new ItemStack(Material.BOOK);
clickHandler = (panel, user, clickType, slot) -> {
new AnvilGUI(this.addon.getPlugin(),
this.user.getPlayer(),
"unique_id",
(player, reply) -> {
String newName = Util.getWorld(this.world).getName() + "_" + reply;
if (!this.addon.getChallengesManager().containsChallenge(newName))
{
new EditChallengeGUI(this.addon,
this.world,
this.user,
this.addon.getChallengesManager().createChallenge(newName),
this.topLabel,
this.permissionPrefix,
this).build();
}
else
{
this.user.sendMessage("challenges.errors.unique-id", "[id]", reply);
}
return reply;
});
return true;
};
glow = false;
break;
case ADD_LEVEL:
permissionSuffix = ADD;
name = this.user.getTranslation("challenges.gui.admin.buttons.add-level");
description = Collections.emptyList();
icon = new ItemStack(Material.BOOK);
clickHandler = (panel, user, clickType, slot) -> {
new AnvilGUI(this.addon.getPlugin(),
this.user.getPlayer(),
"unique_id",
(player, reply) -> {
String newName = Util.getWorld(this.world).getName() + "_" + reply;
if (!this.addon.getChallengesManager().containsLevel(newName))
{
new EditLevelGUI(this.addon,
this.world,
this.user,
this.addon.getChallengesManager().createLevel(newName),
this.topLabel,
this.permissionPrefix,
this).build();
}
else
{
this.user.sendMessage("challenges.errors.unique-id", "[id]", reply);
}
return reply;
});
return true;
};
glow = false;
break;
case EDIT_CHALLENGE:
permissionSuffix = EDIT;
name = this.user.getTranslation("challenges.gui.admin.buttons.edit-challenge");
description = Collections.emptyList();
icon = new ItemStack(Material.ANVIL);
clickHandler = (panel, user, clickType, slot) -> {
new ListChallengesGUI(this.addon,
this.world,
this.user,
ListChallengesGUI.Mode.EDIT,
this.topLabel,
this.permissionPrefix,
this).build();
return true;
};
glow = false;
break;
case EDIT_LEVEL:
{
permissionSuffix = EDIT;
name = this.user.getTranslation("challenges.gui.admin.buttons.edit-level");
description = Collections.emptyList();
icon = new ItemStack(Material.ANVIL);
clickHandler = (panel, user, clickType, slot) -> {
new ListLevelsGUI(this.addon,
this.world,
this.user,
ListLevelsGUI.Mode.EDIT,
this.topLabel,
this.permissionPrefix,
this).build();
return true;
};
glow = false;
break;
}
case DELETE_CHALLENGE:
{
permissionSuffix = DELETE;
name = this.user.getTranslation("challenges.gui.admin.buttons.delete-challenge");
description = Collections.emptyList();
icon = new ItemStack(Material.LAVA_BUCKET);
clickHandler = (panel, user, clickType, slot) -> {
new ListChallengesGUI(this.addon,
this.world,
this.user,
ListChallengesGUI.Mode.DELETE,
this.topLabel,
this.permissionPrefix,
this).build();
return true;
};
glow = false;
break;
}
case DELETE_LEVEL:
{
permissionSuffix = DELETE;
name = this.user.getTranslation("challenges.gui.admin.buttons.delete-level");
description = Collections.emptyList();
icon = new ItemStack(Material.LAVA_BUCKET);
clickHandler = (panel, user, clickType, slot) -> {
new ListLevelsGUI(this.addon,
this.world,
this.user,
ListLevelsGUI.Mode.DELETE,
this.topLabel,
this.permissionPrefix,
this).build();
return true;
};
glow = false;
break;
}
case IMPORT_CHALLENGES:
{
permissionSuffix = IMPORT;
name = this.user.getTranslation("challenges.gui.admin.buttons.import");
description = Collections.emptyList();
icon = new ItemStack(Material.HOPPER);
clickHandler = (panel, user, clickType, slot) -> {
if (clickType.isRightClick())
{
this.overwriteMode = !this.overwriteMode;
this.build();
}
else
{
// Run import command.
this.user.performCommand(this.topLabel + " " + CHALLENGES + " " + IMPORT +
(this.overwriteMode ? " overwrite" : ""));
}
return true;
};
glow = this.overwriteMode;
break;
}
case EDIT_SETTINGS:
{
permissionSuffix = SETTINGS;
name = this.user.getTranslation("challenges.gui.admin.buttons.settings");
description = Collections.emptyList();
icon = new ItemStack(Material.CRAFTING_TABLE);
clickHandler = (panel, user, clickType, slot) -> {
new EditSettingsGUI(this.addon,
this.world,
this.user,
this.topLabel,
this.permissionPrefix,
this).build();
return true;
};
glow = false;
break;
}
default:
// This should never happen.
return null;
}
// If user does not have permission to run command, then change icon and clickHandler.
final String actionPermission = this.permissionPrefix + ADMIN + "." + CHALLENGES + "." + permissionSuffix;
if (!this.user.hasPermission(actionPermission))
{
icon = new ItemStack(Material.BARRIER);
clickHandler = (panel, user, clickType, slot) -> {
this.user.sendMessage("general.errors.no-permission", "[permission]", actionPermission);
return true;
};
}
return new PanelItem(icon, name, description, glow, clickHandler, false);
}
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,648 @@
package world.bentobox.challenges.panel.admin;
import org.bukkit.Material;
import org.bukkit.World;
import org.bukkit.inventory.ItemStack;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import net.wesjd.anvilgui.AnvilGUI;
import world.bentobox.bentobox.api.panels.PanelItem;
import world.bentobox.bentobox.api.panels.builders.PanelBuilder;
import world.bentobox.bentobox.api.panels.builders.PanelItemBuilder;
import world.bentobox.bentobox.api.user.User;
import world.bentobox.challenges.ChallengesAddon;
import world.bentobox.challenges.ChallengesManager;
import world.bentobox.challenges.database.object.Challenge;
import world.bentobox.challenges.database.object.ChallengeLevel;
import world.bentobox.challenges.panel.CommonGUI;
import world.bentobox.challenges.panel.util.ItemSwitchGUI;
import world.bentobox.challenges.panel.util.NumberGUI;
import world.bentobox.challenges.panel.util.SelectChallengeGUI;
import world.bentobox.challenges.panel.util.StringListGUI;
import world.bentobox.challenges.utils.GuiUtils;
/**
* This class contains all necessary elements to create Levels Edit GUI.
*/
public class EditLevelGUI extends CommonGUI
{
// ---------------------------------------------------------------------
// Section: Constructors
// ---------------------------------------------------------------------
/**
* {@inheritDoc}
* @param challengeLevel ChallengeLevel that must be edited.
*/
public EditLevelGUI(ChallengesAddon addon,
World world,
User user,
ChallengeLevel challengeLevel,
String topLabel,
String permissionPrefix)
{
this(addon, world, user, challengeLevel, topLabel, permissionPrefix, null);
}
/**
* {@inheritDoc}
* @param challengeLevel ChallengeLevel that must be edited.
*/
public EditLevelGUI(ChallengesAddon addon,
World world,
User user,
ChallengeLevel challengeLevel,
String topLabel,
String permissionPrefix,
CommonGUI parentGUI)
{
super(addon, world, user, topLabel, permissionPrefix, parentGUI);
this.challengeLevel = challengeLevel;
this.currentMenuType = MenuType.PROPERTIES;
}
// ---------------------------------------------------------------------
// Section: Methods
// ---------------------------------------------------------------------
/**
* This method builds all necessary elements in GUI panel.
*/
@Override
public void build()
{
PanelBuilder panelBuilder = new PanelBuilder().user(this.user).name(
this.user.getTranslation("challenges.gui.admin.edit-level-title"));
GuiUtils.fillBorder(panelBuilder);
panelBuilder.item(2, this.createMenuButton(MenuType.PROPERTIES));
panelBuilder.item(4, this.createMenuButton(MenuType.REWARDS));
panelBuilder.item(6, this.createMenuButton(MenuType.CHALLENGES));
if (this.currentMenuType.equals(MenuType.PROPERTIES))
{
this.buildMainPropertiesPanel(panelBuilder);
}
else if (this.currentMenuType.equals(MenuType.CHALLENGES))
{
this.buildChallengesPanel(panelBuilder);
}
else if (this.currentMenuType.equals(MenuType.REWARDS))
{
this.buildRewardsPanel(panelBuilder);
}
panelBuilder.item(44, this.returnButton);
panelBuilder.build();
}
/**
* This class populate LevelsEditGUI with main level settings.
* @param panelBuilder PanelBuilder where icons must be added.
*/
private void buildMainPropertiesPanel(PanelBuilder panelBuilder)
{
panelBuilder.item(10, this.createButton(Button.NAME));
panelBuilder.item(19, this.createButton(Button.ICON));
panelBuilder.item(22, this.createButton(Button.UNLOCK_MESSAGE));
panelBuilder.item(25, this.createButton(Button.ORDER));
panelBuilder.item(31, this.createButton(Button.WAIVER_AMOUNT));
}
/**
* This class populate LevelsEditGUI with level rewards.
* @param panelBuilder PanelBuilder where icons must be added.
*/
private void buildRewardsPanel(PanelBuilder panelBuilder)
{
panelBuilder.item(12, this.createButton(Button.REWARD_DESCRIPTION));
panelBuilder.item(21, this.createButton(Button.REWARD_COMMANDS));
panelBuilder.item(13, this.createButton(Button.REWARD_ITEM));
panelBuilder.item(22, this.createButton(Button.REWARD_EXPERIENCE));
panelBuilder.item(31, this.createButton(Button.REWARD_MONEY));
}
/**
* This class populate LevelsEditGUI with level challenges.
* @param panelBuilder PanelBuilder where icons must be added.
*/
private void buildChallengesPanel(PanelBuilder panelBuilder)
{
List<Challenge> challengeList = this.addon.getChallengesManager().getLevelChallenges(this.challengeLevel);
final int MAX_ELEMENTS = 21;
if (this.pageIndex < 0)
{
this.pageIndex = challengeList.size() / MAX_ELEMENTS;
}
else if (this.pageIndex > (challengeList.size() / MAX_ELEMENTS))
{
this.pageIndex = 0;
}
int challengeIndex = MAX_ELEMENTS * this.pageIndex;
// I want first row to be only for navigation and return button.
int index = 10;
while (challengeIndex < ((this.pageIndex + 1) * MAX_ELEMENTS) &&
challengeIndex < challengeList.size() &&
index < 36)
{
if (!panelBuilder.slotOccupied(index))
{
panelBuilder.item(index, this.createChallengeIcon(challengeList.get(challengeIndex++)));
}
index++;
}
// Navigation buttons only if necessary
if (challengeList.size() > MAX_ELEMENTS)
{
panelBuilder.item(18, this.getButton(CommonButtons.PREVIOUS));
panelBuilder.item(26, this.getButton(CommonButtons.NEXT));
}
panelBuilder.item(39, this.createButton(Button.ADD_CHALLENGE));
panelBuilder.item(41, this.createButton(Button.REMOVE_CHALLENGE));
}
// ---------------------------------------------------------------------
// Section: Other methods
// ---------------------------------------------------------------------
/**
* This method creates top menu buttons, that allows to switch "tabs".
* @param menuType Menu Type which button must be constructed.
* @return PanelItem that represents given menu type.
*/
private PanelItem createMenuButton(MenuType menuType)
{
ItemStack icon;
String name;
List<String> description;
boolean glow;
PanelItem.ClickHandler clickHandler;
switch (menuType)
{
case PROPERTIES:
{
name = this.user.getTranslation("challenges.gui.admin.buttons.properties");
description = Collections.emptyList();
icon = new ItemStack(Material.CRAFTING_TABLE);
clickHandler = (panel, user, clickType, slot) -> {
this.currentMenuType = MenuType.PROPERTIES;
this.build();
return true;
};
glow = this.currentMenuType.equals(MenuType.PROPERTIES);
break;
}
case CHALLENGES:
{
name = this.user.getTranslation("challenges.gui.admin.buttons.challenges");
description = Collections.emptyList();
icon = new ItemStack(Material.RAIL);
clickHandler = (panel, user, clickType, slot) -> {
this.currentMenuType = MenuType.CHALLENGES;
this.build();
return true;
};
glow = this.currentMenuType.equals(MenuType.CHALLENGES);
break;
}
case REWARDS:
{
name = this.user.getTranslation("challenges.gui.admin.buttons.rewards");
description = Collections.emptyList();
icon = new ItemStack(Material.DROPPER);
clickHandler = (panel, user, clickType, slot) -> {
this.currentMenuType = MenuType.REWARDS;
this.build();
return true;
};
glow = this.currentMenuType.equals(MenuType.REWARDS);
break;
}
default:
return null;
}
return new PanelItem(icon, name, GuiUtils.stringSplit(description), glow, clickHandler, false);
}
/**
* This method creates given challenge icon. On click it should open Edit Challenge GUI.
* @param challenge Challenge which icon must be created.
* @return PanelItem that represents given challenge.
*/
private PanelItem createChallengeIcon(Challenge challenge)
{
return new PanelItemBuilder().
name(challenge.getFriendlyName()).
description(GuiUtils.stringSplit(challenge.getDescription())).
icon(challenge.getIcon()).
clickHandler((panel, user1, clickType, slot) -> {
// Open challenges edit screen.
new EditChallengeGUI(this.addon,
this.world,
this.user,
challenge,
this.topLabel,
this.permissionPrefix,
this).build();
return true;
}).
glow(!challenge.isDeployed()).
build();
}
/**
* This method creates buttons for default main menu.
* @param button Button which panel item must be created.
* @return PanelItem that represents given button.
*/
private PanelItem createButton(Button button)
{
ItemStack icon;
String name;
List<String> description;
boolean glow;
PanelItem.ClickHandler clickHandler;
switch (button)
{
case NAME:
{
name = this.user.getTranslation("challenges.gui.admin.buttons.name");
description = Collections.singletonList(this.challengeLevel.getFriendlyName());
icon = new ItemStack(Material.DROPPER);
clickHandler = (panel, user, clickType, slot) -> {
new AnvilGUI(this.addon.getPlugin(),
this.user.getPlayer(),
this.challengeLevel.getFriendlyName(),
(player, reply) -> {
this.challengeLevel.setFriendlyName(reply);
this.build();
return reply;
});
return true;
};
glow = false;
break;
}
case ICON:
{
name = this.user.getTranslation("challenges.gui.admin.buttons.icon");
description = Collections.emptyList();
icon = this.challengeLevel.getIcon();
clickHandler = (panel, user, clickType, slot) -> {
new AnvilGUI(this.addon.getPlugin(),
this.user.getPlayer(),
this.challengeLevel.getIcon().getType().name(),
(player, reply) -> {
Material material = Material.getMaterial(reply);
if (material != null)
{
this.challengeLevel.setIcon(new ItemStack(material));
this.build();
}
else
{
this.user.sendMessage("challenges.errors.wrong-icon", "[value]", reply);
}
return reply;
});
return true;
};
glow = false;
break;
}
case UNLOCK_MESSAGE:
{
name = this.user.getTranslation("challenges.gui.admin.buttons.description");
description = Collections.singletonList(this.challengeLevel.getUnlockMessage());
icon = new ItemStack(Material.WRITABLE_BOOK);
clickHandler = (panel, user, clickType, slot) -> {
new AnvilGUI(this.addon.getPlugin(),
this.user.getPlayer(),
this.challengeLevel.getUnlockMessage(),
(player, reply) -> {
this.challengeLevel.setUnlockMessage(reply);
this.build();
return reply;
});
return true;
};
glow = false;
break;
}
case ORDER:
{
name = this.user.getTranslation("challenges.gui.admin.buttons.order");
description = Collections.singletonList(
this.user.getTranslation("challenges.gui.admin.descriptions.order",
"[value]",
Integer.toString(this.challengeLevel.getOrder())));
icon = new ItemStack(Material.DROPPER);
clickHandler = (panel, user, clickType, slot) -> {
new NumberGUI(this.user, this.challengeLevel.getOrder(), -1, 54, (status, value) -> {
if (status)
{
this.challengeLevel.setOrder(value);
}
this.build();
});
return true;
};
glow = false;
break;
}
case WAIVER_AMOUNT:
{
name = this.user.getTranslation("challenges.gui.admin.buttons.waiver-amount");
description = Collections.singletonList(
this.user.getTranslation("challenges.gui.admin.descriptions.waiver-amount",
"[value]",
Integer.toString(this.challengeLevel.getWaiverAmount())));
icon = new ItemStack(Material.REDSTONE_TORCH);
clickHandler = (panel, user, clickType, slot) -> {
new NumberGUI(this.user, this.challengeLevel.getWaiverAmount(), 0, (status, value) -> {
if (status)
{
this.challengeLevel.setWaiverAmount(value);
}
this.build();
});
return true;
};
glow = false;
break;
}
case REWARD_DESCRIPTION:
{
name = this.user.getTranslation("challenges.gui.admin.buttons.reward-text");
description = Collections.singletonList(this.challengeLevel.getRewardText());
icon = new ItemStack(Material.WRITTEN_BOOK);
clickHandler = (panel, user, clickType, slot) -> {
new AnvilGUI(this.addon.getPlugin(),
this.user.getPlayer(),
this.challengeLevel.getRewardText(),
(player, reply) -> {
this.challengeLevel.setRewardText(reply);
this.build();
return reply;
});
return true;
};
glow = false;
break;
}
case REWARD_ITEM:
{
List<String> values = new ArrayList<>(this.challengeLevel.getRewardItems().size());
for (ItemStack itemStack : this.challengeLevel.getRewardItems())
{
values.add(itemStack.getType().name() + " " + itemStack.getAmount());
}
name = this.user.getTranslation("challenges.gui.admin.buttons.reward-items");
description = values;
icon = new ItemStack(Material.CHEST);
clickHandler = (panel, user, clickType, slot) -> {
new ItemSwitchGUI(this.user, this.challengeLevel.getRewardItems(), (status, value) -> {
if (status)
{
this.challengeLevel.setRewardItems(value);
}
this.build();
});
return true;
};
glow = false;
break;
}
case REWARD_EXPERIENCE:
{
name = this.user.getTranslation("challenges.gui.admin.buttons.reward-exp");
description = Collections.singletonList(
this.user.getTranslation("challenges.gui.admin.descriptions.reward-exp",
"[value]",
Integer.toString(this.challengeLevel.getRewardExperience())));
icon = new ItemStack(Material.EXPERIENCE_BOTTLE);
clickHandler = (panel, user, clickType, slot) -> {
new NumberGUI(this.user, this.challengeLevel.getRewardExperience(), 0, (status, value) -> {
if (status)
{
this.challengeLevel.setRewardExperience(value);
}
this.build();
});
return true;
};
glow = false;
break;
}
case REWARD_MONEY:
{
name = this.user.getTranslation("challenges.gui.admin.buttons.reward-money");
description = Collections.singletonList(
this.user.getTranslation("challenges.gui.admin.descriptions.reward-money",
"[value]",
Integer.toString(this.challengeLevel.getRewardMoney())));
if (this.addon.isEconomyProvided())
{
icon = new ItemStack(Material.GOLD_INGOT);
clickHandler = (panel, user, clickType, slot) -> {
new NumberGUI(this.user, this.challengeLevel.getRewardMoney(), 0, (status, value) -> {
if (status)
{
this.challengeLevel.setRewardMoney(value);
}
this.build();
});
return true;
};
}
else
{
icon = new ItemStack(Material.BARRIER);
clickHandler = null;
}
glow = false;
break;
}
case REWARD_COMMANDS:
{
name = this.user.getTranslation("challenges.gui.admin.buttons.reward-command");
description = this.challengeLevel.getRewardCommands();
icon = new ItemStack(Material.COMMAND_BLOCK);
clickHandler = (panel, user, clickType, slot) -> {
new StringListGUI(this.user, this.challengeLevel.getRewardCommands(), (status, value) -> {
if (status)
{
this.challengeLevel.setRewardCommands(value);
}
this.build();
});
return true;
};
glow = false;
break;
}
case ADD_CHALLENGE:
{
name = this.user.getTranslation("challenges.gui.admin.buttons.add-challenge");
description = Collections.emptyList();
icon = new ItemStack(Material.WATER_BUCKET);
clickHandler = (panel, user, clickType, slot) -> {
ChallengesManager manager = this.addon.getChallengesManager();
// Get all challenge that is not in current challenge.
List<Challenge> challengeList = manager.getAllChallenges(this.world);
challengeList.removeAll(manager.getLevelChallenges(this.challengeLevel));
new SelectChallengeGUI(this.user, challengeList, (status, value) -> {
if (status)
{
manager.addChallengeToLevel(value, this.challengeLevel);
}
this.build();
});
return true;
};
glow = false;
break;
}
case REMOVE_CHALLENGE:
{
name = this.user.getTranslation("challenges.gui.admin.buttons.remove-challenge");
description = Collections.emptyList();
icon = new ItemStack(Material.LAVA_BUCKET);
clickHandler = (panel, user, clickType, slot) -> {
ChallengesManager manager = this.addon.getChallengesManager();
new SelectChallengeGUI(this.user, manager.getLevelChallenges(this.challengeLevel), (status, value) -> {
if (status)
{
manager.removeChallengeFromLevel(value, this.challengeLevel);
}
this.build();
});
return true;
};
glow = false;
break;
}
default:
return null;
}
return new PanelItem(icon, name, GuiUtils.stringSplit(description), glow, clickHandler, false);
}
// ---------------------------------------------------------------------
// Section: Enums
// ---------------------------------------------------------------------
/**
* Represents different buttons that could be in menus.
*/
private enum Button
{
NAME,
ICON,
UNLOCK_MESSAGE,
ORDER,
WAIVER_AMOUNT,
REWARD_DESCRIPTION,
REWARD_ITEM,
REWARD_EXPERIENCE,
REWARD_MONEY,
REWARD_COMMANDS,
ADD_CHALLENGE,
REMOVE_CHALLENGE
}
/**
* Represents different types of menus
*/
private enum MenuType
{
PROPERTIES,
CHALLENGES,
REWARDS
}
// ---------------------------------------------------------------------
// Section: Variables
// ---------------------------------------------------------------------
/**
* This variable holds current challenge level that is in editing GUI.
*/
private ChallengeLevel challengeLevel;
/**
* Variable holds current active menu.
*/
private MenuType currentMenuType;
}

View File

@ -0,0 +1,141 @@
package world.bentobox.challenges.panel.admin;
import org.bukkit.Material;
import org.bukkit.World;
import world.bentobox.bentobox.api.panels.builders.PanelBuilder;
import world.bentobox.bentobox.api.panels.builders.PanelItemBuilder;
import world.bentobox.bentobox.api.user.User;
import world.bentobox.challenges.ChallengesAddon;
import world.bentobox.challenges.panel.CommonGUI;
import world.bentobox.challenges.utils.GuiUtils;
/**
* This Class creates GUI that allows to change Challenges Addon Settings via in-game
* menu.
*/
public class EditSettingsGUI extends CommonGUI
{
// ---------------------------------------------------------------------
// Section: Constructors
// ---------------------------------------------------------------------
/**
* {@inheritDoc}
*/
public EditSettingsGUI(ChallengesAddon addon,
World world,
User user,
String topLabel,
String permissionPrefix)
{
this(addon, world, user, topLabel, permissionPrefix, null);
}
/**
* {@inheritDoc}
*/
public EditSettingsGUI(ChallengesAddon addon,
World world,
User user,
String topLabel,
String permissionPrefix,
CommonGUI parentGUI)
{
super(addon, world, user, topLabel, permissionPrefix, parentGUI);
}
// ---------------------------------------------------------------------
// Section: Methods
// ---------------------------------------------------------------------
@Override
public void build()
{
PanelBuilder panelBuilder = new PanelBuilder().user(this.user).name(
this.user.getTranslation("challenges.gui.admin.settings-title"));
GuiUtils.fillBorder(panelBuilder);
// resetChallenges
panelBuilder.item(19, new PanelItemBuilder().
name(this.user.getTranslation("challenges.gui.admin.buttons.reset")).
description(GuiUtils.stringSplit(this.user.getTranslation("challenges.gui.admin.descriptions.reset"))).
icon(Material.LAVA_BUCKET).
clickHandler((panel, user1, clickType, i) -> {
this.addon.getChallengesSettings().setResetChallenges(
!this.addon.getChallengesSettings().isResetChallenges());
this.build();
return true;
}).
glow(this.addon.getChallengesSettings().isResetChallenges()).
build());
// broadcastMessages
panelBuilder.item(20, new PanelItemBuilder().
name(this.user.getTranslation("challenges.gui.admin.buttons.broadcast")).
description(GuiUtils.stringSplit(this.user.getTranslation("challenges.gui.admin.descriptions.broadcast"))).
icon(Material.JUKEBOX).
clickHandler((panel, user1, clickType, i) -> {
this.addon.getChallengesSettings().setBroadcastMessages(
!this.addon.getChallengesSettings().isBroadcastMessages());
this.build();
return true;
}).
glow(this.addon.getChallengesSettings().isBroadcastMessages()).
build());
// removeCompleteOneTimeChallenges
panelBuilder.item(21, new PanelItemBuilder().
name(this.user.getTranslation("challenges.gui.admin.buttons.remove-on-complete")).
description(GuiUtils.stringSplit(this.user.getTranslation("challenges.gui.admin.descriptions.remove-on-complete"))).
icon(Material.MAGMA_BLOCK).
clickHandler((panel, user1, clickType, i) -> {
this.addon.getChallengesSettings().setRemoveCompleteOneTimeChallenges(
!this.addon.getChallengesSettings().isRemoveCompleteOneTimeChallenges());
this.build();
return true;
}).
glow(this.addon.getChallengesSettings().isRemoveCompleteOneTimeChallenges()).
build());
// addCompletedGlow
panelBuilder.item(22, new PanelItemBuilder().
name(this.user.getTranslation("challenges.gui.admin.buttons.glow")).
description(GuiUtils.stringSplit(this.user.getTranslation("challenges.gui.admin.descriptions.glow"))).
icon(Material.GLOWSTONE).
clickHandler((panel, user1, clickType, i) -> {
this.addon.getChallengesSettings().setAddCompletedGlow(
!this.addon.getChallengesSettings().isAddCompletedGlow());
this.build();
return true;
}).
glow(this.addon.getChallengesSettings().isAddCompletedGlow()).
build());
// freeChallengesAtTheTop
panelBuilder.item(23, new PanelItemBuilder().
name(this.user.getTranslation("challenges.gui.admin.buttons.free-challenges")).
description(GuiUtils.stringSplit(this.user.getTranslation("challenges.gui.admin.descriptions.free-challenges"))).
icon(Material.FILLED_MAP).
clickHandler((panel, user1, clickType, i) -> {
this.addon.getChallengesSettings().setFreeChallengesFirst(
!this.addon.getChallengesSettings().isFreeChallengesFirst());
this.build();
return true;
}).
glow(this.addon.getChallengesSettings().isFreeChallengesFirst()).
build());
// Return Button
panelBuilder.item(44, this.returnButton);
panelBuilder.build();
}
}

View File

@ -0,0 +1,194 @@
package world.bentobox.challenges.panel.admin;
import org.bukkit.Material;
import org.bukkit.World;
import java.util.List;
import world.bentobox.bentobox.api.panels.PanelItem;
import world.bentobox.bentobox.api.panels.builders.PanelBuilder;
import world.bentobox.bentobox.api.panels.builders.PanelItemBuilder;
import world.bentobox.bentobox.api.user.User;
import world.bentobox.challenges.ChallengesAddon;
import world.bentobox.challenges.database.object.Challenge;
import world.bentobox.challenges.panel.CommonGUI;
import world.bentobox.challenges.panel.util.ConfirmationGUI;
import world.bentobox.challenges.utils.GuiUtils;
/**
* This class contains all necessary elements to create GUI that lists all challenges.
* It allows to edit them or remove, depending on given input mode.
*/
public class ListChallengesGUI extends CommonGUI
{
// ---------------------------------------------------------------------
// Section: Constructor
// ---------------------------------------------------------------------
/**
* {@inheritDoc}
* @param mode - mode that indicate what should do icon clicking.
*/
public ListChallengesGUI(ChallengesAddon addon,
World world,
User user,
Mode mode,
String topLabel,
String permissionPrefix)
{
this(addon, world, user, mode, topLabel, permissionPrefix, null);
}
/**
* {@inheritDoc}
* @param mode - mode that indicate what should do icon clicking.
*/
public ListChallengesGUI(ChallengesAddon addon,
World world,
User user,
Mode mode,
String topLabel,
String permissionPrefix,
CommonGUI parentGUI)
{
super(addon, world, user, topLabel, permissionPrefix, parentGUI);
this.currentMode = mode;
}
// ---------------------------------------------------------------------
// Section: Methods
// ---------------------------------------------------------------------
/**
* {@inheritDoc}
*/
@Override
public void build()
{
PanelBuilder panelBuilder = new PanelBuilder().user(this.user).name(
this.user.getTranslation("challenges.gui.admin.choose-challenge-title"));
if (this.currentMode.equals(Mode.DELETE))
{
GuiUtils.fillBorder(panelBuilder, Material.RED_STAINED_GLASS_PANE);
}
else
{
GuiUtils.fillBorder(panelBuilder);
}
List<Challenge> challengeList = this.addon.getChallengesManager().getAllChallenges(this.world);
final int MAX_ELEMENTS = 21;
if (this.pageIndex < 0)
{
this.pageIndex = challengeList.size() / MAX_ELEMENTS;
}
else if (this.pageIndex > (challengeList.size() / MAX_ELEMENTS))
{
this.pageIndex = 0;
}
int challengeIndex = MAX_ELEMENTS * this.pageIndex;
// I want first row to be only for navigation and return button.
int index = 10;
while (challengeIndex < ((this.pageIndex + 1) * MAX_ELEMENTS) &&
challengeIndex < challengeList.size() &&
index < 36)
{
if (!panelBuilder.slotOccupied(index))
{
panelBuilder.item(index, this.createChallengeIcon(challengeList.get(challengeIndex++)));
}
index++;
}
// Navigation buttons only if necessary
if (challengeList.size() > MAX_ELEMENTS)
{
panelBuilder.item(18, this.getButton(CommonButtons.PREVIOUS));
panelBuilder.item(26, this.getButton(CommonButtons.NEXT));
}
panelBuilder.item(44, this.returnButton);
panelBuilder.build();
}
/**
* This method creates button for given challenge.
* @param challenge Challenge which button must be created.
* @return Challenge button.
*/
private PanelItem createChallengeIcon(Challenge challenge)
{
PanelItemBuilder itemBuilder = new PanelItemBuilder().
name(challenge.getFriendlyName()).
description(GuiUtils.stringSplit(challenge.getDescription())).
icon(challenge.getIcon()).
glow(challenge.isDeployed());
if (this.currentMode.equals(Mode.EDIT))
{
itemBuilder.clickHandler((panel, user1, clickType, i) -> {
new EditChallengeGUI(this.addon,
this.world,
this.user,
challenge,
this.topLabel,
this.permissionPrefix,
this).build();
return true;
});
}
else if (this.currentMode.equals(Mode.DELETE))
{
itemBuilder.clickHandler((panel, user1, clickType, i) -> {
new ConfirmationGUI(this.user, value -> {
if (value)
{
this.addon.getChallengesManager().deleteChallenge(challenge);
}
});
return true;
});
}
return itemBuilder.build();
}
// ---------------------------------------------------------------------
// Section: Enums
// ---------------------------------------------------------------------
/**
* Mode in which gui icons should processed.
*/
public enum Mode
{
EDIT,
DELETE
}
// ---------------------------------------------------------------------
// Section: Variables
// ---------------------------------------------------------------------
/**
* Current mode in which icons will act.
*/
private Mode currentMode;
}

View File

@ -0,0 +1,195 @@
package world.bentobox.challenges.panel.admin;
import org.bukkit.Material;
import org.bukkit.World;
import java.util.List;
import world.bentobox.bentobox.api.panels.PanelItem;
import world.bentobox.bentobox.api.panels.builders.PanelBuilder;
import world.bentobox.bentobox.api.panels.builders.PanelItemBuilder;
import world.bentobox.bentobox.api.user.User;
import world.bentobox.challenges.ChallengesAddon;
import world.bentobox.challenges.database.object.ChallengeLevel;
import world.bentobox.challenges.panel.CommonGUI;
import world.bentobox.challenges.panel.util.ConfirmationGUI;
import world.bentobox.challenges.utils.GuiUtils;
/**
* This class creates GUI that lists all Levels. Clicking on Level icon will be processed
* by input mode.
*/
public class ListLevelsGUI extends CommonGUI
{
// ---------------------------------------------------------------------
// Section: Constructor
// ---------------------------------------------------------------------
/**
* {@inheritDoc}
* @param mode - mode that indicate what should do icon clicking.
*/
public ListLevelsGUI(ChallengesAddon addon,
World world,
User user,
Mode mode,
String topLabel,
String permissionPrefix)
{
this(addon, world, user, mode, topLabel, permissionPrefix, null);
}
/**
* {@inheritDoc}
* @param mode - mode that indicate what should do icon clicking.
*/
public ListLevelsGUI(ChallengesAddon addon,
World world,
User user,
Mode mode,
String topLabel,
String permissionPrefix,
CommonGUI parentGUI)
{
super(addon, world, user, topLabel, permissionPrefix, parentGUI);
this.currentMode = mode;
}
// ---------------------------------------------------------------------
// Section: Methods
// ---------------------------------------------------------------------
/**
* {@inheritDoc}
*/
@Override
public void build()
{
PanelBuilder panelBuilder = new PanelBuilder().user(this.user).name(
this.user.getTranslation("challenges.gui.admin.choose-level-title"));
if (this.currentMode.equals(Mode.DELETE))
{
GuiUtils.fillBorder(panelBuilder, Material.RED_STAINED_GLASS_PANE);
}
else
{
GuiUtils.fillBorder(panelBuilder);
}
List<ChallengeLevel> levelList = this.addon.getChallengesManager().getLevels(this.world);
final int MAX_ELEMENTS = 21;
if (this.pageIndex < 0)
{
this.pageIndex = levelList.size() / MAX_ELEMENTS;
}
else if (this.pageIndex > (levelList.size() / MAX_ELEMENTS))
{
this.pageIndex = 0;
}
int levelIndex = MAX_ELEMENTS * this.pageIndex;
// I want first row to be only for navigation and return button.
int index = 10;
while (levelIndex < ((this.pageIndex + 1) * MAX_ELEMENTS) &&
levelIndex < levelList.size() &&
index < 36)
{
if (!panelBuilder.slotOccupied(index))
{
panelBuilder.item(index, this.createLevelIcon(levelList.get(levelIndex++)));
}
index++;
}
// Navigation buttons only if necessary
if (levelList.size() > MAX_ELEMENTS)
{
panelBuilder.item(18, this.getButton(CommonButtons.PREVIOUS));
panelBuilder.item(26, this.getButton(CommonButtons.NEXT));
}
panelBuilder.item(44, this.returnButton);
panelBuilder.build();
}
/**
* This method creates button for given level
* @param challengeLevel Level which button must be created.
* @return Level button.
*/
private PanelItem createLevelIcon(ChallengeLevel challengeLevel)
{
PanelItemBuilder itemBuilder = new PanelItemBuilder().
name(challengeLevel.getFriendlyName()).
description(GuiUtils.stringSplit(challengeLevel.getUnlockMessage())).
icon(challengeLevel.getIcon()).
glow(false);
if (this.currentMode.equals(Mode.EDIT))
{
itemBuilder.clickHandler((panel, user1, clickType, i) -> {
new EditLevelGUI(this.addon,
this.world,
this.user,
challengeLevel,
this.topLabel,
this.permissionPrefix,
this).build();
return true;
});
}
else if (this.currentMode.equals(Mode.DELETE))
{
itemBuilder.clickHandler((panel, user1, clickType, i) -> {
new ConfirmationGUI(this.user, value -> {
if (value)
{
this.addon.getChallengesManager().
deleteChallengeLevel(challengeLevel);
}
});
return true;
});
}
return itemBuilder.build();
}
// ---------------------------------------------------------------------
// Section: Enums
// ---------------------------------------------------------------------
/**
* Mode in which gui icons should processed.
*/
public enum Mode
{
EDIT,
DELETE
}
// ---------------------------------------------------------------------
// Section: Variables
// ---------------------------------------------------------------------
/**
* Current mode in which icons will act.
*/
private Mode currentMode;
}

View File

@ -0,0 +1,299 @@
package world.bentobox.challenges.panel.admin;
import org.bukkit.Bukkit;
import org.bukkit.Material;
import org.bukkit.World;
import org.bukkit.entity.Player;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
import world.bentobox.bentobox.api.panels.PanelItem;
import world.bentobox.bentobox.api.panels.builders.PanelBuilder;
import world.bentobox.bentobox.api.panels.builders.PanelItemBuilder;
import world.bentobox.bentobox.api.user.User;
import world.bentobox.bentobox.database.objects.Players;
import world.bentobox.challenges.ChallengesAddon;
import world.bentobox.challenges.ChallengesManager;
import world.bentobox.challenges.panel.CommonGUI;
import world.bentobox.challenges.panel.util.ConfirmationGUI;
import world.bentobox.challenges.panel.util.SelectChallengeGUI;
import world.bentobox.challenges.utils.GuiUtils;
/**
* This class contains methods that allows to select specific user.
*/
public class ListUsersGUI extends CommonGUI
{
// ---------------------------------------------------------------------
// Section: Variables
// ---------------------------------------------------------------------
/**
* List with players that should be in GUI.
*/
private List<Player> onlineUsers;
/**
* Current operation mode.
*/
private Mode operationMode;
/**
* Current index of view mode
*/
private int modeIndex = 2;
/**
* This allows to switch which users should be in the list.
*/
private enum ViewMode
{
ONLINE,
WITH_ISLAND,
IN_WORLD
}
/**
* This allows to decide what User Icon should do.
*/
public enum Mode
{
COMPLETE,
RESET,
RESET_ALL
}
// ---------------------------------------------------------------------
// Section: Constructors
// ---------------------------------------------------------------------
/**
* {@inheritDoc}
* @param operationMode Indicate what should happen on player icon click.
*/
public ListUsersGUI(ChallengesAddon addon,
World world,
User user,
Mode operationMode,
String topLabel,
String permissionPrefix)
{
this(addon, world, user, operationMode, topLabel, permissionPrefix, null);
}
/**
* {@inheritDoc}
* @param operationMode Indicate what should happen on player icon click.
*/
public ListUsersGUI(ChallengesAddon addon,
World world,
User user,
Mode operationMode,
String topLabel,
String permissionPrefix,
CommonGUI parentPanel)
{
super(addon, world, user, topLabel, permissionPrefix, parentPanel);
this.onlineUsers = this.collectUsers(ViewMode.IN_WORLD);
this.operationMode = operationMode;
}
// ---------------------------------------------------------------------
// Section: Methods
// ---------------------------------------------------------------------
@Override
public void build()
{
PanelBuilder panelBuilder = new PanelBuilder().user(this.user).name(
this.user.getTranslation("challenges.gui.admin.choose-user-title"));
GuiUtils.fillBorder(panelBuilder);
final int MAX_ELEMENTS = 21;
if (this.pageIndex < 0)
{
this.pageIndex = this.onlineUsers.size() / MAX_ELEMENTS;
}
else if (this.pageIndex > (this.onlineUsers.size() / MAX_ELEMENTS))
{
this.pageIndex = 0;
}
int playerIndex = MAX_ELEMENTS * this.pageIndex;
// I want first row to be only for navigation and return button.
int index = 10;
while (playerIndex < ((this.pageIndex + 1) * MAX_ELEMENTS) &&
playerIndex < this.onlineUsers.size() &&
index < 36)
{
if (!panelBuilder.slotOccupied(index))
{
panelBuilder.item(index, this.createPlayerIcon(this.onlineUsers.get(playerIndex++)));
}
index++;
}
// Add button that allows to toogle different player lists.
panelBuilder.item( 4, this.createToggleButton());
// Navigation buttons only if necessary
if (this.onlineUsers.size() > MAX_ELEMENTS)
{
panelBuilder.item(18, this.getButton(CommonButtons.PREVIOUS));
panelBuilder.item(26, this.getButton(CommonButtons.NEXT));
}
panelBuilder.item(44, this.returnButton);
panelBuilder.build();
}
/**
* This method creates button for given user. If user has island it will add valid click handler.
* @param player Player which button must be created.
* @return Player button.
*/
private PanelItem createPlayerIcon(Player player)
{
if (this.addon.getIslands().hasIsland(this.world, player.getUniqueId()))
{
return new PanelItemBuilder().name(player.getName()).icon(player.getName()).clickHandler(
(panel, user1, clickType, slot) -> {
ChallengesManager manager = this.addon.getChallengesManager();
switch (this.operationMode)
{
case COMPLETE:
new SelectChallengeGUI(this.user, manager.getAllChallenges(this.world), (status, value) -> {
if (status)
{
manager.setChallengeComplete(User.getInstance(player), value);
}
this.build();
});
break;
case RESET:
new SelectChallengeGUI(this.user, manager.getAllChallenges(this.world), (status, value) -> {
if (status)
{
manager.resetChallenge(User.getInstance(player), value);
}
this.build();
});
break;
case RESET_ALL:
new ConfirmationGUI(this.user, status -> {
if (status)
{
manager.resetAllChallenges(this.user, this.world);
}
});
break;
}
return true;
}).build();
}
else
{
return new PanelItemBuilder().
name(player.getName()).
icon(Material.BARRIER).
description(GuiUtils.stringSplit(this.user.getTranslation("general.errors.player-has-no-island"))).
clickHandler((panel, user1, clickType, slot) -> false).
build();
}
}
/**
* This method collects users based on view mode.
* @param mode Given view mode.
* @return List with players in necessary view mode.
*/
private List<Player> collectUsers(ViewMode mode)
{
if (mode.equals(ViewMode.ONLINE))
{
return new ArrayList<>(Bukkit.getOnlinePlayers());
}
else if (mode.equals(ViewMode.WITH_ISLAND))
{
return this.addon.getPlayers().getPlayers().stream().
filter(player -> this.addon.getIslands().getIsland(this.world, player.getPlayerUUID()) != null).
map(Players::getPlayer).
collect(Collectors.toList());
}
else
{
return new ArrayList<>(this.world.getPlayers());
}
}
/**
* This method creates Player List view Mode toggle button.
* @return Button that toggles through player view mode.
*/
private PanelItem createToggleButton()
{
List<String> values = new ArrayList<>(ViewMode.values().length);
for (int i = 0; i < ViewMode.values().length; i++)
{
values.add((this.modeIndex == i ? "&2" : "&c") +
this.user.getTranslation("challenges.gui.admin.descriptions." +
ViewMode.values()[i].name().toLowerCase()));
}
return new PanelItemBuilder().
name(this.user.getTranslation("challenges.gui.admin.buttons.toggle-users",
"[value]",
this.user.getTranslation("challenges.gui.admin.descriptions." + ViewMode.values()[this.modeIndex].name().toLowerCase()))).
description(GuiUtils.stringSplit(values)).
icon(Material.STONE_BUTTON).
clickHandler(
(panel, user1, clickType, slot) -> {
if (clickType.isRightClick())
{
this.modeIndex--;
if (this.modeIndex < 0)
{
this.modeIndex = ViewMode.values().length - 1;
}
}
else
{
this.modeIndex++;
if (this.modeIndex >= ViewMode.values().length)
{
this.modeIndex = 0;
}
}
this.onlineUsers = this.collectUsers(ViewMode.values()[this.modeIndex]);
this.pageIndex = 0;
this.build();
return true;
}).build();
}
}

View File

@ -0,0 +1,225 @@
package world.bentobox.challenges.panel.admin;
import org.apache.commons.lang.WordUtils;
import org.bukkit.Material;
import org.bukkit.World;
import java.util.*;
import world.bentobox.bentobox.api.panels.PanelItem;
import world.bentobox.bentobox.api.panels.builders.PanelBuilder;
import world.bentobox.bentobox.api.panels.builders.PanelItemBuilder;
import world.bentobox.bentobox.api.user.User;
import world.bentobox.challenges.ChallengesAddon;
import world.bentobox.challenges.panel.CommonGUI;
import world.bentobox.challenges.panel.util.NumberGUI;
import world.bentobox.challenges.panel.util.SelectBlocksGUI;
import world.bentobox.challenges.utils.GuiUtils;
/**
* This class allows to edit material that are in required material map.
*/
public class ManageBlocksGUI extends CommonGUI
{
public ManageBlocksGUI(ChallengesAddon addon,
World world,
User user,
Map<Material, Integer> materialMap,
String topLabel,
String permissionPrefix,
CommonGUI parentGUI)
{
super(addon, world, user, topLabel, permissionPrefix, parentGUI);
this.materialMap = materialMap;
this.materialList = new ArrayList<>(this.materialMap.keySet());
// Sort materials by their ordinal value.
this.materialList.sort(Comparator.comparing(Enum::ordinal));
this.selectedMaterials = new HashSet<>();
}
// ---------------------------------------------------------------------
// Section: Methods
// ---------------------------------------------------------------------
/**
* This method builds all necessary elements in GUI panel.
*/
@Override
public void build()
{
PanelBuilder panelBuilder = new PanelBuilder().user(this.user).
name(this.user.getTranslation("challenges.gui.admin.manage-blocks"));
// Create nice border.
GuiUtils.fillBorder(panelBuilder);
panelBuilder.item(3, this.createButton(Button.ADD));
panelBuilder.item(5, this.createButton(Button.REMOVE));
final int MAX_ELEMENTS = 21;
if (this.pageIndex < 0)
{
this.pageIndex = this.materialList.size() / MAX_ELEMENTS;
}
else if (this.pageIndex > (this.materialList.size() / MAX_ELEMENTS))
{
this.pageIndex = 0;
}
int entitiesIndex = MAX_ELEMENTS * this.pageIndex;
// I want first row to be only for navigation and return button.
int index = 10;
while (entitiesIndex < ((this.pageIndex + 1) * MAX_ELEMENTS) &&
entitiesIndex < this.materialList.size() &&
index < 36)
{
if (!panelBuilder.slotOccupied(index))
{
panelBuilder.item(index, this.createElementButton(this.materialList.get(entitiesIndex++)));
}
index++;
}
// Navigation buttons only if necessary
if (this.materialList.size() > MAX_ELEMENTS)
{
panelBuilder.item(18, this.getButton(CommonButtons.PREVIOUS));
panelBuilder.item(26, this.getButton(CommonButtons.NEXT));
}
// Add return button.
panelBuilder.item(44, this.returnButton);
panelBuilder.build();
}
/**
* This method creates PanelItem button of requested type.
* @param button Button which must be created.
* @return new PanelItem with requested functionality.
*/
private PanelItem createButton(Button button)
{
PanelItemBuilder builder = new PanelItemBuilder();
switch (button)
{
case ADD:
builder.name(this.user.getTranslation("challenges.gui.button.add"));
builder.icon(Material.BUCKET);
builder.clickHandler((panel, user1, clickType, slot) -> {
new SelectBlocksGUI(this.user, new HashSet<>(this.materialList), (status, material) -> {
if (status)
{
this.materialMap.put(material, 1);
this.materialList.add(material);
}
this.build();
});
return true;
});
break;
case REMOVE:
builder.name(this.user.getTranslation("challenges.gui.button.remove-selected"));
builder.icon(Material.LAVA_BUCKET);
builder.clickHandler((panel, user1, clickType, slot) -> {
this.materialMap.keySet().removeAll(this.selectedMaterials);
this.materialList.removeAll(this.selectedMaterials);
this.build();
return true;
});
break;
}
return builder.build();
}
/**
* This method creates button for given material.
* @param material material which button must be created.
* @return new Button for material.
*/
private PanelItem createElementButton(Material material)
{
return new PanelItemBuilder().
name(WordUtils.capitalize(material.name().toLowerCase().replace("_", " "))).
icon(GuiUtils.getMaterialItem(material, this.materialMap.get(material))).
clickHandler((panel, user1, clickType, slot) -> {
// On right click change which entities are selected for deletion.
if (clickType.isRightClick())
{
if (!this.selectedMaterials.add(material))
{
// Remove material if it is already selected
this.selectedMaterials.remove(material);
}
this.build();
}
else
{
new NumberGUI(this.user, this.materialMap.get(material), 1, (status, value) -> {
if (status)
{
// Update value only when something changes.
this.materialMap.put(material, value);
}
this.build();
});
}
return true;
}).
glow(this.selectedMaterials.contains(material)).
build();
}
// ---------------------------------------------------------------------
// Section: Enums
// ---------------------------------------------------------------------
/**
* Functional buttons in current GUI.
*/
private enum Button
{
ADD,
REMOVE
}
// ---------------------------------------------------------------------
// Section: Variables
// ---------------------------------------------------------------------
/**
* Contains selected materials.
*/
private Set<Material> selectedMaterials;
/**
* List of materials to avoid order issues.
*/
private List<Material> materialList;
/**
* List of required materials.
*/
private Map<Material, Integer> materialMap;
}

View File

@ -0,0 +1,234 @@
package world.bentobox.challenges.panel.admin;
import org.apache.commons.lang.WordUtils;
import org.bukkit.Material;
import org.bukkit.World;
import org.bukkit.entity.EntityType;
import org.bukkit.inventory.ItemStack;
import java.util.*;
import world.bentobox.bentobox.api.panels.PanelItem;
import world.bentobox.bentobox.api.panels.builders.PanelBuilder;
import world.bentobox.bentobox.api.panels.builders.PanelItemBuilder;
import world.bentobox.bentobox.api.user.User;
import world.bentobox.challenges.ChallengesAddon;
import world.bentobox.challenges.panel.CommonGUI;
import world.bentobox.challenges.panel.util.NumberGUI;
import world.bentobox.challenges.panel.util.SelectEntityGUI;
import world.bentobox.challenges.utils.GuiUtils;
/**
* This class allows to edit entities that are in required entities map.
*/
public class ManageEntitiesGUI extends CommonGUI
{
public ManageEntitiesGUI(ChallengesAddon addon,
World world,
User user,
Map<EntityType, Integer> requiredEntities,
String topLabel,
String permissionPrefix,
CommonGUI parentGUI)
{
super(addon, world, user, topLabel, permissionPrefix, parentGUI);
this.requiredEntities = requiredEntities;
this.entityList = new ArrayList<>(this.requiredEntities.keySet());
this.entityList.sort(Comparator.comparing(Enum::name));
this.selectedEntities = new HashSet<>(EntityType.values().length);
}
// ---------------------------------------------------------------------
// Section: Methods
// ---------------------------------------------------------------------
/**
* This method builds all necessary elements in GUI panel.
*/
@Override
public void build()
{
PanelBuilder panelBuilder = new PanelBuilder().user(this.user).
name(this.user.getTranslation("challenges.gui.admin.edit-entities"));
// create border
GuiUtils.fillBorder(panelBuilder);
panelBuilder.item(3, this.createButton(Button.ADD));
panelBuilder.item(5, this.createButton(Button.REMOVE));
final int MAX_ELEMENTS = 21;
if (this.pageIndex < 0)
{
this.pageIndex = this.entityList.size() / MAX_ELEMENTS;
}
else if (this.pageIndex > (this.entityList.size() / MAX_ELEMENTS))
{
this.pageIndex = 0;
}
int entitiesIndex = MAX_ELEMENTS * this.pageIndex;
// I want first row to be only for navigation and return button.
int index = 10;
while (entitiesIndex < ((this.pageIndex + 1) * MAX_ELEMENTS) &&
entitiesIndex < this.entityList.size() &&
index < 26)
{
if (!panelBuilder.slotOccupied(index))
{
panelBuilder.item(index, this.createEntityButton(this.entityList.get(entitiesIndex++)));
}
index++;
}
// Navigation buttons only if necessary
if (this.entityList.size() > MAX_ELEMENTS)
{
panelBuilder.item(18, this.getButton(CommonButtons.PREVIOUS));
panelBuilder.item(26, this.getButton(CommonButtons.NEXT));
}
// Add return button.
panelBuilder.item(44, this.returnButton);
panelBuilder.build();
}
/**
* This method creates PanelItem button of requested type.
* @param button Button which must be created.
* @return new PanelItem with requested functionality.
*/
private PanelItem createButton(Button button)
{
PanelItemBuilder builder = new PanelItemBuilder();
switch (button)
{
case ADD:
builder.name(this.user.getTranslation("challenges.gui.button.add"));
builder.icon(Material.BUCKET);
builder.clickHandler((panel, user1, clickType, slot) -> {
new SelectEntityGUI(this.user, (status, entity) -> {
if (status)
{
if (!this.requiredEntities.containsKey(entity))
{
this.requiredEntities.put(entity, 1);
this.entityList.add(entity);
}
}
this.build();
});
return true;
});
break;
case REMOVE:
builder.name(this.user.getTranslation("challenges.gui.button.remove-selected"));
builder.icon(Material.LAVA_BUCKET);
builder.clickHandler((panel, user1, clickType, slot) -> {
this.requiredEntities.keySet().removeAll(this.selectedEntities);
this.entityList.removeAll(this.selectedEntities);
this.build();
return true;
});
break;
}
return builder.build();
}
/**
* This method creates button for given entity.
* @param entity Entity which button must be created.
* @return new Button for entity.
*/
private PanelItem createEntityButton(EntityType entity)
{
return new PanelItemBuilder().
name(WordUtils.capitalize(entity.name().toLowerCase().replace("_", " "))).
icon(this.asEggs ?
GuiUtils.getEntityEgg(entity, this.requiredEntities.get(entity)) :
GuiUtils.getEntityHead(entity, this.requiredEntities.get(entity))).
clickHandler((panel, user1, clickType, slot) -> {
// On right click change which entities are selected for deletion.
if (clickType.isRightClick())
{
if (!this.selectedEntities.add(entity))
{
// Remove entity if it is already selected
this.selectedEntities.remove(entity);
}
this.build();
}
else
{
new NumberGUI(this.user, this.requiredEntities.get(entity), 1, (status, value) -> {
if (status)
{
// Update value only when something changes.
this.requiredEntities.put(entity, value);
}
this.build();
});
}
return true;
}).
glow(this.selectedEntities.contains(entity)).
build();
}
// ---------------------------------------------------------------------
// Section: Enums
// ---------------------------------------------------------------------
/**
* Functional buttons in current GUI.
*/
private enum Button
{
ADD,
REMOVE
}
// ---------------------------------------------------------------------
// Section: Variables
// ---------------------------------------------------------------------
/**
* List with entities to avoid list irregularities.
*/
private List<EntityType> entityList;
/**
* Set with entities that are selected.
*/
private Set<EntityType> selectedEntities;
/**
* Map that contains all entities and their cound.
*/
private Map<EntityType, Integer> requiredEntities;
/**
* Boolean indicate if entities should be displayed as eggs or mob heads.
*/
private boolean asEggs;
}

View File

@ -0,0 +1,557 @@
package world.bentobox.challenges.panel.user;
import org.bukkit.Material;
import org.bukkit.World;
import org.bukkit.inventory.ItemStack;
import java.util.ArrayList;
import java.util.List;
import world.bentobox.bentobox.api.panels.PanelItem;
import world.bentobox.bentobox.api.panels.builders.PanelBuilder;
import world.bentobox.bentobox.api.panels.builders.PanelItemBuilder;
import world.bentobox.bentobox.api.user.User;
import world.bentobox.challenges.ChallengesAddon;
import world.bentobox.challenges.ChallengesManager;
import world.bentobox.challenges.database.object.Challenge;
import world.bentobox.challenges.panel.CommonGUI;
import world.bentobox.challenges.panel.TryToComplete;
import world.bentobox.challenges.utils.GuiUtils;
import world.bentobox.challenges.utils.LevelStatus;
/**
* This is UserGUI class. It contains everything necessary for user to use it.
*/
public class ChallengesGUI extends CommonGUI
{
// ---------------------------------------------------------------------
// Section: Constructors
// ---------------------------------------------------------------------
/**
* Default constructor that inits panels with minimal requirements, without parent panel.
*
* @param addon Addon where panel operates.
* @param world World from which panel was created.
* @param user User who created panel.
* @param topLabel Command top label which creates panel (f.e. island or ai)
* @param permissionPrefix Command permission prefix (f.e. bskyblock.)
*/
public ChallengesGUI(ChallengesAddon addon,
World world,
User user,
String topLabel,
String permissionPrefix)
{
super(addon, world, user, topLabel, permissionPrefix);
this.challengesManager = this.addon.getChallengesManager();
this.levelStatusList = this.challengesManager.getChallengeLevelStatus(this.user, this.world);
for (LevelStatus levelStatus : this.levelStatusList)
{
if (levelStatus.isUnlocked())
{
this.lastSelectedLevel = levelStatus;
}
else
{
break;
}
}
}
// ---------------------------------------------------------------------
// Section: Methods
// ---------------------------------------------------------------------
/**
* This method builds all necessary elements in GUI panel.
*/
@Override
public void build()
{
PanelBuilder panelBuilder = new PanelBuilder().user(this.user).
name(this.user.getTranslation("challenges.gui.title"));
// TODO: get last completed level.
if (this.addon.getChallengesSettings().isFreeChallengesFirst())
{
this.addFreeChallenges(panelBuilder);
// Start new row for challenges.
while (panelBuilder.nextSlot() % 9 != 0)
{
panelBuilder.item(
new PanelItemBuilder().icon(Material.LIGHT_GRAY_STAINED_GLASS_PANE).name(" ").build());
}
}
this.addChallenges(panelBuilder);
// Start new row for levels.
while (panelBuilder.nextSlot() % 9 != 0)
{
panelBuilder.item(
new PanelItemBuilder().icon(Material.LIGHT_GRAY_STAINED_GLASS_PANE).name(" ").build());
}
this.addChallengeLevels(panelBuilder);
if (!this.addon.getChallengesSettings().isFreeChallengesFirst())
{
// Start new row for free challenges.
while (panelBuilder.nextSlot() % 9 != 0)
{
panelBuilder.item(
new PanelItemBuilder().icon(Material.LIGHT_GRAY_STAINED_GLASS_PANE).name(" ").build());
}
this.addFreeChallenges(panelBuilder);
}
panelBuilder.build();
}
/**
* This method adds free challenges to panelBuilder.
* @param panelBuilder where free challenges must be added.
*/
private void addFreeChallenges(PanelBuilder panelBuilder)
{
List<Challenge> freeChallenges = this.challengesManager.getFreeChallenges(this.world);
final int freeChallengesCount = freeChallenges.size();
if (freeChallengesCount > 18)
{
int firstIndex = panelBuilder.nextSlot();
if (this.freeChallengeIndex > 0)
{
panelBuilder.item(new PanelItemBuilder().
icon(Material.SIGN).
name(this.user.getTranslation("challenges.gui.buttons.previous")).
clickHandler((panel, user1, clickType, slot) -> {
this.freeChallengeIndex--;
this.build();
return true;
}).build());
}
int currentIndex = this.freeChallengeIndex;
while (panelBuilder.nextSlot() != firstIndex + 18 && currentIndex < freeChallengesCount)
{
panelBuilder.item(this.getChallengeButton(freeChallenges.get(currentIndex++)));
}
// Check if one challenge is left
if (currentIndex + 1 == freeChallengesCount)
{
panelBuilder.item(this.getChallengeButton(freeChallenges.get(currentIndex)));
}
else if (currentIndex < freeChallengesCount)
{
panelBuilder.item(new PanelItemBuilder().
icon(Material.SIGN).
name(this.user.getTranslation("challenges.gui.buttons.next")).
clickHandler((panel, user1, clickType, slot) -> {
this.freeChallengeIndex++;
this.build();
return true;
}).build());
}
}
else
{
for (Challenge challenge : freeChallenges)
{
// there are no limitations. Just bunch insert.
panelBuilder.item(this.getChallengeButton(challenge));
}
}
}
/**
* This method adds last selected level challenges to panelBuilder.
* @param panelBuilder where last selected level challenges must be added.
*/
private void addChallenges(PanelBuilder panelBuilder)
{
if (this.lastSelectedLevel != null)
{
List<Challenge> challenges = this.challengesManager.getLevelChallenges(this.lastSelectedLevel.getLevel());
final int challengesCount = challenges.size();
if (challengesCount > 18)
{
int firstIndex = panelBuilder.nextSlot();
if (this.pageIndex > 0)
{
panelBuilder.item(new PanelItemBuilder().
icon(Material.SIGN).
name(this.user.getTranslation("challenges.gui.buttons.previous")).
clickHandler((panel, user1, clickType, slot) -> {
this.pageIndex--;
this.build();
return true;
}).build());
}
int currentIndex = this.pageIndex;
while (panelBuilder.nextSlot() != firstIndex + 18 && currentIndex < challengesCount)
{
panelBuilder.item(this.getChallengeButton(challenges.get(currentIndex++)));
}
// Check if one challenge is left
if (currentIndex + 1 == challengesCount)
{
panelBuilder.item(this.getChallengeButton(challenges.get(currentIndex)));
}
else if (currentIndex < challengesCount)
{
panelBuilder.item(new PanelItemBuilder().
icon(Material.SIGN).
name(this.user.getTranslation("challenges.gui.buttons.next")).
clickHandler((panel, user1, clickType, slot) -> {
this.pageIndex++;
this.build();
return true;
}).build());
}
}
else
{
for (Challenge challenge : challenges)
{
// there are no limitations. Just bunch insert.
panelBuilder.item(this.getChallengeButton(challenge));
}
}
}
}
/**
* This method adds challenge levels to panelBuilder.
* @param panelBuilder where challenge levels must be added.
*/
private void addChallengeLevels(PanelBuilder panelBuilder)
{
// Clone to avoid creating new level on each build.
List<LevelStatus> leftLevels = new ArrayList<>(this.levelStatusList);
leftLevels.remove(this.lastSelectedLevel);
// TODO: Focusing on middle should be awsome.
final int levelCounts = leftLevels.size();
if (levelCounts > 9)
{
int firstIndex = panelBuilder.nextSlot();
if (this.levelIndex > 0)
{
panelBuilder.item(new PanelItemBuilder().
icon(Material.SIGN).
name(this.user.getTranslation("challenges.gui.buttons.previous")).
clickHandler((panel, user1, clickType, slot) -> {
this.levelIndex--;
this.build();
return true;
}).build());
}
int currentIndex = this.levelIndex;
while (panelBuilder.nextSlot() != firstIndex + 9 && currentIndex < levelCounts)
{
panelBuilder.item(this.getLevelButton(leftLevels.get(currentIndex++)));
}
// Check if one challenge is left
if (currentIndex + 1 == levelCounts)
{
panelBuilder.item(this.getLevelButton(leftLevels.get(currentIndex)));
}
else if (currentIndex < levelCounts)
{
panelBuilder.item(new PanelItemBuilder().
icon(Material.SIGN).
name(this.user.getTranslation("challenges.gui.buttons.next")).
clickHandler((panel, user1, clickType, slot) -> {
this.levelIndex++;
this.build();
return true;
}).build());
}
}
else
{
for (LevelStatus level : leftLevels)
{
// there are no limitations. Just bunch insert.
panelBuilder.item(this.getLevelButton(level));
}
}
}
// ---------------------------------------------------------------------
// Section: Icon building
// ---------------------------------------------------------------------
/**
* This method creates given challenges icon that on press tries to complete it.
* @param challenge which icon must be constructed.
* @return PanelItem icon for challenge.
*/
private PanelItem getChallengeButton(Challenge challenge)
{
return new PanelItemBuilder().
icon(challenge.getIcon()).
name(challenge.getFriendlyName().isEmpty() ? challenge.getUniqueId() : challenge.getFriendlyName()).
description(GuiUtils.stringSplit(this.createChallengeDescription(challenge))).
clickHandler((panel, user1, clickType, slot) -> {
new TryToComplete(this.addon,
this.user,
challenge,
this.world,
this.topLabel,
this.permissionPrefix);
return true;
}).
glow(this.challengesManager.isChallengeComplete(this.user, challenge)).
build();
}
/**
* This method creates challenges description by adding all information that is necessary for this challenge.
* @param challenge Which information must be retrieved.
* @return List with strings that contains information about given challenge.
*/
private List<String> createChallengeDescription(Challenge challenge)
{
List<String> result = new ArrayList<>();
result.add(this.user.getTranslation("challenges.level",
"[level]", this.challengesManager.getLevel(challenge).getFriendlyName()));
boolean completed = this.challengesManager.isChallengeComplete(this.user, challenge);
if (completed)
{
result.add(this.user.getTranslation("challenges.complete"));
}
if (challenge.isRepeatable())
{
int maxTimes = challenge.getMaxTimes();
long doneTimes = this.challengesManager.getChallengeTimes(this.user, challenge);
if (maxTimes > 0)
{
if (doneTimes < maxTimes)
{
result.add(this.user.getTranslation("challenges.completed-times",
"[donetimes]", String.valueOf(doneTimes),
"[maxtimes]", String.valueOf(maxTimes)));
// Change value to false, as max count not reached.
completed = false;
}
else
{
result.add(this.user.getTranslation("challenges.maxed-reached",
"[donetimes]", String.valueOf(doneTimes),
"[maxtimes]", String.valueOf(maxTimes)));
}
}
else
{
result.add(this.user.getTranslation("challenges.completed-times",
"[donetimes]", String.valueOf(doneTimes)));
// Change value to false, as max count not reached.
completed = false;
}
}
if (!completed)
{
result.addAll(challenge.getDescription());
if (challenge.getChallengeType().equals(Challenge.ChallengeType.INVENTORY))
{
if (challenge.isTakeItems())
{
result.add(this.user.getTranslation("challenges.item-take-warning"));
}
}
else if (challenge.getChallengeType().equals(Challenge.ChallengeType.ISLAND))
{
result.add(this.user.getTranslation("challenges.items-closeby"));
if (challenge.isRemoveEntities() && !challenge.getRequiredEntities().isEmpty())
{
result.add(this.user.getTranslation("challenges.entities-kill-warning"));
}
if (challenge.isRemoveBlocks() && !challenge.getRequiredBlocks().isEmpty())
{
result.add(this.user.getTranslation("challenges.blocks-take-warning"));
}
}
}
if (completed)
{
result.add(this.user.getTranslation("challenges.not-repeatable"));
}
else
{
result.addAll(this.challengeRewards(challenge));
}
result.replaceAll(x -> x.replace("[label]", this.topLabel));
return result;
}
/**
* This method returns list of strings that contains basic information about challenge rewards.
* @param challenge which reward message must be created.
* @return list of strings that contains rewards message.
*/
private List<String> challengeRewards(Challenge challenge)
{
String rewardText;
double rewardMoney;
int rewardExperience;
if (!this.challengesManager.isChallengeComplete(this.user, challenge))
{
rewardText = challenge.getRewardText();
rewardMoney = challenge.getRewardMoney();
rewardExperience = challenge.getRewardExperience();
}
else
{
rewardText = challenge.getRepeatRewardText();
rewardMoney = challenge.getRepeatMoneyReward();
rewardExperience = challenge.getRepeatExperienceReward();
}
List<String> result = new ArrayList<>();
// Add reward text
result.add(rewardText);
// Add message about reward XP
if (rewardExperience > 0)
{
result.add(this.user.getTranslation("challenges.exp-reward",
"[reward]", Integer.toString(rewardExperience)));
}
// Add message about reward money
if (this.addon.getPlugin().getSettings().isUseEconomy() && rewardMoney > 0)
{
result.add(this.user.getTranslation("challenges.money-reward",
"[reward]", Double.toString(rewardMoney)));
}
return result;
}
/**
* This method creates button for given level.
* @param level which button must be created.
* @return Button for given level.
*/
private PanelItem getLevelButton(LevelStatus level)
{
// Create a nice name for the level
String name = level.getLevel().getFriendlyName().isEmpty() ?
level.getLevel().getUniqueId() :
level.getLevel().getFriendlyName();
ItemStack icon;
List<String> description;
PanelItem.ClickHandler clickHandler;
boolean glow;
if (level.isUnlocked())
{
icon = level.getLevel().getIcon();
description = GuiUtils.stringSplit(this.user.getTranslation("challenges.navigation", "[level]", name));
clickHandler = (panel, user1, clickType, slot) -> {
this.lastSelectedLevel = level;
// Reset level and page index.
this.levelIndex = 0;
this.pageIndex = 0;
this.build();
return true;
};
glow = this.challengesManager.isLevelCompleted(this.user, level.getLevel());
}
else
{
icon = new ItemStack(Material.BOOK);
description = GuiUtils.stringSplit(
this.user.getTranslation("challenges.to-complete",
"[challengesToDo]", Integer.toString(level.getNumberOfChallengesStillToDo()),
"[thisLevel]", level.getPreviousLevel().getFriendlyName()));
clickHandler = null;
glow = false;
}
return new PanelItem(icon, name, description, glow, clickHandler, false);
}
// ---------------------------------------------------------------------
// Section: Variables
// ---------------------------------------------------------------------
/**
* This will be used if free challenges are more then 18.
*/
private int freeChallengeIndex = 0;
/**
* This will be used if levels are more then 9.
*/
private int levelIndex;
/**
* This list contains all information about level completion in current world.
*/
private List<LevelStatus> levelStatusList;
/**
* This indicate last selected level.
*/
private LevelStatus lastSelectedLevel;
/**
* Challenge Manager object.
*/
private ChallengesManager challengesManager;
}

View File

@ -0,0 +1,114 @@
package world.bentobox.challenges.panel.util;
import org.bukkit.Material;
import java.util.function.Consumer;
import world.bentobox.bentobox.api.panels.PanelItem;
import world.bentobox.bentobox.api.panels.builders.PanelBuilder;
import world.bentobox.bentobox.api.panels.builders.PanelItemBuilder;
import world.bentobox.bentobox.api.user.User;
import world.bentobox.challenges.utils.GuiUtils;
/**
* This GUI is used to confirm that user wants to run command, that should be created from
* command string list.
*/
public class ConfirmationGUI
{
/**
* This constructor inits and opens ConfirmationGUI.
*
* @param user Gui Caller.
*/
public ConfirmationGUI(User user, Consumer<Boolean> consumer)
{
this.user = user;
this.consumer = consumer;
this.build();
}
/**
* This method builds confirmation panel with 2 buttons.
*/
public void build()
{
PanelBuilder panelBuilder = new PanelBuilder().user(this.user).name(this.user.getTranslation("challenges.gui.admin.confirm-title"));
GuiUtils.fillBorder(panelBuilder, Material.BLUE_STAINED_GLASS_PANE);
// Accept buttons
panelBuilder.item(10, this.getButton(true));
panelBuilder.item(11, this.getButton(true));
panelBuilder.item(12, this.getButton(true));
panelBuilder.item(19, this.getButton(true));
panelBuilder.item(20, this.getButton(true));
panelBuilder.item(21, this.getButton(true));
panelBuilder.item(28, this.getButton(true));
panelBuilder.item(29, this.getButton(true));
panelBuilder.item(30, this.getButton(true));
// Cancel Buttons
panelBuilder.item(14, this.getButton(false));
panelBuilder.item(15, this.getButton(false));
panelBuilder.item(16, this.getButton(false));
panelBuilder.item(23, this.getButton(false));
panelBuilder.item(24, this.getButton(false));
panelBuilder.item(25, this.getButton(false));
panelBuilder.item(32, this.getButton(false));
panelBuilder.item(33, this.getButton(false));
panelBuilder.item(34, this.getButton(false));
panelBuilder.item(44,
new PanelItemBuilder().
icon(Material.OAK_DOOR).
name(this.user.getTranslation("challenges.gui.buttons.return")).
clickHandler( (panel, user1, clickType, slot) -> {
this.consumer.accept(false);
return true;
}).build());
panelBuilder.build();
}
/**
* This method creates button with requested value.
* @param returnValue requested value
* @return PanelItem button.
*/
private PanelItem getButton(boolean returnValue)
{
return new PanelItemBuilder().
name(this.user.getTranslation("challenges.gui.admin.buttons." + (returnValue ? "accept" : "cancel"))).
icon(returnValue ? Material.GRAY_STAINED_GLASS_PANE : Material.RED_STAINED_GLASS_PANE).
clickHandler((panel, user1, clickType, i) -> {
this.consumer.accept(returnValue);
return true;
}).
build();
}
// ---------------------------------------------------------------------
// Section: Variables
// ---------------------------------------------------------------------
/**
* User who wants to run command.
*/
private User user;
/**
* Stores current Consumer
*/
private Consumer<Boolean> consumer;
}

View File

@ -0,0 +1,236 @@
package world.bentobox.challenges.panel.util;
import org.bukkit.Material;
import org.bukkit.event.inventory.InventoryClickEvent;
import org.bukkit.event.inventory.InventoryCloseEvent;
import org.bukkit.inventory.ItemStack;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.function.BiConsumer;
import world.bentobox.bentobox.api.panels.PanelItem;
import world.bentobox.bentobox.api.panels.PanelListener;
import world.bentobox.bentobox.api.panels.builders.PanelBuilder;
import world.bentobox.bentobox.api.user.User;
import world.bentobox.challenges.utils.GuiUtils;
/**
* This class allows to change Input ItemStacks to different ItemStacks.
*/
public class ItemSwitchGUI
{
public ItemSwitchGUI(User user, List<ItemStack> itemStacks, BiConsumer<Boolean, List<ItemStack>> consumer)
{
this.consumer = consumer;
this.user = user;
this.itemStacks = itemStacks;
this.build();
}
/**
* This method builds panel that allows to change given number value.
*/
private void build()
{
PanelBuilder panelBuilder = new PanelBuilder().user(this.user).name(this.user.getTranslation("challenges.gui.change-items"));
// Size of inventory that user can set via GUI.
panelBuilder.size(45);
panelBuilder.listener(new CustomPanelListener());
panelBuilder.item(0, this.getButton(Button.SAVE));
for (int i = 1; i < 8; i++)
{
panelBuilder.item(i, this.getButton(Button.EMPTY));
}
panelBuilder.item(8, this.getButton(Button.CANCEL));
for (ItemStack itemStack : this.itemStacks)
{
panelBuilder.item(new CustomPanelItem(itemStack));
}
panelBuilder.build().open(this.user);
}
/**
* This method create button that does some functionality in current gui.
* @param button Button functionality.
* @return PanelItem.
*/
private PanelItem getButton(Button button)
{
ItemStack icon;
String name;
List<String> description;
PanelItem.ClickHandler clickHandler;
switch (button)
{
case SAVE:
{
name = this.user.getTranslation("challenges.gui.buttons.save");
description = Collections.emptyList();
icon = new ItemStack(Material.COMMAND_BLOCK);
clickHandler = (panel, user, clickType, slot) -> {
// Magic number 9 - second row. First row is for custom buttons.
// Magic number 45 - This GUI is initialed with 45 elements.
List<ItemStack> returnItems = new ArrayList<>(36);
for (int i = 9; i < 45; i++)
{
ItemStack itemStack = panel.getInventory().getItem(i);
if (itemStack != null)
{
returnItems.add(itemStack);
}
}
this.consumer.accept(true, returnItems);
return true;
};
break;
}
case CANCEL:
{
name = this.user.getTranslation("challenges.gui.buttons.cancel");
description = Collections.emptyList();
icon = new ItemStack(Material.IRON_DOOR);
clickHandler = (panel, user, clickType, slot) -> {
this.consumer.accept(false, Collections.emptyList());
return true;
};
break;
}
case EMPTY:
{
name = "";
description = Collections.emptyList();
icon = new ItemStack(Material.BARRIER);
clickHandler = (panel, user, clickType, slot) -> true;
break;
}
default:
return null;
}
return new PanelItem(icon, name, GuiUtils.stringSplit(description), false, clickHandler, false);
}
// ---------------------------------------------------------------------
// Section: Private classes
// ---------------------------------------------------------------------
/**
* This CustomPanelItem does no lose Item original MetaData. After PanelItem has been
* created it restores original meta data. It also does not allow to change anything that
* could destroy meta data.
*/
private class CustomPanelItem extends PanelItem
{
CustomPanelItem(ItemStack item)
{
super(item.clone(), "", Collections.emptyList(), false, null, false);
this.getItem().setItemMeta(item.getItemMeta());
}
@Override
public void setGlow(boolean glow)
{
}
@Override
public void setDescription(List<String> description)
{
}
@Override
public void setName(String name)
{
}
@Override
public void setHead(ItemStack itemStack)
{
}
}
/**
* This CustomPanelListener allows to move items in current panel.
*/
private class CustomPanelListener implements PanelListener
{
@Override
public void setup()
{
}
@Override
public void onInventoryClose(InventoryCloseEvent inventoryCloseEvent)
{
}
@Override
public void onInventoryClick(User user, InventoryClickEvent event)
{
// First row of elements should be ignored, as it contains buttons and blocked slots.
event.setCancelled(event.getRawSlot() < 9);
}
}
// ---------------------------------------------------------------------
// Section: Enums
// ---------------------------------------------------------------------
/**
* This enum holds all button values in current gui.
*/
private enum Button
{
CANCEL,
SAVE,
EMPTY
}
// ---------------------------------------------------------------------
// Section: Variables
// ---------------------------------------------------------------------
/**
* User who opens current gui.
*/
private User user;
/**
* List with original items.
*/
private List<ItemStack> itemStacks;
/**
* Consumer that returns item stacks on save action.
*/
private BiConsumer<Boolean, List<ItemStack>> consumer;
}

View File

@ -0,0 +1,420 @@
package world.bentobox.challenges.panel.util;
import org.bukkit.Material;
import org.bukkit.inventory.ItemStack;
import java.util.Collections;
import java.util.List;
import java.util.function.BiConsumer;
import net.wesjd.anvilgui.AnvilGUI;
import world.bentobox.bentobox.BentoBox;
import world.bentobox.bentobox.api.panels.PanelItem;
import world.bentobox.bentobox.api.panels.builders.PanelBuilder;
import world.bentobox.bentobox.api.panels.builders.PanelItemBuilder;
import world.bentobox.bentobox.api.user.User;
import world.bentobox.challenges.utils.GuiUtils;
/**
* This gui allows to change current number and returns it to previous GUI
*/
public class NumberGUI
{
public NumberGUI(User user, int value, BiConsumer<Boolean, Integer> consumer)
{
this(user, value, Integer.MIN_VALUE, Integer.MAX_VALUE, consumer);
}
public NumberGUI(User user, int value, int minValue, BiConsumer<Boolean, Integer> consumer)
{
this(user, value, minValue, Integer.MAX_VALUE, consumer);
}
public NumberGUI(User user, int value, int minValue, int maxValue, BiConsumer<Boolean, Integer> consumer)
{
this.user = user;
this.value = value;
this.consumer = consumer;
this.minValue = minValue;
this.maxValue = maxValue;
this.currentOperation = Button.SET;
this.build();
}
/**
* This method builds panel that allows to change given number value.
*/
private void build()
{
PanelBuilder panelBuilder = new PanelBuilder().user(this.user).name(this.user.getTranslation("challenges.gui.edit-number-title"));
GuiUtils.fillBorder(panelBuilder);
// Others
panelBuilder.item(1, this.getButton(Button.SAVE));
panelBuilder.item(19, this.getButton(Button.VALUE));
panelBuilder.item(44, this.getButton(Button.CANCEL));
panelBuilder.item(2, this.getButton(Button.INPUT));
// operations
panelBuilder.item(3, this.getButton(Button.SET));
panelBuilder.item(4, this.getButton(Button.INCREASE));
panelBuilder.item(5, this.getButton(Button.REDUCE));
panelBuilder.item(6, this.getButton(Button.MULTIPLY));
// Numbers
panelBuilder.item(11, this.createNumberButton(1));
panelBuilder.item(12, this.createNumberButton(10));
panelBuilder.item(13, this.createNumberButton(100));
panelBuilder.item(14, this.createNumberButton(1000));
panelBuilder.item(15, this.createNumberButton(10000));
panelBuilder.item(20, this.createNumberButton(2));
panelBuilder.item(21, this.createNumberButton(20));
panelBuilder.item(22, this.createNumberButton(200));
panelBuilder.item(23, this.createNumberButton(2000));
panelBuilder.item(24, this.createNumberButton(20000));
panelBuilder.item(29, this.createNumberButton(5));
panelBuilder.item(30, this.createNumberButton(50));
panelBuilder.item(31, this.createNumberButton(500));
panelBuilder.item(32, this.createNumberButton(5000));
panelBuilder.item(33, this.createNumberButton(50000));
panelBuilder.build();
}
/**
* This method creates PanelItem with required functionality.
* @param button Functionality requirement.
* @return PanelItem with functionality.
*/
private PanelItem getButton(Button button)
{
ItemStack icon;
String name;
List<String> description;
PanelItem.ClickHandler clickHandler;
boolean glow;
switch (button)
{
case SAVE:
{
name = this.user.getTranslation("challenges.gui.buttons.save");
description = Collections.emptyList();
icon = new ItemStack(Material.COMMAND_BLOCK);
clickHandler = (panel, user, clickType, slot) -> {
this.consumer.accept(true, this.value);
return true;
};
glow = false;
break;
}
case CANCEL:
{
name = this.user.getTranslation("challenges.gui.buttons.cancel");
description = Collections.emptyList();
icon = new ItemStack(Material.OAK_DOOR);
clickHandler = (panel, user, clickType, slot) -> {
this.consumer.accept(false, this.value);
return true;
};
glow = false;
break;
}
case INPUT:
{
name = this.user.getTranslation("challenges.gui.buttons.input");
description = Collections.emptyList();
icon = new ItemStack(Material.ANVIL);
clickHandler = (panel, user, clickType, slot) -> {
new AnvilGUI(BentoBox.getInstance(),
this.user.getPlayer(),
Integer.toString(this.value),
(player, reply) -> {
try
{
this.value = Integer.parseInt(reply);
if (this.value > this.maxValue || this.value < this.minValue)
{
this.user.sendMessage("challenges.error.not-valid-integer",
"[value]", reply,
"[min]", Integer.toString(this.minValue),
"[max]", Integer.toString(this.maxValue));
}
else
{
this.build();
}
}
catch (Exception e)
{
reply = Integer.toString(this.value);
this.user.sendMessage("challenges.error.not-a-integer", "[value]", reply);
}
return reply;
});
return true;
};
glow = false;
break;
}
case VALUE:
{
name = this.user.getTranslation("challenges.gui.buttons.value");
description = Collections.singletonList(Integer.toString(this.value));
icon = new ItemStack(Material.PAPER);
clickHandler = (panel, user, clickType, slot) -> true;
glow = false;
break;
}
case SET:
{
name = this.user.getTranslation("challenges.gui.buttons.set");
description = Collections.emptyList();
icon = new ItemStack(Material.WHITE_STAINED_GLASS_PANE);
clickHandler = (panel, user, clickType, slot) -> {
this.currentOperation = Button.SET;
this.build();
return true;
};
glow = this.currentOperation.equals(Button.SET);
break;
}
case INCREASE:
{
name = this.user.getTranslation("challenges.gui.buttons.increase");
description = Collections.emptyList();
icon = new ItemStack(Material.GREEN_STAINED_GLASS_PANE);
clickHandler = (panel, user, clickType, slot) -> {
this.currentOperation = Button.INCREASE;
this.build();
return true;
};
glow = this.currentOperation.equals(Button.INCREASE);
break;
}
case REDUCE:
{
name = this.user.getTranslation("challenges.gui.buttons.reduce");
description = Collections.emptyList();
icon = new ItemStack(Material.RED_STAINED_GLASS_PANE);
clickHandler = (panel, user, clickType, slot) -> {
this.currentOperation = Button.REDUCE;
this.build();
return true;
};
glow = this.currentOperation.equals(Button.REDUCE);
break;
}
case MULTIPLY:
{
name = this.user.getTranslation("challenges.gui.buttons.multiply");
description = Collections.emptyList();
icon = new ItemStack(Material.BLUE_STAINED_GLASS_PANE);
clickHandler = (panel, user, clickType, slot) -> {
this.currentOperation = Button.MULTIPLY;
this.build();
return true;
};
glow = this.currentOperation.equals(Button.MULTIPLY);
break;
}
default:
return null;
}
return new PanelItem(icon, name, GuiUtils.stringSplit(description), glow, clickHandler, false);
}
/**
* This method creates Number Button based on input number.
* @param number Number which button must be created.
* @return PanelItem that represents number button.
*/
private PanelItem createNumberButton(int number)
{
PanelItemBuilder itemBuilder = new PanelItemBuilder();
switch (this.currentOperation)
{
case SET:
{
itemBuilder.name(this.user.getTranslation("biomes.gui.buttons.set","[number]", Integer.toString(number)));
itemBuilder.icon(Material.WHITE_STAINED_GLASS_PANE);
itemBuilder.clickHandler((panel, user1, clickType, i) -> {
this.value = number;
if (this.value > this.maxValue)
{
this.user.sendMessage("challenges.error.not-valid-integer",
"[value]", Integer.toString(this.value),
"[min]", Integer.toString(this.minValue),
"[max]", Integer.toString(this.maxValue));
this.value = this.maxValue;
}
if (this.value < this.minValue)
{
this.user.sendMessage("challenges.error.not-valid-integer",
"[value]", Integer.toString(this.value),
"[min]", Integer.toString(this.minValue),
"[max]", Integer.toString(this.maxValue));
this.value = this.minValue;
}
this.build();
return true;
});
break;
}
case INCREASE:
{
itemBuilder.name(this.user.getTranslation("biomes.gui.buttons.increase","[number]", Integer.toString(number)));
itemBuilder.icon(Material.GREEN_STAINED_GLASS_PANE);
itemBuilder.clickHandler((panel, user1, clickType, i) -> {
this.value += number;
if (this.value > this.maxValue)
{
this.user.sendMessage("challenges.error.not-valid-integer",
"[value]", Integer.toString(this.value),
"[min]", Integer.toString(this.minValue),
"[max]", Integer.toString(this.maxValue));
this.value = this.maxValue;
}
this.build();
return true;
});
break;
}
case REDUCE:
{
itemBuilder.name(this.user.getTranslation("biomes.gui.buttons.reduce","[number]", Integer.toString(number)));
itemBuilder.icon(Material.RED_STAINED_GLASS_PANE);
itemBuilder.clickHandler((panel, user1, clickType, i) -> {
this.value -= number;
if (this.value < this.minValue)
{
this.user.sendMessage("challenges.error.not-valid-integer",
"[value]", Integer.toString(this.value),
"[min]", Integer.toString(this.minValue),
"[max]", Integer.toString(this.maxValue));
this.value = this.minValue;
}
this.build();
return true;
});
break;
}
case MULTIPLY:
{
itemBuilder.name(this.user.getTranslation("biomes.gui.buttons.multiply","[number]", Integer.toString(number)));
itemBuilder.icon(Material.BLUE_STAINED_GLASS_PANE);
itemBuilder.clickHandler((panel, user1, clickType, i) -> {
this.value *= number;
if (this.value > this.maxValue)
{
this.user.sendMessage("challenges.error.not-valid-integer",
"[value]", Integer.toString(this.value),
"[min]", Integer.toString(this.minValue),
"[max]", Integer.toString(this.maxValue));
this.value = this.maxValue;
}
this.build();
return true;
});
break;
}
}
return itemBuilder.build();
}
// ---------------------------------------------------------------------
// Section: Enums
// ---------------------------------------------------------------------
/**
* This enum contains all button types.
*/
private enum Button
{
SAVE,
CANCEL,
INPUT,
VALUE,
SET,
INCREASE,
REDUCE,
MULTIPLY
}
// ---------------------------------------------------------------------
// Section: Variables
// ---------------------------------------------------------------------
/**
* This variable stores current GUI consumer.
*/
private BiConsumer<Boolean, Integer> consumer;
/**
* User who runs GUI.
*/
private User user;
/**
* Current value.
*/
private int value;
/**
* Minimal value that is allowed to set.
*/
private int minValue;
/**
* Maximal value that is allowed to set.
*/
private int maxValue;
/**
* This variable holds which operation now is processed.
*/
private Button currentOperation;
}

View File

@ -0,0 +1,195 @@
package world.bentobox.challenges.panel.util;
import org.apache.commons.lang.WordUtils;
import org.bukkit.Material;
import org.bukkit.inventory.ItemStack;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Set;
import java.util.function.BiConsumer;
import world.bentobox.bentobox.api.panels.PanelItem;
import world.bentobox.bentobox.api.panels.builders.PanelBuilder;
import world.bentobox.bentobox.api.panels.builders.PanelItemBuilder;
import world.bentobox.bentobox.api.user.User;
import world.bentobox.challenges.utils.GuiUtils;
/**
* This class contains all necessary things that allows to select single block from all ingame blocks. Selected
* block will be returned via BiConsumer.
*/
public class SelectBlocksGUI
{
public SelectBlocksGUI(User user, BiConsumer<Boolean, Material> consumer)
{
this(user, Collections.emptySet(), consumer);
}
public SelectBlocksGUI(User user, Set<Material> excludedMaterial, BiConsumer<Boolean, Material> consumer)
{
this.consumer = consumer;
this.user = user;
// Current GUI cannot display air blocks. It crashes with null-pointer
excludedMaterial.add(Material.AIR);
excludedMaterial.add(Material.CAVE_AIR);
excludedMaterial.add(Material.VOID_AIR);
// Piston head and moving piston is not necessary. useless.
excludedMaterial.add(Material.PISTON_HEAD);
excludedMaterial.add(Material.MOVING_PISTON);
// Barrier cannot be accessible to user.
excludedMaterial.add(Material.BARRIER);
this.elements = new ArrayList<>();
for (Material material : Material.values())
{
if (material.isBlock() && !material.isLegacy() && !excludedMaterial.contains(material))
{
this.elements.add(material);
}
}
this.build(0);
}
// ---------------------------------------------------------------------
// Section: Methods
// ---------------------------------------------------------------------
/**
* This method builds all necessary elements in GUI panel.
*/
public void build(int pageIndex)
{
PanelBuilder panelBuilder = new PanelBuilder().user(this.user).
name(this.user.getTranslation("challenges.gui.admin.select-block"));
GuiUtils.fillBorder(panelBuilder, Material.BLUE_STAINED_GLASS_PANE);
final int MAX_ELEMENTS = 21;
final int correctPage;
if (pageIndex < 0)
{
correctPage = this.elements.size() / MAX_ELEMENTS;
}
else if (pageIndex > (this.elements.size() / MAX_ELEMENTS))
{
correctPage = 0;
}
else
{
correctPage = pageIndex;
}
int entitiesIndex = MAX_ELEMENTS * correctPage;
// I want first row to be only for navigation and return button.
int index = 10;
while (entitiesIndex < ((correctPage + 1) * MAX_ELEMENTS) &&
entitiesIndex < this.elements.size())
{
if (!panelBuilder.slotOccupied(index))
{
panelBuilder.item(index, this.createMaterialButton(this.elements.get(entitiesIndex++)));
}
index++;
}
panelBuilder.item(4,
new PanelItemBuilder().
icon(Material.RED_STAINED_GLASS_PANE).
name(this.user.getTranslation("challenges.gui.buttons.cancel")).
clickHandler( (panel, user1, clickType, slot) -> {
this.consumer.accept(false, null);
return true;
}).build());
if (this.elements.size() > MAX_ELEMENTS)
{
// Navigation buttons if necessary
panelBuilder.item(18,
new PanelItemBuilder().
icon(Material.SIGN).
name(this.user.getTranslation("challenges.gui.buttons.previous")).
clickHandler((panel, user1, clickType, slot) -> {
this.build(correctPage - 1);
return true;
}).build());
panelBuilder.item(26,
new PanelItemBuilder().
icon(Material.SIGN).
name(this.user.getTranslation("challenges.gui.buttons.next")).
clickHandler((panel, user1, clickType, slot) -> {
this.build(correctPage + 1);
return true;
}).build());
}
panelBuilder.item(44,
new PanelItemBuilder().
icon(Material.OAK_DOOR).
name(this.user.getTranslation("challenges.gui.buttons.return")).
clickHandler( (panel, user1, clickType, slot) -> {
this.consumer.accept(false, null);
return true;
}).build());
panelBuilder.build();
}
/**
* This method creates PanelItem that represents given material.
* Some materials is not displayable in Inventory GUI, so they are replaced with "placeholder" items.
* @param material Material which icon must be created.
* @return PanelItem that represents given material.
*/
private PanelItem createMaterialButton(Material material)
{
ItemStack itemStack = GuiUtils.getMaterialItem(material);
return new PanelItemBuilder().
name(WordUtils.capitalize(material.name().toLowerCase().replace("_", " "))).
icon(itemStack).
clickHandler((panel, user1, clickType, slot) -> {
this.consumer.accept(true, material);
return true;
}).
glow(!itemStack.getType().equals(material)).
build();
}
// ---------------------------------------------------------------------
// Section: Variables
// ---------------------------------------------------------------------
/**
* List with elements that will be displayed in current GUI.
*/
private List<Material> elements;
/**
* This variable stores consumer.
*/
private BiConsumer<Boolean, Material> consumer;
/**
* User who runs GUI.
*/
private User user;
}

View File

@ -0,0 +1,158 @@
package world.bentobox.challenges.panel.util;
import org.bukkit.Material;
import java.util.List;
import java.util.function.BiConsumer;
import world.bentobox.bentobox.api.panels.PanelItem;
import world.bentobox.bentobox.api.panels.builders.PanelBuilder;
import world.bentobox.bentobox.api.panels.builders.PanelItemBuilder;
import world.bentobox.bentobox.api.user.User;
import world.bentobox.challenges.database.object.Challenge;
import world.bentobox.challenges.utils.GuiUtils;
/**
* This class creates new GUI that allows to select single challenge, which is returned via consumer.
*/
public class SelectChallengeGUI
{
public SelectChallengeGUI(User user, List<Challenge> challengesList, BiConsumer<Boolean, Challenge> consumer)
{
this.consumer = consumer;
this.user = user;
this.challengesList = challengesList;
this.build(0);
}
/**
* This method builds panel that allows to select single challenge from input challenges.
*/
private void build(int pageIndex)
{
PanelBuilder panelBuilder = new PanelBuilder().user(this.user).name(this.user.getTranslation("challenges.gui.choose-challenge-title"));
GuiUtils.fillBorder(panelBuilder, Material.BLUE_STAINED_GLASS_PANE);
// Maximal elements in page.
final int MAX_ELEMENTS = 21;
final int correctPage;
if (pageIndex < 0)
{
correctPage = this.challengesList.size() / MAX_ELEMENTS;
}
else if (pageIndex > (this.challengesList.size() / MAX_ELEMENTS))
{
correctPage = 0;
}
else
{
correctPage = pageIndex;
}
panelBuilder.item(4,
new PanelItemBuilder().
icon(Material.RED_STAINED_GLASS_PANE).
name(this.user.getTranslation("challenges.gui.buttons.return")).
clickHandler( (panel, user1, clickType, slot) -> {
this.consumer.accept(false, null);
return true;
}).build());
if (this.challengesList.size() > MAX_ELEMENTS)
{
// Navigation buttons if necessary
panelBuilder.item(18,
new PanelItemBuilder().
icon(Material.SIGN).
name(this.user.getTranslation("challenges.gui.buttons.previous")).
clickHandler((panel, user1, clickType, slot) -> {
this.build(correctPage - 1);
return true;
}).build());
panelBuilder.item(26,
new PanelItemBuilder().
icon(Material.SIGN).
name(this.user.getTranslation("challenges.gui.buttons.next")).
clickHandler((panel, user1, clickType, slot) -> {
this.build(correctPage + 1);
return true;
}).build());
}
int challengesIndex = MAX_ELEMENTS * correctPage;
// I want first row to be only for navigation and return button.
int index = 10;
while (challengesIndex < ((correctPage + 1) * MAX_ELEMENTS) &&
challengesIndex < this.challengesList.size() &&
index < 36)
{
if (!panelBuilder.slotOccupied(index))
{
panelBuilder.item(index,
this.createChallengeButton(this.challengesList.get(challengesIndex++)));
}
index++;
}
panelBuilder.item(44,
new PanelItemBuilder().
icon(Material.OAK_DOOR).
name(this.user.getTranslation("challenges.gui.buttons.return")).
clickHandler( (panel, user1, clickType, slot) -> {
this.consumer.accept(false, null);
return true;
}).build());
panelBuilder.build();
}
/**
* This method builds PanelItem for given challenge.
* @param challenge Challenge which PanelItem must be created.
* @return new PanelItem for given Challenge.
*/
private PanelItem createChallengeButton(Challenge challenge)
{
return new PanelItemBuilder().
name(challenge.getFriendlyName()).
description(GuiUtils.stringSplit(challenge.getDescription())).
icon(challenge.getIcon()).
clickHandler((panel, user1, clickType, slot) -> {
this.consumer.accept(true, challenge);
return true;
}).build();
}
// ---------------------------------------------------------------------
// Section: Variables
// ---------------------------------------------------------------------
/**
* This variable stores consumer.
*/
private BiConsumer<Boolean, Challenge> consumer;
/**
* User who runs GUI.
*/
private User user;
/**
* Current value.
*/
private List<Challenge> challengesList;
}

View File

@ -0,0 +1,190 @@
package world.bentobox.challenges.panel.util;
import org.apache.commons.lang.WordUtils;
import org.bukkit.Material;
import org.bukkit.entity.EntityType;
import org.bukkit.inventory.ItemStack;
import java.util.*;
import java.util.function.BiConsumer;
import world.bentobox.bentobox.api.panels.PanelItem;
import world.bentobox.bentobox.api.panels.builders.PanelBuilder;
import world.bentobox.bentobox.api.panels.builders.PanelItemBuilder;
import world.bentobox.bentobox.api.user.User;
import world.bentobox.challenges.utils.GuiUtils;
/**
* This GUI allows to select single entity and return it via Consumer.
*/
public class SelectEntityGUI
{
public SelectEntityGUI(User user, BiConsumer<Boolean, EntityType> consumer)
{
this(user, Collections.emptySet(), true, consumer);
}
public SelectEntityGUI(User user, Set<EntityType> excludedEntities, boolean asEggs, BiConsumer<Boolean, EntityType> consumer)
{
this.consumer = consumer;
this.user = user;
this.asEggs = asEggs;
this.entities = new ArrayList<>(EntityType.values().length);
for (EntityType entityType : EntityType.values())
{
if (entityType.isAlive() && !excludedEntities.contains(entityType))
{
this.entities.add(entityType);
}
}
// Sort mobs by their name for easier search.
this.entities.sort(Comparator.comparing(Enum::name));
this.build(0);
}
// ---------------------------------------------------------------------
// Section: Methods
// ---------------------------------------------------------------------
/**
* This method builds
*/
private void build(int pageIndex)
{
PanelBuilder panelBuilder = new PanelBuilder().user(this.user).name(this.user.getTranslation("challenges.gui.choose-entity-title"));
GuiUtils.fillBorder(panelBuilder, Material.BLUE_STAINED_GLASS_PANE);
// Maximal elements in page.
final int MAX_ELEMENTS = 21;
final int correctPage;
if (pageIndex < 0)
{
correctPage = this.entities.size() / MAX_ELEMENTS;
}
else if (pageIndex > (this.entities.size() / MAX_ELEMENTS))
{
correctPage = 0;
}
else
{
correctPage = pageIndex;
}
panelBuilder.item(4,
new PanelItemBuilder().
icon(Material.RED_STAINED_GLASS_PANE).
name(this.user.getTranslation("challenges.gui.buttons.cancel")).
clickHandler( (panel, user1, clickType, slot) -> {
this.consumer.accept(false, null);
return true;
}).build());
if (this.entities.size() > MAX_ELEMENTS)
{
// Navigation buttons if necessary
panelBuilder.item(18,
new PanelItemBuilder().
icon(Material.SIGN).
name(this.user.getTranslation("challenges.gui.buttons.previous")).
clickHandler((panel, user1, clickType, slot) -> {
this.build(correctPage - 1);
return true;
}).build());
panelBuilder.item(26,
new PanelItemBuilder().
icon(Material.SIGN).
name(this.user.getTranslation("challenges.gui.buttons.next")).
clickHandler((panel, user1, clickType, slot) -> {
this.build(correctPage + 1);
return true;
}).build());
}
int entitiesIndex = MAX_ELEMENTS * correctPage;
// I want first row to be only for navigation and return button.
int slot = 10;
while (entitiesIndex < ((correctPage + 1) * MAX_ELEMENTS) &&
entitiesIndex < this.entities.size() &&
slot < 36)
{
if (!panelBuilder.slotOccupied(slot))
{
panelBuilder.item(slot,
this.createEntityButton(this.entities.get(entitiesIndex++)));
}
slot++;
}
panelBuilder.item(44,
new PanelItemBuilder().
icon(Material.OAK_DOOR).
name(this.user.getTranslation("challenges.gui.buttons.return")).
clickHandler( (panel, user1, clickType, i) -> {
this.consumer.accept(false, null);
return true;
}).build());
panelBuilder.build();
}
/**
* This method builds PanelItem for given entity.
* @param entity Entity which PanelItem must be created.
* @return new PanelItem for given Entity.
*/
private PanelItem createEntityButton(EntityType entity)
{
ItemStack itemStack = this.asEggs ? GuiUtils.getEntityEgg(entity) : GuiUtils.getEntityHead(entity);
return new PanelItemBuilder().
name(WordUtils.capitalize(entity.name().toLowerCase().replace("_", " "))).
icon(itemStack).
clickHandler((panel, user1, clickType, slot) -> {
this.consumer.accept(true, entity);
return true;
}).build();
}
// ---------------------------------------------------------------------
// Section: Variables
// ---------------------------------------------------------------------
/**
* This variable stores consumer.
*/
private BiConsumer<Boolean, EntityType> consumer;
/**
* User who runs GUI.
*/
private User user;
/**
* This variable stores if mobs must be displayed as Eggs "true" or Heads "false".
*/
private boolean asEggs;
/**
* Entities that must be in list.
*/
private List<EntityType> entities;
}

View File

@ -0,0 +1,147 @@
package world.bentobox.challenges.panel.util;
import org.bukkit.Material;
import org.bukkit.World;
import java.util.Collections;
import java.util.Set;
import java.util.function.BiConsumer;
import world.bentobox.bentobox.api.panels.builders.PanelBuilder;
import world.bentobox.bentobox.api.panels.builders.PanelItemBuilder;
import world.bentobox.bentobox.api.user.User;
import world.bentobox.challenges.utils.GuiUtils;
/**
* This class creates panel that allows to select and deselect World Environments. On save it runs
* input consumer with true and selected values.
*/
public class SelectEnvironmentGUI
{
public SelectEnvironmentGUI(User user, Set<World.Environment> values, BiConsumer<Boolean, Set<World.Environment>> consumer)
{
this.user = user;
this.values = values;
this.consumer = consumer;
this.build();
}
/**
* This method builds environment select panel.
*/
private void build()
{
PanelBuilder panelBuilder = new PanelBuilder().user(this.user).name(this.user.getTranslation("challenges.gui.admin.environment-title"));
GuiUtils.fillBorder(panelBuilder, Material.BLUE_STAINED_GLASS_PANE);
panelBuilder.item(3, new PanelItemBuilder().
name(this.user.getTranslation("challenges.gui.admin.buttons.save")).
icon(Material.GREEN_STAINED_GLASS_PANE).
clickHandler((panel, user1, clickType, index) -> {
this.consumer.accept(true, this.values);
return true;
}).
build());
panelBuilder.item(5, new PanelItemBuilder().
name(this.user.getTranslation("challenges.gui.admin.buttons.cancel")).
icon(Material.RED_STAINED_GLASS_PANE).
clickHandler((panel, user1, clickType, i) -> {
this.consumer.accept(false, Collections.emptySet());
return true;
}).
build());
panelBuilder.item(20, new PanelItemBuilder().
name(this.user.getTranslation("challenges.gui.admin.buttons.nether")).
icon(Material.NETHERRACK).
clickHandler((panel, user1, clickType, i) -> {
if (this.values.contains(World.Environment.NETHER))
{
this.values.remove(World.Environment.NETHER);
}
else
{
this.values.add(World.Environment.NETHER);
}
this.build();
return true;
}).
glow(this.values.contains(World.Environment.NETHER)).
build());
panelBuilder.item(22, new PanelItemBuilder().
name(this.user.getTranslation("challenges.gui.admin.buttons.normal")).
icon(Material.DIRT).
clickHandler((panel, user1, clickType, i) -> {
if (this.values.contains(World.Environment.NORMAL))
{
this.values.remove(World.Environment.NORMAL);
}
else
{
this.values.add(World.Environment.NORMAL);
}
this.build();
return true;
}).
glow(this.values.contains(World.Environment.NORMAL)).
build());
panelBuilder.item(24, new PanelItemBuilder().
name(this.user.getTranslation("challenges.gui.admin.buttons.end")).
icon(Material.END_STONE).
clickHandler((panel, user1, clickType, i) -> {
if (this.values.contains(World.Environment.THE_END))
{
this.values.remove(World.Environment.THE_END);
}
else
{
this.values.add(World.Environment.THE_END);
}
this.build();
return true;
}).
glow(this.values.contains(World.Environment.THE_END)).
build());
panelBuilder.item(44, new PanelItemBuilder().
name(this.user.getTranslation("challenges.gui.admin.buttons.return")).
icon(Material.OAK_DOOR).
clickHandler((panel, user1, clickType, i) -> {
this.consumer.accept(false, Collections.emptySet());
return true;
}).
build());
panelBuilder.build();
}
// ---------------------------------------------------------------------
// Section: Variables
// ---------------------------------------------------------------------
/**
* User who wants to run command.
*/
private User user;
/**
* List with selected environments.
*/
private Set<World.Environment> values;
/**
* Stores current Consumer
*/
private BiConsumer<Boolean, Set<World.Environment>> consumer;
}

View File

@ -0,0 +1,246 @@
package world.bentobox.challenges.panel.util;
import org.bukkit.Material;
import org.bukkit.inventory.ItemStack;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.function.BiConsumer;
import net.wesjd.anvilgui.AnvilGUI;
import world.bentobox.bentobox.BentoBox;
import world.bentobox.bentobox.api.panels.PanelItem;
import world.bentobox.bentobox.api.panels.builders.PanelBuilder;
import world.bentobox.bentobox.api.panels.builders.PanelItemBuilder;
import world.bentobox.bentobox.api.user.User;
import world.bentobox.challenges.utils.GuiUtils;
/**
* This GUI allows to edit List of strings. AnvilGUI has limited text space, so splitting
* text in multiple rows allows to edit each row separately.
*/
public class StringListGUI
{
public StringListGUI(User user, Collection<String> value, BiConsumer<Boolean, List<String>> consumer)
{
this(user, new ArrayList<>(value), consumer);
}
public StringListGUI(User user, List<String> value, BiConsumer<Boolean, List<String>> consumer)
{
this.consumer = consumer;
this.user = user;
this.value = value;
if (this.value.size() > 21)
{
// TODO: throw error that so large list cannot be edited.
this.consumer.accept(false, this.value);
}
else
{
this.build();
}
}
/**
* This method builds panel that allows to change given string value.
*/
private void build()
{
PanelBuilder panelBuilder = new PanelBuilder().user(this.user).
name(this.user.getTranslation("challenges.gui.text-edit-title"));
GuiUtils.fillBorder(panelBuilder, Material.BLACK_STAINED_GLASS_PANE);
panelBuilder.item(1, this.getButton(Button.SAVE));
panelBuilder.item(2, this.getButton(Button.VALUE));
panelBuilder.item(4, this.getButton(Button.ADD));
panelBuilder.item(5, this.getButton(Button.REMOVE));
panelBuilder.item(6, this.getButton(Button.CLEAR));
panelBuilder.item(44, this.getButton(Button.CANCEL));
int slot = 10;
for (int stringIndex = 0; stringIndex < this.value.size() && slot < 36; stringIndex++)
{
if (!panelBuilder.slotOccupied(slot))
{
panelBuilder.item(slot,
this.createStringElement(this.value.get(stringIndex), stringIndex));
}
slot++;
}
panelBuilder.build();
}
/**
* This method create button that does some functionality in current gui.
* @param button Button functionality.
* @return PanelItem.
*/
private PanelItem getButton(Button button)
{
ItemStack icon;
String name;
List<String> description;
PanelItem.ClickHandler clickHandler;
switch (button)
{
case SAVE:
{
name = this.user.getTranslation("challenges.gui.buttons.save");
description = Collections.emptyList();
icon = new ItemStack(Material.GREEN_STAINED_GLASS_PANE);
clickHandler = (panel, user, clickType, slot) -> {
this.consumer.accept(true, this.value);
return true;
};
break;
}
case CANCEL:
{
name = this.user.getTranslation("challenges.gui.buttons.cancel");
description = Collections.emptyList();
icon = new ItemStack(Material.OAK_DOOR);
clickHandler = (panel, user, clickType, slot) -> {
this.consumer.accept(false, this.value);
return true;
};
break;
}
case VALUE:
{
name = this.user.getTranslation("challenges.gui.buttons.value");
description = this.value;
icon = new ItemStack(Material.PAPER);
clickHandler = (panel, user, clickType, slot) -> true;
break;
}
case ADD:
{
name = this.user.getTranslation("challenges.gui.buttons.add");
description = Collections.emptyList();
icon = new ItemStack(Material.WHITE_STAINED_GLASS_PANE);
clickHandler = (panel, user, clickType, slot) -> {
new AnvilGUI(BentoBox.getInstance(),
this.user.getPlayer(),
" ",
(player, reply) -> {
this.value.add(reply);
this.build();
return reply;
});
return true;
};
break;
}
case CLEAR:
{
name = this.user.getTranslation("challenges.gui.buttons.clear");
description = Collections.emptyList();
icon = new ItemStack(Material.RED_STAINED_GLASS_PANE);
clickHandler = (panel, user, clickType, slot) -> {
this.value.clear();
this.build();
return true;
};
break;
}
case REMOVE:
{
name = this.user.getTranslation("challenges.gui.buttons.remove");
description = Collections.emptyList();
icon = new ItemStack(Material.BLUE_STAINED_GLASS_PANE);
clickHandler = (panel, user, clickType, slot) -> {
this.value.removeIf(String::isEmpty);
this.build();
return true;
};
break;
}
default:
return null;
}
return new PanelItem(icon, name, GuiUtils.stringSplit(description), false, clickHandler, false);
}
/**
* This method creates paper icon that represents single line from list.
* @param element Paper Icon name
* @return PanelItem.
*/
private PanelItem createStringElement(String element, int stringIndex)
{
return new PanelItemBuilder().
name(element).
icon(Material.PAPER).
clickHandler((panel, user1, clickType, i) -> {
new AnvilGUI(BentoBox.getInstance(),
this.user.getPlayer(),
element,
(player, reply) -> {
this.value.set(stringIndex, reply);
this.build();
return reply;
});
return true;
}).build();
}
// ---------------------------------------------------------------------
// Section: Enums
// ---------------------------------------------------------------------
/**
* This enum holds all button values in current gui.
*/
private enum Button
{
VALUE,
ADD,
REMOVE,
CANCEL,
CLEAR,
SAVE
}
// ---------------------------------------------------------------------
// Section: Variables
// ---------------------------------------------------------------------
/**
* This variable stores consumer.
*/
private BiConsumer<Boolean, List<String>> consumer;
/**
* User who runs GUI.
*/
private User user;
/**
* Current value.
*/
private List<String> value;
}

View File

@ -0,0 +1,407 @@
package world.bentobox.challenges.utils;
import org.apache.commons.lang.WordUtils;
import org.bukkit.ChatColor;
import org.bukkit.Material;
import org.bukkit.entity.EntityType;
import org.bukkit.inventory.ItemStack;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import world.bentobox.bentobox.api.panels.PanelItem;
import world.bentobox.bentobox.api.panels.builders.PanelBuilder;
/**
* This class contains static methods that is used through multiple GUIs.
*/
public class GuiUtils
{
// ---------------------------------------------------------------------
// Section: Border around GUIs
// ---------------------------------------------------------------------
/**
* This method creates border of black panes around given panel with 5 rows.
* @param panelBuilder PanelBuilder which must be filled with border blocks.
*/
public static void fillBorder(PanelBuilder panelBuilder)
{
GuiUtils.fillBorder(panelBuilder, 5, Material.BLACK_STAINED_GLASS_PANE);
}
/**
* This method sets black stained glass pane around Panel with given row count.
* @param panelBuilder object that builds Panel.
* @param rowCount in Panel.
*/
public static void fillBorder(PanelBuilder panelBuilder, int rowCount)
{
GuiUtils.fillBorder(panelBuilder, rowCount, Material.BLACK_STAINED_GLASS_PANE);
}
/**
* This method sets blocks with given Material around Panel with 5 rows.
* @param panelBuilder object that builds Panel.
* @param material that will be around Panel.
*/
public static void fillBorder(PanelBuilder panelBuilder, Material material)
{
GuiUtils.fillBorder(panelBuilder, 5, material);
}
/**
* This method sets blocks with given Material around Panel with given row count.
* @param panelBuilder object that builds Panel.
* @param rowCount in Panel.
* @param material that will be around Panel.
*/
public static void fillBorder(PanelBuilder panelBuilder, int rowCount, Material material)
{
// Only for useful filling.
if (rowCount < 3)
{
return;
}
for (int i = 0; i < 9 * rowCount; i++)
{
// First (i < 9) and last (i > 35) rows must be filled
// First column (i % 9 == 0) and last column (i % 9 == 8) also must be filled.
if (i < 9 || i > 9 * (rowCount - 1) || i % 9 == 0 || i % 9 == 8)
{
panelBuilder.item(i, BorderBlock.getPanelBorder(material));
}
}
}
// ---------------------------------------------------------------------
// Section: ItemStack transformations
// ---------------------------------------------------------------------
/**
* This method transforms entity into egg or block that corresponds given entity.
* If entity egg is not found, then it is replaced by block that represents entity or
* barrier block.
* @param entity Entity which egg must be returned.
* @return ItemStack that may be egg for given entity.
*/
public static ItemStack getEntityEgg(EntityType entity)
{
return GuiUtils.getEntityEgg(entity, 1);
}
/**
* This method transforms entity into egg or block that corresponds given entity.
* If entity egg is not found, then it is replaced by block that represents entity or
* barrier block.
* @param entity Entity which egg must be returned.
* @param amount Amount of ItemStack elements.
* @return ItemStack that may be egg for given entity.
*/
public static ItemStack getEntityEgg(EntityType entity, int amount)
{
ItemStack itemStack;
switch (entity)
{
case PIG_ZOMBIE:
itemStack = new ItemStack(Material.ZOMBIE_PIGMAN_SPAWN_EGG);
break;
case ENDER_DRAGON:
itemStack = new ItemStack(Material.DRAGON_EGG);
break;
case WITHER:
itemStack = new ItemStack(Material.SOUL_SAND);
break;
case PLAYER:
itemStack = new ItemStack(Material.PLAYER_HEAD);
break;
case MUSHROOM_COW:
itemStack = new ItemStack(Material.MOOSHROOM_SPAWN_EGG);
break;
case SNOWMAN:
itemStack = new ItemStack(Material.CARVED_PUMPKIN);
break;
case IRON_GOLEM:
itemStack = new ItemStack(Material.IRON_BLOCK);
break;
case ARMOR_STAND:
itemStack = new ItemStack(Material.ARMOR_STAND);
break;
default:
Material material = Material.getMaterial(entity.name() + "_SPAWN_EGG");
if (material == null)
{
itemStack = new ItemStack(Material.BARRIER);
}
else
{
itemStack = new ItemStack(material);
}
break;
}
itemStack.setAmount(amount);
return itemStack;
}
/**
* This method transforms entity into player head with skin that corresponds given
* entity. If entity head is not found, then it is replaced by barrier block.
* @param entity Entity which head must be returned.
* @return ItemStack that may be head for given entity.
*/
public static ItemStack getEntityHead(EntityType entity)
{
return GuiUtils.getEntityHead(entity, 1);
}
/**
* This method transforms entity into player head with skin that corresponds given
* entity. If entity head is not found, then it is replaced by barrier block.
* @param entity Entity which head must be returned.
* @param amount Amount of ItemStack elements.
* @return ItemStack that may be head for given entity.
*/
public static ItemStack getEntityHead(EntityType entity, int amount)
{
ItemStack itemStack;
switch (entity)
{
case PLAYER:
itemStack = new ItemStack(Material.PLAYER_HEAD);
break;
case WITHER_SKELETON:
itemStack = new ItemStack(Material.WITHER_SKELETON_SKULL);
break;
case ARMOR_STAND:
itemStack = new ItemStack(Material.ARMOR_STAND);
break;
case SKELETON:
itemStack = new ItemStack(Material.SKELETON_SKULL);
break;
case GIANT:
case ZOMBIE:
itemStack = new ItemStack(Material.ZOMBIE_HEAD);
break;
case CREEPER:
itemStack = new ItemStack(Material.CREEPER_HEAD);
break;
case ENDER_DRAGON:
itemStack = new ItemStack(Material.DRAGON_HEAD);
break;
default:
HeadLib head = HeadLib.getHead(entity.name());
if (head == null)
{
itemStack = new ItemStack(Material.BARRIER);
}
else
{
itemStack = head.toItemStack();
}
break;
}
itemStack.setAmount(amount);
return itemStack;
}
/**
* This method transforms material into item stack that can be displayed in users
* inventory.
* @param material Material which item stack must be returned.
* @return ItemStack that represents given material.
*/
public static ItemStack getMaterialItem(Material material)
{
return GuiUtils.getMaterialItem(material, 1);
}
/**
* This method transforms material into item stack that can be displayed in users
* inventory.
* @param material Material which item stack must be returned.
* @param amount Amount of ItemStack elements.
* @return ItemStack that represents given material.
*/
public static ItemStack getMaterialItem(Material material, int amount)
{
ItemStack itemStack;
// Process items that cannot be item-stacks.
if (material.name().contains("WALL_"))
{
// Materials that is attached to wall cannot be showed in GUI. But they should be in list.
itemStack = new ItemStack(Material.getMaterial(material.name().replace("WALL_", "")));
}
else if (material.name().startsWith("POTTED_"))
{
// Materials Potted elements cannot be in inventory.
itemStack = new ItemStack(Material.getMaterial(material.name().replace("POTTED_", "")));
}
else if (material.equals(Material.MELON_STEM) || material.equals(Material.ATTACHED_MELON_STEM))
{
itemStack = new ItemStack(Material.MELON_SEEDS);
}
else if (material.equals(Material.PUMPKIN_STEM) || material.equals(Material.ATTACHED_PUMPKIN_STEM))
{
itemStack = new ItemStack(Material.PUMPKIN_SEEDS);
}
else if (material.equals(Material.TALL_SEAGRASS))
{
itemStack = new ItemStack(Material.SEAGRASS);
}
else if (material.equals(Material.CARROTS))
{
itemStack = new ItemStack(Material.CARROT);
}
else if (material.equals(Material.BEETROOTS))
{
itemStack = new ItemStack(Material.BEETROOT);
}
else if (material.equals(Material.POTATOES))
{
itemStack = new ItemStack(Material.POTATO);
}
else if (material.equals(Material.COCOA))
{
itemStack = new ItemStack(Material.COCOA_BEANS);
}
else if (material.equals(Material.KELP_PLANT))
{
itemStack = new ItemStack(Material.KELP);
}
else if (material.equals(Material.REDSTONE_WIRE))
{
itemStack = new ItemStack(Material.REDSTONE);
}
else if (material.equals(Material.TRIPWIRE))
{
itemStack = new ItemStack(Material.STRING);
}
else if (material.equals(Material.FROSTED_ICE))
{
itemStack = new ItemStack(Material.ICE);
}
else if (material.equals(Material.END_PORTAL) || material.equals(Material.END_GATEWAY) || material.equals(Material.NETHER_PORTAL))
{
itemStack = new ItemStack(Material.PAPER);
}
else if (material.equals(Material.BUBBLE_COLUMN) || material.equals(Material.WATER))
{
itemStack = new ItemStack(Material.WATER_BUCKET);
}
else if (material.equals(Material.LAVA))
{
itemStack = new ItemStack(Material.LAVA_BUCKET);
}
else if (material.equals(Material.FIRE))
{
itemStack = new ItemStack(Material.FIRE_CHARGE);
}
else if (material.equals(Material.AIR) || material.equals(Material.CAVE_AIR) || material.equals(Material.VOID_AIR))
{
itemStack = new ItemStack(Material.GLASS_BOTTLE);
}
else if (material.equals(Material.PISTON_HEAD) || material.equals(Material.MOVING_PISTON))
{
itemStack = new ItemStack(Material.PISTON);
}
else
{
itemStack = new ItemStack(material);
}
itemStack.setAmount(amount);
return itemStack;
}
/**
* This BorderBlock is simple PanelItem but without item meta data.
*/
private static class BorderBlock extends PanelItem
{
private BorderBlock(ItemStack icon)
{
super(icon.clone(), " ", Collections.emptyList(), false, null, false);
}
/**
* This method retunrs BorderBlock with requested item stack.
* @param material of which broder must be created.
* @return PanelItem that acts like border.
*/
private static BorderBlock getPanelBorder(Material material)
{
ItemStack itemStack = new ItemStack(material);
itemStack.getItemMeta().setDisplayName(" ");
return new BorderBlock(itemStack);
}
}
/**
* Simple splitter
*
* @param string - string to be split
* @return list of split strings
*/
public static List<String> stringSplit(String string)
{
// Remove all ending lines from string.
string = string.replaceAll("([\\r\\n])", "\\|");
string = ChatColor.translateAlternateColorCodes('&', string);
// Check length of lines
List<String> result = new ArrayList<>();
Arrays.stream(string.split("\\|")).
map(line -> Arrays.asList(WordUtils.wrap(line, 25).split("\\r\\n"))).
forEach(result::addAll);
return result;
}
/**
* Simple splitter for all strings in list.
* @param stringList - list of string to be split
* @return list of split strings
*/
public static List<String> stringSplit(List<String> stringList)
{
if (stringList.isEmpty())
{
return stringList;
}
List<String> newList = new ArrayList<>(stringList.size());
stringList.stream().map(GuiUtils::stringSplit).forEach(newList::addAll);
return newList;
}
}

View File

@ -0,0 +1,298 @@
/*
* Written in 2018 by Daniel Saukel
*
* To the extent possible under law, the author(s) have dedicated all
* copyright and related and neighboring rights to this software
* to the public domain worldwide.
*
* This software is distributed without any warranty.
*
* You should have received a copy of the CC0 Public Domain Dedication
* along with this software. If not, see <http://creativecommons.org/publicdomain/zero/1.0/>.
*
* @url https://github.com/DRE2N/HeadLib
*/
package world.bentobox.challenges.utils;
import org.bukkit.ChatColor;
import org.bukkit.Material;
import org.bukkit.craftbukkit.v1_13_R2.inventory.CraftItemStack;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.ItemMeta;
import java.util.*;
import net.minecraft.server.v1_13_R2.NBTBase;
import net.minecraft.server.v1_13_R2.NBTTagCompound;
import net.minecraft.server.v1_13_R2.NBTTagList;
/**
* @author Daniel Saukel
*
* BONNe modified it for BentoBox by leaving only mob heads and removing unused code.
*/
public enum HeadLib
{
// ---------------------------------------------------------------------
// Section: Library of All Mob heads
// ---------------------------------------------------------------------
/**
* All enum values.
*/
SPIDER("8bdb71d0-4724-48b2-9344-e79480424798", "eyJ0ZXh0dXJlcyI6eyJTS0lOIjp7InVybCI6Imh0dHA6Ly90ZXh0dXJlcy5taW5lY3JhZnQubmV0L3RleHR1cmUvY2Q1NDE1NDFkYWFmZjUwODk2Y2QyNThiZGJkZDRjZjgwYzNiYTgxNjczNTcyNjA3OGJmZTM5MzkyN2U1N2YxIn19fQ=="),
CAVE_SPIDER("39173a7a-c957-4ec1-ac1a-43e5a64983df", "eyJ0ZXh0dXJlcyI6eyJTS0lOIjp7InVybCI6Imh0dHA6Ly90ZXh0dXJlcy5taW5lY3JhZnQubmV0L3RleHR1cmUvNDE2NDVkZmQ3N2QwOTkyMzEwN2IzNDk2ZTk0ZWViNWMzMDMyOWY5N2VmYzk2ZWQ3NmUyMjZlOTgyMjQifX19"),
ENDERMAN("0de98464-1274-4dd6-bba8-370efa5d41a8", "eyJ0ZXh0dXJlcyI6eyJTS0lOIjp7InVybCI6Imh0dHA6Ly90ZXh0dXJlcy5taW5lY3JhZnQubmV0L3RleHR1cmUvN2E1OWJiMGE3YTMyOTY1YjNkOTBkOGVhZmE4OTlkMTgzNWY0MjQ1MDllYWRkNGU2YjcwOWFkYTUwYjljZiJ9fX0="),
SLIME("7f0b0873-df6a-4a19-9bcd-f6c90ef804c7", "eyJ0ZXh0dXJlcyI6eyJTS0lOIjp7InVybCI6Imh0dHA6Ly90ZXh0dXJlcy5taW5lY3JhZnQubmV0L3RleHR1cmUvODk1YWVlYzZiODQyYWRhODY2OWY4NDZkNjViYzQ5NzYyNTk3ODI0YWI5NDRmMjJmNDViZjNiYmI5NDFhYmU2YyJ9fX0="),
GUARDIAN("f3898fe0-04fb-4f9c-8f8b-146a1d894007", "eyJ0ZXh0dXJlcyI6eyJTS0lOIjp7InVybCI6Imh0dHA6Ly90ZXh0dXJlcy5taW5lY3JhZnQubmV0L3RleHR1cmUvYzI1YWY5NjZhMzI2ZjlkOTg0NjZhN2JmODU4MmNhNGRhNjQ1M2RlMjcxYjNiYzllNTlmNTdhOTliNjM1MTFjNiJ9fX0="),
GHAST("807f287f-6499-4e93-a887-0a298ab3091f", "eyJ0ZXh0dXJlcyI6eyJTS0lOIjp7InVybCI6Imh0dHA6Ly90ZXh0dXJlcy5taW5lY3JhZnQubmV0L3RleHR1cmUvOGI2YTcyMTM4ZDY5ZmJiZDJmZWEzZmEyNTFjYWJkODcxNTJlNGYxYzk3ZTVmOTg2YmY2ODU1NzFkYjNjYzAifX19"),
BLAZE("7ceb88b2-7f5f-4399-abb9-7068251baa9d", "eyJ0ZXh0dXJlcyI6eyJTS0lOIjp7InVybCI6Imh0dHA6Ly90ZXh0dXJlcy5taW5lY3JhZnQubmV0L3RleHR1cmUvYjc4ZWYyZTRjZjJjNDFhMmQxNGJmZGU5Y2FmZjEwMjE5ZjViMWJmNWIzNWE0OWViNTFjNjQ2Nzg4MmNiNWYwIn19fQ=="),
MAGMA_CUBE("96aced64-5b85-4b99-b825-53cd7a9f9726", "eyJ0ZXh0dXJlcyI6eyJTS0lOIjp7InVybCI6Imh0dHA6Ly90ZXh0dXJlcy5taW5lY3JhZnQubmV0L3RleHR1cmUvMzg5NTdkNTAyM2M5MzdjNGM0MWFhMjQxMmQ0MzQxMGJkYTIzY2Y3OWE5ZjZhYjM2Yjc2ZmVmMmQ3YzQyOSJ9fX0="),
WITHER("119c371b-ea16-47c9-ad7f-23b3d894520a", "eyJ0ZXh0dXJlcyI6eyJTS0lOIjp7InVybCI6Imh0dHA6Ly90ZXh0dXJlcy5taW5lY3JhZnQubmV0L3RleHR1cmUvY2RmNzRlMzIzZWQ0MTQzNjk2NWY1YzU3ZGRmMjgxNWQ1MzMyZmU5OTllNjhmYmI5ZDZjZjVjOGJkNDEzOWYifX19"),
ENDER_DRAGON("433562fa-9e23-443e-93b0-d67228435e77", "eyJ0ZXh0dXJlcyI6eyJTS0lOIjp7InVybCI6Imh0dHA6Ly90ZXh0dXJlcy5taW5lY3JhZnQubmV0L3RleHR1cmUvNzRlY2MwNDA3ODVlNTQ2NjNlODU1ZWYwNDg2ZGE3MjE1NGQ2OWJiNGI3NDI0YjczODFjY2Y5NWIwOTVhIn19fQ=="),
SHULKER("d700b0b9-be74-4630-8cb5-62c979828ef6", "eyJ0ZXh0dXJlcyI6eyJTS0lOIjp7InVybCI6Imh0dHA6Ly90ZXh0dXJlcy5taW5lY3JhZnQubmV0L3RleHR1cmUvYjFkMzUzNGQyMWZlODQ5OTI2MmRlODdhZmZiZWFjNGQyNWZmZGUzNWM4YmRjYTA2OWU2MWUxNzg3ZmYyZiJ9fX0="),
CREEPER("eed2d903-ca32-4cc7-b33b-ca3bdbe18da4", "eyJ0ZXh0dXJlcyI6eyJTS0lOIjp7InVybCI6Imh0dHA6Ly90ZXh0dXJlcy5taW5lY3JhZnQubmV0L3RleHR1cmUvZjQyNTQ4MzhjMzNlYTIyN2ZmY2EyMjNkZGRhYWJmZTBiMDIxNWY3MGRhNjQ5ZTk0NDQ3N2Y0NDM3MGNhNjk1MiJ9fX0="),
ZOMBIE("9959dd98-efb3-4ee9-a8fb-2fda0218cda0", "eyJ0ZXh0dXJlcyI6eyJTS0lOIjp7InVybCI6Imh0dHA6Ly90ZXh0dXJlcy5taW5lY3JhZnQubmV0L3RleHR1cmUvNTZmYzg1NGJiODRjZjRiNzY5NzI5Nzk3M2UwMmI3OWJjMTA2OTg0NjBiNTFhNjM5YzYwZTVlNDE3NzM0ZTExIn19fQ=="),
ZOMBIE_VILLAGER("bcaf2b85-d421-47cc-a40a-455e77bfb60b", "eyJ0ZXh0dXJlcyI6eyJTS0lOIjp7InVybCI6Imh0dHA6Ly90ZXh0dXJlcy5taW5lY3JhZnQubmV0L3RleHR1cmUvMzdlODM4Y2NjMjY3NzZhMjE3YzY3ODM4NmY2YTY1NzkxZmU4Y2RhYjhjZTljYTRhYzZiMjgzOTdhNGQ4MWMyMiJ9fX0="),
ZOMBIE_PIGMAN("6540c046-d6ea-4aff-9766-32a54ebe6958", "eyJ0ZXh0dXJlcyI6eyJTS0lOIjp7InVybCI6Imh0dHA6Ly90ZXh0dXJlcy5taW5lY3JhZnQubmV0L3RleHR1cmUvNzRlOWM2ZTk4NTgyZmZkOGZmOGZlYjMzMjJjZDE4NDljNDNmYjE2YjE1OGFiYjExY2E3YjQyZWRhNzc0M2ViIn19fQ=="),
DOG("9655594c-5b1c-48a5-8e12-ffd7e0c735f2", "eyJ0ZXh0dXJlcyI6eyJTS0lOIjp7InVybCI6Imh0dHA6Ly90ZXh0dXJlcy5taW5lY3JhZnQubmV0L3RleHR1cmUvNDk1MTgzY2E0Y2RkMjk2MjhmZTZjNzIyZjc3OTA4N2I4M2MyMWJhOTdmNDIyNWU0YWQ5YjNlNjE4ZWNjZDMwIn19fQ=="),
HORSE("c6abc94e-a5ff-45fe-a0d7-4e479f290a6f", "eyJ0ZXh0dXJlcyI6eyJTS0lOIjp7InVybCI6Imh0dHA6Ly90ZXh0dXJlcy5taW5lY3JhZnQubmV0L3RleHR1cmUvNDJlYjk2N2FiOTRmZGQ0MWE2MzI1ZjEyNzdkNmRjMDE5MjI2ZTVjZjM0OTc3ZWVlNjk1OTdmYWZjZjVlIn19fQ=="),
TURTLE("ef56c7a3-a5e7-4a7f-9786-a4b6273a591d", "eyJ0ZXh0dXJlcyI6eyJTS0lOIjp7InVybCI6Imh0dHA6Ly90ZXh0dXJlcy5taW5lY3JhZnQubmV0L3RleHR1cmUvMTJlNTQ4NDA4YWI3NWQ3ZGY4ZTZkNWQyNDQ2ZDkwYjZlYzYyYWE0ZjdmZWI3OTMwZDFlZTcxZWVmZGRmNjE4OSJ9fX0="),
OCELOT("664dd492-3fcd-443b-9e61-4c7ebd9e4e10", "eyJ0ZXh0dXJlcyI6eyJTS0lOIjp7InVybCI6Imh0dHA6Ly90ZXh0dXJlcy5taW5lY3JhZnQubmV0L3RleHR1cmUvNTY1N2NkNWMyOTg5ZmY5NzU3MGZlYzRkZGNkYzY5MjZhNjhhMzM5MzI1MGMxYmUxZjBiMTE0YTFkYjEifX19"),
SHEEP("fa234925-9dbe-4b8f-a544-7c70fb6b6ac5", "eyJ0ZXh0dXJlcyI6eyJTS0lOIjp7InVybCI6Imh0dHA6Ly90ZXh0dXJlcy5taW5lY3JhZnQubmV0L3RleHR1cmUvZjMxZjljY2M2YjNlMzJlY2YxM2I4YTExYWMyOWNkMzNkMThjOTVmYzczZGI4YTY2YzVkNjU3Y2NiOGJlNzAifX19"),
COW("97ddf3b3-9dbe-4a3b-8a0f-1b19ddeac0bd", "eyJ0ZXh0dXJlcyI6eyJTS0lOIjp7InVybCI6Imh0dHA6Ly90ZXh0dXJlcy5taW5lY3JhZnQubmV0L3RleHR1cmUvNWQ2YzZlZGE5NDJmN2Y1ZjcxYzMxNjFjNzMwNmY0YWVkMzA3ZDgyODk1ZjlkMmIwN2FiNDUyNTcxOGVkYzUifX19"),
CHICKEN("7d3a8ace-e045-4eba-ab71-71dbf525daf1", "eyJ0ZXh0dXJlcyI6eyJTS0lOIjp7InVybCI6Imh0dHA6Ly90ZXh0dXJlcy5taW5lY3JhZnQubmV0L3RleHR1cmUvMTYzODQ2OWE1OTljZWVmNzIwNzUzNzYwMzI0OGE5YWIxMWZmNTkxZmQzNzhiZWE0NzM1YjM0NmE3ZmFlODkzIn19fQ=="),
PIG("e1e1c2e4-1ed2-473d-bde2-3ec718535399", "eyJ0ZXh0dXJlcyI6eyJTS0lOIjp7InVybCI6Imh0dHA6Ly90ZXh0dXJlcy5taW5lY3JhZnQubmV0L3RleHR1cmUvNjIxNjY4ZWY3Y2I3OWRkOWMyMmNlM2QxZjNmNGNiNmUyNTU5ODkzYjZkZjRhNDY5NTE0ZTY2N2MxNmFhNCJ9fX0="),
SQUID("f95d9504-ea2b-4b89-b2d0-d400654a7010", "eyJ0ZXh0dXJlcyI6eyJTS0lOIjp7InVybCI6Imh0dHA6Ly90ZXh0dXJlcy5taW5lY3JhZnQubmV0L3RleHR1cmUvMDE0MzNiZTI0MjM2NmFmMTI2ZGE0MzRiODczNWRmMWViNWIzY2IyY2VkZTM5MTQ1OTc0ZTljNDgzNjA3YmFjIn19fQ=="),
MUSHROOM_COW("e206ac29-ae69-475b-909a-fb523d894336", "eyJ0ZXh0dXJlcyI6eyJTS0lOIjp7InVybCI6Imh0dHA6Ly90ZXh0dXJlcy5taW5lY3JhZnQubmV0L3RleHR1cmUvZDBiYzYxYjk3NTdhN2I4M2UwM2NkMjUwN2EyMTU3OTEzYzJjZjAxNmU3YzA5NmE0ZDZjZjFmZTFiOGRiIn19fQ=="),
ELDER_GUARDIAN("f2e933a7-614f-44e0-bf18-289b102104ab", "eyJ0ZXh0dXJlcyI6eyJTS0lOIjp7InVybCI6Imh0dHA6Ly90ZXh0dXJlcy5taW5lY3JhZnQubmV0L3RleHR1cmUvMWM3OTc0ODJhMTRiZmNiODc3MjU3Y2IyY2ZmMWI2ZTZhOGI4NDEzMzM2ZmZiNGMyOWE2MTM5Mjc4YjQzNmIifX19"),
STRAY("644c9bad-958b-43ce-9d2f-199d85be607c", "eyJ0ZXh0dXJlcyI6eyJTS0lOIjp7InVybCI6Imh0dHA6Ly90ZXh0dXJlcy5taW5lY3JhZnQubmV0L3RleHR1cmUvNzhkZGY3NmU1NTVkZDVjNGFhOGEwYTVmYzU4NDUyMGNkNjNkNDg5YzI1M2RlOTY5ZjdmMjJmODVhOWEyZDU2In19fQ=="),
HUSK("2e387bc6-774b-4fda-ba22-eb54a26dfd9e", "eyJ0ZXh0dXJlcyI6eyJTS0lOIjp7InVybCI6Imh0dHA6Ly90ZXh0dXJlcy5taW5lY3JhZnQubmV0L3RleHR1cmUvNzc3MDY4MWQxYTI1NWZiNGY3NTQ3OTNhYTA1NWIyMjA0NDFjZGFiOWUxMTQxZGZhNTIzN2I0OTkzMWQ5YjkxYyJ9fX0="),
SKELETON_HORSE("bcbce5bf-86c4-4e62-9fc5-0cc90de94b6d", "eyJ0ZXh0dXJlcyI6eyJTS0lOIjp7InVybCI6Imh0dHA6Ly90ZXh0dXJlcy5taW5lY3JhZnQubmV0L3RleHR1cmUvNDdlZmZjZTM1MTMyYzg2ZmY3MmJjYWU3N2RmYmIxZDIyNTg3ZTk0ZGYzY2JjMjU3MGVkMTdjZjg5NzNhIn19fQ=="),
ZOMBIE_HORSE("506ced1a-dac8-4d84-b341-645fbb297335", "eyJ0ZXh0dXJlcyI6eyJTS0lOIjp7InVybCI6Imh0dHA6Ly90ZXh0dXJlcy5taW5lY3JhZnQubmV0L3RleHR1cmUvY2Q2YjllZjhkZDEwYmE2NDE0MjJiNDQ5ZWQxNWFkYzI5MmQ3M2Y1NzI5ODRkNDdlMjhhMjI2YWE2ZWRkODcifX19"),
DONKEY("3da7917b-cb95-40b3-a516-9befa4f4d71d", "eyJ0ZXh0dXJlcyI6eyJTS0lOIjp7InVybCI6Imh0dHA6Ly90ZXh0dXJlcy5taW5lY3JhZnQubmV0L3RleHR1cmUvYjEyNTJjMjI1MGM0NjhkOWZkZTUzODY3Nzg1NWJjOWYyODQzM2RmNjkyNDdkNzEzODY4NzgxYjgyZDE0YjU1In19fQ=="),
MULE("fac6815e-02d5-4776-a5d6-f6d6535b7831", "eyJ0ZXh0dXJlcyI6eyJTS0lOIjp7InVybCI6Imh0dHA6Ly90ZXh0dXJlcy5taW5lY3JhZnQubmV0L3RleHR1cmUvNzY5Y2E0YzI5NTZhNTY3Yzk2ZWUwNGM1MzE0OWYxODY0NjIxODM5M2JjN2IyMWVkNDVmZGFhMTNiZWJjZGFkIn19fQ=="),
EVOKER("36ee7e5b-c092-48ad-9673-2a73b0a44b4f", "eyJ0ZXh0dXJlcyI6eyJTS0lOIjp7InVybCI6Imh0dHA6Ly90ZXh0dXJlcy5taW5lY3JhZnQubmV0L3RleHR1cmUvYTAwZDNmZmYxNmMyZGNhNTliOWM1OGYwOTY1MjVjODY5NzExNjZkYmFlMTMzYjFiMDUwZTVlZTcxNjQ0MyJ9fX0="),
VEX("f83bcfc1-0213-4957-888e-d3e2fae71203", "eyJ0ZXh0dXJlcyI6eyJTS0lOIjp7InVybCI6Imh0dHA6Ly90ZXh0dXJlcy5taW5lY3JhZnQubmV0L3RleHR1cmUvNWU3MzMwYzdkNWNkOGEwYTU1YWI5ZTk1MzIxNTM1YWM3YWUzMGZlODM3YzM3ZWE5ZTUzYmVhN2JhMmRlODZiIn19fQ=="),
VINDICATOR("5f958e1c-91ea-42d3-9d26-09e5925f2d9c", "eyJ0ZXh0dXJlcyI6eyJTS0lOIjp7InVybCI6Imh0dHA6Ly90ZXh0dXJlcy5taW5lY3JhZnQubmV0L3RleHR1cmUvN2RhNTg1ZWJkZGNjNDhmMzA3YmU2YTgzOTE2Zjg3OGVkNGEwMTRlYzNkNGYyODZhMmNmZDk1MzI4MTk2OSJ9fX0="),
ILLUSIONER("ccb79aa9-1764-4e5b-8ff3-e7be661ac7e2", "eyJ0ZXh0dXJlcyI6eyJTS0lOIjp7InVybCI6Imh0dHA6Ly90ZXh0dXJlcy5taW5lY3JhZnQubmV0L3RleHR1cmUvNjYxNWUxMjQ1ZDBkODJkODFkZmEzNzUzMDYzZDhhYWQwZmE2NjU3NTk5ODcxY2Y0YzY5YmFiNzNjNjk5MDU1In19fQ=="),
PIG_ZOMBIE("6540c046-d6ea-4aff-9766-32a54ebe6958", "eyJ0ZXh0dXJlcyI6eyJTS0lOIjp7InVybCI6Imh0dHA6Ly90ZXh0dXJlcy5taW5lY3JhZnQubmV0L3RleHR1cmUvNzRlOWM2ZTk4NTgyZmZkOGZmOGZlYjMzMjJjZDE4NDljNDNmYjE2YjE1OGFiYjExY2E3YjQyZWRhNzc0M2ViIn19fQ=="),
SILVERFISH("30a4cd5c-5754-4db8-8960-18022a74627d", "eyJ0ZXh0dXJlcyI6eyJTS0lOIjp7InVybCI6Imh0dHA6Ly90ZXh0dXJlcy5taW5lY3JhZnQubmV0L3RleHR1cmUvZGE5MWRhYjgzOTFhZjVmZGE1NGFjZDJjMGIxOGZiZDgxOWI4NjVlMWE4ZjFkNjIzODEzZmE3NjFlOTI0NTQwIn19fQ=="),
BAT("cfdaf903-18cf-4a92-acf2-efa8626cf0b2", "eyJ0ZXh0dXJlcyI6eyJTS0lOIjp7InVybCI6Imh0dHA6Ly90ZXh0dXJlcy5taW5lY3JhZnQubmV0L3RleHR1cmUvOWU5OWRlZWY5MTlkYjY2YWMyYmQyOGQ2MzAyNzU2Y2NkNTdjN2Y4YjEyYjlkY2E4ZjQxYzNlMGEwNGFjMWNjIn19fQ=="),
WITCH("7f92b3d6-5ee0-4ab6-afae-2206b9514a63", "eyJ0ZXh0dXJlcyI6eyJTS0lOIjp7InVybCI6Imh0dHA6Ly90ZXh0dXJlcy5taW5lY3JhZnQubmV0L3RleHR1cmUvMjBlMTNkMTg0NzRmYzk0ZWQ1NWFlYjcwNjk1NjZlNDY4N2Q3NzNkYWMxNmY0YzNmODcyMmZjOTViZjlmMmRmYSJ9fX0="),
ENDERMITE("33c425bb-a294-4e01-9b5b-a8ad652bb5cf", "eyJ0ZXh0dXJlcyI6eyJTS0lOIjp7InVybCI6Imh0dHA6Ly90ZXh0dXJlcy5taW5lY3JhZnQubmV0L3RleHR1cmUvODRhYWZmYTRjMDllMmVhZmI4NWQzNTIyMTIyZGIwYWE0NTg3NGJlYTRlM2Y1ZTc1NjZiNGQxNjZjN2RmOCJ9fX0="),
WOLF("4aabc2be-340a-46ad-a42b-0c348344750a", "eyJ0ZXh0dXJlcyI6eyJTS0lOIjp7InVybCI6Imh0dHA6Ly90ZXh0dXJlcy5taW5lY3JhZnQubmV0L3RleHR1cmUvZDdhZGU0OWY1MDEzMTExNTExZGM1MWJhYjc2OWMxYWQ2OTUzMTlhNWQzNTViMzZhZTkyMzRlYTlkMWZmOGUifX19"),
SNOWMAN("d71e165b-b49d-4180-9ccf-8ad3084df1dc", "eyJ0ZXh0dXJlcyI6eyJTS0lOIjp7InVybCI6Imh0dHA6Ly90ZXh0dXJlcy5taW5lY3JhZnQubmV0L3RleHR1cmUvMTdlOTgzMWRhZjY4MWY4YzRjNDc3NWNiNDY1M2MzNGJlMjg5OGY4N2VmZDNiNTk4ZDU1NTUxOGYyZmFjNiJ9fX0="),
IRON_GOLEM("7cb6e9a5-994f-40d5-9bfc-4ba5d796d21e", "eyJ0ZXh0dXJlcyI6eyJTS0lOIjp7InVybCI6Imh0dHA6Ly90ZXh0dXJlcy5taW5lY3JhZnQubmV0L3RleHR1cmUvODkwOTFkNzllYTBmNTllZjdlZjk0ZDdiYmE2ZTVmMTdmMmY3ZDQ1NzJjNDRmOTBmNzZjNDgxOWE3MTQifX19"),
RABBIT("2186bdc6-55b1-4b44-8a46-3c8a11d40f3d", "eyJ0ZXh0dXJlcyI6eyJTS0lOIjp7InVybCI6Imh0dHA6Ly90ZXh0dXJlcy5taW5lY3JhZnQubmV0L3RleHR1cmUvN2QxMTY5YjI2OTRhNmFiYTgyNjM2MDk5MjM2NWJjZGE1YTEwYzg5YTNhYTJiNDhjNDM4NTMxZGQ4Njg1YzNhNyJ9fX0="),
POLAR_BEAR("87324464-1700-468f-8333-e7779ec8c21e", "eyJ0ZXh0dXJlcyI6eyJTS0lOIjp7InVybCI6Imh0dHA6Ly90ZXh0dXJlcy5taW5lY3JhZnQubmV0L3RleHR1cmUvZDQ2ZDIzZjA0ODQ2MzY5ZmEyYTM3MDJjMTBmNzU5MTAxYWY3YmZlODQxOTk2NjQyOTUzM2NkODFhMTFkMmIifX19"),
LLAMA("75fb08e5-2419-46fa-bf09-57362138f234", "eyJ0ZXh0dXJlcyI6eyJTS0lOIjp7InVybCI6Imh0dHA6Ly90ZXh0dXJlcy5taW5lY3JhZnQubmV0L3RleHR1cmUvYzJiMWVjZmY3N2ZmZTNiNTAzYzMwYTU0OGViMjNhMWEwOGZhMjZmZDY3Y2RmZjM4OTg1NWQ3NDkyMTM2OCJ9fX0="),
PARROT("da0cac14-3763-45df-b884-c99a567882ac", "eyJ0ZXh0dXJlcyI6eyJTS0lOIjp7InVybCI6Imh0dHA6Ly90ZXh0dXJlcy5taW5lY3JhZnQubmV0L3RleHR1cmUvNTZkZTFlYjllMzI1ZTYyZjI4ZjJjMTgzZDM5YTY4MzExMzY0NDYzNjU3MjY0Njc1YThiNDYxY2QyOGM5In19fQ=="),
VILLAGER("b3ed4a1b-dfff-464c-87c0-c8029e1de47b", "eyJ0ZXh0dXJlcyI6eyJTS0lOIjp7InVybCI6Imh0dHA6Ly90ZXh0dXJlcy5taW5lY3JhZnQubmV0L3RleHR1cmUvYzZhYjYxYWNlMTM2MDE3YTg3YjFiODFiMTQ1ZWJjNjNlMmU2ZGE5ZDM2NGM4MTE5NGIzM2VlODY2ZmU0ZCJ9fX0="),
PHANTOM("9290add8-c291-4a5a-8f8a-594f165406a3", "eyJ0ZXh0dXJlcyI6eyJTS0lOIjp7InVybCI6Imh0dHA6Ly90ZXh0dXJlcy5taW5lY3JhZnQubmV0L3RleHR1cmUvN2U5NTE1M2VjMjMyODRiMjgzZjAwZDE5ZDI5NzU2ZjI0NDMxM2EwNjFiNzBhYzAzYjk3ZDIzNmVlNTdiZDk4MiJ9fX0="),
COD("d6d4c744-06b4-4a8a-bc7a-bdb0770bb1cf", "eyJ0ZXh0dXJlcyI6eyJTS0lOIjp7InVybCI6Imh0dHA6Ly90ZXh0dXJlcy5taW5lY3JhZnQubmV0L3RleHR1cmUvNzg5MmQ3ZGQ2YWFkZjM1Zjg2ZGEyN2ZiNjNkYTRlZGRhMjExZGY5NmQyODI5ZjY5MTQ2MmE0ZmIxY2FiMCJ9fX0="),
SALMON("0354c430-3979-4b6e-8e65-a99eb3ea8818", "eyJ0ZXh0dXJlcyI6eyJTS0lOIjp7InVybCI6Imh0dHA6Ly90ZXh0dXJlcy5taW5lY3JhZnQubmV0L3RleHR1cmUvOGFlYjIxYTI1ZTQ2ODA2Y2U4NTM3ZmJkNjY2ODI4MWNmMTc2Y2VhZmU5NWFmOTBlOTRhNWZkODQ5MjQ4NzgifX19"),
PUFFERFISH("258e3114-368c-48a1-85fd-be580912f0df", "eyJ0ZXh0dXJlcyI6eyJTS0lOIjp7InVybCI6Imh0dHA6Ly90ZXh0dXJlcy5taW5lY3JhZnQubmV0L3RleHR1cmUvMTcxNTI4NzZiYzNhOTZkZDJhMjI5OTI0NWVkYjNiZWVmNjQ3YzhhNTZhYzg4NTNhNjg3YzNlN2I1ZDhiYiJ9fX0="),
TROPICAL_FISH("d93c1bf6-616f-401a-af6e-f9b9803a0024", "eyJ0ZXh0dXJlcyI6eyJTS0lOIjp7InVybCI6Imh0dHA6Ly90ZXh0dXJlcy5taW5lY3JhZnQubmV0L3RleHR1cmUvMTc5ZTQ4ZDgxNGFhM2JjOTg0ZThhNmZkNGZiMTcwYmEwYmI0ODkzZjRiYmViZGU1ZmRmM2Y4Zjg3MWNiMjkyZiJ9fX0="),
DROWNED("2f169660-61be-46bd-acb5-1abef9fe5731", "eyJ0ZXh0dXJlcyI6eyJTS0lOIjp7InVybCI6Imh0dHA6Ly90ZXh0dXJlcy5taW5lY3JhZnQubmV0L3RleHR1cmUvYzNmN2NjZjYxZGJjM2Y5ZmU5YTYzMzNjZGUwYzBlMTQzOTllYjJlZWE3MWQzNGNmMjIzYjNhY2UyMjA1MSJ9fX0="),
DOLPHIN("8b7ccd6d-36de-47e0-8d5a-6f6799c6feb8", "eyJ0ZXh0dXJlcyI6eyJTS0lOIjp7InVybCI6Imh0dHA6Ly90ZXh0dXJlcy5taW5lY3JhZnQubmV0L3RleHR1cmUvOGU5Njg4Yjk1MGQ4ODBiNTViN2FhMmNmY2Q3NmU1YTBmYTk0YWFjNmQxNmY3OGU4MzNmNzQ0M2VhMjlmZWQzIn19fQ==");
// ---------------------------------------------------------------------
// Section: Variables
// ---------------------------------------------------------------------
/**
* User UUID that has given skin.
*/
private String uuid;
/**
* Base64 Encoded link to Minecraft texture.
*/
private String textureValue;
/**
* Skull owner.
*/
private Object skullOwner;
/**
* This map allows to access all enum values via their string.
*/
private final static Map<String, HeadLib> BY_NAME = new HashMap<>();
// ---------------------------------------------------------------------
// Section: Constructor
// ---------------------------------------------------------------------
/**
* This inits new enum value by given UUID and textureValue that is encoded in Base64.
* @param uuid User UUID String which skin must be loaded.
* @param textureValue Texture link encoded in Base64.
*/
HeadLib(String uuid, String textureValue)
{
this.uuid = uuid;
this.textureValue = textureValue;
}
// ---------------------------------------------------------------------
// Section: Methods that returns ItemStacks
// ---------------------------------------------------------------------
/**
* Returns an ItemStack of the size 1 of the custom head.
*
* @return an ItemStack of the custom head.
*/
public ItemStack toItemStack()
{
return this.toItemStack(1);
}
/**
* Returns an ItemStack of the custom head.
*
* @param amount the amount of items in the stack
* @return an ItemStack of the custom head.
*/
public ItemStack toItemStack(int amount)
{
return this.toItemStack(amount, null);
}
/**
* Returns an ItemStack of the size 1 of the custom head.
*
* @param displayName the name to display. Supports "&amp;" color codes
* @param loreLines optional lore lines. Supports "&amp;" color codes
* @return an ItemStack of the custom head.
*/
public ItemStack toItemStack(String displayName, String... loreLines)
{
return this.toItemStack(1, displayName, loreLines);
}
/**
* Returns an ItemStack of the custom head.
*
* @param amount the amount of items in the stack
* @param displayName the name to display. Supports "&amp;" color codes
* @param loreLines optional lore lines. Supports "&amp;" color codes
* @return an ItemStack of the custom head.
*/
public ItemStack toItemStack(int amount, String displayName, String... loreLines)
{
ItemStack item = new ItemStack(Material.PLAYER_HEAD, amount);
if (displayName != null)
{
ItemMeta meta = item.getItemMeta();
meta.setDisplayName(ChatColor.translateAlternateColorCodes('&', displayName));
if (loreLines.length != 0)
{
List<String> loreCC = new ArrayList<>();
Arrays.stream(loreLines).forEach(l -> loreCC.add(ChatColor.translateAlternateColorCodes('&', l)));
meta.setLore(loreCC);
}
item.setItemMeta(meta);
}
return this.setSkullOwner(item, this.getSkullOwner());
}
// ---------------------------------------------------------------------
// Section: Private inner methods
// ---------------------------------------------------------------------
/**
* This method returns SkullOwner or create new one if it is not created yet.
* SkullOwner is NBTTagCompound object that contains information about player_head skin.
* @return skullOwner object.
*/
private Object getSkullOwner()
{
if (this.skullOwner == null)
{
this.skullOwner = this.createOwnerCompound(this.uuid, this.textureValue);
}
return this.skullOwner;
}
/**
* This method creates new NBTTagCompound object that contains UUID and texture link.
* @param id - UUID of user.
* @param textureValue - Encoded texture string.
* @return NBTTagCompound object that contains all necessary information about player_head skin.
*/
private NBTTagCompound createOwnerCompound(String id, String textureValue)
{
NBTTagCompound skullOwner = new NBTTagCompound();
skullOwner.setString("Id", id);
NBTTagCompound properties = new NBTTagCompound();
NBTTagList textures = new NBTTagList();
NBTTagCompound value = new NBTTagCompound();
value.setString("Value", textureValue);
textures.add(value);
properties.set("textures", textures);
skullOwner.set("Properties", properties);
return skullOwner;
}
/**
* This method adds SkullOwner tag to given item.
* @param item Item whom SkullOwner tag must be added.
* @param compound NBTTagCompound object that contains UUID and texture link.
* @return new copy of given item with SkullOwner tag.
*/
private ItemStack setSkullOwner(ItemStack item, Object compound)
{
net.minecraft.server.v1_13_R2.ItemStack nmsStack = CraftItemStack.asNMSCopy(item);
nmsStack.getOrCreateTag().set("SkullOwner", (NBTBase) compound);
return CraftItemStack.asBukkitCopy(nmsStack);
}
// ---------------------------------------------------------------------
// Section: Other methods
// ---------------------------------------------------------------------
/**
* This method returns HeadLib enum object with given name. If enum value with given name does not exist,
* then return null.
* @param name Name of object that must be returned.
* @return HeadLib with given name or null.
*/
public static HeadLib getHead(String name)
{
return BY_NAME.get(name.toUpperCase());
}
//
// This static call populates all existing enum values into static map.
//
static
{
for (HeadLib head : values())
{
BY_NAME.put(head.name(), head);
}
}
}

View File

@ -1,6 +1,6 @@
package world.bentobox.challenges;
package world.bentobox.challenges.utils;
import world.bentobox.challenges.database.object.ChallengeLevels;
import world.bentobox.challenges.database.object.ChallengeLevel;
/**
* Level status class
@ -8,8 +8,8 @@ import world.bentobox.challenges.database.object.ChallengeLevels;
*
*/
public class LevelStatus {
private final ChallengeLevels level;
private final ChallengeLevels previousLevel;
private final ChallengeLevel level;
private final ChallengeLevel previousLevel;
private final int numberOfChallengesStillToDo;
private final boolean complete;
private final boolean isUnlocked;
@ -21,7 +21,7 @@ public class LevelStatus {
* @param complete - whether complete or not
* @param isUnlocked
*/
public LevelStatus(ChallengeLevels level, ChallengeLevels previousLevel, int numberOfChallengesStillToDo, boolean complete, boolean isUnlocked) {
public LevelStatus(ChallengeLevel level, ChallengeLevel previousLevel, int numberOfChallengesStillToDo, boolean complete, boolean isUnlocked) {
super();
this.level = level;
this.previousLevel = previousLevel;
@ -32,7 +32,7 @@ public class LevelStatus {
/**
* @return the level
*/
public ChallengeLevels getLevel() {
public ChallengeLevel getLevel() {
return level;
}
/**
@ -44,7 +44,7 @@ public class LevelStatus {
/**
* @return the previousLevel
*/
public ChallengeLevels getPreviousLevel() {
public ChallengeLevel getPreviousLevel() {
return previousLevel;
}
/**

View File

@ -1,16 +1,31 @@
# Challenges Config
# Challenges Configuration ${project.version}
# This config file is dynamic and saved when the server is shutdown.
# You cannot edit it while the server is running because changes will
# be lost! Use in-game settings GUI or edit when server is offline.
#
#
# Reset Challenges - if this is true, player's challenges will reset when they
# reset an island or if they are kicked or leave a team. Prevents exploiting the
# challenges by doing them repeatedly.
resetchallenges: true
resetChallenges: true
#
# Broadcast 1st time challenge completion messages to all players.
# Change to false if the spam becomes too much.
broadcastmessages: true
# Remove non-repeatable challenges from the challenge GUI when complete
removecompleteonetimechallenges: false
broadcastMessages: true
#
# Remove non-repeatable challenges from the challenge GUI when complete.
removeCompleteOneTimeChallenges: false
#
# Add enchanted glow to completed challenges
addcompletedglow: true
addCompletedGlow: true
#
# This indicate if free challenges must be at the start (true) or at the end (false) of list.
freeChallengesFirst: false
#
# This list stores GameModes in which Challenges addon should not work.
# To disable addon it is necessary to write its name in new line that starts with -. Example:
# disabled-gamemodes:
# - BSkyBlock
disabled-gamemodes: []
#
uniqueId: config

View File

@ -8,96 +8,211 @@
challenges:
admin:
challenge-created: "[challenge] created!"
challenge-created: '[challenge] created!'
complete:
description: "Mark challenge complete"
parameters: "<player> <unique challenge name>"
unknown-challenge: "&cUnknown challenge"
description: Mark challenge complete
parameters: <player> <unique challenge name>
unknown-challenge: '&cUnknown challenge'
create:
description: "&6Collect:"
description-item-color: "&B"
description: '&6Collect:'
description-item-color: '&B'
inventory:
description: "create an inventory challenge"
parameters: "[challenge name]"
description: create an inventory challenge
parameters: '[challenge name]'
surrounding:
description: "create a surrounding challenge"
hit-things: "Hit things to add them to the list of things required. Right click when done."
parameters: "[challenge name]"
description: "challenges admin"
description: create a surrounding challenge
hit-things: Hit things to add them to the list of things required. Right click when done.
parameters: '[challenge name]'
description: challenges admin
error:
no-name: "You must include a challenge name"
gui-title: "&aChallenges Admin"
no-name: You must include a challenge name
gui-title: '&aChallenges Admin'
import:
description: "import challenges from challenges.yml"
imported: "Imported '[challenge]'"
levels: "Importing levels: [levels]"
no-file: "&cCould not find challenges.yml file to import!"
no-levels: "Warning: No levels defined in challenges.yml"
no-load: "&cError: Could not load challenges.yml. [message]"
number: "Imported [number] challenges"
overwriting: "Overwriting '[challenge]'"
parameters: "[overwrite]"
skipping: "'[challenge]' already exists - skipping"
parameters: ""
add: 'Adding new challenge: [object]'
description: import challenges from challenges.yml
imported: Imported '[challenge]'
levels: 'Importing levels: [levels]'
no-file: '&cCould not find challenges.yml file to import!'
no-levels: 'Warning: No levels defined in challenges.yml'
no-load: '&cError: Could not load challenges.yml. [message]'
number: Imported [number] challenges
overwriting: Overwriting '[challenge]'
parameters: '[overwrite]'
skipping: '''[challenge]'' already exists - skipping'
parameters: ''
reload:
description: "reload challenges from the database"
parameters: ""
description: reload challenges from the database
parameters: ''
reset:
description: "Reset challenge to 0 times / incomplete"
parameters: "<player> <unique challenge name>"
description: Reset challenge to 0 times / incomplete
parameters: <player> <unique challenge name>
seticon:
description: "sets the challenge icon to inhand item"
description: sets the challenge icon to inhand item
error:
no-such-challenge: "&cNo such challenge name"
parameters: "[challenge name]"
you-added: "You added one [thing] to the challenge"
no-such-challenge: '&cNo such challenge name'
parameters: '[challenge name]'
you-added: You added one [thing] to the challenge
blocks-take-warning: Blocks will be removed.
challenge:
format: "[description]"
complete: "&BComplete"
format: '[description]'
complete: '&BComplete'
completechallenge:
challange-completed: "Challenge: [challengename] has been completed for [name]"
completed-times: "Completed [donetimes] out of [maxtimes]"
description: "Open the challenges menu"
challange-completed: 'Challenge: [challengename] has been completed for [name]'
completed-times: Completed [donetimes] out of [maxtimes]
description: Open the challenges menu
entities-kill-warning: Entities will be killed.
error:
could-not-save: "&cCould not save the challenge!"
island-level: "&cYour island must be level [number] to complete this challenge!"
items-not-there: "&cAll required items must be close to you on your island!"
no-items-clicked: "&cYou did not click on anything. Cancelling."
not-close-enough: "&cYou must be standing within [number] blocks of all required items."
not-enough-items: "&cYou do not have enough [items] to complete this challenge!"
not-on-island: "&cYou must be on your island to do that!"
reward-problem: "&cThere was a problem giving your reward. Ask Admin to check log!"
you-still-need: "&cYou still need [amount] x [item]"
exp-reward: "&6Exp reward: [reward]"
first-time-rewards: "&6First time reward(s)"
gui-title: "&aChallenges"
could-not-save: '&cCould not save the challenge!'
island-level: '&cYour island must be level [number] to complete this challenge!'
items-not-there: '&cAll required items must be close to you on your island!'
no-items-clicked: '&cYou did not click on anything. Cancelling.'
not-close-enough: '&cYou must be standing within [number] blocks of all required
items.'
not-enough-items: '&cYou do not have enough [items] to complete this challenge!'
not-on-island: '&cYou must be on your island to do that!'
reward-problem: '&cThere was a problem giving your reward. Ask Admin to check
log!'
you-still-need: '&cYou still need [amount] x [item]'
not-deployed: '&cChallenge is not deployed.'
errors:
challenge-level-not-available: You have not unlocked level to complete this challenge.
unique-id: Unique ID [id] is already taken. Choose different.
wrong-environment: You are in wrong environment!
wrong-icon: Material [icon] is not recognized
exp-reward: '&6Exp reward: [reward]'
first-time-rewards: '&6First time reward(s)'
gui:
admin:
buttons:
add-challenge: Create Challenge
add-level: Create Level
blocks: Blocks
broadcast: Broadcast Messages
challenges: Challenges
complete: Complete
delete-challenge: Delete Challenge
delete-level: Delete Level
deployed: Deployment status
description: Description
edit-challenge: Edit Challenge
edit-level: Edit Level
entities: Entities
environment: Environment
free-challenges: Free Challenges Position
glow: Completion Glowing
icon: Icon
name: Name
order: Order Number
permissions: Permissions
properties: Properties
remove-blocks: Remove Blocks
remove-challenge: Remove Challenge
remove-entities: Remove Entities
remove-exp: Take Experience
remove-items: Remove items
remove-money: Remove Money
remove-on-complete: Remove on completion
repeat-count: Repeat Count
repeat-reward-command: Repeat Reward Command
repeat-reward-exp: Repeat Reward Experience
repeat-reward-items: Repeat Reward Items
repeat-reward-money: Repeat Reward Money
repeat-reward-text: Repeat Reward Text
repeatable: Repeatable
required-exp: Required Experience
required-items: Required items
required-level: Required Island Level
required-money: Required Money
requirements: Requirements
reset: Reset
reward-command: Reward Command
reward-exp: Reward Experience
reward-items: Reward Items
reward-money: Reward Money
reward-text: Reward Text
rewards: Rewards
search-radius: Search radius
settings: Settings
toggle-users: Choose players
type: 'Challenge Type: [value]'
waiver-amount: Waiver Amount
import: Import
choose-challenge-title: Challenges List
choose-level-title: Levels List
choose-user-title: Users List
descriptions:
broadcast: Broadcast 1st time challenge completion messages to all players.
disabled: disabled
enabled: enabled
free-challenges: This indicate if free challenges must be at the start (true) or at the end (false) of list.
glow: Add enchanted glow to completed challenges
in_world: In World
inventory: This type of challenges allows to define blocks and entities on island requirements.
island: This type of challenges allows to define inventory item requirements.
nether: Nether
normal: Normal
online: Online
order: Current order [value]
other: This type of challenges allows to define Money, Experience or island level requirements.
remove-on-complete: Remove non-repeatable challenges from the challenge GUI when complete.
repeat-count: 'Current value: [value]'
repeat-reward-exp: 'Current value: [value]'
repeat-reward-money: 'Current value: [value]'
required-exp: Current necessary [value]
required-level: 'Current value: [value]'
required-money: 'Current value: [value]'
reset: Reset Challenges - if this is true, player's challenges will reset when they reset an island or if they are kicked or leave a team
reward-exp: 'Current value: [value]'
reward-money: 'Current value: [value]'
search-radius: Current radius [value]
the_end: The End
waiver-amount: 'Current value: [value]'
with_island: With Island
edit-challenge-title: Edit Challenge
edit-entities: Manage Entities
edit-level-title: Edit Levels
manage-blocks: Manage Blocks
settings-title: Edit Settings
button:
add: Add
remove-selected: Remove Selected
buttons:
back: Return
next: Next
previous: Previous
title: '"Challenges GUI"'
gui-title: '&aChallenges'
help:
command: "/challenges: &fshow challenges"
config-reloaded: "Configuration reloaded from file."
reset-all-challenges: "resets all of the player's challenges"
reset-challenge: "marks a challenge as incomplete"
reset-challenge-for-all: "globally resets a challenge for every player with an optional repetition"
command: '/challenges: &fshow challenges'
config-reloaded: Configuration reloaded from file.
reset-all-challenges: resets all of the player's challenges
reset-challenge: marks a challenge as incomplete
reset-challenge-for-all: globally resets a challenge for every player with an optional repetition
incomplete: Incomplete
item-take-warning: "&cAll required items are|&ctaken when you complete|&cthis challenge!"
items-closeby: "&cAll required items|&cmust be close to you|&con your island!"
level: "&FLevel: [level]"
max-reached: "Max reached [donetimes] out of [maxtimes]"
money-reward: "&6Money reward: $[reward]"
name: "Challenge Name"
name-has-completed: "[name] has completed the [challenge] challenge!"
navigation: "Click to see [level] challenges!"
not-repeatable: "This challenge is not repeatable!"
parameters: "[Level]"
repeat-rewards: "&6Repeat reward(s)"
repeatable: "This challenge can be repeated [maxtimes] times"
item-take-warning: '&cAll required items are|&ctaken when you complete|&cthis
challenge!'
items-closeby: '&cAll required items|&cmust be close to you|&con your island!'
level: '&FLevel: [level]'
max-reached: Max reached [donetimes] out of [maxtimes]
maxed-reached: Completed [donetimes] out of [maxtimes]
money-reward: '&6Money reward: $[reward]'
name: Challenge Name
name-has-completed: '[name] has completed the [challenge] challenge!'
name-has-completed-level: '[name] completed all challenges in [level]!'
navigation: Click to see [level] challenges!
not-enough-exp: It is necessary to have [xp] EXP to complete challenge.
not-enough-money: It is necessary to have [money] on your account to complete the challenge.
not-repeatable: This challenge is not repeatable!
parameters: '[Level]'
repeat-rewards: '&6Repeat reward(s)'
repeatable: This challenge can be repeated [maxtimes] times
resetallchallenges:
success: "[name] has had all challenges reset."
success: '[name] has had all challenges reset.'
resetchallenge:
challenge-reset: "Challenge: [challengename] has been reset for [name]"
error-challenge-does-not-exist: "Challenge doesn't exist or isn't yet completed"
rewards: "&FReward(s)"
to-complete: "Complete [challengesToDo] more [thisLevel] challenges to unlock this level!"
you-completed: "You completed the [challenge] challenge!"
you-repeated: "You repeated the [challenge] challenge!"
not-enough-money: "It is necessary to have [money] on your account to complete the challenge."
not-enough-exp: "It is necessary to have [xp] EXP to complete challenge."
challenge-reset: 'Challenge: [challengename] has been reset for [name]'
error-challenge-does-not-exist: Challenge doesn't exist or isn't yet completed
rewards: '&FReward(s)'
to-complete: Complete [challengesToDo] more [thisLevel] challenges to unlock this level!
you-completed: You completed the [challenge] challenge!
you-completed-level: Congratulations, you complete [level]!
you-repeated: You repeated the [challenge] challenge!

View File

@ -35,8 +35,8 @@ import org.powermock.modules.junit4.PowerMockRunner;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import world.bentobox.challenges.database.object.Challenges;
import world.bentobox.challenges.database.object.Challenges.ChallengeType;
import world.bentobox.challenges.database.object.Challenge;
import world.bentobox.challenges.database.object.Challenge.ChallengeType;
/**
* @author tastybento
@ -81,7 +81,7 @@ public class ChallengesAddonTest {
public void test() {
Gson gson = new GsonBuilder().setPrettyPrinting().create();
Challenges challenges = new Challenges();
Challenge challenges = new Challenge();
challenges.setChallengeType(ChallengeType.ISLAND);
Map<Material, Integer> map = new HashMap<>();
map.put(Material.DIRT, 5);

View File

@ -26,6 +26,7 @@ import world.bentobox.challenges.ChallengesAddon;
import world.bentobox.challenges.ParseItem;
@RunWith(PowerMockRunner.class)
@Deprecated
public class ParseItemTest {
private static ChallengesAddon addon;