mirror of
https://github.com/BentoBoxWorld/Challenges.git
synced 2024-11-23 11:05:47 +01:00
Moved everything to world.bentobox.challenges package
This commit is contained in:
parent
5009729300
commit
8f51ddb634
105
src/main/java/world/bentobox/challenges/ChallengesAddon.java
Normal file
105
src/main/java/world/bentobox/challenges/ChallengesAddon.java
Normal file
@ -0,0 +1,105 @@
|
|||||||
|
package world.bentobox.challenges;
|
||||||
|
|
||||||
|
import org.bukkit.Bukkit;
|
||||||
|
|
||||||
|
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;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add-on to BSkyBlock that enables challenges
|
||||||
|
* @author tastybento
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public class ChallengesAddon extends Addon {
|
||||||
|
|
||||||
|
private ChallengesManager challengesManager;
|
||||||
|
private String permissionPrefix = "addon";
|
||||||
|
private FreshSqueezedChallenges importManager;
|
||||||
|
private boolean hooked;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onLoad() {
|
||||||
|
// Save default config.yml
|
||||||
|
saveDefaultConfig();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onEnable() {
|
||||||
|
// Check if it is enabled - it might be loaded, but not enabled.
|
||||||
|
if (getPlugin() == null || !getPlugin().isEnabled()) {
|
||||||
|
Bukkit.getLogger().severe("BentoBox is not available or disabled!");
|
||||||
|
this.setState(State.DISABLED);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Challenges Manager
|
||||||
|
challengesManager = new ChallengesManager(this);
|
||||||
|
// Challenge import setup
|
||||||
|
importManager = new FreshSqueezedChallenges(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;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
// 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!");
|
||||||
|
}
|
||||||
|
// Register the reset listener
|
||||||
|
this.registerListener(new ResetListener(this));
|
||||||
|
// Register the autosave listener.
|
||||||
|
this.registerListener(new SaveListener(this));
|
||||||
|
// Done
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onDisable(){
|
||||||
|
if (challengesManager != null) {
|
||||||
|
challengesManager.save(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public ChallengesManager getChallengesManager() {
|
||||||
|
return challengesManager;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getPermissionPrefix() {
|
||||||
|
return permissionPrefix ;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the importManager
|
||||||
|
*/
|
||||||
|
public FreshSqueezedChallenges getImportManager() {
|
||||||
|
return importManager;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
529
src/main/java/world/bentobox/challenges/ChallengesManager.java
Normal file
529
src/main/java/world/bentobox/challenges/ChallengesManager.java
Normal file
@ -0,0 +1,529 @@
|
|||||||
|
package world.bentobox.challenges;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.LinkedHashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Map.Entry;
|
||||||
|
import java.util.Optional;
|
||||||
|
import java.util.Set;
|
||||||
|
import java.util.UUID;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
import org.apache.commons.lang.WordUtils;
|
||||||
|
import org.bukkit.ChatColor;
|
||||||
|
import org.bukkit.Material;
|
||||||
|
import org.bukkit.World;
|
||||||
|
import org.bukkit.inventory.Inventory;
|
||||||
|
import org.bukkit.inventory.ItemStack;
|
||||||
|
|
||||||
|
import world.bentobox.challenges.commands.admin.SurroundChallengeBuilder;
|
||||||
|
import world.bentobox.challenges.objects.ChallengeLevels;
|
||||||
|
import world.bentobox.challenges.objects.Challenges;
|
||||||
|
import world.bentobox.challenges.objects.Challenges.ChallengeType;
|
||||||
|
import world.bentobox.challenges.objects.ChallengesPlayerData;
|
||||||
|
import world.bentobox.challenges.panel.ChallengesPanels;
|
||||||
|
import world.bentobox.bentobox.api.configuration.Config;
|
||||||
|
import world.bentobox.bentobox.api.user.User;
|
||||||
|
import world.bentobox.bentobox.database.Database;
|
||||||
|
import world.bentobox.bentobox.util.Util;
|
||||||
|
|
||||||
|
public class ChallengesManager {
|
||||||
|
|
||||||
|
public static final String FREE = "Free";
|
||||||
|
private Map<ChallengeLevels, Set<Challenges>> challengeMap;
|
||||||
|
private Config<Challenges> chConfig;
|
||||||
|
private Config<ChallengeLevels> lvConfig;
|
||||||
|
private Database<ChallengesPlayerData> players;
|
||||||
|
private ChallengesPanels challengesPanels;
|
||||||
|
private Map<UUID,ChallengesPlayerData> playerData;
|
||||||
|
private ChallengesAddon addon;
|
||||||
|
|
||||||
|
public ChallengesManager(ChallengesAddon addon) {
|
||||||
|
this.addon = addon;
|
||||||
|
// Set up the configs
|
||||||
|
chConfig = new Config<>(addon, Challenges.class);
|
||||||
|
lvConfig = new Config<>(addon, ChallengeLevels.class);
|
||||||
|
// Players is where all the player history will be stored
|
||||||
|
players = new Database<>(addon, ChallengesPlayerData.class);
|
||||||
|
// Cache of challenges
|
||||||
|
challengeMap = new LinkedHashMap<>();
|
||||||
|
// Cache of player data
|
||||||
|
playerData = new HashMap<>();
|
||||||
|
load();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Load player from database into the cache or create new player data
|
||||||
|
* @param user - user to add
|
||||||
|
*/
|
||||||
|
private void addPlayer(User user) {
|
||||||
|
if (playerData.containsKey(user.getUniqueId())) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// The player is not in the cache
|
||||||
|
// Check if the player exists in the database
|
||||||
|
if (players.objectExists(user.getUniqueId().toString())) {
|
||||||
|
// Load player from database
|
||||||
|
ChallengesPlayerData data = players.loadObject(user.getUniqueId().toString());
|
||||||
|
// Store in cache
|
||||||
|
playerData.put(user.getUniqueId(), data);
|
||||||
|
} else {
|
||||||
|
// Create the player data
|
||||||
|
ChallengesPlayerData pd = new ChallengesPlayerData(user.getUniqueId().toString());
|
||||||
|
players.saveObject(pd);
|
||||||
|
// Add to cache
|
||||||
|
playerData.put(user.getUniqueId(), pd);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check how many times a player has done a challenge before
|
||||||
|
* @param user - user
|
||||||
|
* @param challenge - challenge
|
||||||
|
* @return - number of times
|
||||||
|
*/
|
||||||
|
public long checkChallengeTimes(User user, Challenges challenge, World world) {
|
||||||
|
addPlayer(user);
|
||||||
|
return playerData.get(user.getUniqueId()).getTimes(world, challenge.getUniqueId());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a simple example description of the requirements
|
||||||
|
* @param user - user of this command
|
||||||
|
* @param requiredItems - list of items
|
||||||
|
* @return Description list
|
||||||
|
*/
|
||||||
|
private List<String> createDescription(User user, List<ItemStack> requiredItems) {
|
||||||
|
addPlayer(user);
|
||||||
|
List<String> result = new ArrayList<>();
|
||||||
|
result.add(user.getTranslation("challenges.admin.create.description"));
|
||||||
|
for (ItemStack item : requiredItems) {
|
||||||
|
result.add(user.getTranslation("challenges.admin.create.description-item-color") + item.getAmount() + " x " + Util.prettifyText(item.getType().toString()));
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates an inventory challenge
|
||||||
|
* @param user - the user who is making the challenge
|
||||||
|
* @param inventory - the inventory that will be used to make the challenge
|
||||||
|
*/
|
||||||
|
public boolean createInvChallenge(User user, Inventory inventory) {
|
||||||
|
addPlayer(user);
|
||||||
|
if (inventory.getContents().length == 0) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
Challenges newChallenge = new Challenges();
|
||||||
|
newChallenge.setChallengeType(ChallengeType.INVENTORY);
|
||||||
|
newChallenge.setFriendlyName(inventory.getTitle());
|
||||||
|
newChallenge.setDeployed(false);
|
||||||
|
List<ItemStack> requiredItems = new ArrayList<>();
|
||||||
|
inventory.forEach(item -> {
|
||||||
|
if (item != null && !item.getType().equals(Material.AIR)) {
|
||||||
|
requiredItems.add(item);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
newChallenge.setRequiredItems(requiredItems);
|
||||||
|
newChallenge.setTakeItems(true);
|
||||||
|
newChallenge.setUniqueId(inventory.getTitle());
|
||||||
|
newChallenge.setIcon(new ItemStack(Material.MAP));
|
||||||
|
newChallenge.setLevel(FREE);
|
||||||
|
newChallenge.setDescription(createDescription(user, requiredItems));
|
||||||
|
|
||||||
|
// Move all the items back to the player's inventory
|
||||||
|
inventory.forEach(item -> {
|
||||||
|
if (item != null) {
|
||||||
|
Map<Integer, ItemStack> residual = user.getInventory().addItem(item);
|
||||||
|
// Drop any residual items at the foot of the player
|
||||||
|
residual.forEach((k, v) -> user.getWorld().dropItem(user.getLocation(), v));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// Save the challenge
|
||||||
|
if (!chConfig.saveConfigObject(newChallenge)) {
|
||||||
|
user.sendRawMessage(ChatColor.RED + "Challenge creation failed!");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
user.sendRawMessage("Success");
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a surrounding challenge
|
||||||
|
* @param challengeInfo - info on the challenge from the builder
|
||||||
|
* @return true if successful, false if not
|
||||||
|
*/
|
||||||
|
public boolean createSurroundingChallenge(SurroundChallengeBuilder challengeInfo) {
|
||||||
|
if (challengeInfo.getReqBlocks().isEmpty() && challengeInfo.getReqEntities().isEmpty()) {
|
||||||
|
challengeInfo.getOwner().sendMessage("challenges.error.no-items-clicked");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
Challenges newChallenge = new Challenges();
|
||||||
|
newChallenge.setChallengeType(ChallengeType.ISLAND);
|
||||||
|
newChallenge.setFriendlyName(challengeInfo.getName());
|
||||||
|
newChallenge.setDeployed(true);
|
||||||
|
newChallenge.setRequiredBlocks(challengeInfo.getReqBlocks());
|
||||||
|
newChallenge.setRequiredEntities(challengeInfo.getReqEntities());
|
||||||
|
newChallenge.setUniqueId(challengeInfo.getName());
|
||||||
|
newChallenge.setIcon(new ItemStack(Material.ARMOR_STAND));
|
||||||
|
newChallenge.setLevel(FREE);
|
||||||
|
|
||||||
|
// Save the challenge
|
||||||
|
if (!chConfig.saveConfigObject(newChallenge)) {
|
||||||
|
challengeInfo.getOwner().sendMessage("challenges.error.could-not-save");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the list of all challenge unique names.
|
||||||
|
* @return List of challenge names
|
||||||
|
*/
|
||||||
|
public List<String> getAllChallengesList() {
|
||||||
|
List<String> result = new ArrayList<>();
|
||||||
|
challengeMap.values().forEach(ch -> ch.forEach(c -> result.add(c.getUniqueId())));
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the list of all challenge unique names for world.
|
||||||
|
* @param world - the world to check
|
||||||
|
* @return List of challenge names
|
||||||
|
*/
|
||||||
|
public List<String> getAllChallengesList(World world) {
|
||||||
|
List<String> result = new ArrayList<>();
|
||||||
|
challengeMap.values().forEach(ch -> ch.stream().filter(c -> c.getWorld().equals(Util.getWorld(world).getName())).forEach(c -> result.add(c.getUniqueId())));
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get challenge by name
|
||||||
|
* @param name - unique name of challenge
|
||||||
|
* @param world - world to check
|
||||||
|
* @return - challenge or null if it does not exist
|
||||||
|
*/
|
||||||
|
public Challenges getChallenge(String name, World world) {
|
||||||
|
String worldName = Util.getWorld(world).getName();
|
||||||
|
for (Set<Challenges> ch : challengeMap.values()) {
|
||||||
|
Optional<Challenges> challenge = ch.stream().filter(c -> c.getUniqueId().equalsIgnoreCase(worldName + name)).findFirst();
|
||||||
|
if (challenge.isPresent()) {
|
||||||
|
return challenge.get();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the status on every level
|
||||||
|
* @param user - user
|
||||||
|
* @param world - world to check
|
||||||
|
* @return Level status - how many challenges still to do on which level
|
||||||
|
*/
|
||||||
|
public List<LevelStatus> getChallengeLevelStatus(User user, World world) {
|
||||||
|
addPlayer(user);
|
||||||
|
ChallengesPlayerData pd = playerData.get(user.getUniqueId());
|
||||||
|
List<LevelStatus> result = new ArrayList<>();
|
||||||
|
ChallengeLevels previousLevel = null;
|
||||||
|
// The first level is always unlocked
|
||||||
|
boolean isUnlocked = true;
|
||||||
|
// For each challenge level, check how many the user has done
|
||||||
|
for (Entry<ChallengeLevels, Set<Challenges>> en : challengeMap.entrySet()) {
|
||||||
|
int total = challengeMap.values().size();
|
||||||
|
int waiverAmount = en.getKey().getWaiveramount();
|
||||||
|
int challengesDone = (int) en.getValue().stream().filter(ch -> pd.isChallengeDone(world, ch.getUniqueId())).count();
|
||||||
|
int challsToDo = Math.max(0,total - challengesDone - waiverAmount);
|
||||||
|
boolean complete = challsToDo > 0 ? false : true;
|
||||||
|
// Create result class with the data
|
||||||
|
result.add(new LevelStatus(en.getKey(), previousLevel, challsToDo, complete, isUnlocked));
|
||||||
|
// Set up the next level for the next loop
|
||||||
|
previousLevel = en.getKey();
|
||||||
|
isUnlocked = complete;
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the challenge list
|
||||||
|
* @return the challengeList
|
||||||
|
*/
|
||||||
|
public Map<ChallengeLevels, Set<Challenges>> getChallengeList() {
|
||||||
|
// TODO return the challenges for world
|
||||||
|
return challengeMap;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the set of challenges for this level for this world
|
||||||
|
* @param level - the level required
|
||||||
|
* @param world
|
||||||
|
* @return the set of challenges for this level, or the first set of challenges if level is blank, or a blank list if there are no challenges
|
||||||
|
*/
|
||||||
|
public Set<Challenges> getChallenges(String level, World world) {
|
||||||
|
String worldName = Util.getWorld(world).getName();
|
||||||
|
Optional<ChallengeLevels> lv = challengeMap.keySet().stream().filter(l -> l.getUniqueId().equalsIgnoreCase(level)).findFirst();
|
||||||
|
// Get the challenges applicable to this world
|
||||||
|
return lv.isPresent() ? challengeMap.get(lv.get()).stream()
|
||||||
|
.filter(c -> c.getWorld().equalsIgnoreCase(worldName) || c.getWorld().isEmpty()).collect(Collectors.toSet())
|
||||||
|
: new HashSet<>();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the challengesPanels
|
||||||
|
*/
|
||||||
|
public ChallengesPanels getChallengesPanels() {
|
||||||
|
return challengesPanels;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the previous level to the one supplied
|
||||||
|
* @param currentLevel - the current level
|
||||||
|
* @return the previous level, or null if there is none
|
||||||
|
*/
|
||||||
|
public ChallengeLevels getPreviousLevel(ChallengeLevels currentLevel) {
|
||||||
|
ChallengeLevels result = null;
|
||||||
|
for (ChallengeLevels level : challengeMap.keySet()) {
|
||||||
|
if (level.equals(currentLevel)) {
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
result = level;
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if a challenge exists - case insensitive
|
||||||
|
* @param name - name of challenge
|
||||||
|
* @return true if it exists, otherwise false
|
||||||
|
*/
|
||||||
|
public boolean isChallenge(String name) {
|
||||||
|
for (Set<Challenges> ch : challengeMap.values()) {
|
||||||
|
if (ch.stream().anyMatch(c -> c.getUniqueId().equalsIgnoreCase(name))) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if a challenge exists in world - case insensitive
|
||||||
|
* @param world - world to check
|
||||||
|
* @param name - name of challenge
|
||||||
|
* @return true if it exists, otherwise false
|
||||||
|
*/
|
||||||
|
public boolean isChallenge(World world, String name) {
|
||||||
|
for (Set<Challenges> ch : challengeMap.values()) {
|
||||||
|
if (ch.stream().filter(c -> c.getWorld().equals(Util.getWorld(world).getName())).anyMatch(c -> c.getUniqueId().equalsIgnoreCase(name))) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks if a challenge is complete or not
|
||||||
|
* @param uniqueId - unique ID - player's UUID
|
||||||
|
* @param challengeName - Challenge uniqueId
|
||||||
|
* @return - true if completed
|
||||||
|
*/
|
||||||
|
public boolean isChallengeComplete(User user, String challengeName, World world) {
|
||||||
|
addPlayer(user);
|
||||||
|
return playerData.get(user.getUniqueId()).isChallengeDone(world, challengeName);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check is user can see level
|
||||||
|
* @param user - user
|
||||||
|
* @param level - level unique id
|
||||||
|
* @return true if level is unlocked
|
||||||
|
*/
|
||||||
|
public boolean isLevelUnlocked(User user, String level, World world) {
|
||||||
|
addPlayer(user);
|
||||||
|
return getChallengeLevelStatus(user, world).stream().filter(LevelStatus::isUnlocked).anyMatch(lv -> lv.getLevel().getUniqueId().equalsIgnoreCase(level));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Clear and reload all challenges
|
||||||
|
*/
|
||||||
|
public void load() {
|
||||||
|
// Load the challenges
|
||||||
|
challengeMap.clear();
|
||||||
|
addon.getLogger().info("Loading challenges...");
|
||||||
|
chConfig.loadConfigObjects().forEach(this::storeChallenge);
|
||||||
|
sortChallenges();
|
||||||
|
players.loadObjects().forEach(pd -> {
|
||||||
|
try {
|
||||||
|
UUID uuid = UUID.fromString(pd.getUniqueId());
|
||||||
|
playerData.put(uuid,pd);
|
||||||
|
} catch (Exception e) {
|
||||||
|
addon.getLogger().severe("UUID for player in challenge data file is invalid!");
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Save configs and player data
|
||||||
|
*/
|
||||||
|
private void save() {
|
||||||
|
challengeMap.entrySet().forEach(en -> {
|
||||||
|
lvConfig.saveConfigObject(en.getKey());
|
||||||
|
en.getValue().forEach(chConfig::saveConfigObject);
|
||||||
|
});
|
||||||
|
savePlayers();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void savePlayers() {
|
||||||
|
playerData.values().forEach(players :: saveObject);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void savePlayer(UUID playerUUID) {
|
||||||
|
if (playerData.containsKey(playerUUID)) {
|
||||||
|
players.saveObject(playerData.get(playerUUID));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Save to the database
|
||||||
|
* @param async - if true, saving will be done async
|
||||||
|
*/
|
||||||
|
public void save(boolean async) {
|
||||||
|
if (async) {
|
||||||
|
addon.getServer().getScheduler().runTaskAsynchronously(addon.getPlugin(), this::save);
|
||||||
|
} else {
|
||||||
|
save();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the challenge as complete and increments the number of times it has been completed
|
||||||
|
* @param user - user
|
||||||
|
* @param challengeUniqueId - unique challenge id
|
||||||
|
* @param world - world to set
|
||||||
|
*/
|
||||||
|
public void setChallengeComplete(User user, String challengeUniqueId, World world) {
|
||||||
|
addPlayer(user);
|
||||||
|
playerData.get(user.getUniqueId()).setChallengeDone(world, challengeUniqueId);
|
||||||
|
// Save
|
||||||
|
savePlayer(user.getUniqueId());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reset the challenge to zero time / not done
|
||||||
|
* @param user - user
|
||||||
|
* @param challengeUniqueId - unique challenge id
|
||||||
|
* @param world - world to set
|
||||||
|
*/
|
||||||
|
public void setResetChallenge(User user, String challengeUniqueId, World world) {
|
||||||
|
addPlayer(user);
|
||||||
|
playerData.get(user.getUniqueId()).setChallengeTimes(world, challengeUniqueId, 0);
|
||||||
|
// Save
|
||||||
|
savePlayer(user.getUniqueId());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param challengeList the challengeList to set
|
||||||
|
*/
|
||||||
|
public void setChallengeList(Map<ChallengeLevels, Set<Challenges>> challengeList) {
|
||||||
|
this.challengeMap = challengeList;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void sortChallenges() {
|
||||||
|
// Sort the challenge list into level order
|
||||||
|
challengeMap = challengeMap.entrySet().stream()
|
||||||
|
.sorted(Map.Entry.comparingByKey())
|
||||||
|
.collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue,
|
||||||
|
(oldValue, newValue) -> oldValue, LinkedHashMap::new));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Store challenge silently. Used when loading.
|
||||||
|
* @param challenge
|
||||||
|
* @return true if successful
|
||||||
|
*/
|
||||||
|
private boolean storeChallenge(Challenges challenge) {
|
||||||
|
return storeChallenge(challenge, true, null, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Stores the challenge.
|
||||||
|
* @param challenge - challenge
|
||||||
|
* @param overwrite - true if previous challenge should be overwritten
|
||||||
|
* @param user - user making the request
|
||||||
|
* @param silent - if true, no messages are sent to user
|
||||||
|
* @return - true if imported
|
||||||
|
*/
|
||||||
|
public boolean storeChallenge(Challenges challenge, boolean overwrite, User user, boolean silent) {
|
||||||
|
// See if we have this level already
|
||||||
|
ChallengeLevels level;
|
||||||
|
if (lvConfig.configObjectExists(challenge.getLevel())) {
|
||||||
|
// Get it from the database
|
||||||
|
level = lvConfig.loadConfigObject(challenge.getLevel());
|
||||||
|
} else {
|
||||||
|
// Make it
|
||||||
|
level = new ChallengeLevels();
|
||||||
|
level.setUniqueId(challenge.getLevel());
|
||||||
|
lvConfig.saveConfigObject(level);
|
||||||
|
}
|
||||||
|
challengeMap.putIfAbsent(level, new HashSet<>());
|
||||||
|
if (challengeMap.get(level).contains(challenge)) {
|
||||||
|
if (!overwrite) {
|
||||||
|
if (!silent) {
|
||||||
|
user.sendMessage("challenges.admin.import.skipping", "[challenge]", challenge.getFriendlyName());
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
} else {
|
||||||
|
if (!silent) {
|
||||||
|
user.sendMessage("challenges.admin.import.overwriting", "[challenge]", challenge.getFriendlyName());
|
||||||
|
}
|
||||||
|
challengeMap.get(level).add(challenge);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!silent) {
|
||||||
|
user.sendMessage("challenges.admin.import.imported", "[challenge]", challenge.getFriendlyName());
|
||||||
|
}
|
||||||
|
challengeMap.get(level).add(challenge);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Store a challenge level
|
||||||
|
* @param level the challenge level
|
||||||
|
*/
|
||||||
|
public void storeLevel(ChallengeLevels level) {
|
||||||
|
lvConfig.saveConfigObject(level);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Simple splitter
|
||||||
|
* @param string - string to be split
|
||||||
|
* @return list of split strings
|
||||||
|
*/
|
||||||
|
public List<String> stringSplit(String string) {
|
||||||
|
string = ChatColor.translateAlternateColorCodes('&', string);
|
||||||
|
// Check length of lines
|
||||||
|
List<String> result = new ArrayList<>();
|
||||||
|
Arrays.asList(string.split("\\|")).forEach(line -> result.addAll(Arrays.asList(WordUtils.wrap(line,25).split("\\n"))));
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Resets all the challenges for user in world
|
||||||
|
* @param uuid - island owner's UUID
|
||||||
|
* @param world - world
|
||||||
|
*/
|
||||||
|
public void resetAllChallenges(UUID uuid, World world) {
|
||||||
|
User user = User.getInstance(uuid);
|
||||||
|
addPlayer(user);
|
||||||
|
playerData.get(user.getUniqueId()).reset(world);
|
||||||
|
// Save
|
||||||
|
savePlayer(user.getUniqueId());
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,193 @@
|
|||||||
|
package world.bentobox.challenges;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.EnumMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import org.bukkit.Material;
|
||||||
|
import org.bukkit.World;
|
||||||
|
import org.bukkit.configuration.ConfigurationSection;
|
||||||
|
import org.bukkit.configuration.InvalidConfigurationException;
|
||||||
|
import org.bukkit.configuration.file.YamlConfiguration;
|
||||||
|
import org.bukkit.entity.EntityType;
|
||||||
|
import org.bukkit.inventory.ItemStack;
|
||||||
|
|
||||||
|
import world.bentobox.challenges.objects.ChallengeLevels;
|
||||||
|
import world.bentobox.challenges.objects.Challenges;
|
||||||
|
import world.bentobox.bentobox.api.user.User;
|
||||||
|
import world.bentobox.bentobox.util.Util;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Imports challenges
|
||||||
|
* @author tastybento
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public class FreshSqueezedChallenges {
|
||||||
|
|
||||||
|
private ChallengesAddon addon;
|
||||||
|
private YamlConfiguration chal;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Import challenges from challenges.yml
|
||||||
|
* @param challengesAddon
|
||||||
|
*/
|
||||||
|
public FreshSqueezedChallenges(ChallengesAddon challengesAddon) {
|
||||||
|
this.addon = challengesAddon;
|
||||||
|
File challengeFile = new File(addon.getDataFolder(), "challenges.yml");
|
||||||
|
if (!challengeFile.exists()) {
|
||||||
|
addon.saveResource("challenges.yml",false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Import challenges
|
||||||
|
* @param user - user
|
||||||
|
* @param world - world to import into
|
||||||
|
* @param overwrite - true if previous ones should be overwritten
|
||||||
|
* @return true if successful
|
||||||
|
*/
|
||||||
|
public boolean importChallenges(User user, World world, boolean overwrite) {
|
||||||
|
File challengeFile = new File(addon.getDataFolder(), "challenges.yml");
|
||||||
|
if (!challengeFile.exists()) {
|
||||||
|
user.sendMessage("challenges.admin.import.no-file");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
chal = new YamlConfiguration();
|
||||||
|
try {
|
||||||
|
chal.load(challengeFile);
|
||||||
|
} catch (IOException | InvalidConfigurationException e) {
|
||||||
|
user.sendMessage("challenges.admin.import.no-load","[message]", e.getMessage());
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
makeLevels(user);
|
||||||
|
makeChallenges(user, world, overwrite);
|
||||||
|
addon.getChallengesManager().save(false);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void makeLevels(User user) {
|
||||||
|
// Parse the levels
|
||||||
|
String levels = chal.getString("challenges.levels", "");
|
||||||
|
if (!levels.isEmpty()) {
|
||||||
|
user.sendMessage("challenges.admin.import.levels", "[levels]", levels);
|
||||||
|
String[] lvs = levels.split(" ");
|
||||||
|
int order = 0;
|
||||||
|
for (String level : lvs) {
|
||||||
|
ChallengeLevels challengeLevel = new ChallengeLevels();
|
||||||
|
challengeLevel.setFriendlyName(level);
|
||||||
|
challengeLevel.setUniqueId(level);
|
||||||
|
challengeLevel.setOrder(order++);
|
||||||
|
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.setRewardItems(parseItems(unlock.getString("itemReward","")));
|
||||||
|
challengeLevel.setMoneyReward(unlock.getInt("moneyReward"));
|
||||||
|
challengeLevel.setExpReward(unlock.getInt("expReward"));
|
||||||
|
challengeLevel.setRewardCommands(unlock.getStringList("commands"));
|
||||||
|
}
|
||||||
|
addon.getChallengesManager().storeLevel(challengeLevel);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
user.sendMessage("challenges.admin.import.no-levels");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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();
|
||||||
|
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.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.setRepeatable(details.getBoolean("repeatable"));
|
||||||
|
newChallenge.setRepeatRewardText(details.getString("repeatRewardText",""));
|
||||||
|
newChallenge.setRepeatMoneyReward(details.getInt("repearMoneyReward"));
|
||||||
|
newChallenge.setRepeatExpReward(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"));
|
||||||
|
String reqItems = details.getString("requiredItems","");
|
||||||
|
if (newChallenge.getChallengeType().equals(Challenges.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)) {
|
||||||
|
parseEntities(newChallenge, reqItems);
|
||||||
|
}
|
||||||
|
newChallenge.setRewardItems(parseItems(details.getString("itemReward")));
|
||||||
|
newChallenge.setRepeatItemReward(parseItems(details.getString("repeatItemReward")));
|
||||||
|
// Save
|
||||||
|
if (addon.getChallengesManager().storeChallenge(newChallenge, overwrite, user, false)) {
|
||||||
|
size++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
addon.getChallengesManager().sortChallenges();
|
||||||
|
user.sendMessage("challenges.admin.import.number", "[number]", String.valueOf(size));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Run through entity types and materials and try to match to the string given
|
||||||
|
* @param challenge - challenge to be adjusted
|
||||||
|
* @param string - string from YAML file
|
||||||
|
*/
|
||||||
|
private void parseEntities(Challenges challenge, String string) {
|
||||||
|
Map<EntityType, Integer> req = new EnumMap<>(EntityType.class);
|
||||||
|
Map<Material, Integer> blocks = new EnumMap<>(Material.class);
|
||||||
|
if (!string.isEmpty()) {
|
||||||
|
for (String s : string.split(" ")) {
|
||||||
|
String[] part = s.split(":");
|
||||||
|
try {
|
||||||
|
Arrays.asList(EntityType.values()).stream().filter(t -> t.name().equalsIgnoreCase(part[0])).forEach(t -> req.put(t, Integer.valueOf(part[1])));
|
||||||
|
Arrays.asList(Material.values()).stream().filter(t -> t.name().equalsIgnoreCase(part[0])).forEach(t -> blocks.put(t, Integer.valueOf(part[1])));
|
||||||
|
} catch (Exception e) {
|
||||||
|
addon.getLogger().severe("Cannot parse '" + s + "'. Skipping...");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
challenge.setRequiredEntities(req);
|
||||||
|
challenge.setRequiredBlocks(blocks);
|
||||||
|
}
|
||||||
|
|
||||||
|
private List<ItemStack> parseItems(String reqList) {
|
||||||
|
List<ItemStack> result = new ArrayList<>();
|
||||||
|
if (!reqList.isEmpty()) {
|
||||||
|
for (String s : reqList.split(" ")) {
|
||||||
|
ItemStack item = new ParseItem(addon,s).getItem();
|
||||||
|
if (item != null) {
|
||||||
|
result.add(item);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
64
src/main/java/world/bentobox/challenges/LevelStatus.java
Normal file
64
src/main/java/world/bentobox/challenges/LevelStatus.java
Normal file
@ -0,0 +1,64 @@
|
|||||||
|
package world.bentobox.challenges;
|
||||||
|
|
||||||
|
import world.bentobox.challenges.objects.ChallengeLevels;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Level status class
|
||||||
|
* @author tastybento
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public class LevelStatus {
|
||||||
|
private final ChallengeLevels level;
|
||||||
|
private final ChallengeLevels previousLevel;
|
||||||
|
private final int numberOfChallengesStillToDo;
|
||||||
|
private final boolean complete;
|
||||||
|
private final boolean isUnlocked;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param level - level
|
||||||
|
* @param previousLevel - previous level
|
||||||
|
* @param numberOfChallengesStillToDo - number of challenges still to do on this level
|
||||||
|
* @param complete - whether complete or not
|
||||||
|
* @param isUnlocked
|
||||||
|
*/
|
||||||
|
public LevelStatus(ChallengeLevels level, ChallengeLevels previousLevel, int numberOfChallengesStillToDo, boolean complete, boolean isUnlocked) {
|
||||||
|
super();
|
||||||
|
this.level = level;
|
||||||
|
this.previousLevel = previousLevel;
|
||||||
|
this.numberOfChallengesStillToDo = numberOfChallengesStillToDo;
|
||||||
|
this.complete = complete;
|
||||||
|
this.isUnlocked = isUnlocked;
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* @return the level
|
||||||
|
*/
|
||||||
|
public ChallengeLevels getLevel() {
|
||||||
|
return level;
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* @return the numberOfChallengesStillToDo
|
||||||
|
*/
|
||||||
|
public int getNumberOfChallengesStillToDo() {
|
||||||
|
return numberOfChallengesStillToDo;
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* @return the previousLevel
|
||||||
|
*/
|
||||||
|
public ChallengeLevels getPreviousLevel() {
|
||||||
|
return previousLevel;
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* @return the complete
|
||||||
|
*/
|
||||||
|
public boolean isComplete() {
|
||||||
|
return complete;
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* @return the isUnlocked
|
||||||
|
*/
|
||||||
|
public boolean isUnlocked() {
|
||||||
|
return isUnlocked;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
167
src/main/java/world/bentobox/challenges/ParseItem.java
Normal file
167
src/main/java/world/bentobox/challenges/ParseItem.java
Normal file
@ -0,0 +1,167 @@
|
|||||||
|
package world.bentobox.challenges;
|
||||||
|
|
||||||
|
import org.bukkit.Material;
|
||||||
|
import org.bukkit.inventory.ItemStack;
|
||||||
|
import org.bukkit.inventory.meta.PotionMeta;
|
||||||
|
import org.bukkit.potion.PotionData;
|
||||||
|
import org.bukkit.potion.PotionType;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class that parses a string into an ItemStack
|
||||||
|
* Used for converting config file entries to objects
|
||||||
|
* @author tastybento
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public class ParseItem {
|
||||||
|
|
||||||
|
private final ItemStack item;
|
||||||
|
private ChallengesAddon addon;
|
||||||
|
|
||||||
|
public ParseItem(ChallengesAddon addon, String s) {
|
||||||
|
this.addon = addon;
|
||||||
|
item = parseItem(s);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Parse a string into an itemstack
|
||||||
|
* @param s - input string
|
||||||
|
* @return ItemStack or null if parsing failed
|
||||||
|
*/
|
||||||
|
private ItemStack parseItem(String s) {
|
||||||
|
String[] part = s.split(":");
|
||||||
|
if (part.length > 0 && (part[0].equalsIgnoreCase("POTION") || part[0].equalsIgnoreCase("TIPPED_ARROW"))) {
|
||||||
|
return potion(s, part);
|
||||||
|
}
|
||||||
|
// Material:Qty
|
||||||
|
if (part.length == 2) {
|
||||||
|
return two(s, part);
|
||||||
|
} else if (part.length == 3) {
|
||||||
|
return three(s, part);
|
||||||
|
}
|
||||||
|
showError(s);
|
||||||
|
return null;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private ItemStack potion(String s, String[] part) {
|
||||||
|
/*
|
||||||
|
* # Format POTION:NAME:<LEVEL>:<EXTENDED>:<SPLASH/LINGER>:QTY
|
||||||
|
# LEVEL, EXTENDED, SPLASH, LINGER are optional.
|
||||||
|
# LEVEL is a number, 1 or 2
|
||||||
|
# LINGER is for V1.9 servers and later
|
||||||
|
# Examples:
|
||||||
|
# POTION:STRENGTH:1:EXTENDED:SPLASH:1
|
||||||
|
# POTION:INSTANT_DAMAGE:2::LINGER:2
|
||||||
|
# POTION:JUMP:2:NOTEXTENDED:NOSPLASH:1
|
||||||
|
# POTION:WEAKNESS::::1 - any weakness potion
|
||||||
|
*/
|
||||||
|
|
||||||
|
ItemStack result = new ItemStack(Material.POTION);
|
||||||
|
if (part[0].equalsIgnoreCase("TIPPED_ARROW")) {
|
||||||
|
result = new ItemStack(Material.TIPPED_ARROW);
|
||||||
|
} else if (part[0].equalsIgnoreCase("SPLASH_POTION")) {
|
||||||
|
result = new ItemStack(Material.SPLASH_POTION);
|
||||||
|
} else if (part[0].equalsIgnoreCase("LINGERING_POTION")) {
|
||||||
|
result = new ItemStack(Material.LINGERING_POTION);
|
||||||
|
}
|
||||||
|
int reqAmount = 0;
|
||||||
|
String amount = "1";
|
||||||
|
String level = "1";
|
||||||
|
String ext = "";
|
||||||
|
String splashLinger = "";
|
||||||
|
switch (part.length) {
|
||||||
|
case 3:
|
||||||
|
amount = part[2];
|
||||||
|
break;
|
||||||
|
case 4:
|
||||||
|
level = part[2];
|
||||||
|
amount = part[3];
|
||||||
|
break;
|
||||||
|
case 5:
|
||||||
|
level = part[2];
|
||||||
|
ext = part[3];
|
||||||
|
amount = part[4];
|
||||||
|
break;
|
||||||
|
case 6:
|
||||||
|
level = part[2];
|
||||||
|
ext = part[3];
|
||||||
|
splashLinger = part[4];
|
||||||
|
amount = part[5];
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
// Because I don't know!
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
// Parse the quantity
|
||||||
|
try {
|
||||||
|
reqAmount = Integer.parseInt(amount);
|
||||||
|
} catch (Exception e) {
|
||||||
|
addon.getLogger().severe(() -> "Could not parse the quantity of the potion or tipped arrow " + s);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
result.setAmount(reqAmount);
|
||||||
|
|
||||||
|
// Parse the legacy splash / linger
|
||||||
|
if (splashLinger.equalsIgnoreCase("SPLASH")) {
|
||||||
|
result = new ItemStack(Material.SPLASH_POTION);
|
||||||
|
} else if (splashLinger.equalsIgnoreCase("LINGER")) {
|
||||||
|
result = new ItemStack(Material.LINGERING_POTION);
|
||||||
|
}
|
||||||
|
// Parse the type of potion
|
||||||
|
PotionMeta potionMeta = (PotionMeta)(result.getItemMeta());
|
||||||
|
PotionType type = PotionType.valueOf(part[1].toUpperCase());
|
||||||
|
boolean isUpgraded = (level.isEmpty() || level.equalsIgnoreCase("1")) ? false: true;
|
||||||
|
boolean isExtended = ext.equalsIgnoreCase("EXTENDED") ? true : false;
|
||||||
|
PotionData data = new PotionData(type, isExtended, isUpgraded);
|
||||||
|
potionMeta.setBasePotionData(data);
|
||||||
|
result.setItemMeta(potionMeta);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
private ItemStack three(String s, String[] part) {
|
||||||
|
// Rearrange
|
||||||
|
String[] twoer = {part[0], part[2]};
|
||||||
|
ItemStack result = two(s, twoer);
|
||||||
|
if (result == null) {
|
||||||
|
showError(s);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private void showError(String s) {
|
||||||
|
addon.getLogger().severe(() -> "Problem with " + s + " in config.yml!");
|
||||||
|
}
|
||||||
|
|
||||||
|
private ItemStack two(String s, String[] part) {
|
||||||
|
int reqAmount = 0;
|
||||||
|
try {
|
||||||
|
reqAmount = Integer.parseInt(part[1]);
|
||||||
|
} catch (Exception e) {
|
||||||
|
showError(s);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
Material reqItem = Material.getMaterial(part[0].toUpperCase() + "_ITEM");
|
||||||
|
if (reqItem == null) {
|
||||||
|
// Try the item
|
||||||
|
reqItem = Material.getMaterial(part[0].toUpperCase());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (reqItem == null) {
|
||||||
|
showError(s);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return new ItemStack(reqItem, reqAmount);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the item
|
||||||
|
*/
|
||||||
|
public ItemStack getItem() {
|
||||||
|
return item;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,38 @@
|
|||||||
|
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;
|
||||||
|
|
||||||
|
public class ChallengesCommand extends CompositeCommand {
|
||||||
|
public static final String CHALLENGE_COMMAND = "challenges";
|
||||||
|
|
||||||
|
public ChallengesCommand(ChallengesAddon addon, CompositeCommand cmd) {
|
||||||
|
super(addon, cmd, CHALLENGE_COMMAND);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
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);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
// Show help
|
||||||
|
showHelp(this, user);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setup() {
|
||||||
|
this.setPermission(CHALLENGE_COMMAND);
|
||||||
|
this.setParametersHelp(CHALLENGE_COMMAND + ".parameters");
|
||||||
|
this.setDescription(CHALLENGE_COMMAND + ".description");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,46 @@
|
|||||||
|
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;
|
||||||
|
|
||||||
|
public class Challenges extends CompositeCommand {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Admin command for challenges
|
||||||
|
* @param parent
|
||||||
|
*/
|
||||||
|
public Challenges(ChallengesAddon addon, CompositeCommand parent) {
|
||||||
|
super(addon, parent, "challenges");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setup() {
|
||||||
|
this.setPermission("admin.challenges");
|
||||||
|
this.setParametersHelp("challeneges.admin.parameters");
|
||||||
|
this.setDescription("challenges.admin.description");
|
||||||
|
// Register sub commands
|
||||||
|
new ImportCommand(getAddon(), this);
|
||||||
|
new CompleteChallenge(getAddon(), this);
|
||||||
|
new ReloadChallenges(getAddon(), this);
|
||||||
|
new ResetChallenge(getAddon(), this);
|
||||||
|
//new ShowChallenges(getAddon(), this);
|
||||||
|
//new CreateChallenge(getAddon(), this);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
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);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,77 @@
|
|||||||
|
package world.bentobox.challenges.commands.admin;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Optional;
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
import world.bentobox.challenges.ChallengesAddon;
|
||||||
|
import world.bentobox.challenges.ChallengesManager;
|
||||||
|
import world.bentobox.bentobox.api.addons.Addon;
|
||||||
|
import world.bentobox.bentobox.api.commands.CompositeCommand;
|
||||||
|
import world.bentobox.bentobox.api.localization.TextVariables;
|
||||||
|
import world.bentobox.bentobox.api.user.User;
|
||||||
|
import world.bentobox.bentobox.util.Util;
|
||||||
|
|
||||||
|
public class CompleteChallenge extends CompositeCommand {
|
||||||
|
|
||||||
|
private ChallengesManager manager;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Admin command to complete user challenges
|
||||||
|
* @param parent
|
||||||
|
*/
|
||||||
|
public CompleteChallenge(Addon addon, CompositeCommand parent) {
|
||||||
|
super(addon, parent, "complete");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setup() {
|
||||||
|
this.setPermission("admin.challenges");
|
||||||
|
this.setParametersHelp("challenges.admin.complete.parameters");
|
||||||
|
this.setDescription("challenges.admin.complete.description");
|
||||||
|
manager = ((ChallengesAddon)getAddon()).getChallengesManager();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean execute(User user, String label, List<String> args) {
|
||||||
|
if (args.size() != 2) {
|
||||||
|
// Show help
|
||||||
|
showHelp(this, user);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
// Get target player
|
||||||
|
UUID targetUUID = getPlayers().getUUID(args.get(0));
|
||||||
|
if (targetUUID == null) {
|
||||||
|
user.sendMessage("general.errors.unknown-player", TextVariables.NAME, args.get(0));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (!getPlugin().getIslands().hasIsland(getWorld(), targetUUID)) {
|
||||||
|
user.sendMessage("general.errors.player-has-no-island");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
// Check for valid challenge name
|
||||||
|
if (!manager.isChallenge(getWorld(), 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());
|
||||||
|
user.sendMessage("general.success");
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Optional<List<String>> tabComplete(User user, String alias, List<String> args) {
|
||||||
|
String lastArg = !args.isEmpty() ? args.get(args.size()-1) : "";
|
||||||
|
if (args.size() == 3) {
|
||||||
|
// Online players
|
||||||
|
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.empty();
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,47 @@
|
|||||||
|
package world.bentobox.challenges.commands.admin;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import world.bentobox.challenges.ChallengesAddon;
|
||||||
|
import world.bentobox.challenges.panel.CreateChallengeListener;
|
||||||
|
import world.bentobox.bentobox.api.addons.Addon;
|
||||||
|
import world.bentobox.bentobox.api.commands.CompositeCommand;
|
||||||
|
import world.bentobox.bentobox.api.panels.builders.PanelBuilder;
|
||||||
|
import world.bentobox.bentobox.api.user.User;
|
||||||
|
|
||||||
|
public class CreateChallenge extends CompositeCommand {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Admin command to make challenges
|
||||||
|
* @param parent
|
||||||
|
*/
|
||||||
|
public CreateChallenge(Addon addon, CompositeCommand parent) {
|
||||||
|
super(addon, parent, "create");
|
||||||
|
new CreateSurrounding(addon, this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setup() {
|
||||||
|
this.setOnlyPlayer(true);
|
||||||
|
this.setPermission("admin.challenges");
|
||||||
|
this.setParametersHelp("challaneges.admin.create.parameters");
|
||||||
|
this.setDescription("challenges.admin.create.description");
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean execute(User user, String label, List<String> args) {
|
||||||
|
if (args.isEmpty()) {
|
||||||
|
user.sendRawMessage("not enough args");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
new PanelBuilder()
|
||||||
|
.name(args.get(0))
|
||||||
|
.size(49)
|
||||||
|
.listener(new CreateChallengeListener((ChallengesAddon) getAddon(), user))
|
||||||
|
.user(user)
|
||||||
|
.build();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,124 @@
|
|||||||
|
package world.bentobox.challenges.commands.admin;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
import org.bukkit.entity.Player;
|
||||||
|
import org.bukkit.event.Cancellable;
|
||||||
|
import org.bukkit.event.EventHandler;
|
||||||
|
import org.bukkit.event.EventPriority;
|
||||||
|
import org.bukkit.event.Listener;
|
||||||
|
import org.bukkit.event.block.Action;
|
||||||
|
import org.bukkit.event.block.BlockBreakEvent;
|
||||||
|
import org.bukkit.event.entity.EntityDamageByEntityEvent;
|
||||||
|
import org.bukkit.event.player.PlayerInteractAtEntityEvent;
|
||||||
|
import org.bukkit.event.player.PlayerInteractEvent;
|
||||||
|
import org.bukkit.event.player.PlayerQuitEvent;
|
||||||
|
|
||||||
|
import world.bentobox.challenges.ChallengesAddon;
|
||||||
|
import world.bentobox.bentobox.api.addons.Addon;
|
||||||
|
import world.bentobox.bentobox.api.commands.CompositeCommand;
|
||||||
|
import world.bentobox.bentobox.api.user.User;
|
||||||
|
import world.bentobox.bentobox.util.Util;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Command to create a surrounding type challenge
|
||||||
|
* @author tastybento
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public class CreateSurrounding extends CompositeCommand implements Listener {
|
||||||
|
|
||||||
|
HashMap<UUID,SurroundChallengeBuilder> inProgress = new HashMap<>();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Admin command to make surrounding challenges
|
||||||
|
* @param parent
|
||||||
|
*/
|
||||||
|
public CreateSurrounding(Addon addon, CompositeCommand parent) {
|
||||||
|
super(addon, parent, "surrounding");
|
||||||
|
addon.getServer().getPluginManager().registerEvents(this, addon.getPlugin());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setup() {
|
||||||
|
this.setOnlyPlayer(true);
|
||||||
|
this.setPermission("admin.challenges");
|
||||||
|
this.setParametersHelp("challaneges.admin.create.surrounding.parameters");
|
||||||
|
this.setDescription("challenges.admin.create.surrounding.description");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean execute(User user, String label, List<String> args) {
|
||||||
|
if (args.isEmpty()) {
|
||||||
|
user.sendMessage("challenges.admin.error.no-name");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
// Tell user to hit objects to add to the surrounding object requirements
|
||||||
|
user.sendMessage("challenges.admin.create.surrounding.hit-things");
|
||||||
|
inProgress.put(user.getUniqueId(), new SurroundChallengeBuilder((ChallengesAddon) getAddon()).owner(user).name(args.get(0)));
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@EventHandler(priority = EventPriority.LOWEST, ignoreCancelled = true)
|
||||||
|
public void onBlockBreak(BlockBreakEvent e) {
|
||||||
|
e.setCancelled(inProgress.containsKey(e.getPlayer().getUniqueId()) ? true : false);
|
||||||
|
}
|
||||||
|
|
||||||
|
@EventHandler(priority = EventPriority.LOWEST, ignoreCancelled = true)
|
||||||
|
public void onPlayerQuit(PlayerQuitEvent e) {
|
||||||
|
inProgress.remove(e.getPlayer().getUniqueId());
|
||||||
|
}
|
||||||
|
|
||||||
|
@EventHandler(priority = EventPriority.LOWEST, ignoreCancelled = true)
|
||||||
|
public boolean onPlayerInteract(PlayerInteractEvent e) {
|
||||||
|
if (e.getAction().equals(Action.LEFT_CLICK_BLOCK) && inProgress.containsKey(e.getPlayer().getUniqueId())) {
|
||||||
|
// Prevent damage
|
||||||
|
e.setCancelled(true);
|
||||||
|
inProgress.get(e.getPlayer().getUniqueId()).addBlock(e.getClickedBlock().getType());
|
||||||
|
User.getInstance(e.getPlayer()).sendMessage("challenges.admin.you-added", "[thing]", Util.prettifyText(e.getClickedBlock().getType().toString()));
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (e.getAction().equals(Action.RIGHT_CLICK_BLOCK)) {
|
||||||
|
return finished(e, e.getPlayer().getUniqueId());
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean finished(Cancellable e, UUID uuid) {
|
||||||
|
if (inProgress.containsKey(uuid)) {
|
||||||
|
e.setCancelled(true);
|
||||||
|
boolean status = inProgress.get(uuid).build();
|
||||||
|
if (status) {
|
||||||
|
inProgress.get(uuid).getOwner().sendMessage("challenges.admin.challenge-created", "[challenge]", inProgress.get(uuid).getName());
|
||||||
|
}
|
||||||
|
inProgress.remove(uuid);
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@EventHandler(priority = EventPriority.LOWEST, ignoreCancelled = true)
|
||||||
|
public boolean onPlayerInteract(PlayerInteractAtEntityEvent e) {
|
||||||
|
return finished(e, e.getPlayer().getUniqueId());
|
||||||
|
}
|
||||||
|
|
||||||
|
@EventHandler(priority = EventPriority.LOWEST, ignoreCancelled = true)
|
||||||
|
public boolean onLeft(EntityDamageByEntityEvent e) {
|
||||||
|
if (!(e.getDamager() instanceof Player)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
Player player = (Player)e.getDamager();
|
||||||
|
if (inProgress.containsKey(player.getUniqueId())) {
|
||||||
|
// Prevent damage
|
||||||
|
e.setCancelled(true);
|
||||||
|
inProgress.get(player.getUniqueId()).addEntity(e.getEntityType());
|
||||||
|
User.getInstance(player).sendMessage("challenges.admin.you-added", "[thing]", Util.prettifyText(e.getEntityType().toString()));
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,42 @@
|
|||||||
|
package world.bentobox.challenges.commands.admin;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Optional;
|
||||||
|
|
||||||
|
import world.bentobox.challenges.ChallengesAddon;
|
||||||
|
import world.bentobox.bentobox.api.addons.Addon;
|
||||||
|
import world.bentobox.bentobox.api.commands.CompositeCommand;
|
||||||
|
import world.bentobox.bentobox.api.user.User;
|
||||||
|
import world.bentobox.bentobox.util.Util;
|
||||||
|
|
||||||
|
public class ImportCommand extends CompositeCommand {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Import challenges
|
||||||
|
* @param addon
|
||||||
|
* @param cmd
|
||||||
|
*/
|
||||||
|
public ImportCommand(Addon addon, CompositeCommand cmd) {
|
||||||
|
super(addon, cmd, "import");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean execute(User user, String label, List<String> args) {
|
||||||
|
return ((ChallengesAddon)getAddon()).getImportManager().importChallenges(user, getWorld(), !args.isEmpty() && args.get(0).equalsIgnoreCase("overwrite"));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setup() {
|
||||||
|
this.setPermission("challenges.admin");
|
||||||
|
this.setParametersHelp("challenges.admin.import.parameters");
|
||||||
|
this.setDescription("challenges.admin.import.description");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Optional<List<String>> tabComplete(User user, String alias, List<String> args) {
|
||||||
|
String lastArg = !args.isEmpty() ? args.get(args.size()-1) : "";
|
||||||
|
return Optional.of(Util.tabLimit(Arrays.asList("overwrite"), lastArg));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,43 @@
|
|||||||
|
package world.bentobox.challenges.commands.admin;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import world.bentobox.challenges.ChallengesAddon;
|
||||||
|
import world.bentobox.challenges.ChallengesManager;
|
||||||
|
import world.bentobox.bentobox.api.addons.Addon;
|
||||||
|
import world.bentobox.bentobox.api.commands.CompositeCommand;
|
||||||
|
import world.bentobox.bentobox.api.user.User;
|
||||||
|
|
||||||
|
public class ReloadChallenges extends CompositeCommand {
|
||||||
|
|
||||||
|
private ChallengesManager manager;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Admin command to complete user challenges
|
||||||
|
* @param parent
|
||||||
|
*/
|
||||||
|
public ReloadChallenges(Addon addon, CompositeCommand parent) {
|
||||||
|
super(addon, parent, "reload");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setup() {
|
||||||
|
this.setPermission("admin.challenges");
|
||||||
|
this.setParametersHelp("challenges.admin.reload.parameters");
|
||||||
|
this.setDescription("challenges.admin.reload.description");
|
||||||
|
manager = ((ChallengesAddon)getAddon()).getChallengesManager();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean execute(User user, String label, List<String> args) {
|
||||||
|
if (!args.isEmpty()) {
|
||||||
|
// Show help
|
||||||
|
showHelp(this, user);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
manager.load();
|
||||||
|
user.sendMessage("general.success");
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,77 @@
|
|||||||
|
package world.bentobox.challenges.commands.admin;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Optional;
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
import world.bentobox.challenges.ChallengesAddon;
|
||||||
|
import world.bentobox.challenges.ChallengesManager;
|
||||||
|
import world.bentobox.bentobox.api.addons.Addon;
|
||||||
|
import world.bentobox.bentobox.api.commands.CompositeCommand;
|
||||||
|
import world.bentobox.bentobox.api.localization.TextVariables;
|
||||||
|
import world.bentobox.bentobox.api.user.User;
|
||||||
|
import world.bentobox.bentobox.util.Util;
|
||||||
|
|
||||||
|
public class ResetChallenge extends CompositeCommand {
|
||||||
|
|
||||||
|
private ChallengesManager manager;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Admin command to complete user challenges
|
||||||
|
* @param parent
|
||||||
|
*/
|
||||||
|
public ResetChallenge(Addon addon, CompositeCommand parent) {
|
||||||
|
super(addon, parent, "reset");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setup() {
|
||||||
|
this.setPermission("admin.challenges");
|
||||||
|
this.setParametersHelp("challenges.admin.reset.parameters");
|
||||||
|
this.setDescription("challenges.admin.reset.description");
|
||||||
|
manager = ((ChallengesAddon)getAddon()).getChallengesManager();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean execute(User user, String label, List<String> args) {
|
||||||
|
if (args.size() != 2) {
|
||||||
|
// Show help
|
||||||
|
showHelp(this, user);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
// Get target player
|
||||||
|
UUID targetUUID = getPlayers().getUUID(args.get(0));
|
||||||
|
if (targetUUID == null) {
|
||||||
|
user.sendMessage("general.errors.unknown-player", TextVariables.NAME, args.get(0));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (!getPlugin().getIslands().hasIsland(getWorld(), targetUUID)) {
|
||||||
|
user.sendMessage("general.errors.player-has-no-island");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
// Check for valid challenge name
|
||||||
|
if (!manager.isChallenge(getWorld(), 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());
|
||||||
|
user.sendMessage("general.success");
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Optional<List<String>> tabComplete(User user, String alias, List<String> args) {
|
||||||
|
String lastArg = !args.isEmpty() ? args.get(args.size()-1) : "";
|
||||||
|
if (args.size() == 3) {
|
||||||
|
// Online players
|
||||||
|
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.empty();
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,35 @@
|
|||||||
|
package world.bentobox.challenges.commands.admin;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import world.bentobox.challenges.ChallengesAddon;
|
||||||
|
import world.bentobox.bentobox.api.addons.Addon;
|
||||||
|
import world.bentobox.bentobox.api.commands.CompositeCommand;
|
||||||
|
import world.bentobox.bentobox.api.user.User;
|
||||||
|
|
||||||
|
public class ShowChallenges extends CompositeCommand {
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Admin command to show challenges and manage them
|
||||||
|
* @param parent
|
||||||
|
*/
|
||||||
|
public ShowChallenges(Addon addon, CompositeCommand parent) {
|
||||||
|
super(addon, parent, "show");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setup() {
|
||||||
|
this.setPermission("admin.challenges");
|
||||||
|
this.setParametersHelp("challaneges.admin.show.parameters");
|
||||||
|
this.setDescription("challenges.admin.show.description");
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean execute(User user, String label, List<String> args) {
|
||||||
|
((ChallengesAddon)getAddon()).getChallengesManager().getAllChallengesList().forEach(user::sendRawMessage);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,83 @@
|
|||||||
|
package world.bentobox.challenges.commands.admin;
|
||||||
|
|
||||||
|
import java.util.EnumMap;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import org.bukkit.Material;
|
||||||
|
import org.bukkit.entity.EntityType;
|
||||||
|
|
||||||
|
import world.bentobox.challenges.ChallengesAddon;
|
||||||
|
import world.bentobox.bentobox.api.user.User;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Enables the state of a Surrounding Challenge to be stored as it is built
|
||||||
|
* @author tastybento
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public class SurroundChallengeBuilder {
|
||||||
|
private ChallengesAddon addon;
|
||||||
|
private String name;
|
||||||
|
private User owner;
|
||||||
|
private Map<Material, Integer> reqBlocks = new EnumMap<>(Material.class);
|
||||||
|
private Map<EntityType, Integer> reqEntities = new EnumMap<>(EntityType.class);
|
||||||
|
|
||||||
|
public SurroundChallengeBuilder(ChallengesAddon addon) {
|
||||||
|
this.addon = addon;
|
||||||
|
}
|
||||||
|
|
||||||
|
SurroundChallengeBuilder name(String name) {
|
||||||
|
this.name = name;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
SurroundChallengeBuilder owner(User user) {
|
||||||
|
this.owner = user;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
SurroundChallengeBuilder addBlock(Material mat) {
|
||||||
|
reqBlocks.computeIfPresent(mat, (material, amount) -> amount + 1);
|
||||||
|
reqBlocks.putIfAbsent(mat, 1);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
SurroundChallengeBuilder addEntity(EntityType ent) {
|
||||||
|
reqEntities.computeIfPresent(ent, (type, amount) -> amount + 1);
|
||||||
|
reqEntities.putIfAbsent(ent, 1);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the name
|
||||||
|
*/
|
||||||
|
public String getName() {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the owner
|
||||||
|
*/
|
||||||
|
public User getOwner() {
|
||||||
|
return owner;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the reqBlocks
|
||||||
|
*/
|
||||||
|
public Map<Material, Integer> getReqBlocks() {
|
||||||
|
return reqBlocks;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the reqEntities
|
||||||
|
*/
|
||||||
|
public Map<EntityType, Integer> getReqEntities() {
|
||||||
|
return reqEntities;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean build() {
|
||||||
|
return addon.getChallengesManager().createSurroundingChallenge(this);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,33 @@
|
|||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
package world.bentobox.challenges.listeners;
|
||||||
|
|
||||||
|
import org.bukkit.event.EventHandler;
|
||||||
|
import org.bukkit.event.EventPriority;
|
||||||
|
import org.bukkit.event.Listener;
|
||||||
|
|
||||||
|
import world.bentobox.challenges.ChallengesAddon;
|
||||||
|
import world.bentobox.bentobox.api.events.island.IslandEvent;
|
||||||
|
import world.bentobox.bentobox.api.events.island.IslandEvent.Reason;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Resets challenges when the island is reset
|
||||||
|
* @author tastybento
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public class ResetListener implements Listener {
|
||||||
|
|
||||||
|
private ChallengesAddon addon;
|
||||||
|
|
||||||
|
public ResetListener(ChallengesAddon addon) {
|
||||||
|
this.addon = addon;
|
||||||
|
}
|
||||||
|
|
||||||
|
@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());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,39 @@
|
|||||||
|
package world.bentobox.challenges.listeners;
|
||||||
|
|
||||||
|
|
||||||
|
import org.bukkit.event.EventHandler;
|
||||||
|
import org.bukkit.event.EventPriority;
|
||||||
|
import org.bukkit.event.Listener;
|
||||||
|
import org.bukkit.event.world.WorldSaveEvent;
|
||||||
|
|
||||||
|
import world.bentobox.challenges.ChallengesAddon;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This is Simple World Save event listener. On each world save, this method
|
||||||
|
* asks challenge manager to save its data.
|
||||||
|
*/
|
||||||
|
public class SaveListener implements Listener
|
||||||
|
{
|
||||||
|
public SaveListener(ChallengesAddon addon) {
|
||||||
|
this.addon = addon;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@EventHandler(priority = EventPriority.LOW, ignoreCancelled = true)
|
||||||
|
public void onWorldSave(WorldSaveEvent e)
|
||||||
|
{
|
||||||
|
if (!this.addon.getChallengesManager().getAllChallengesList(e.getWorld()).isEmpty())
|
||||||
|
{
|
||||||
|
this.addon.getChallengesManager().save(e.isAsynchronous());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// ---------------------------------------------------------------------
|
||||||
|
// Section: Variables
|
||||||
|
// ---------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
|
private ChallengesAddon addon;
|
||||||
|
}
|
@ -0,0 +1,225 @@
|
|||||||
|
package world.bentobox.challenges.objects;
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
633
src/main/java/world/bentobox/challenges/objects/Challenges.java
Normal file
633
src/main/java/world/bentobox/challenges/objects/Challenges.java
Normal file
@ -0,0 +1,633 @@
|
|||||||
|
package world.bentobox.challenges.objects;
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,192 @@
|
|||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
package world.bentobox.challenges.objects;
|
||||||
|
|
||||||
|
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;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Stores the player's challenge situation
|
||||||
|
* @author tastybento
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public class ChallengesPlayerData implements DataObject {
|
||||||
|
|
||||||
|
@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<>();
|
||||||
|
@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());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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) {
|
||||||
|
this.uniqueId = uniqueId;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* (non-Javadoc)
|
||||||
|
* @see world.bentobox.bbox.database.objects.DataObject#getUniqueId()
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
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
|
||||||
|
*/
|
||||||
|
public Map<String, Integer> getChallengeStatus() {
|
||||||
|
return challengeStatus;
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* @param challengeStatus the challengeStatus to set
|
||||||
|
*/
|
||||||
|
public void setChallengeStatus(Map<String, Integer> challengeStatus) {
|
||||||
|
this.challengeStatus = challengeStatus;
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* @return the challengesTimestamp
|
||||||
|
*/
|
||||||
|
public Map<String, Long> getChallengesTimestamp() {
|
||||||
|
return challengesTimestamp;
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* @param challengesTimestamp the challengesTimestamp to set
|
||||||
|
*/
|
||||||
|
public void setChallengesTimestamp(Map<String, Long> challengesTimestamp) {
|
||||||
|
this.challengesTimestamp = challengesTimestamp;
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* @return the levelsDone
|
||||||
|
*/
|
||||||
|
public Set<String> getLevelsDone() {
|
||||||
|
return levelsDone;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param levelsDone the levelsDone to set
|
||||||
|
*/
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Resets all challenges and levels in world for this player
|
||||||
|
* @param 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));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,64 @@
|
|||||||
|
package world.bentobox.challenges.panel;
|
||||||
|
|
||||||
|
import org.bukkit.Material;
|
||||||
|
import org.bukkit.World;
|
||||||
|
import org.bukkit.event.inventory.ClickType;
|
||||||
|
import org.bukkit.inventory.ItemStack;
|
||||||
|
|
||||||
|
import world.bentobox.challenges.ChallengesAddon;
|
||||||
|
import world.bentobox.challenges.objects.Challenges;
|
||||||
|
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;
|
||||||
|
|
||||||
|
public class AdminEditGUI implements ClickHandler {
|
||||||
|
|
||||||
|
private ChallengesAddon addon;
|
||||||
|
private User requester;
|
||||||
|
private Challenges challenge;
|
||||||
|
private World world;
|
||||||
|
private String permPrefix;
|
||||||
|
private String label;
|
||||||
|
private User target;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Shows the admin panel for the challenge for a player
|
||||||
|
* @param addon addon
|
||||||
|
* @param requester admin user
|
||||||
|
* @param target target of admin
|
||||||
|
* @param challenge challenge
|
||||||
|
* @param world world
|
||||||
|
* @param permPrefix permission prefix for world
|
||||||
|
* @param label command label
|
||||||
|
*/
|
||||||
|
public AdminEditGUI(ChallengesAddon addon, User requester, User target, Challenges challenge, World world,
|
||||||
|
String permPrefix, String label) {
|
||||||
|
super();
|
||||||
|
this.addon = addon;
|
||||||
|
this.requester = requester;
|
||||||
|
this.target = target;
|
||||||
|
this.challenge = challenge;
|
||||||
|
this.world = world;
|
||||||
|
this.permPrefix = permPrefix;
|
||||||
|
this.label = label;
|
||||||
|
|
||||||
|
new PanelBuilder().size(27).user(requester).name(requester.getTranslation("challenges.admin.gui-title"))
|
||||||
|
.item(new PanelItemBuilder().icon(challenge.getIcon()).name("Icon").build())
|
||||||
|
.item(9, new PanelItemBuilder().icon(new ItemStack(Material.WHITE_BANNER)).name("Description").description(challenge.getDescription()).build())
|
||||||
|
.item(18, new PanelItemBuilder().icon(new ItemStack(Material.GREEN_STAINED_GLASS_PANE)).name("Active").build())
|
||||||
|
.item(27, new PanelItemBuilder().icon(new ItemStack(Material.BOOK)).name("Edit required items").clickHandler(this).build())
|
||||||
|
.build();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean onClick(Panel panel, User user, ClickType clickType, int slot) {
|
||||||
|
if (slot == 27) {
|
||||||
|
new RequiredPanel(challenge, user, panel);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
61
src/main/java/world/bentobox/challenges/panel/AdminGUI.java
Normal file
61
src/main/java/world/bentobox/challenges/panel/AdminGUI.java
Normal file
@ -0,0 +1,61 @@
|
|||||||
|
package world.bentobox.challenges.panel;
|
||||||
|
|
||||||
|
import org.bukkit.Material;
|
||||||
|
import org.bukkit.World;
|
||||||
|
import org.bukkit.event.inventory.ClickType;
|
||||||
|
import org.bukkit.inventory.ItemStack;
|
||||||
|
|
||||||
|
import world.bentobox.challenges.ChallengesAddon;
|
||||||
|
import world.bentobox.challenges.objects.Challenges;
|
||||||
|
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;
|
||||||
|
|
||||||
|
public class AdminGUI implements ClickHandler {
|
||||||
|
|
||||||
|
private ChallengesAddon addon;
|
||||||
|
private User player;
|
||||||
|
private Challenges challenge;
|
||||||
|
private World world;
|
||||||
|
private String permPrefix;
|
||||||
|
private String label;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Shows the admin panel for the challenge
|
||||||
|
* @param addon
|
||||||
|
* @param player
|
||||||
|
* @param challenge
|
||||||
|
* @param world
|
||||||
|
* @param permPrefix
|
||||||
|
* @param label
|
||||||
|
*/
|
||||||
|
public AdminGUI(ChallengesAddon addon, User player, Challenges challenge, World world,
|
||||||
|
String permPrefix, String label) {
|
||||||
|
super();
|
||||||
|
this.addon = addon;
|
||||||
|
this.player = player;
|
||||||
|
this.challenge = challenge;
|
||||||
|
this.world = world;
|
||||||
|
this.permPrefix = permPrefix;
|
||||||
|
this.label = label;
|
||||||
|
|
||||||
|
new PanelBuilder().size(27).user(player).name(player.getTranslation("challenges.admin.gui-title"))
|
||||||
|
.item(new PanelItemBuilder().icon(challenge.getIcon()).name("Icon").build())
|
||||||
|
.item(9, new PanelItemBuilder().icon(new ItemStack(Material.WHITE_BANNER)).name("Description").description(challenge.getDescription()).build())
|
||||||
|
.item(18, new PanelItemBuilder().icon(new ItemStack(Material.GREEN_STAINED_GLASS_PANE)).name("Active").build())
|
||||||
|
.item(27, new PanelItemBuilder().icon(new ItemStack(Material.BOOK)).name("Edit required items").clickHandler(this).build())
|
||||||
|
.build();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean onClick(Panel panel, User user, ClickType clickType, int slot) {
|
||||||
|
if (slot == 27) {
|
||||||
|
new RequiredPanel(challenge, user, panel);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,240 @@
|
|||||||
|
package world.bentobox.challenges.panel;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
import org.bukkit.Material;
|
||||||
|
import org.bukkit.World;
|
||||||
|
import org.bukkit.inventory.ItemStack;
|
||||||
|
|
||||||
|
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.objects.Challenges;
|
||||||
|
import world.bentobox.challenges.objects.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;
|
||||||
|
|
||||||
|
|
||||||
|
public class ChallengesPanels {
|
||||||
|
private ChallengesAddon addon;
|
||||||
|
private ChallengesManager manager;
|
||||||
|
private User user;
|
||||||
|
private String level;
|
||||||
|
private World world;
|
||||||
|
private String permPrefix;
|
||||||
|
private String label;
|
||||||
|
|
||||||
|
public ChallengesPanels(ChallengesAddon addon, User user, String level, World world, String permPrefix, String label) {
|
||||||
|
this.addon = addon;
|
||||||
|
this.manager = addon.getChallengesManager();
|
||||||
|
this.user = user;
|
||||||
|
this.world = world;
|
||||||
|
this.permPrefix = permPrefix;
|
||||||
|
this.label = label;
|
||||||
|
|
||||||
|
if (manager.getChallengeList().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();
|
||||||
|
}
|
||||||
|
this.level = level;
|
||||||
|
// Check if level is valid
|
||||||
|
if (!manager.isLevelUnlocked(user, level, world)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
PanelBuilder panelBuilder = new PanelBuilder()
|
||||||
|
.name(user.getTranslation("challenges.gui-title"));
|
||||||
|
|
||||||
|
addChallengeItems(panelBuilder);
|
||||||
|
addNavigation(panelBuilder);
|
||||||
|
addFreeChallanges(panelBuilder);
|
||||||
|
|
||||||
|
// Create the panel
|
||||||
|
Panel panel = panelBuilder.build();
|
||||||
|
panel.open(user);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void addChallengeItems(PanelBuilder panelBuilder) {
|
||||||
|
Set<Challenges> levelChallenges = manager.getChallenges(level, world);
|
||||||
|
// Only show a control panel for the level requested.
|
||||||
|
for (Challenges challenge : levelChallenges) {
|
||||||
|
createItem(panelBuilder, challenge);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void addFreeChallanges(PanelBuilder panelBuilder) {
|
||||||
|
manager.getChallenges(ChallengesManager.FREE, world).forEach(challenge -> createItem(panelBuilder, challenge));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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) {
|
||||||
|
// Check completion
|
||||||
|
boolean completed = manager.isChallengeComplete(user, challenge.getUniqueId(), world);
|
||||||
|
// If challenge is removed after completion, remove it
|
||||||
|
if (completed && challenge.isRemoveWhenCompleted()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
PanelItem item = new PanelItemBuilder()
|
||||||
|
.icon(challenge.getIcon())
|
||||||
|
.name(challenge.getFriendlyName().isEmpty() ? challenge.getUniqueId() : challenge.getFriendlyName())
|
||||||
|
.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);
|
||||||
|
} else {
|
||||||
|
panelBuilder.item(item);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void addNavigation(PanelBuilder panelBuilder) {
|
||||||
|
// TODO: This if fix for wrong getNumberOfChallengesStillToDo() issue. #23
|
||||||
|
LevelStatus previousStatus = null;
|
||||||
|
|
||||||
|
// Add navigation to other levels
|
||||||
|
for (LevelStatus status: manager.getChallengeLevelStatus(user, world)) {
|
||||||
|
if (status.getLevel().getUniqueId().equals(level)) {
|
||||||
|
// Skip if this is the current level
|
||||||
|
previousStatus = status;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
// Create a nice name for the level
|
||||||
|
String name = status.getLevel().getFriendlyName().isEmpty() ? status.getLevel().getUniqueId() : status.getLevel().getFriendlyName();
|
||||||
|
|
||||||
|
if (status.isUnlocked()) {
|
||||||
|
// Clicking on this icon will open up this level's challenges
|
||||||
|
PanelItem item = new PanelItemBuilder()
|
||||||
|
.icon(new ItemStack(Material.ENCHANTED_BOOK))
|
||||||
|
.name(name)
|
||||||
|
.description(manager.stringSplit(user.getTranslation("challenges.navigation","[level]",name)))
|
||||||
|
.clickHandler((p, u, c, s) -> {
|
||||||
|
u.closeInventory();
|
||||||
|
u.performCommand(label + " " + ChallengesCommand.CHALLENGE_COMMAND + " " + status.getLevel().getUniqueId());
|
||||||
|
return true;
|
||||||
|
})
|
||||||
|
.build();
|
||||||
|
panelBuilder.item(item);
|
||||||
|
} else {
|
||||||
|
// Clicking on this icon will do nothing because the challenge is not unlocked yet
|
||||||
|
String previousLevelName = status.getPreviousLevel().getFriendlyName().isEmpty() ? status.getPreviousLevel().getUniqueId() : status.getPreviousLevel().getFriendlyName();
|
||||||
|
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)))
|
||||||
|
.build();
|
||||||
|
panelBuilder.item(item);
|
||||||
|
}
|
||||||
|
|
||||||
|
previousStatus = status;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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) {
|
||||||
|
List<String> result = new ArrayList<String>();
|
||||||
|
String level = challenge.getLevel();
|
||||||
|
if (!level.isEmpty()) {
|
||||||
|
result.addAll(splitTrans(user, "challenges.level", "[level]", level));
|
||||||
|
}
|
||||||
|
// Check if completed or not
|
||||||
|
|
||||||
|
boolean complete = addon.getChallengesManager().isChallengeComplete(user, challenge.getUniqueId(), world);
|
||||||
|
int maxTimes = challenge.getMaxTimes();
|
||||||
|
long doneTimes = addon.getChallengesManager().checkChallengeTimes(user, challenge, world);
|
||||||
|
if (complete) {
|
||||||
|
result.add(user.getTranslation("challenges.complete"));
|
||||||
|
}
|
||||||
|
if (challenge.isRepeatable()) {
|
||||||
|
if (maxTimes == 0) {
|
||||||
|
|
||||||
|
// Check if the player has maxed out the challenge
|
||||||
|
if (doneTimes < maxTimes) {
|
||||||
|
result.addAll(splitTrans(user, "challenges.completed-times","[donetimes]", String.valueOf(doneTimes),"[maxtimes]", String.valueOf(maxTimes)));
|
||||||
|
} else {
|
||||||
|
result.addAll(splitTrans(user, "challenges.maxed-reached","[donetimes]", String.valueOf(doneTimes),"[maxtimes]", String.valueOf(maxTimes)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!complete || (complete && challenge.isRepeatable())) {
|
||||||
|
result.addAll(challenge.getDescription());
|
||||||
|
if (challenge.getChallengeType().equals(ChallengeType.INVENTORY)) {
|
||||||
|
if (challenge.isTakeItems()) {
|
||||||
|
result.addAll(splitTrans(user, "challenges.item-take-warning"));
|
||||||
|
}
|
||||||
|
} else if (challenge.getChallengeType().equals(ChallengeType.ISLAND)) {
|
||||||
|
result.addAll(splitTrans(user, "challenges.items-closeby"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (complete && (!challenge.getChallengeType().equals(ChallengeType.INVENTORY) || !challenge.isRepeatable())) {
|
||||||
|
result.addAll(splitTrans(user, "challenges.not-repeatable"));
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
double moneyReward = 0;
|
||||||
|
int expReward = 0;
|
||||||
|
String rewardText = "";
|
||||||
|
if (!complete) {
|
||||||
|
// First time
|
||||||
|
moneyReward = challenge.getRewardMoney();
|
||||||
|
rewardText = challenge.getRewardText();
|
||||||
|
expReward = challenge.getRewardExp();
|
||||||
|
if (!rewardText.isEmpty()) {
|
||||||
|
result.addAll(splitTrans(user, "challenges.first-time-rewards"));
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// Repeat challenge
|
||||||
|
moneyReward = challenge.getRepeatMoneyReward();
|
||||||
|
rewardText = challenge.getRepeatRewardText();
|
||||||
|
expReward = challenge.getRepeatExpReward();
|
||||||
|
if (!rewardText.isEmpty()) {
|
||||||
|
result.addAll(splitTrans(user, "challenges.repeat-rewards"));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
if (!rewardText.isEmpty()) {
|
||||||
|
result.addAll(splitTrans(user,rewardText));
|
||||||
|
}
|
||||||
|
if (expReward > 0) {
|
||||||
|
result.addAll(splitTrans(user,"challenges.exp-reward", "[reward]", String.valueOf(expReward)));
|
||||||
|
}
|
||||||
|
if (addon.getPlugin().getSettings().isUseEconomy() && moneyReward > 0) {
|
||||||
|
result.addAll(splitTrans(user,"challenges.money-reward", "[reward]", String.valueOf(moneyReward)));
|
||||||
|
}
|
||||||
|
// Final placeholder change for [label]
|
||||||
|
result.replaceAll(x -> x.replace("[label]", label));
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
private Collection<? extends String> splitTrans(User user, String string, String...strings) {
|
||||||
|
return addon.getChallengesManager().stringSplit(user.getTranslation(string, strings));
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,316 @@
|
|||||||
|
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 world.bentobox.challenges.ChallengesAddon;
|
||||||
|
import world.bentobox.challenges.ChallengesManager;
|
||||||
|
import world.bentobox.challenges.LevelStatus;
|
||||||
|
import world.bentobox.challenges.commands.ChallengesCommand;
|
||||||
|
import world.bentobox.challenges.objects.Challenges;
|
||||||
|
import world.bentobox.challenges.objects.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;
|
||||||
|
|
||||||
|
|
||||||
|
public class ChallengesPanels2 {
|
||||||
|
|
||||||
|
public enum Mode {
|
||||||
|
ADMIN,
|
||||||
|
EDIT,
|
||||||
|
PLAYER
|
||||||
|
}
|
||||||
|
private ChallengesAddon addon;
|
||||||
|
private ChallengesManager manager;
|
||||||
|
private User requester;
|
||||||
|
private String level;
|
||||||
|
private World world;
|
||||||
|
private String permPrefix;
|
||||||
|
private String label;
|
||||||
|
private Mode mode;
|
||||||
|
private User target;
|
||||||
|
|
||||||
|
public ChallengesPanels2(ChallengesAddon addon, User requester, User target, String level, World world, String permPrefix, String label, Mode mode) {
|
||||||
|
this.addon = addon;
|
||||||
|
this.manager = addon.getChallengesManager();
|
||||||
|
this.requester = requester;
|
||||||
|
this.target = target;
|
||||||
|
this.world = world;
|
||||||
|
this.permPrefix = permPrefix;
|
||||||
|
this.label = label;
|
||||||
|
this.mode = mode;
|
||||||
|
|
||||||
|
if (manager.getChallengeList().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();
|
||||||
|
}
|
||||||
|
this.level = level;
|
||||||
|
// Check if level is valid
|
||||||
|
if (mode.equals(Mode.PLAYER) && !manager.isLevelUnlocked(requester, level, world)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
PanelBuilder panelBuilder = new PanelBuilder();
|
||||||
|
switch (mode) {
|
||||||
|
case ADMIN:
|
||||||
|
panelBuilder.name(requester.getTranslation("challenges.admin.gui-title"));
|
||||||
|
break;
|
||||||
|
case EDIT:
|
||||||
|
panelBuilder.name(requester.getTranslation("challenges.admin.edit-gui-title"));
|
||||||
|
break;
|
||||||
|
case PLAYER:
|
||||||
|
panelBuilder.name(requester.getTranslation("challenges.gui-title"));
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
addChallengeItems(panelBuilder);
|
||||||
|
addNavigation(panelBuilder);
|
||||||
|
addFreeChallanges(panelBuilder);
|
||||||
|
|
||||||
|
// Create the panel
|
||||||
|
Panel panel = panelBuilder.build();
|
||||||
|
panel.open(requester);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void addChallengeItems(PanelBuilder panelBuilder) {
|
||||||
|
// Only show a control panel for the level requested.
|
||||||
|
for (Challenges challenge : manager.getChallenges(level, world)) {
|
||||||
|
createItem(panelBuilder, challenge);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void addFreeChallanges(PanelBuilder panelBuilder) {
|
||||||
|
manager.getChallenges(ChallengesManager.FREE, world).forEach(challenge -> createItem(panelBuilder, challenge));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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) {
|
||||||
|
// For admin, glow means activated. For user, glow means done
|
||||||
|
boolean glow = false;
|
||||||
|
switch (mode) {
|
||||||
|
case ADMIN:
|
||||||
|
glow = challenge.isDeployed();
|
||||||
|
break;
|
||||||
|
case EDIT:
|
||||||
|
glow = manager.isChallengeComplete(requester, challenge.getUniqueId(), world);
|
||||||
|
break;
|
||||||
|
case PLAYER:
|
||||||
|
glow = manager.isChallengeComplete(requester, challenge.getUniqueId(), world);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
|
||||||
|
}
|
||||||
|
// If not admin and challenge is removed after completion, remove it
|
||||||
|
if (mode.equals(Mode.PLAYER) && glow && challenge.isRemoveWhenCompleted()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
PanelItemBuilder itemBuilder = new PanelItemBuilder()
|
||||||
|
.icon(challenge.getIcon())
|
||||||
|
.name(challenge.getFriendlyName().isEmpty() ? challenge.getUniqueId() : challenge.getFriendlyName())
|
||||||
|
.description(challengeDescription(challenge))
|
||||||
|
.glow(glow);
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// If the challenge has a specific slot allocated, use it
|
||||||
|
if (challenge.getSlot() >= 0) {
|
||||||
|
panelBuilder.item(challenge.getSlot(),itemBuilder.build());
|
||||||
|
} else {
|
||||||
|
panelBuilder.item(itemBuilder.build());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void addNavigation(PanelBuilder panelBuilder) {
|
||||||
|
// TODO: This if fix for wrong getNumberOfChallengesStillToDo() issue. #23
|
||||||
|
LevelStatus previousStatus = null;
|
||||||
|
|
||||||
|
// Add navigation to other levels
|
||||||
|
for (LevelStatus status: manager.getChallengeLevelStatus(requester, world)) {
|
||||||
|
if (status.getLevel().getUniqueId().equalsIgnoreCase(level)) {
|
||||||
|
// Skip if this is the current level
|
||||||
|
previousStatus = status;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
// Create a nice name for the level
|
||||||
|
String name = status.getLevel().getFriendlyName().isEmpty() ? status.getLevel().getUniqueId() : status.getLevel().getFriendlyName();
|
||||||
|
|
||||||
|
if (mode.equals(Mode.ADMIN) || mode.equals(Mode.EDIT) || status.isUnlocked()) {
|
||||||
|
// Clicking on this icon will open up this level's challenges
|
||||||
|
PanelItem item = new PanelItemBuilder()
|
||||||
|
.icon(new ItemStack(Material.ENCHANTED_BOOK))
|
||||||
|
.name(name)
|
||||||
|
.description(manager.stringSplit(requester.getTranslation("challenges.navigation","[level]",name)))
|
||||||
|
.clickHandler((p, u, c, s) -> {
|
||||||
|
u.closeInventory();
|
||||||
|
u.performCommand(label + " " + ChallengesCommand.CHALLENGE_COMMAND + " " + status.getLevel().getUniqueId());
|
||||||
|
return true;
|
||||||
|
})
|
||||||
|
.build();
|
||||||
|
panelBuilder.item(item);
|
||||||
|
} else {
|
||||||
|
// Clicking on this icon will do nothing because the challenge is not unlocked yet
|
||||||
|
String previousLevelName = status.getPreviousLevel().getFriendlyName().isEmpty() ? status.getPreviousLevel().getUniqueId() : status.getPreviousLevel().getFriendlyName();
|
||||||
|
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)))
|
||||||
|
.build();
|
||||||
|
panelBuilder.item(item);
|
||||||
|
}
|
||||||
|
|
||||||
|
previousStatus = status;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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) {
|
||||||
|
List<String> result = new ArrayList<String>();
|
||||||
|
String level = challenge.getLevel();
|
||||||
|
if (!level.isEmpty()) {
|
||||||
|
result.addAll(splitTrans(requester, "challenges.level", "[level]", level));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mode.equals(Mode.ADMIN)) {
|
||||||
|
if ((!challenge.getChallengeType().equals(ChallengeType.INVENTORY) || !challenge.isRepeatable())) {
|
||||||
|
result.addAll(splitTrans(requester, "challenges.not-repeatable"));
|
||||||
|
} else {
|
||||||
|
result.addAll(splitTrans(requester, "challenges.repeatable", "[maxtimes]", String.valueOf(challenge.getMaxTimes())));
|
||||||
|
}
|
||||||
|
if (challenge.getChallengeType().equals(ChallengeType.INVENTORY) && challenge.isTakeItems()) {
|
||||||
|
result.addAll(splitTrans(requester, "challenges.item-take-warning"));
|
||||||
|
}
|
||||||
|
result.addAll(addRewards(challenge, true, true));
|
||||||
|
} else {
|
||||||
|
// Check if completed or not
|
||||||
|
boolean complete = addon.getChallengesManager().isChallengeComplete(requester, challenge.getUniqueId(), world);
|
||||||
|
int maxTimes = challenge.getMaxTimes();
|
||||||
|
long doneTimes = addon.getChallengesManager().checkChallengeTimes(requester, challenge, world);
|
||||||
|
if (complete) {
|
||||||
|
result.add(requester.getTranslation("challenges.complete"));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (challenge.isRepeatable()) {
|
||||||
|
if (maxTimes == 0) {
|
||||||
|
|
||||||
|
// Check if the player has maxed out the challenge
|
||||||
|
if (doneTimes < maxTimes) {
|
||||||
|
result.addAll(splitTrans(requester, "challenges.completed-times","[donetimes]", String.valueOf(doneTimes),"[maxtimes]", String.valueOf(maxTimes)));
|
||||||
|
} else {
|
||||||
|
result.addAll(splitTrans(requester, "challenges.maxed-reached","[donetimes]", String.valueOf(doneTimes),"[maxtimes]", String.valueOf(maxTimes)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!complete || (complete && challenge.isRepeatable())) {
|
||||||
|
result.addAll(challenge.getDescription());
|
||||||
|
if (challenge.getChallengeType().equals(ChallengeType.INVENTORY)) {
|
||||||
|
if (challenge.isTakeItems()) {
|
||||||
|
result.addAll(splitTrans(requester, "challenges.item-take-warning"));
|
||||||
|
}
|
||||||
|
} else if (challenge.getChallengeType().equals(ChallengeType.ISLAND)) {
|
||||||
|
result.addAll(splitTrans(requester, "challenges.items-closeby"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (complete && (!challenge.getChallengeType().equals(ChallengeType.INVENTORY) || !challenge.isRepeatable())) {
|
||||||
|
result.addAll(splitTrans(requester, "challenges.not-repeatable"));
|
||||||
|
result.replaceAll(x -> x.replace("[label]", label));
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
result.addAll(addRewards(challenge, complete, false));
|
||||||
|
}
|
||||||
|
// Final placeholder change for [label]
|
||||||
|
result.replaceAll(x -> x.replace("[label]", label));
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
private List<String> addRewards(Challenges challenge, boolean complete, boolean admin) {
|
||||||
|
List<String> result = new ArrayList<>();
|
||||||
|
double moneyReward = 0;
|
||||||
|
int expReward = 0;
|
||||||
|
String rewardText = "";
|
||||||
|
if (admin || !complete) {
|
||||||
|
// First time
|
||||||
|
moneyReward = challenge.getRewardMoney();
|
||||||
|
rewardText = challenge.getRewardText();
|
||||||
|
expReward = challenge.getRewardExp();
|
||||||
|
if (!rewardText.isEmpty()) {
|
||||||
|
result.addAll(splitTrans(requester, "challenges.first-time-rewards"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (admin || complete){
|
||||||
|
// Repeat challenge
|
||||||
|
moneyReward = challenge.getRepeatMoneyReward();
|
||||||
|
rewardText = challenge.getRepeatRewardText();
|
||||||
|
expReward = challenge.getRepeatExpReward();
|
||||||
|
if (!rewardText.isEmpty()) {
|
||||||
|
result.addAll(splitTrans(requester, "challenges.repeat-rewards"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!rewardText.isEmpty()) {
|
||||||
|
result.addAll(splitTrans(requester,rewardText));
|
||||||
|
}
|
||||||
|
if (expReward > 0) {
|
||||||
|
result.addAll(splitTrans(requester,"challenges.exp-reward", "[reward]", String.valueOf(expReward)));
|
||||||
|
}
|
||||||
|
if (addon.getPlugin().getSettings().isUseEconomy() && moneyReward > 0) {
|
||||||
|
result.addAll(splitTrans(requester,"challenges.money-reward", "[reward]", String.valueOf(moneyReward)));
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
private Collection<? extends String> splitTrans(User user, String string, String...strings) {
|
||||||
|
return addon.getChallengesManager().stringSplit(user.getTranslation(string, strings));
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,35 @@
|
|||||||
|
package world.bentobox.challenges.panel;
|
||||||
|
|
||||||
|
import org.bukkit.event.inventory.InventoryClickEvent;
|
||||||
|
import org.bukkit.event.inventory.InventoryCloseEvent;
|
||||||
|
|
||||||
|
import world.bentobox.challenges.ChallengesAddon;
|
||||||
|
import world.bentobox.bentobox.api.panels.PanelListener;
|
||||||
|
import world.bentobox.bentobox.api.user.User;
|
||||||
|
|
||||||
|
public class CreateChallengeListener implements PanelListener {
|
||||||
|
|
||||||
|
private ChallengesAddon addon;
|
||||||
|
private User user;
|
||||||
|
|
||||||
|
public CreateChallengeListener(ChallengesAddon addon, User user) {
|
||||||
|
this.addon = addon;
|
||||||
|
this.user = user;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setup() {
|
||||||
|
// Nothing to setup
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onInventoryClose(InventoryCloseEvent event) {
|
||||||
|
addon.getChallengesManager().createInvChallenge(user, event.getInventory());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onInventoryClick(User user, InventoryClickEvent event) {
|
||||||
|
// Allow drag and drop
|
||||||
|
event.setCancelled(false);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,13 @@
|
|||||||
|
package world.bentobox.challenges.panel;
|
||||||
|
|
||||||
|
import world.bentobox.challenges.ChallengesAddon;
|
||||||
|
import world.bentobox.bentobox.api.panels.builders.PanelBuilder;
|
||||||
|
import world.bentobox.bentobox.api.user.User;
|
||||||
|
|
||||||
|
public class CreateChallengePanel {
|
||||||
|
|
||||||
|
public CreateChallengePanel(ChallengesAddon addon, User user) {
|
||||||
|
new PanelBuilder().size(49).listener(new CreateChallengeListener(addon, user)).user(user).build();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
166
src/main/java/world/bentobox/challenges/panel/RequiredPanel.java
Normal file
166
src/main/java/world/bentobox/challenges/panel/RequiredPanel.java
Normal file
@ -0,0 +1,166 @@
|
|||||||
|
package world.bentobox.challenges.panel;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map.Entry;
|
||||||
|
|
||||||
|
import org.bukkit.Bukkit;
|
||||||
|
import org.bukkit.Material;
|
||||||
|
import org.bukkit.entity.EntityType;
|
||||||
|
import org.bukkit.event.inventory.ClickType;
|
||||||
|
import org.bukkit.event.inventory.InventoryClickEvent;
|
||||||
|
import org.bukkit.event.inventory.InventoryCloseEvent;
|
||||||
|
import org.bukkit.inventory.ItemStack;
|
||||||
|
|
||||||
|
import world.bentobox.challenges.objects.Challenges;
|
||||||
|
import world.bentobox.bentobox.api.panels.Panel;
|
||||||
|
import world.bentobox.bentobox.api.panels.PanelItem.ClickHandler;
|
||||||
|
import world.bentobox.bentobox.api.panels.PanelListener;
|
||||||
|
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.util.Util;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handles the requirements for a challenge
|
||||||
|
* Items, blocks, entities
|
||||||
|
* @author tastybento
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public class RequiredPanel implements ClickHandler, PanelListener {
|
||||||
|
private static final int CONTROL_NUMBER = 4;
|
||||||
|
private Challenges challenge;
|
||||||
|
private User user;
|
||||||
|
private Panel panel;
|
||||||
|
private Panel referringPanel;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param challenge
|
||||||
|
* @param user
|
||||||
|
*/
|
||||||
|
public RequiredPanel(Challenges challenge, User user, Panel referringPanel) {
|
||||||
|
this.challenge = challenge;
|
||||||
|
this.user = user;
|
||||||
|
this.panel = openPanel();
|
||||||
|
this.referringPanel = referringPanel;
|
||||||
|
}
|
||||||
|
|
||||||
|
private Panel openPanel() {
|
||||||
|
PanelBuilder pb = new PanelBuilder().listener(this).name("Required Items").size(49);
|
||||||
|
// Add the name and description icon
|
||||||
|
pb.item(new PanelItemBuilder().icon(Material.BOOK).name(challenge.getFriendlyName()).description(challenge.getDescription()).clickHandler(this).build());
|
||||||
|
// Add take all button
|
||||||
|
pb.item(new PanelItemBuilder().icon(Material.BOOK).name("Take Items").description(challenge.isTakeItems() ? "Yes" : "No").clickHandler(this).build());
|
||||||
|
// Add save button
|
||||||
|
pb.item(new PanelItemBuilder().icon(Material.BOOK).name("Save").clickHandler(this).build());
|
||||||
|
// Add cancel button
|
||||||
|
pb.item(new PanelItemBuilder().icon(Material.BOOK).name("Cancel").clickHandler(this).build());
|
||||||
|
|
||||||
|
switch (challenge.getChallengeType()) {
|
||||||
|
case INVENTORY:
|
||||||
|
// Show the required items in the inventory
|
||||||
|
challenge.getRequiredItems().stream().map(i -> new PanelItemBuilder().icon(i).clickHandler(this).build()).forEach(pb::item);
|
||||||
|
return pb.user(user).build();
|
||||||
|
case ISLAND:
|
||||||
|
// Create the blocks required
|
||||||
|
challenge.getRequiredBlocks().entrySet().stream().map(en -> new ItemStack(en.getKey(), en.getValue())).map(i -> new PanelItemBuilder().icon(i).clickHandler(this).build()).forEach(pb::item);
|
||||||
|
// Create the entities required
|
||||||
|
challenge.getRequiredEntities().entrySet().stream().map(this::toSpawnEgg).map(i -> new PanelItemBuilder()
|
||||||
|
.icon(i)
|
||||||
|
.name(Util.prettifyText(i.getType().toString()))
|
||||||
|
.description("Entity")
|
||||||
|
.clickHandler(this)
|
||||||
|
.build()).forEach(pb::item);
|
||||||
|
return pb.user(user).build();
|
||||||
|
case LEVEL:
|
||||||
|
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
|
||||||
|
}
|
||||||
|
return panel;
|
||||||
|
}
|
||||||
|
|
||||||
|
private ItemStack toSpawnEgg(Entry<EntityType, Integer> en) {
|
||||||
|
Material mat = Material.getMaterial(en.getKey().name() + "_SPAWN_EGG");
|
||||||
|
if (mat != null) {
|
||||||
|
return new ItemStack(mat, en.getValue());
|
||||||
|
} else {
|
||||||
|
return new ItemStack(Material.COW_SPAWN_EGG);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean onClick(Panel panel, User user, ClickType clickType, int slot) {
|
||||||
|
Bukkit.getLogger().info("DEBUG: slot = " + slot);
|
||||||
|
return slot < CONTROL_NUMBER;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setup() {
|
||||||
|
// nothing to do
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onInventoryClose(InventoryCloseEvent event) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onInventoryClick(User user, InventoryClickEvent event) {
|
||||||
|
// Allow drag and drop
|
||||||
|
event.setCancelled(event.getRawSlot() < CONTROL_NUMBER);
|
||||||
|
|
||||||
|
Bukkit.getLogger().info("DEBUG: inv slot = " + event.getSlot());
|
||||||
|
Bukkit.getLogger().info("DEBUG: inv slot type = " + event.getSlotType());
|
||||||
|
if (event.getSlot() == 1) {
|
||||||
|
// Take items
|
||||||
|
challenge.setTakeItems(!challenge.isTakeItems());
|
||||||
|
// Update item
|
||||||
|
event.getInventory().setItem(event.getSlot(), new PanelItemBuilder().icon(Material.BOOK).name("Take Items").description(challenge.isTakeItems() ? "Yes" : "No").build().getItem());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (event.getSlot() == 3) {
|
||||||
|
// Cancel
|
||||||
|
referringPanel.open(user);
|
||||||
|
return;
|
||||||
|
// Return to previous panel
|
||||||
|
}
|
||||||
|
// Save
|
||||||
|
if (event.getSlot() != 2) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// Save changes
|
||||||
|
switch (challenge.getChallengeType()) {
|
||||||
|
case ICON:
|
||||||
|
break;
|
||||||
|
case INVENTORY:
|
||||||
|
List<ItemStack> reqItems = new ArrayList<>();
|
||||||
|
// Skip first item
|
||||||
|
for (int i = CONTROL_NUMBER; i < event.getInventory().getSize(); i++) {
|
||||||
|
if (event.getInventory().getItem(i) != null) {
|
||||||
|
reqItems.add(event.getInventory().getItem(i));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
challenge.setRequiredItems(reqItems);
|
||||||
|
user.sendMessage("challenges.admin.saved");
|
||||||
|
// TODO: save challenges
|
||||||
|
event.getInventory().setItem(event.getSlot(), new PanelItemBuilder().icon(Material.BOOK).name("Save").description("Saved").build().getItem());
|
||||||
|
break;
|
||||||
|
case ISLAND:
|
||||||
|
break;
|
||||||
|
case LEVEL:
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
482
src/main/java/world/bentobox/challenges/panel/TryToComplete.java
Normal file
482
src/main/java/world/bentobox/challenges/panel/TryToComplete.java
Normal file
@ -0,0 +1,482 @@
|
|||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
package world.bentobox.challenges.panel;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.EnumMap;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Objects;
|
||||||
|
import java.util.Optional;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
import org.bukkit.Material;
|
||||||
|
import org.bukkit.World;
|
||||||
|
import org.bukkit.entity.EntityType;
|
||||||
|
import org.bukkit.entity.Player;
|
||||||
|
import org.bukkit.inventory.ItemStack;
|
||||||
|
import org.bukkit.util.Vector;
|
||||||
|
|
||||||
|
import world.bentobox.challenges.ChallengesAddon;
|
||||||
|
import world.bentobox.challenges.ChallengesManager;
|
||||||
|
import world.bentobox.challenges.commands.ChallengesCommand;
|
||||||
|
import world.bentobox.challenges.objects.Challenges;
|
||||||
|
import world.bentobox.challenges.objects.Challenges.ChallengeType;
|
||||||
|
import world.bentobox.bentobox.api.localization.TextVariables;
|
||||||
|
import world.bentobox.bentobox.api.user.User;
|
||||||
|
import world.bentobox.bentobox.hooks.VaultHook;
|
||||||
|
import world.bentobox.bentobox.util.Util;
|
||||||
|
import world.bentobox.level.Level;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Run when a user tries to complete a challenge
|
||||||
|
* @author tastybento
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public class TryToComplete {
|
||||||
|
|
||||||
|
private ChallengesAddon addon;
|
||||||
|
private World world;
|
||||||
|
private String permPrefix;
|
||||||
|
private User user;
|
||||||
|
private ChallengesManager manager;
|
||||||
|
private Challenges challenge;
|
||||||
|
private String label;
|
||||||
|
|
||||||
|
public TryToComplete label(String label) {
|
||||||
|
this.label = label;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public TryToComplete user(User user) {
|
||||||
|
this.user = user;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public TryToComplete manager(ChallengesManager manager) {
|
||||||
|
this.manager = manager;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public TryToComplete challenge(Challenges challenge) {
|
||||||
|
this.challenge = challenge;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public TryToComplete world(World world) {
|
||||||
|
this.world = world;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public TryToComplete permPrefix(String prefix) {
|
||||||
|
this.permPrefix = prefix;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public TryToComplete(ChallengesAddon addon) {
|
||||||
|
this.addon = addon;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ChallengeResult build() {
|
||||||
|
// Check if can complete challenge
|
||||||
|
ChallengeResult result = checkIfCanCompleteChallenge();
|
||||||
|
if (!result.meetsRequirements) {
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
if (!result.repeat) {
|
||||||
|
// Give rewards
|
||||||
|
for (ItemStack reward : challenge.getRewardItems()) {
|
||||||
|
user.getInventory().addItem(reward).forEach((k,v) -> user.getWorld().dropItem(user.getLocation(), v));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Give money
|
||||||
|
this.addon.getPlugin().getVault().ifPresent(
|
||||||
|
vaultHook -> vaultHook.deposit(this.user, this.challenge.getRewardMoney()));
|
||||||
|
|
||||||
|
// Give exp
|
||||||
|
user.getPlayer().giveExp(challenge.getRewardExp());
|
||||||
|
// Run commands
|
||||||
|
runCommands(challenge.getRewardCommands());
|
||||||
|
user.sendMessage("challenges.you-completed", "[challenge]", challenge.getFriendlyName());
|
||||||
|
if (addon.getConfig().getBoolean("broadcastmessages", false)) {
|
||||||
|
for (Player p : addon.getServer().getOnlinePlayers()) {
|
||||||
|
User.getInstance(p).sendMessage("challenges.name-has-completed",
|
||||||
|
"[name]", user.getName(), "[challenge]", challenge.getFriendlyName());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// Give rewards
|
||||||
|
for (ItemStack reward : challenge.getRepeatItemReward()) {
|
||||||
|
user.getInventory().addItem(reward).forEach((k,v) -> user.getWorld().dropItem(user.getLocation(), v));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Give money
|
||||||
|
this.addon.getPlugin().getVault().ifPresent(
|
||||||
|
vaultHook -> vaultHook.deposit(this.user, this.challenge.getRepeatMoneyReward()));
|
||||||
|
|
||||||
|
// Give exp
|
||||||
|
user.getPlayer().giveExp(challenge.getRepeatExpReward());
|
||||||
|
// Run commands
|
||||||
|
runCommands(challenge.getRepeatRewardCommands());
|
||||||
|
user.sendMessage("challenges.you-repeated", "[challenge]", challenge.getFriendlyName());
|
||||||
|
}
|
||||||
|
// Mark as complete
|
||||||
|
manager.setChallengeComplete(user, challenge.getUniqueId(), world);
|
||||||
|
user.closeInventory();
|
||||||
|
user.getPlayer().performCommand(label + " " + ChallengesCommand.CHALLENGE_COMMAND + " " + challenge.getLevel());
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param addon
|
||||||
|
* @param user
|
||||||
|
* @param manager
|
||||||
|
* @param challenge
|
||||||
|
* @param world
|
||||||
|
* @param permPrefix
|
||||||
|
*/
|
||||||
|
public TryToComplete(ChallengesAddon addon, User user, ChallengesManager manager, Challenges challenge, World world, String permPrefix, String label) {
|
||||||
|
this.addon = addon;
|
||||||
|
this.world = world;
|
||||||
|
this.permPrefix = permPrefix;
|
||||||
|
this.user = user;
|
||||||
|
this.manager = manager;
|
||||||
|
this.challenge = challenge;
|
||||||
|
|
||||||
|
// Check if can complete challenge
|
||||||
|
ChallengeResult result = checkIfCanCompleteChallenge();
|
||||||
|
if (!result.meetsRequirements) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (!result.repeat) {
|
||||||
|
// Give rewards
|
||||||
|
for (ItemStack reward : challenge.getRewardItems()) {
|
||||||
|
user.getInventory().addItem(reward).forEach((k,v) -> user.getWorld().dropItem(user.getLocation(), v));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Give money
|
||||||
|
this.addon.getPlugin().getVault().ifPresent(
|
||||||
|
vaultHook -> vaultHook.deposit(this.user, this.challenge.getRewardMoney()));
|
||||||
|
|
||||||
|
// Give exp
|
||||||
|
user.getPlayer().giveExp(challenge.getRewardExp());
|
||||||
|
// Run commands
|
||||||
|
runCommands(challenge.getRewardCommands());
|
||||||
|
user.sendMessage("challenges.you-completed", "[challenge]", challenge.getFriendlyName());
|
||||||
|
if (addon.getConfig().getBoolean("broadcastmessages", false)) {
|
||||||
|
for (Player p : addon.getServer().getOnlinePlayers()) {
|
||||||
|
User.getInstance(p).sendMessage("challenges.name-has-completed",
|
||||||
|
"[name]", user.getName(), "[challenge]", challenge.getFriendlyName());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// Give rewards
|
||||||
|
for (ItemStack reward : challenge.getRepeatItemReward()) {
|
||||||
|
user.getInventory().addItem(reward).forEach((k,v) -> user.getWorld().dropItem(user.getLocation(), v));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Give money
|
||||||
|
this.addon.getPlugin().getVault().ifPresent(
|
||||||
|
vaultHook -> vaultHook.deposit(this.user, this.challenge.getRepeatMoneyReward()));
|
||||||
|
|
||||||
|
// Give exp
|
||||||
|
user.getPlayer().giveExp(challenge.getRepeatExpReward());
|
||||||
|
// Run commands
|
||||||
|
runCommands(challenge.getRepeatRewardCommands());
|
||||||
|
user.sendMessage("challenges.you-repeated", "[challenge]", challenge.getFriendlyName());
|
||||||
|
}
|
||||||
|
// Mark as complete
|
||||||
|
manager.setChallengeComplete(user, challenge.getUniqueId(), world);
|
||||||
|
user.closeInventory();
|
||||||
|
user.getPlayer().performCommand(label + " " + ChallengesCommand.CHALLENGE_COMMAND + " " + challenge.getLevel());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks if a challenge can be completed or not
|
||||||
|
*/
|
||||||
|
private ChallengeResult checkIfCanCompleteChallenge() {
|
||||||
|
// Check the world
|
||||||
|
if (!Util.getWorld(user.getWorld()).getName().equalsIgnoreCase(challenge.getWorld())) {
|
||||||
|
user.sendMessage("general.errors.wrong-world");
|
||||||
|
return new ChallengeResult();
|
||||||
|
}
|
||||||
|
// Check if user has the
|
||||||
|
if (!challenge.getLevel().equals(ChallengesManager.FREE) && !manager.isLevelUnlocked(user, challenge.getLevel(), world)) {
|
||||||
|
user.sendMessage("challenges.errors.challenge-level-not-available");
|
||||||
|
return new ChallengeResult();
|
||||||
|
}
|
||||||
|
// Check max times
|
||||||
|
if (challenge.isRepeatable() && challenge.getMaxTimes() > 0 && manager.checkChallengeTimes(user, challenge, world) >= challenge.getMaxTimes()) {
|
||||||
|
user.sendMessage("challenges.not-repeatable");
|
||||||
|
return new ChallengeResult();
|
||||||
|
}
|
||||||
|
// Check repeatability
|
||||||
|
if (manager.isChallengeComplete(user, challenge.getUniqueId(), world)
|
||||||
|
&& (!challenge.isRepeatable() || challenge.getChallengeType().equals(ChallengeType.LEVEL)
|
||||||
|
|| challenge.getChallengeType().equals(ChallengeType.ISLAND))) {
|
||||||
|
user.sendMessage("challenges.not-repeatable");
|
||||||
|
return new ChallengeResult();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check money
|
||||||
|
Optional<VaultHook> vaultHook = this.addon.getPlugin().getVault();
|
||||||
|
|
||||||
|
if (vaultHook.isPresent())
|
||||||
|
{
|
||||||
|
if (!vaultHook.get().has(this.user, this.challenge.getReqMoney()))
|
||||||
|
{
|
||||||
|
this.user.sendMessage("challenges.not-enough-money", "[money]", Integer.toString(this.challenge.getReqMoney()));
|
||||||
|
return new ChallengeResult();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check exp
|
||||||
|
if (this.user.getPlayer().getTotalExperience() < this.challenge.getReqExp())
|
||||||
|
{
|
||||||
|
this.user.sendMessage("challenges.not-enough-exp", "[xp]", Integer.toString(this.challenge.getReqExp()));
|
||||||
|
return new ChallengeResult();
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (challenge.getChallengeType()) {
|
||||||
|
case INVENTORY:
|
||||||
|
return checkInventory();
|
||||||
|
case LEVEL:
|
||||||
|
return checkLevel();
|
||||||
|
case ISLAND:
|
||||||
|
return checkSurrounding();
|
||||||
|
default:
|
||||||
|
return new ChallengeResult();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private ChallengeResult checkInventory() {
|
||||||
|
// Run through inventory
|
||||||
|
List<ItemStack> required = new ArrayList<>(challenge.getRequiredItems());
|
||||||
|
for (ItemStack req : required) {
|
||||||
|
// Check for FIREWORK_ROCKET, ENCHANTED_BOOK, WRITTEN_BOOK, POTION and FILLED_MAP because these have unique meta when created
|
||||||
|
switch (req.getType()) {
|
||||||
|
case FIREWORK_ROCKET:
|
||||||
|
case ENCHANTED_BOOK:
|
||||||
|
case WRITTEN_BOOK:
|
||||||
|
case FILLED_MAP:
|
||||||
|
// Get how many items are in the inventory. Item stacks amounts need to be summed
|
||||||
|
int numInInventory = Arrays.stream(user.getInventory().getContents()).filter(Objects::nonNull).filter(i -> i.getType().equals(req.getType())).mapToInt(i -> i.getAmount()).sum();
|
||||||
|
if (numInInventory < req.getAmount()) {
|
||||||
|
user.sendMessage("challenges.error.not-enough-items", "[items]", Util.prettifyText(req.getType().toString()));
|
||||||
|
return new ChallengeResult();
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
// General checking
|
||||||
|
if (!user.getInventory().containsAtLeast(req, req.getAmount())) {
|
||||||
|
user.sendMessage("challenges.error.not-enough-items", "[items]", Util.prettifyText(req.getType().toString()));
|
||||||
|
return new ChallengeResult();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
// If remove items, then remove them
|
||||||
|
if (challenge.isTakeItems()) {
|
||||||
|
removeItems(required);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// process money removal
|
||||||
|
this.removeMoney();
|
||||||
|
|
||||||
|
// Return the result
|
||||||
|
return new ChallengeResult().setMeetsRequirements().setRepeat(manager.isChallengeComplete(user, challenge.getUniqueId(), world));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method withdraw user money, if challenge Required Money is larger then 0, and
|
||||||
|
* it is set to removal.
|
||||||
|
* This works only if vaultHook is enabled.
|
||||||
|
*/
|
||||||
|
private void removeMoney()
|
||||||
|
{
|
||||||
|
Optional<VaultHook> vaultHook = this.addon.getPlugin().getVault();
|
||||||
|
|
||||||
|
if (vaultHook.isPresent() &&
|
||||||
|
this.challenge.isTakeMoney() &&
|
||||||
|
this.challenge.getReqMoney() > 0)
|
||||||
|
{
|
||||||
|
vaultHook.get().withdraw(this.user, this.challenge.getReqMoney());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Removes items from a user's inventory
|
||||||
|
* @param required - a list of item stacks to be removed
|
||||||
|
* @return Map of item type and quantity that were successfully removed from the user's inventory
|
||||||
|
*/
|
||||||
|
public Map<Material, Integer> removeItems(List<ItemStack> required) {
|
||||||
|
Map<Material, Integer> removed = new HashMap<>();
|
||||||
|
for (ItemStack req : required) {
|
||||||
|
int amountToBeRemoved = req.getAmount();
|
||||||
|
List<ItemStack> itemsInInv = Arrays.stream(user.getInventory().getContents()).filter(Objects::nonNull).filter(i -> i.getType().equals(req.getType())).collect(Collectors.toList());
|
||||||
|
for (ItemStack i : itemsInInv) {
|
||||||
|
if (amountToBeRemoved > 0) {
|
||||||
|
// Remove either the full amount or the remaining amount
|
||||||
|
if (i.getAmount() >= amountToBeRemoved) {
|
||||||
|
i.setAmount(i.getAmount() - amountToBeRemoved);
|
||||||
|
removed.merge(i.getType(), amountToBeRemoved, Integer::sum);
|
||||||
|
amountToBeRemoved = 0;
|
||||||
|
} else {
|
||||||
|
removed.merge(i.getType(), i.getAmount(), Integer::sum);
|
||||||
|
amountToBeRemoved -= i.getAmount();
|
||||||
|
i.setAmount(0);
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (amountToBeRemoved > 0) {
|
||||||
|
addon.logError("Could not remove " + amountToBeRemoved + " of " + req.getType() + " from player's inventory!");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return removed;
|
||||||
|
}
|
||||||
|
|
||||||
|
private ChallengeResult checkLevel() {
|
||||||
|
// Check if the level addon is installed or not
|
||||||
|
long level = addon.getAddonByName("Level")
|
||||||
|
.map(l -> ((Level)l).getIslandLevel(world, user.getUniqueId())).orElse(0L);
|
||||||
|
if (level >= challenge.getReqIslandlevel()) {
|
||||||
|
// process money removal
|
||||||
|
this.removeMoney();
|
||||||
|
return new ChallengeResult().setMeetsRequirements();
|
||||||
|
} else {
|
||||||
|
user.sendMessage("challenges.error.island-level", TextVariables.NUMBER, String.valueOf(challenge.getReqIslandlevel()));
|
||||||
|
return new ChallengeResult();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private ChallengeResult checkSurrounding() {
|
||||||
|
if (!addon.getIslands().userIsOnIsland(world, user)) {
|
||||||
|
// Player is not on island
|
||||||
|
user.sendMessage("challenges.error.not-on-island");
|
||||||
|
return new ChallengeResult();
|
||||||
|
}
|
||||||
|
// Check for items or entities in the area
|
||||||
|
ChallengeResult result = searchForEntities(challenge.getRequiredEntities(), challenge.getSearchRadius());
|
||||||
|
if (result.meetsRequirements && !challenge.getRequiredBlocks().isEmpty()) {
|
||||||
|
// Search for items only if entities found
|
||||||
|
result = searchForBlocks(challenge.getRequiredBlocks(), challenge.getSearchRadius());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (result.meetsRequirements && this.challenge.isTakeMoney())
|
||||||
|
{
|
||||||
|
// process money removal
|
||||||
|
this.removeMoney();
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
private ChallengeResult searchForBlocks(Map<Material, Integer> map, int searchRadius) {
|
||||||
|
Map<Material, Integer> blocks = new EnumMap<>(map);
|
||||||
|
for (int x = -searchRadius; x <= searchRadius; x++) {
|
||||||
|
for (int y = -searchRadius; y <= searchRadius; y++) {
|
||||||
|
for (int z = -searchRadius; z <= searchRadius; z++) {
|
||||||
|
Material mat = user.getWorld().getBlockAt(user.getLocation().add(new Vector(x,y,z))).getType();
|
||||||
|
// Remove one
|
||||||
|
blocks.computeIfPresent(mat, (b, amount) -> amount - 1);
|
||||||
|
// Remove any that have an amount of 0
|
||||||
|
blocks.entrySet().removeIf(en -> en.getValue() <= 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (blocks.isEmpty()) {
|
||||||
|
return new ChallengeResult().setMeetsRequirements();
|
||||||
|
}
|
||||||
|
user.sendMessage("challenges.error.not-close-enough", "[number]", String.valueOf(searchRadius));
|
||||||
|
blocks.forEach((k,v) -> user.sendMessage("challenges.error.you-still-need",
|
||||||
|
"[amount]", String.valueOf(v),
|
||||||
|
"[item]", Util.prettifyText(k.toString())));
|
||||||
|
|
||||||
|
return new ChallengeResult();
|
||||||
|
}
|
||||||
|
|
||||||
|
private ChallengeResult searchForEntities(Map<EntityType, Integer> map, int searchRadius) {
|
||||||
|
Map<EntityType, Integer> entities = map.isEmpty() ? new EnumMap<>(EntityType.class) : new EnumMap<>(map);
|
||||||
|
user.getPlayer().getNearbyEntities(searchRadius, searchRadius, searchRadius).forEach(entity -> {
|
||||||
|
// Look through all the nearby Entities, filtering by type
|
||||||
|
entities.computeIfPresent(entity.getType(), (reqEntity, amount) -> amount - 1);
|
||||||
|
entities.entrySet().removeIf(e -> e.getValue() == 0);
|
||||||
|
});
|
||||||
|
if (entities.isEmpty()) {
|
||||||
|
return new ChallengeResult().setMeetsRequirements();
|
||||||
|
}
|
||||||
|
entities.forEach((reqEnt, amount) -> user.sendMessage("challenges.error.you-still-need",
|
||||||
|
"[amount]", String.valueOf(amount),
|
||||||
|
"[item]", Util.prettifyText(reqEnt.toString())));
|
||||||
|
return new ChallengeResult();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Contains flags on completion of challenge
|
||||||
|
* @author tastybento
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public class ChallengeResult {
|
||||||
|
private boolean meetsRequirements;
|
||||||
|
private boolean repeat;
|
||||||
|
|
||||||
|
|
||||||
|
public ChallengeResult setMeetsRequirements() {
|
||||||
|
this.meetsRequirements = true;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* @param repeat the repeat to set
|
||||||
|
*/
|
||||||
|
public ChallengeResult setRepeat(boolean repeat) {
|
||||||
|
this.repeat = repeat;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private void runCommands(List<String> commands) {
|
||||||
|
// Ignore commands with this perm
|
||||||
|
if (user.hasPermission(permPrefix + "command.challengeexempt") && !user.isOp()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
for (String cmd : commands) {
|
||||||
|
if (cmd.startsWith("[SELF]")) {
|
||||||
|
String alert = "Running command '" + cmd + "' as " + user.getName();
|
||||||
|
addon.getLogger().info(alert);
|
||||||
|
cmd = cmd.substring(6,cmd.length()).replace("[player]", user.getName()).trim();
|
||||||
|
try {
|
||||||
|
if (!user.performCommand(cmd)) {
|
||||||
|
showError(cmd);
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
showError(cmd);
|
||||||
|
}
|
||||||
|
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
// Substitute in any references to player
|
||||||
|
try {
|
||||||
|
if (!addon.getServer().dispatchCommand(addon.getServer().getConsoleSender(), cmd.replace("[player]", user.getName()))) {
|
||||||
|
showError(cmd);
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
showError(cmd);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void showError(final String cmd) {
|
||||||
|
addon.getLogger().severe("Problem executing command executed by player - skipping!");
|
||||||
|
addon.getLogger().severe(() -> "Command was : " + cmd);
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
@ -1,5 +1,5 @@
|
|||||||
name: BentoBox-Challenges
|
name: BentoBox-Challenges
|
||||||
main: bentobox.addon.challenges.ChallengesAddon
|
main: world.bentobox.challenges.ChallengesAddon
|
||||||
version: ${version}
|
version: ${version}
|
||||||
|
|
||||||
authors: tastybento
|
authors: tastybento
|
||||||
|
117
src/test/java/world/bentobox/challenges/ChallengesAddonTest.java
Normal file
117
src/test/java/world/bentobox/challenges/ChallengesAddonTest.java
Normal file
@ -0,0 +1,117 @@
|
|||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
package world.bentobox.challenges;
|
||||||
|
|
||||||
|
import static org.mockito.Matchers.any;
|
||||||
|
import static org.mockito.Mockito.mock;
|
||||||
|
import static org.mockito.Mockito.when;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.UUID;
|
||||||
|
import java.util.logging.Logger;
|
||||||
|
|
||||||
|
import org.bukkit.Bukkit;
|
||||||
|
import org.bukkit.Material;
|
||||||
|
import org.bukkit.OfflinePlayer;
|
||||||
|
import org.bukkit.Server;
|
||||||
|
import org.bukkit.World;
|
||||||
|
import org.bukkit.enchantments.Enchantment;
|
||||||
|
import org.bukkit.inventory.ItemFactory;
|
||||||
|
import org.bukkit.inventory.ItemStack;
|
||||||
|
import org.bukkit.inventory.meta.PotionMeta;
|
||||||
|
import org.bukkit.plugin.PluginManager;
|
||||||
|
import org.bukkit.potion.PotionData;
|
||||||
|
import org.bukkit.potion.PotionType;
|
||||||
|
import org.junit.BeforeClass;
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.junit.runner.RunWith;
|
||||||
|
import org.mockito.Mockito;
|
||||||
|
import org.powermock.modules.junit4.PowerMockRunner;
|
||||||
|
|
||||||
|
import com.google.gson.Gson;
|
||||||
|
import com.google.gson.GsonBuilder;
|
||||||
|
|
||||||
|
import world.bentobox.challenges.objects.Challenges;
|
||||||
|
import world.bentobox.challenges.objects.Challenges.ChallengeType;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author tastybento
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
@RunWith(PowerMockRunner.class)
|
||||||
|
public class ChallengesAddonTest {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @throws java.lang.Exception
|
||||||
|
*/
|
||||||
|
@BeforeClass
|
||||||
|
public static void setUpBeforeClass() throws Exception {
|
||||||
|
Server server = mock(Server.class);
|
||||||
|
World world = mock(World.class);
|
||||||
|
world = mock(World.class);
|
||||||
|
Mockito.when(server.getLogger()).thenReturn(Logger.getAnonymousLogger());
|
||||||
|
Mockito.when(server.getWorld("world")).thenReturn(world);
|
||||||
|
Mockito.when(server.getVersion()).thenReturn("BSB_Mocking");
|
||||||
|
|
||||||
|
PluginManager pluginManager = mock(PluginManager.class);
|
||||||
|
when(server.getPluginManager()).thenReturn(pluginManager);
|
||||||
|
|
||||||
|
ItemFactory itemFactory = mock(ItemFactory.class);
|
||||||
|
when(server.getItemFactory()).thenReturn(itemFactory);
|
||||||
|
|
||||||
|
Bukkit.setServer(server);
|
||||||
|
|
||||||
|
PotionMeta potionMeta = mock(PotionMeta.class);
|
||||||
|
when(itemFactory.getItemMeta(any())).thenReturn(potionMeta);
|
||||||
|
|
||||||
|
OfflinePlayer offlinePlayer = mock(OfflinePlayer.class);
|
||||||
|
when(Bukkit.getOfflinePlayer(any(UUID.class))).thenReturn(offlinePlayer);
|
||||||
|
when(offlinePlayer.getName()).thenReturn("tastybento");
|
||||||
|
|
||||||
|
when(Bukkit.getItemFactory()).thenReturn(itemFactory);
|
||||||
|
when(Bukkit.getLogger()).thenReturn(Logger.getAnonymousLogger());
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void test() {
|
||||||
|
|
||||||
|
Gson gson = new GsonBuilder().setPrettyPrinting().create();
|
||||||
|
Challenges challenges = new Challenges();
|
||||||
|
challenges.setChallengeType(ChallengeType.ISLAND);
|
||||||
|
Map<Material, Integer> map = new HashMap<>();
|
||||||
|
map.put(Material.DIRT, 5);
|
||||||
|
map.put(Material.ACACIA_FENCE_GATE, 3);
|
||||||
|
challenges.setRequiredBlocks(map);
|
||||||
|
challenges.setIcon(new ItemStack(Material.ACACIA_FENCE_GATE));
|
||||||
|
List<ItemStack> requiredItems = new ArrayList<>();
|
||||||
|
ItemStack result = new ItemStack(Material.POTION, 55);
|
||||||
|
ItemStack result2 = new ItemStack(Material.SPLASH_POTION, 22);
|
||||||
|
ItemStack result3 = new ItemStack(Material.LINGERING_POTION, 11);
|
||||||
|
|
||||||
|
PotionMeta potionMeta = (PotionMeta) result.getItemMeta();
|
||||||
|
PotionData potionData = new PotionData(PotionType.FIRE_RESISTANCE, true, false);
|
||||||
|
potionMeta.setBasePotionData(potionData);
|
||||||
|
result.setItemMeta(potionMeta);
|
||||||
|
|
||||||
|
PotionMeta potionMeta2 = (PotionMeta) result2.getItemMeta();
|
||||||
|
PotionData potionData2 = new PotionData(PotionType.SPEED, true, false);
|
||||||
|
potionMeta2.setBasePotionData(potionData2);
|
||||||
|
potionMeta2.addEnchant(Enchantment.BINDING_CURSE, 1, true);
|
||||||
|
result2.setItemMeta(potionMeta2);
|
||||||
|
|
||||||
|
requiredItems.add(result);
|
||||||
|
requiredItems.add(result2);
|
||||||
|
requiredItems.add(result3);
|
||||||
|
challenges.setRequiredItems(requiredItems);
|
||||||
|
String json = gson.toJson(challenges);
|
||||||
|
|
||||||
|
Logger.getAnonymousLogger().info(json);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
123
src/test/java/world/bentobox/challenges/ParseItemTest.java
Normal file
123
src/test/java/world/bentobox/challenges/ParseItemTest.java
Normal file
@ -0,0 +1,123 @@
|
|||||||
|
package world.bentobox.challenges;
|
||||||
|
|
||||||
|
import static org.junit.Assert.assertEquals;
|
||||||
|
import static org.junit.Assert.assertNotNull;
|
||||||
|
import static org.junit.Assert.assertNull;
|
||||||
|
import static org.mockito.Matchers.any;
|
||||||
|
import static org.mockito.Mockito.mock;
|
||||||
|
import static org.mockito.Mockito.when;
|
||||||
|
|
||||||
|
import java.util.logging.Logger;
|
||||||
|
|
||||||
|
import org.bukkit.Bukkit;
|
||||||
|
import org.bukkit.Material;
|
||||||
|
import org.bukkit.Server;
|
||||||
|
import org.bukkit.World;
|
||||||
|
import org.bukkit.inventory.ItemFactory;
|
||||||
|
import org.bukkit.inventory.ItemStack;
|
||||||
|
import org.bukkit.inventory.meta.PotionMeta;
|
||||||
|
import org.bukkit.inventory.meta.SpawnEggMeta;
|
||||||
|
import org.bukkit.plugin.PluginManager;
|
||||||
|
import org.junit.BeforeClass;
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.junit.runner.RunWith;
|
||||||
|
import org.powermock.modules.junit4.PowerMockRunner;
|
||||||
|
import world.bentobox.challenges.ChallengesAddon;
|
||||||
|
import world.bentobox.challenges.ParseItem;
|
||||||
|
|
||||||
|
@RunWith(PowerMockRunner.class)
|
||||||
|
public class ParseItemTest {
|
||||||
|
|
||||||
|
private static ChallengesAddon addon;
|
||||||
|
private static ItemFactory itemFactory;
|
||||||
|
|
||||||
|
|
||||||
|
@BeforeClass
|
||||||
|
public static void setUpBeforeClass() throws Exception {
|
||||||
|
addon = mock(ChallengesAddon.class);
|
||||||
|
when(addon.getLogger()).thenReturn(Logger.getAnonymousLogger());
|
||||||
|
Server server = mock(Server.class);
|
||||||
|
World world = mock(World.class);
|
||||||
|
when(server.getLogger()).thenReturn(Logger.getAnonymousLogger());
|
||||||
|
when(server.getWorld("world")).thenReturn(world);
|
||||||
|
when(server.getVersion()).thenReturn("BSB_Mocking");
|
||||||
|
|
||||||
|
PluginManager pluginManager = mock(PluginManager.class);
|
||||||
|
when(server.getPluginManager()).thenReturn(pluginManager);
|
||||||
|
|
||||||
|
itemFactory = mock(ItemFactory.class);
|
||||||
|
when(server.getItemFactory()).thenReturn(itemFactory);
|
||||||
|
|
||||||
|
Bukkit.setServer(server);
|
||||||
|
|
||||||
|
SpawnEggMeta itemMeta = mock(SpawnEggMeta.class);
|
||||||
|
when(itemFactory.getItemMeta(any())).thenReturn(itemMeta);
|
||||||
|
when(Bukkit.getItemFactory()).thenReturn(itemFactory);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void parseItemTest() {
|
||||||
|
// Nothing test
|
||||||
|
assertNull(new ParseItem(addon, "").getItem());
|
||||||
|
// other
|
||||||
|
assertNull(new ParseItem(addon, "::::::::::::::").getItem());
|
||||||
|
// other
|
||||||
|
assertNull(new ParseItem(addon, "anything:anything").getItem());
|
||||||
|
// Bad material
|
||||||
|
assertNull(new ParseItem(addon, "nosuchmaterial:2").getItem());
|
||||||
|
|
||||||
|
// Material
|
||||||
|
for (Material mat : Material.values()) {
|
||||||
|
ItemStack test = new ParseItem(addon, mat.name() + ":5").getItem();
|
||||||
|
if (test != null) {
|
||||||
|
if (test.getType().toString().endsWith("_ITEM") && !mat.toString().endsWith("_ITEM")) {
|
||||||
|
assertEquals(mat.toString() + "_ITEM", test.getType().toString());
|
||||||
|
} else {
|
||||||
|
assertEquals(mat, test.getType());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Nothing amount
|
||||||
|
ItemStack test = new ParseItem(addon, "STONE:").getItem();
|
||||||
|
assertNull(test);
|
||||||
|
|
||||||
|
|
||||||
|
// Test 3
|
||||||
|
// Bad material
|
||||||
|
assertNull(new ParseItem(addon, "nosuchmaterial:2:2").getItem());
|
||||||
|
|
||||||
|
// Bad amount
|
||||||
|
assertNull(new ParseItem(addon, "STONE:1:sdfgsd").getItem());
|
||||||
|
|
||||||
|
// Missing amount = 1
|
||||||
|
test = new ParseItem(addon, "STONE:1:").getItem();
|
||||||
|
assertNotNull(test); // This is okay, it's just a 2
|
||||||
|
|
||||||
|
// Test Potions
|
||||||
|
PotionMeta itemMeta = mock(PotionMeta.class);
|
||||||
|
when(itemFactory.getItemMeta(any())).thenReturn(itemMeta);
|
||||||
|
when(Bukkit.getItemFactory()).thenReturn(itemFactory);
|
||||||
|
|
||||||
|
// Bad material
|
||||||
|
assertNull(new ParseItem(addon, "nosuchmaterial:JUMP:2:NOTEXTENDED:NOSPLASH:2").getItem());
|
||||||
|
// Bad amount
|
||||||
|
assertNull(new ParseItem(addon, "POTION:JUMP:2:NOTEXTENDED:NOSPLASH:asfdas").getItem());
|
||||||
|
test = new ParseItem(addon, "POTION:JUMP:2:NOTEXTENDED:NOSPLASH:").getItem();
|
||||||
|
assertNull(test);
|
||||||
|
|
||||||
|
test = new ParseItem(addon, "POTION:JUMP:2:NOTEXTENDED:NOSPLASH:1").getItem();
|
||||||
|
assertEquals(Material.POTION, test.getType());
|
||||||
|
test = new ParseItem(addon, "POTION:JUMP:2").getItem();
|
||||||
|
assertEquals(Material.POTION, test.getType());
|
||||||
|
test = new ParseItem(addon, "POTION:STRENGTH:1:EXTENDED:SPLASH:1").getItem();
|
||||||
|
assertEquals(Material.SPLASH_POTION, test.getType());
|
||||||
|
test = new ParseItem(addon, "POTION:INSTANT_DAMAGE:2::LINGER:2").getItem();
|
||||||
|
assertEquals(Material.LINGERING_POTION, test.getType());
|
||||||
|
test = new ParseItem(addon, "TIPPED_ARROW:STRENGTH:1:::1").getItem();
|
||||||
|
assertEquals(Material.TIPPED_ARROW, test.getType());
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,164 @@
|
|||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
package world.bentobox.challenges.panel;
|
||||||
|
|
||||||
|
import static org.junit.Assert.assertTrue;
|
||||||
|
import static org.mockito.Mockito.mock;
|
||||||
|
import static org.mockito.Mockito.when;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import org.bukkit.Material;
|
||||||
|
import org.bukkit.inventory.ItemStack;
|
||||||
|
import org.bukkit.inventory.PlayerInventory;
|
||||||
|
import org.junit.Before;
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.junit.runner.RunWith;
|
||||||
|
import org.mockito.Mockito;
|
||||||
|
import org.powermock.modules.junit4.PowerMockRunner;
|
||||||
|
|
||||||
|
import world.bentobox.challenges.ChallengesAddon;
|
||||||
|
import world.bentobox.bentobox.api.user.User;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author tastybento
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
@RunWith(PowerMockRunner.class)
|
||||||
|
public class TryToCompleteTest {
|
||||||
|
|
||||||
|
private User user;
|
||||||
|
ItemStack[] stacks = { new ItemStack(Material.PAPER, 32),
|
||||||
|
new ItemStack(Material.ACACIA_BOAT),
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
new ItemStack(Material.CACTUS, 32),
|
||||||
|
new ItemStack(Material.CACTUS, 32),
|
||||||
|
new ItemStack(Material.CACTUS, 32),
|
||||||
|
new ItemStack(Material.GOLD_BLOCK, 32)
|
||||||
|
};
|
||||||
|
List<ItemStack> required;
|
||||||
|
private ChallengesAddon addon;
|
||||||
|
private PlayerInventory inv;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @throws java.lang.Exception
|
||||||
|
*/
|
||||||
|
@Before
|
||||||
|
public void setUp() throws Exception {
|
||||||
|
user = mock(User.class);
|
||||||
|
inv = mock(PlayerInventory.class);
|
||||||
|
when(inv.getContents()).thenReturn(stacks);
|
||||||
|
when(user.getInventory()).thenReturn(inv);
|
||||||
|
addon = mock(ChallengesAddon.class);
|
||||||
|
required = new ArrayList<>();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test method for {@link world.bentobox.challenges.panel.TryToComplete#removeItems(java.util.List)}.
|
||||||
|
*/
|
||||||
|
@Test
|
||||||
|
public void testRemoveItemsSuccess() {
|
||||||
|
Material reqMat = Material.PAPER;
|
||||||
|
int reqQty = 21;
|
||||||
|
required.add(new ItemStack(reqMat, reqQty));
|
||||||
|
TryToComplete x = new TryToComplete(addon);
|
||||||
|
x.user(user);
|
||||||
|
Map<Material, Integer> removed = x.removeItems(required);
|
||||||
|
assertTrue(removed.get(reqMat) == reqQty);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test method for {@link world.bentobox.challenges.panel.TryToComplete#removeItems(java.util.List)}.
|
||||||
|
*/
|
||||||
|
@Test
|
||||||
|
public void testRemoveItemsMax() {
|
||||||
|
Material reqMat = Material.PAPER;
|
||||||
|
int reqQty = 50;
|
||||||
|
required.add(new ItemStack(reqMat, reqQty));
|
||||||
|
TryToComplete x = new TryToComplete(addon);
|
||||||
|
x.user(user);
|
||||||
|
Map<Material, Integer> removed = x.removeItems(required);
|
||||||
|
assertTrue(removed.get(reqMat) == 32);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test method for {@link world.bentobox.challenges.panel.TryToComplete#removeItems(java.util.List)}.
|
||||||
|
*/
|
||||||
|
@Test
|
||||||
|
public void testRemoveItemsZero() {
|
||||||
|
Material reqMat = Material.PAPER;
|
||||||
|
int reqQty = 0;
|
||||||
|
required.add(new ItemStack(reqMat, reqQty));
|
||||||
|
TryToComplete x = new TryToComplete(addon);
|
||||||
|
x.user(user);
|
||||||
|
Map<Material, Integer> removed = x.removeItems(required);
|
||||||
|
assertTrue(removed.get(reqMat) == null);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test method for {@link world.bentobox.challenges.panel.TryToComplete#removeItems(java.util.List)}.
|
||||||
|
*/
|
||||||
|
@Test
|
||||||
|
public void testRemoveItemsSuccessMultiple() {
|
||||||
|
required.add(new ItemStack(Material.PAPER, 11));
|
||||||
|
required.add(new ItemStack(Material.PAPER, 5));
|
||||||
|
required.add(new ItemStack(Material.PAPER, 5));
|
||||||
|
TryToComplete x = new TryToComplete(addon);
|
||||||
|
x.user(user);
|
||||||
|
Map<Material, Integer> removed = x.removeItems(required);
|
||||||
|
assertTrue(removed.get(Material.PAPER) == 21);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test method for {@link world.bentobox.challenges.panel.TryToComplete#removeItems(java.util.List)}.
|
||||||
|
*/
|
||||||
|
@Test
|
||||||
|
public void testRemoveItemsSuccessMultipleOther() {
|
||||||
|
required.add(new ItemStack(Material.CACTUS, 5));
|
||||||
|
required.add(new ItemStack(Material.PAPER, 11));
|
||||||
|
required.add(new ItemStack(Material.PAPER, 5));
|
||||||
|
required.add(new ItemStack(Material.PAPER, 5));
|
||||||
|
required.add(new ItemStack(Material.CACTUS, 5));
|
||||||
|
TryToComplete x = new TryToComplete(addon);
|
||||||
|
x.user(user);
|
||||||
|
Map<Material, Integer> removed = x.removeItems(required);
|
||||||
|
assertTrue(removed.get(Material.PAPER) == 21);
|
||||||
|
assertTrue(removed.get(Material.CACTUS) == 10);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test method for {@link world.bentobox.challenges.panel.TryToComplete#removeItems(java.util.List)}.
|
||||||
|
*/
|
||||||
|
@Test
|
||||||
|
public void testRemoveItemsMultipleOtherFail() {
|
||||||
|
required.add(new ItemStack(Material.ACACIA_FENCE, 5));
|
||||||
|
required.add(new ItemStack(Material.ARROW, 11));
|
||||||
|
required.add(new ItemStack(Material.STONE, 5));
|
||||||
|
required.add(new ItemStack(Material.BAKED_POTATO, 5));
|
||||||
|
required.add(new ItemStack(Material.GHAST_SPAWN_EGG, 5));
|
||||||
|
TryToComplete x = new TryToComplete(addon);
|
||||||
|
x.user(user);
|
||||||
|
Map<Material, Integer> removed = x.removeItems(required);
|
||||||
|
assertTrue(removed.isEmpty());
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test method for {@link world.bentobox.challenges.panel.TryToComplete#removeItems(java.util.List)}.
|
||||||
|
*/
|
||||||
|
@Test
|
||||||
|
public void testRemoveItemsFail() {
|
||||||
|
required.add(new ItemStack(Material.GOLD_BLOCK, 55));
|
||||||
|
TryToComplete x = new TryToComplete(addon);
|
||||||
|
x.user(user);
|
||||||
|
Map<Material, Integer> removed = x.removeItems(required);
|
||||||
|
// It will remove 32, but not any more
|
||||||
|
assertTrue(removed.get(Material.GOLD_BLOCK) == 32);
|
||||||
|
// An error will be thrown
|
||||||
|
Mockito.verify(addon, Mockito.times(1)).logError(Mockito.anyString());
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user