Reworked to support multiworld.

This commit is contained in:
tastybento 2018-05-27 21:13:32 -07:00
parent 3e591b1466
commit 983399ec3b
13 changed files with 194 additions and 137 deletions

View File

@ -16,7 +16,7 @@ challenges:
complete: "&BComplete" complete: "&BComplete"
exp-reward: "&6Exp reward: [reward]" exp-reward: "&6Exp reward: [reward]"
first-time-rewards: "&6First time reward(s)" first-time-rewards: "&6First time reward(s)"
gui-title: "BSkyBlock Challenges" gui-title: "&aChallenges"
incomplete: "Incomplete" incomplete: "Incomplete"
item-take-warning: "&cAll required items are|&ctaken when you complete|&cthis challenge!" item-take-warning: "&cAll required items are|&ctaken when you complete|&cthis challenge!"
items-closeby: "&cAll required items|&cmust be close to you|&con your island!" items-closeby: "&cAll required items|&cmust be close to you|&con your island!"

View File

@ -5,6 +5,7 @@ import org.bukkit.Bukkit;
import bskyblock.addon.challenges.commands.ChallengesCommand; import bskyblock.addon.challenges.commands.ChallengesCommand;
import bskyblock.addon.challenges.commands.admin.ChallengesAdminCommand; import bskyblock.addon.challenges.commands.admin.ChallengesAdminCommand;
import us.tastybento.bskyblock.api.addons.Addon; import us.tastybento.bskyblock.api.addons.Addon;
import us.tastybento.bskyblock.api.commands.CompositeCommand;
/** /**
* Add-on to BSkyBlock that enables challenges * Add-on to BSkyBlock that enables challenges
@ -14,6 +15,7 @@ import us.tastybento.bskyblock.api.addons.Addon;
public class ChallengesAddon extends Addon { public class ChallengesAddon extends Addon {
private ChallengesManager challengesManager; private ChallengesManager challengesManager;
private String permissionPrefix = "addon";
@Override @Override
public void onEnable() { public void onEnable() {
@ -29,9 +31,22 @@ public class ChallengesAddon extends Addon {
// First time challenges creation // First time challenges creation
new FreshSqueezedChallenges(this); new FreshSqueezedChallenges(this);
// Register commands // Register commands - run one tick later to allow all addons to load
new ChallengesCommand(this); // AcidIsland hook in
new ChallengesAdminCommand(this); getServer().getScheduler().runTask(getBSkyBlock(), () -> {
this.getBSkyBlock().getAddonsManager().getAddonByName("AcidIsland").ifPresent(a -> {
getLogger().info("DEBUG: " + getBSkyBlock().getCommandsManager().listCommands());
CompositeCommand acidIslandCmd = getBSkyBlock().getCommandsManager().getCommand("ai");
new ChallengesCommand(this, acidIslandCmd);
CompositeCommand acidCmd = getBSkyBlock().getCommandsManager().getCommand("acid");
new ChallengesAdminCommand(this, acidCmd);
});
});
// BSkyBlock hook in
CompositeCommand bsbIslandCmd = getBSkyBlock().getCommandsManager().getCommand("island");
new ChallengesCommand(this, bsbIslandCmd);
CompositeCommand bsbAdminCmd = getBSkyBlock().getCommandsManager().getCommand("bsbadmin");
new ChallengesAdminCommand(this, bsbAdminCmd);
// Done // Done
} }
@ -46,4 +61,8 @@ public class ChallengesAddon extends Addon {
return challengesManager; return challengesManager;
} }
public String getPermissionPrefix() {
return permissionPrefix ;
}
} }

View File

@ -16,6 +16,7 @@ import java.util.stream.Collectors;
import org.apache.commons.lang.WordUtils; import org.apache.commons.lang.WordUtils;
import org.bukkit.ChatColor; import org.bukkit.ChatColor;
import org.bukkit.Material; import org.bukkit.Material;
import org.bukkit.World;
import org.bukkit.inventory.Inventory; import org.bukkit.inventory.Inventory;
import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.ItemStack;
@ -50,8 +51,6 @@ public class ChallengesManager {
players = new BSBDatabase<>(addon, PlayerData.class); players = new BSBDatabase<>(addon, PlayerData.class);
// Cache of challenges // Cache of challenges
challengeMap = new LinkedHashMap<>(); challengeMap = new LinkedHashMap<>();
// Start panels
challengesPanels = new ChallengesPanels(addon, this);
// Cache of player data // Cache of player data
playerData = new HashMap<>(); playerData = new HashMap<>();
load(); load();
@ -87,9 +86,9 @@ public class ChallengesManager {
* @param challenge - challenge * @param challenge - challenge
* @return - number of times * @return - number of times
*/ */
public long checkChallengeTimes(User user, Challenges challenge) { public long checkChallengeTimes(User user, Challenges challenge, World world) {
addPlayer(user); addPlayer(user);
return playerData.get(user.getUniqueId()).getTimes(challenge.getUniqueId()); return playerData.get(user.getUniqueId()).getTimes(world, challenge.getUniqueId());
} }
/** /**
@ -195,11 +194,13 @@ public class ChallengesManager {
/** /**
* Get challenge by name * Get challenge by name
* @param name - unique name of challenge * @param name - unique name of challenge
* @param world - world to check
* @return - challenge or null if it does not exist * @return - challenge or null if it does not exist
*/ */
public Challenges getChallenge(String name) { public Challenges getChallenge(String name, World world) {
String worldName = Util.getWorld(world).getName();
for (Set<Challenges> ch : challengeMap.values()) { for (Set<Challenges> ch : challengeMap.values()) {
Optional<Challenges> challenge = ch.stream().filter(c -> c.getUniqueId().equalsIgnoreCase(name)).findFirst(); Optional<Challenges> challenge = ch.stream().filter(c -> c.getUniqueId().equalsIgnoreCase(worldName + name)).findFirst();
if (challenge.isPresent()) { if (challenge.isPresent()) {
return challenge.get(); return challenge.get();
} }
@ -210,9 +211,10 @@ public class ChallengesManager {
/** /**
* Get the status on every level * Get the status on every level
* @param user - user * @param user - user
* @param world - world to check
* @return Level status - how many challenges still to do on which level * @return Level status - how many challenges still to do on which level
*/ */
public List<LevelStatus> getChallengeLevelStatus(User user) { public List<LevelStatus> getChallengeLevelStatus(User user, World world) {
addPlayer(user); addPlayer(user);
PlayerData pd = playerData.get(user.getUniqueId()); PlayerData pd = playerData.get(user.getUniqueId());
List<LevelStatus> result = new ArrayList<>(); List<LevelStatus> result = new ArrayList<>();
@ -223,7 +225,7 @@ public class ChallengesManager {
for (Entry<ChallengeLevels, Set<Challenges>> en : challengeMap.entrySet()) { for (Entry<ChallengeLevels, Set<Challenges>> en : challengeMap.entrySet()) {
int total = challengeMap.values().size(); int total = challengeMap.values().size();
int waiverAmount = en.getKey().getWaiveramount(); int waiverAmount = en.getKey().getWaiveramount();
int challengesDone = (int) en.getValue().stream().filter(ch -> pd.isChallengeDone(ch.getUniqueId())).count(); int challengesDone = (int) en.getValue().stream().filter(ch -> pd.isChallengeDone(world, ch.getUniqueId())).count();
int challsToDo = Math.max(0,total-challengesDone-waiverAmount); int challsToDo = Math.max(0,total-challengesDone-waiverAmount);
boolean complete = challsToDo > 0 ? false : true; boolean complete = challsToDo > 0 ? false : true;
// Create result class with the data // Create result class with the data
@ -236,20 +238,27 @@ public class ChallengesManager {
} }
/** /**
* Get the challenge list
* @return the challengeList * @return the challengeList
*/ */
public Map<ChallengeLevels, Set<Challenges>> getChallengeList() { public Map<ChallengeLevels, Set<Challenges>> getChallengeList() {
// TODO return the challenges for world
return challengeMap; return challengeMap;
} }
/** /**
* Get the set of challenges for this level * Get the set of challenges for this level for this world
* @param level - the level required * @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 * @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) { 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(); Optional<ChallengeLevels> lv = challengeMap.keySet().stream().filter(l -> l.getUniqueId().equalsIgnoreCase(level)).findFirst();
return lv.isPresent() ? challengeMap.get(lv.get()) : new HashSet<>(); // Get the challenges applicable to this world
return lv.isPresent() ? challengeMap.get(lv.get()).stream()
.filter(c -> c.getWorlds().contains(worldName) || c.getWorlds().isEmpty()).collect(Collectors.toSet())
: new HashSet<>();
} }
/** /**
@ -295,9 +304,9 @@ public class ChallengesManager {
* @param challengeName - Challenge uniqueId * @param challengeName - Challenge uniqueId
* @return - true if completed * @return - true if completed
*/ */
public boolean isChallengeComplete(User user, String challengeName) { public boolean isChallengeComplete(User user, String challengeName, World world) {
addPlayer(user); addPlayer(user);
return playerData.get(user.getUniqueId()).isChallengeDone(challengeName); return playerData.get(user.getUniqueId()).isChallengeDone(world, challengeName);
} }
/** /**
@ -306,9 +315,9 @@ public class ChallengesManager {
* @param level - level unique id * @param level - level unique id
* @return true if level is unlocked * @return true if level is unlocked
*/ */
public boolean isLevelUnlocked(User user, String level) { public boolean isLevelUnlocked(User user, String level, World world) {
addPlayer(user); addPlayer(user);
return getChallengeLevelStatus(user).stream().filter(LevelStatus::isUnlocked).anyMatch(lv -> lv.getLevel().getUniqueId().equalsIgnoreCase(level)); return getChallengeLevelStatus(user, world).stream().filter(LevelStatus::isUnlocked).anyMatch(lv -> lv.getLevel().getUniqueId().equalsIgnoreCase(level));
} }
/** /**
@ -355,12 +364,13 @@ public class ChallengesManager {
/** /**
* Sets the challenge as complete and increments the number of times it has been completed * Sets the challenge as complete and increments the number of times it has been completed
* @param user * @param user - user
* @param uniqueId * @param challengeUniqueId - unique challenge id
* @param world - world to set
*/ */
public void setChallengeComplete(User user, String challengeUniqueId) { public void setChallengeComplete(User user, String challengeUniqueId, World world) {
addPlayer(user); addPlayer(user);
playerData.get(user.getUniqueId()).setChallengeDone(challengeUniqueId); playerData.get(user.getUniqueId()).setChallengeDone(world, challengeUniqueId);
} }
/** /**

View File

@ -3,7 +3,7 @@ package bskyblock.addon.challenges.commands;
import java.util.List; import java.util.List;
import bskyblock.addon.challenges.ChallengesAddon; import bskyblock.addon.challenges.ChallengesAddon;
import us.tastybento.bskyblock.Constants; import bskyblock.addon.challenges.panel.ChallengesPanels;
import us.tastybento.bskyblock.api.commands.CompositeCommand; import us.tastybento.bskyblock.api.commands.CompositeCommand;
import us.tastybento.bskyblock.api.user.User; import us.tastybento.bskyblock.api.user.User;
@ -11,17 +11,16 @@ public class ChallengesCommand extends CompositeCommand {
public static final String CHALLENGE_COMMAND = "challenges"; public static final String CHALLENGE_COMMAND = "challenges";
private ChallengesAddon addon; private ChallengesAddon addon;
public ChallengesCommand(ChallengesAddon addon) { public ChallengesCommand(ChallengesAddon addon, CompositeCommand cmd) {
super(CHALLENGE_COMMAND, "c", "challenge"); super(cmd, CHALLENGE_COMMAND, "c", "challenge");
this.addon = addon; this.addon = addon;
// Set up commands
} }
@Override @Override
public boolean execute(User user, List<String> args) { public boolean execute(User user, List<String> args) {
// Open up the challenges GUI // Open up the challenges GUI
if (user.isPlayer()) { if (user.isPlayer()) {
addon.getChallengesManager().getChallengesPanels().getChallenges(user, args.isEmpty() ? "" : args.get(0)); new ChallengesPanels(addon, user, args.isEmpty() ? "" : args.get(0), getWorld(), getPermissionPrefix(), getTopLabel());
return true; return true;
} }
return false; return false;
@ -30,7 +29,7 @@ public class ChallengesCommand extends CompositeCommand {
@Override @Override
public void setup() { public void setup() {
this.setOnlyPlayer(true); this.setOnlyPlayer(true);
this.setPermission(Constants.PERMPREFIX + CHALLENGE_COMMAND); this.setPermission(getPermissionPrefix() + CHALLENGE_COMMAND);
this.setParameters(CHALLENGE_COMMAND + ".parameters"); this.setParameters(CHALLENGE_COMMAND + ".parameters");
this.setDescription(CHALLENGE_COMMAND + ".description"); this.setDescription(CHALLENGE_COMMAND + ".description");
this.setOnlyPlayer(true); this.setOnlyPlayer(true);

View File

@ -3,17 +3,14 @@ package bskyblock.addon.challenges.commands.admin;
import java.util.List; import java.util.List;
import bskyblock.addon.challenges.ChallengesAddon; import bskyblock.addon.challenges.ChallengesAddon;
import us.tastybento.bskyblock.Constants;
import us.tastybento.bskyblock.api.commands.CompositeCommand; import us.tastybento.bskyblock.api.commands.CompositeCommand;
import us.tastybento.bskyblock.api.user.User; import us.tastybento.bskyblock.api.user.User;
public class ChallengesAdminCommand extends CompositeCommand { public class ChallengesAdminCommand extends CompositeCommand {
private static final String CHALLENGE_ADMIN_COMMAND = "cadmin"; private static final String CHALLENGE_ADMIN_COMMAND = "cadmin";
private ChallengesAddon addon;
public ChallengesAdminCommand(ChallengesAddon addon) { public ChallengesAdminCommand(ChallengesAddon addon, CompositeCommand cmd) {
super(CHALLENGE_ADMIN_COMMAND); super(cmd, CHALLENGE_ADMIN_COMMAND);
this.addon = addon;
// Set up create command // Set up create command
new CreateChallenge(addon, this); new CreateChallenge(addon, this);
new SetIcon(addon, this); new SetIcon(addon, this);
@ -21,18 +18,13 @@ public class ChallengesAdminCommand extends CompositeCommand {
@Override @Override
public boolean execute(User user, List<String> args) { public boolean execute(User user, List<String> args) {
// Open up the challenges GUI
if (user.isPlayer()) {
addon.getChallengesManager().getChallengesPanels().getChallenges(user);
return true;
}
return false; return false;
} }
@Override @Override
public void setup() { public void setup() {
this.setOnlyPlayer(true); this.setOnlyPlayer(true);
this.setPermission(Constants.PERMPREFIX + "challenges.admin"); this.setPermission(getPermissionPrefix() + "challenges.admin");
this.setParameters("challaneges.admin.parameters"); this.setParameters("challaneges.admin.parameters");
this.setDescription("challenges.admin.description"); this.setDescription("challenges.admin.description");
this.setOnlyPlayer(true); this.setOnlyPlayer(true);

View File

@ -4,7 +4,6 @@ import java.util.List;
import bskyblock.addon.challenges.ChallengesAddon; import bskyblock.addon.challenges.ChallengesAddon;
import bskyblock.addon.challenges.panel.CreateChallengeListener; import bskyblock.addon.challenges.panel.CreateChallengeListener;
import us.tastybento.bskyblock.Constants;
import us.tastybento.bskyblock.api.commands.CompositeCommand; import us.tastybento.bskyblock.api.commands.CompositeCommand;
import us.tastybento.bskyblock.api.panels.builders.PanelBuilder; import us.tastybento.bskyblock.api.panels.builders.PanelBuilder;
import us.tastybento.bskyblock.api.user.User; import us.tastybento.bskyblock.api.user.User;
@ -28,7 +27,7 @@ public class CreateChallenge extends CompositeCommand {
@Override @Override
public void setup() { public void setup() {
this.setOnlyPlayer(true); this.setOnlyPlayer(true);
this.setPermission(Constants.PERMPREFIX + "admin.challenges"); this.setPermission(getPermissionPrefix() + "admin.challenges");
this.setParameters("challaneges.admin.create.parameters"); this.setParameters("challaneges.admin.create.parameters");
this.setDescription("challenges.admin.create.description"); this.setDescription("challenges.admin.create.description");

View File

@ -17,7 +17,6 @@ import org.bukkit.event.player.PlayerInteractEvent;
import org.bukkit.event.player.PlayerQuitEvent; import org.bukkit.event.player.PlayerQuitEvent;
import bskyblock.addon.challenges.ChallengesAddon; import bskyblock.addon.challenges.ChallengesAddon;
import us.tastybento.bskyblock.Constants;
import us.tastybento.bskyblock.api.commands.CompositeCommand; import us.tastybento.bskyblock.api.commands.CompositeCommand;
import us.tastybento.bskyblock.api.user.User; import us.tastybento.bskyblock.api.user.User;
import us.tastybento.bskyblock.util.Util; import us.tastybento.bskyblock.util.Util;
@ -46,7 +45,7 @@ public class CreateSurrounding extends CompositeCommand implements Listener {
@Override @Override
public void setup() { public void setup() {
this.setOnlyPlayer(true); this.setOnlyPlayer(true);
this.setPermission(Constants.PERMPREFIX + "admin.challenges"); this.setPermission(getPermissionPrefix() + "admin.challenges");
this.setParameters("challaneges.admin.create.surrounding.parameters"); this.setParameters("challaneges.admin.create.surrounding.parameters");
this.setDescription("challenges.admin.create.surrounding.description"); this.setDescription("challenges.admin.create.surrounding.description");
} }

View File

@ -49,7 +49,7 @@ public class SetIcon extends CompositeCommand {
user.sendMessage("challenges.admin.seticon.description"); user.sendMessage("challenges.admin.seticon.description");
return false; return false;
} }
Challenges challenge = addon.getChallengesManager().getChallenge(args.get(0)); Challenges challenge = addon.getChallengesManager().getChallenge(args.get(0), getWorld());
// Check if this challenge name exists // Check if this challenge name exists
if (challenge == null) { if (challenge == null) {
user.sendMessage("challenges.admin.seticon.error.no-such-challenge"); user.sendMessage("challenges.admin.seticon.error.no-such-challenge");

View File

@ -20,6 +20,9 @@ public class ChallengeLevels implements DataObject, Comparable<ChallengeLevels>
@ConfigComment("A friendly name for the level. If blank, level name is used.") @ConfigComment("A friendly name for the level. If blank, level name is used.")
private String friendlyName = ""; 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") @ConfigComment("Commands to run when this level is completed")
private List<String> rewardCommands = new ArrayList<>(); private List<String> rewardCommands = new ArrayList<>();
@ -52,7 +55,7 @@ public class ChallengeLevels implements DataObject, Comparable<ChallengeLevels>
} }
public List<String> getRewardCommands() { public List<String> getRewardCommands() {
return rewardCommands; return rewardCommands = new ArrayList<>();
} }
@Override @Override
@ -168,6 +171,20 @@ public class ChallengeLevels implements DataObject, Comparable<ChallengeLevels>
this.unlockMessage = 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) /* (non-Javadoc)
* @see java.lang.Object#hashCode() * @see java.lang.Object#hashCode()
*/ */

View File

@ -41,6 +41,9 @@ public class Challenges implements DataObject {
@ConfigComment("Whether this challenge is deployed or not") @ConfigComment("Whether this challenge is deployed or not")
private boolean deployed; private boolean deployed;
@ConfigComment("Worlds that this challenge will run in. String list. List only overworld. Nether and end are automatically covered.")
private List<String> worlds = new ArrayList<>();
// Description // Description
@ConfigComment("Name of the icon and challenge. May include color codes. Single line.") @ConfigComment("Name of the icon and challenge. May include color codes. Single line.")
private String friendlyName = ""; private String friendlyName = "";
@ -196,7 +199,7 @@ public class Challenges implements DataObject {
* @return the icon * @return the icon
*/ */
public ItemStack getIcon() { public ItemStack getIcon() {
return icon; return icon.clone();
} }
/** /**
@ -559,6 +562,20 @@ public class Challenges implements DataObject {
this.environment = environment; this.environment = environment;
} }
/**
* @return the worlds
*/
public List<String> getWorlds() {
return worlds;
}
/**
* @param worlds the worlds to set
*/
public void setWorlds(List<String> worlds) {
this.worlds = worlds;
}
/** /**
* @return the uniqueId * @return the uniqueId
*/ */

View File

@ -8,9 +8,12 @@ import java.util.HashSet;
import java.util.Map; import java.util.Map;
import java.util.Set; import java.util.Set;
import org.bukkit.World;
import com.google.gson.annotations.Expose; import com.google.gson.annotations.Expose;
import us.tastybento.bskyblock.database.objects.DataObject; import us.tastybento.bskyblock.database.objects.DataObject;
import us.tastybento.bskyblock.util.Util;
/** /**
* Stores the player's challenge situation * Stores the player's challenge situation
@ -38,10 +41,11 @@ public class PlayerData implements DataObject {
* Mark a challenge as having been completed. Will increment the number of times and timestamp * Mark a challenge as having been completed. Will increment the number of times and timestamp
* @param challengeName - unique challenge name * @param challengeName - unique challenge name
*/ */
public void setChallengeDone(String challengeName) { public void setChallengeDone(World world, String challengeName) {
int times = challengeStatus.getOrDefault(challengeName, 0) + 1; String name = Util.getWorld(world).getName() + challengeName;
challengeStatus.put(challengeName, times); int times = challengeStatus.getOrDefault(name, 0) + 1;
challengesTimestamp.put(challengeName, System.currentTimeMillis()); challengeStatus.put(name, times);
challengesTimestamp.put(name, System.currentTimeMillis());
} }
/** /**
@ -49,8 +53,8 @@ public class PlayerData implements DataObject {
* @param challengeName - unique challenge name * @param challengeName - unique challenge name
* @return true if done at least once * @return true if done at least once
*/ */
public boolean isChallengeDone(String challengeName) { public boolean isChallengeDone(World world, String challengeName) {
return getTimes(challengeName) > 0 ? true : false; return getTimes(world, challengeName) > 0;
} }
/** /**
@ -58,8 +62,8 @@ public class PlayerData implements DataObject {
* @param challengeName - unique challenge name * @param challengeName - unique challenge name
* @return - number of times * @return - number of times
*/ */
public int getTimes(String challengeName) { public int getTimes(World world, String challengeName) {
return challengeStatus.getOrDefault(challengeName, 0); return challengeStatus.getOrDefault(Util.getWorld(world).getName() + challengeName, 0);
} }
/** /**
@ -75,7 +79,6 @@ public class PlayerData implements DataObject {
*/ */
@Override @Override
public String getUniqueId() { public String getUniqueId() {
// TODO Auto-generated method stub
return uniqueId; return uniqueId;
} }
@ -85,7 +88,6 @@ public class PlayerData implements DataObject {
@Override @Override
public void setUniqueId(String uniqueId) { public void setUniqueId(String uniqueId) {
this.uniqueId = uniqueId; this.uniqueId = uniqueId;
} }
/** /**

View File

@ -6,6 +6,7 @@ import java.util.List;
import java.util.Set; import java.util.Set;
import org.bukkit.Material; import org.bukkit.Material;
import org.bukkit.World;
import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.ItemStack;
import bskyblock.addon.challenges.ChallengesAddon; import bskyblock.addon.challenges.ChallengesAddon;
@ -14,7 +15,6 @@ import bskyblock.addon.challenges.LevelStatus;
import bskyblock.addon.challenges.commands.ChallengesCommand; import bskyblock.addon.challenges.commands.ChallengesCommand;
import bskyblock.addon.challenges.database.object.Challenges; import bskyblock.addon.challenges.database.object.Challenges;
import bskyblock.addon.challenges.database.object.Challenges.ChallengeType; import bskyblock.addon.challenges.database.object.Challenges.ChallengeType;
import us.tastybento.bskyblock.Constants;
import us.tastybento.bskyblock.api.panels.Panel; import us.tastybento.bskyblock.api.panels.Panel;
import us.tastybento.bskyblock.api.panels.PanelItem; import us.tastybento.bskyblock.api.panels.PanelItem;
import us.tastybento.bskyblock.api.panels.builders.PanelBuilder; import us.tastybento.bskyblock.api.panels.builders.PanelBuilder;
@ -25,26 +25,20 @@ import us.tastybento.bskyblock.api.user.User;
public class ChallengesPanels { public class ChallengesPanels {
private ChallengesAddon addon; private ChallengesAddon addon;
private ChallengesManager manager; private ChallengesManager manager;
private User user;
private String level;
private World world;
private String permPrefix;
private String label;
public ChallengesPanels(ChallengesAddon plugin, ChallengesManager manager){ public ChallengesPanels(ChallengesAddon addon, User user, String level, World world, String permPrefix, String label) {
this.addon = plugin; this.addon = addon;
this.manager = manager; this.manager = addon.getChallengesManager();
} this.user = user;
this.world = world;
this.permPrefix = permPrefix;
this.label = label;
/**
* @param user
* @return
*/
public void getChallenges(User user) {
// Get the challenge level this player is on
getChallenges(user, "");
}
/**
* Dynamically creates an inventory of challenges for the player showing the
* level
*/
public void getChallenges(User user, String level) {
if (manager.getChallengeList().isEmpty()) { if (manager.getChallengeList().isEmpty()) {
addon.getLogger().severe("There are no challenges set up!"); addon.getLogger().severe("There are no challenges set up!");
user.sendMessage("general.errors.general"); user.sendMessage("general.errors.general");
@ -53,24 +47,33 @@ public class ChallengesPanels {
if (level.isEmpty()) { if (level.isEmpty()) {
level = manager.getChallengeList().keySet().iterator().next().getUniqueId(); level = manager.getChallengeList().keySet().iterator().next().getUniqueId();
} }
this.level = level;
// Check if level is valid // Check if level is valid
if (!manager.isLevelUnlocked(user, level)) { if (!manager.isLevelUnlocked(user, level, world)) {
return; return;
} }
PanelBuilder panelBuilder = new PanelBuilder() PanelBuilder panelBuilder = new PanelBuilder()
.name(user.getTranslation("challenges.gui-title")); .name(user.getTranslation("challenges.gui-title"));
addChallengeItems(panelBuilder, user, level); addChallengeItems(panelBuilder);
addNavigation(panelBuilder, user, level); addNavigation(panelBuilder);
addFreeChallanges(panelBuilder, user); addFreeChallanges(panelBuilder);
// Create the panel // Create the panel
Panel panel = panelBuilder.build(); Panel panel = panelBuilder.build();
panel.open(user); panel.open(user);
} }
private void addFreeChallanges(PanelBuilder panelBuilder, User user) { private void addChallengeItems(PanelBuilder panelBuilder) {
manager.getChallenges(ChallengesManager.FREE).forEach(challenge -> createItem(panelBuilder, challenge, user)); 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));
} }
@ -80,9 +83,9 @@ public class ChallengesPanels {
* @param challenge * @param challenge
* @param user * @param user
*/ */
private void createItem(PanelBuilder panelBuilder, Challenges challenge, User user) { private void createItem(PanelBuilder panelBuilder, Challenges challenge) {
// Check completion // Check completion
boolean completed = manager.isChallengeComplete(user, challenge.getUniqueId()); boolean completed = manager.isChallengeComplete(user, challenge.getUniqueId(), world);
// If challenge is removed after completion, remove it // If challenge is removed after completion, remove it
if (completed && challenge.isRemoveWhenCompleted()) { if (completed && challenge.isRemoveWhenCompleted()) {
return; return;
@ -90,11 +93,11 @@ public class ChallengesPanels {
PanelItem item = new PanelItemBuilder() PanelItem item = new PanelItemBuilder()
.icon(challenge.getIcon()) .icon(challenge.getIcon())
.name(challenge.getFriendlyName().isEmpty() ? challenge.getUniqueId() : challenge.getFriendlyName()) .name(challenge.getFriendlyName().isEmpty() ? challenge.getUniqueId() : challenge.getFriendlyName())
.description(challengeDescription(challenge, user)) .description(challengeDescription(challenge))
.glow(completed) .glow(completed)
.clickHandler((panel, player, c, s) -> { .clickHandler((panel, player, c, s) -> {
if (!challenge.getChallengeType().equals(ChallengeType.ICON)) { if (!challenge.getChallengeType().equals(ChallengeType.ICON)) {
new TryToComplete(addon, player, manager, challenge); new TryToComplete(addon, player, manager, challenge, world, permPrefix, label);
} }
return true; return true;
}) })
@ -106,17 +109,9 @@ public class ChallengesPanels {
} }
} }
private void addChallengeItems(PanelBuilder panelBuilder, User user, String level) { private void addNavigation(PanelBuilder panelBuilder) {
Set<Challenges> levelChallenges = manager.getChallenges(level);
// Only show a control panel for the level requested.
for (Challenges challenge : levelChallenges) {
createItem(panelBuilder, challenge, user);
}
}
private void addNavigation(PanelBuilder panelBuilder, User user, String level) {
// Add navigation to other levels // Add navigation to other levels
for (LevelStatus status: manager.getChallengeLevelStatus(user)) { for (LevelStatus status: manager.getChallengeLevelStatus(user, world)) {
if (status.getLevel().getUniqueId().equals(level)) { if (status.getLevel().getUniqueId().equals(level)) {
// Skip if this is the current level // Skip if this is the current level
continue; continue;
@ -132,7 +127,7 @@ public class ChallengesPanels {
.description(manager.stringSplit(user.getTranslation("challenges.navigation","[level]",name))) .description(manager.stringSplit(user.getTranslation("challenges.navigation","[level]",name)))
.clickHandler((p, u, c, s) -> { .clickHandler((p, u, c, s) -> {
u.closeInventory(); u.closeInventory();
u.performCommand(ChallengesCommand.CHALLENGE_COMMAND + " " + status.getLevel().getUniqueId()); u.performCommand(label + " " + ChallengesCommand.CHALLENGE_COMMAND + " " + status.getLevel().getUniqueId());
return true; return true;
}) })
.build(); .build();
@ -157,7 +152,7 @@ public class ChallengesPanels {
* @param player * @param player
* @return List of strings splitting challenge string into 25 chars long * @return List of strings splitting challenge string into 25 chars long
*/ */
private List<String> challengeDescription(Challenges challenge, User user) { private List<String> challengeDescription(Challenges challenge) {
List<String> result = new ArrayList<String>(); List<String> result = new ArrayList<String>();
String level = challenge.getLevel(); String level = challenge.getLevel();
if (!level.isEmpty()) { if (!level.isEmpty()) {
@ -165,9 +160,9 @@ public class ChallengesPanels {
} }
// Check if completed or not // Check if completed or not
boolean complete = addon.getChallengesManager().isChallengeComplete(user, challenge.getUniqueId()); boolean complete = addon.getChallengesManager().isChallengeComplete(user, challenge.getUniqueId(), world);
int maxTimes = challenge.getMaxTimes(); int maxTimes = challenge.getMaxTimes();
long doneTimes = addon.getChallengesManager().checkChallengeTimes(user, challenge); long doneTimes = addon.getChallengesManager().checkChallengeTimes(user, challenge, world);
if (complete) { if (complete) {
result.add(user.getTranslation("challenges.complete")); result.add(user.getTranslation("challenges.complete"));
} }
@ -227,7 +222,7 @@ public class ChallengesPanels {
result.addAll(splitTrans(user,"challenges.money-reward", "[reward]", String.valueOf(moneyReward))); result.addAll(splitTrans(user,"challenges.money-reward", "[reward]", String.valueOf(moneyReward)));
} }
// Final placeholder change for [label] // Final placeholder change for [label]
result.replaceAll(x -> x.replace("[label]", Constants.ISLANDCOMMAND)); result.replaceAll(x -> x.replace("[label]", label));
return result; return result;
} }

View File

@ -9,6 +9,7 @@ import java.util.List;
import java.util.Map; import java.util.Map;
import org.bukkit.Material; import org.bukkit.Material;
import org.bukkit.World;
import org.bukkit.entity.EntityType; import org.bukkit.entity.EntityType;
import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.ItemStack;
import org.bukkit.util.Vector; import org.bukkit.util.Vector;
@ -19,7 +20,6 @@ import bskyblock.addon.challenges.commands.ChallengesCommand;
import bskyblock.addon.challenges.database.object.Challenges; import bskyblock.addon.challenges.database.object.Challenges;
import bskyblock.addon.challenges.database.object.Challenges.ChallengeType; import bskyblock.addon.challenges.database.object.Challenges.ChallengeType;
import bskyblock.addon.level.Level; import bskyblock.addon.level.Level;
import us.tastybento.bskyblock.Constants;
import us.tastybento.bskyblock.api.user.User; import us.tastybento.bskyblock.api.user.User;
import us.tastybento.bskyblock.util.Util; import us.tastybento.bskyblock.util.Util;
@ -31,22 +31,30 @@ import us.tastybento.bskyblock.util.Util;
public class TryToComplete { public class TryToComplete {
private ChallengesAddon addon; private ChallengesAddon addon;
private World world;
private String permPrefix;
private User user;
private ChallengesManager manager;
private Challenges challenge;
/** /**
* @param addon * @param addon
* @param user * @param user
* @param manager * @param manager
* @param challenge * @param challenge
* @param world
* @param permPrefix
*/ */
public TryToComplete(ChallengesAddon addon, User user, ChallengesManager manager, Challenges challenge) { public TryToComplete(ChallengesAddon addon, User user, ChallengesManager manager, Challenges challenge, World world, String permPrefix, String label) {
this.addon = addon; this.addon = addon;
// Check if user is in the worlds this.world = world;
if (!Util.inWorld(user.getLocation())) { this.permPrefix = permPrefix;
user.sendMessage("general.errors.wrong-world"); this.user = user;
return; this.manager = manager;
} this.challenge = challenge;
// Check if can complete challenge // Check if can complete challenge
ChallengeResult result = checkIfCanCompleteChallenge(user, manager, challenge); ChallengeResult result = checkIfCanCompleteChallenge();
if (!result.meetsRequirements) { if (!result.meetsRequirements) {
return; return;
} }
@ -60,7 +68,7 @@ public class TryToComplete {
// Give exp // Give exp
user.getPlayer().giveExp(challenge.getExpReward()); user.getPlayer().giveExp(challenge.getExpReward());
// Run commands // Run commands
runCommands(user, challenge.getRewardCommands()); runCommands(challenge.getRewardCommands());
user.sendMessage("challenges.you-completed", "[challenge]", challenge.getFriendlyName()); user.sendMessage("challenges.you-completed", "[challenge]", challenge.getFriendlyName());
} else { } else {
// Give rewards // Give rewards
@ -72,31 +80,31 @@ public class TryToComplete {
// Give exp // Give exp
user.getPlayer().giveExp(challenge.getRepeatExpReward()); user.getPlayer().giveExp(challenge.getRepeatExpReward());
// Run commands // Run commands
runCommands(user, challenge.getRepeatRewardCommands()); runCommands(challenge.getRepeatRewardCommands());
user.sendMessage("challenges.you-repeated", "[challenge]", challenge.getFriendlyName()); user.sendMessage("challenges.you-repeated", "[challenge]", challenge.getFriendlyName());
} }
// Mark as complete // Mark as complete
manager.setChallengeComplete(user, challenge.getUniqueId()); manager.setChallengeComplete(user, challenge.getUniqueId(), world);
user.closeInventory(); user.closeInventory();
user.getPlayer().performCommand(ChallengesCommand.CHALLENGE_COMMAND + " " + challenge.getLevel()); user.getPlayer().performCommand(label + " " + ChallengesCommand.CHALLENGE_COMMAND + " " + challenge.getLevel());
} }
/** /**
* Checks if a challenge can be completed or not * Checks if a challenge can be completed or not
*/ */
private ChallengeResult checkIfCanCompleteChallenge(User user, ChallengesManager manager, Challenges challenge) { private ChallengeResult checkIfCanCompleteChallenge() {
// Check if user has the // Check if user has the
if (!challenge.getLevel().equals(ChallengesManager.FREE) && !manager.isLevelUnlocked(user, challenge.getLevel())) { if (!challenge.getLevel().equals(ChallengesManager.FREE) && !manager.isLevelUnlocked(user, challenge.getLevel(), world)) {
user.sendMessage("challenges.errors.challenge-level-not-available"); user.sendMessage("challenges.errors.challenge-level-not-available");
return new ChallengeResult(); return new ChallengeResult();
} }
// Check max times // Check max times
if (challenge.isRepeatable() && challenge.getMaxTimes() > 0 && manager.checkChallengeTimes(user, challenge) >= challenge.getMaxTimes()) { if (challenge.isRepeatable() && challenge.getMaxTimes() > 0 && manager.checkChallengeTimes(user, challenge, world) >= challenge.getMaxTimes()) {
user.sendMessage("challenges.not-repeatable"); user.sendMessage("challenges.not-repeatable");
return new ChallengeResult(); return new ChallengeResult();
} }
// Check repeatability // Check repeatability
if (manager.isChallengeComplete(user, challenge.getUniqueId()) if (manager.isChallengeComplete(user, challenge.getUniqueId(), world)
&& (!challenge.isRepeatable() || challenge.getChallengeType().equals(ChallengeType.LEVEL) && (!challenge.isRepeatable() || challenge.getChallengeType().equals(ChallengeType.LEVEL)
|| challenge.getChallengeType().equals(ChallengeType.ISLAND))) { || challenge.getChallengeType().equals(ChallengeType.ISLAND))) {
user.sendMessage("challenges.not-repeatable"); user.sendMessage("challenges.not-repeatable");
@ -104,17 +112,17 @@ public class TryToComplete {
} }
switch (challenge.getChallengeType()) { switch (challenge.getChallengeType()) {
case INVENTORY: case INVENTORY:
return checkInventory(user, manager, challenge); return checkInventory();
case LEVEL: case LEVEL:
return checkLevel(user, challenge); return checkLevel();
case ISLAND: case ISLAND:
return checkSurrounding(user, challenge); return checkSurrounding();
default: default:
return new ChallengeResult(); return new ChallengeResult();
} }
} }
private ChallengeResult checkInventory(User user, ChallengesManager manager, Challenges challenge) { private ChallengeResult checkInventory() {
// Run through inventory // Run through inventory
List<ItemStack> required = new ArrayList<>(challenge.getRequiredItems()); List<ItemStack> required = new ArrayList<>(challenge.getRequiredItems());
for (ItemStack req : required) { for (ItemStack req : required) {
@ -130,32 +138,32 @@ public class TryToComplete {
user.getInventory().removeItem(items); user.getInventory().removeItem(items);
} }
} }
return new ChallengeResult().setMeetsRequirements().setRepeat(manager.isChallengeComplete(user, challenge.getUniqueId())); return new ChallengeResult().setMeetsRequirements().setRepeat(manager.isChallengeComplete(user, challenge.getUniqueId(), world));
} }
private ChallengeResult checkLevel(User user, Challenges challenge) { private ChallengeResult checkLevel() {
// Check if the level addon is installed or not // Check if the level addon is installed or not
return addon.getAddonByName("BSkyBlock-Level") return addon.getAddonByName("BSkyBlock-Level")
.map(l -> ((Level)l).getIslandLevel(user.getUniqueId()) >= challenge.getReqIslandlevel() ? new ChallengeResult().setMeetsRequirements() : new ChallengeResult() .map(l -> ((Level)l).getIslandLevel(world, user.getUniqueId()) >= challenge.getReqIslandlevel() ? new ChallengeResult().setMeetsRequirements() : new ChallengeResult()
).orElse(new ChallengeResult()); ).orElse(new ChallengeResult());
} }
private ChallengeResult checkSurrounding(User user, Challenges challenge) { private ChallengeResult checkSurrounding() {
if (!addon.getIslands().userIsOnIsland(user)) { if (!addon.getIslands().userIsOnIsland(world, user)) {
// Player is not on island // Player is not on island
user.sendMessage("challenges.error.not-on-island"); user.sendMessage("challenges.error.not-on-island");
return new ChallengeResult(); return new ChallengeResult();
} }
// Check for items or entities in the area // Check for items or entities in the area
ChallengeResult result = searchForEntities(user, challenge.getRequiredEntities(), challenge.getSearchRadius()); ChallengeResult result = searchForEntities(challenge.getRequiredEntities(), challenge.getSearchRadius());
if (result.meetsRequirements) { if (result.meetsRequirements) {
// Search for items only if entities found // Search for items only if entities found
result = searchForBlocks(user, challenge.getRequiredBlocks(), challenge.getSearchRadius()); result = searchForBlocks(challenge.getRequiredBlocks(), challenge.getSearchRadius());
} }
return result; return result;
} }
private ChallengeResult searchForBlocks(User user, Map<Material, Integer> map, int searchRadius) { private ChallengeResult searchForBlocks(Map<Material, Integer> map, int searchRadius) {
Map<Material, Integer> blocks = new EnumMap<>(map); Map<Material, Integer> blocks = new EnumMap<>(map);
for (int x = -searchRadius; x <= searchRadius; x++) { for (int x = -searchRadius; x <= searchRadius; x++) {
for (int y = -searchRadius; y <= searchRadius; y++) { for (int y = -searchRadius; y <= searchRadius; y++) {
@ -179,7 +187,7 @@ public class TryToComplete {
return new ChallengeResult(); return new ChallengeResult();
} }
private ChallengeResult searchForEntities(User user, Map<EntityType, Integer> map, int searchRadius) { private ChallengeResult searchForEntities(Map<EntityType, Integer> map, int searchRadius) {
Map<EntityType, Integer> entities = new EnumMap<>(map); Map<EntityType, Integer> entities = new EnumMap<>(map);
user.getPlayer().getNearbyEntities(searchRadius, searchRadius, searchRadius).forEach(entity -> { user.getPlayer().getNearbyEntities(searchRadius, searchRadius, searchRadius).forEach(entity -> {
// Look through all the nearby Entities, filtering by type // Look through all the nearby Entities, filtering by type
@ -221,18 +229,18 @@ public class TryToComplete {
} }
private void runCommands(User player, List<String> commands) { private void runCommands(List<String> commands) {
// Ignore commands with this perm // Ignore commands with this perm
if (player.hasPermission(Constants.PERMPREFIX + "command.challengeexempt") && !player.isOp()) { if (user.hasPermission(permPrefix + "command.challengeexempt") && !user.isOp()) {
return; return;
} }
for (String cmd : commands) { for (String cmd : commands) {
if (cmd.startsWith("[SELF]")) { if (cmd.startsWith("[SELF]")) {
String alert = "Running command '" + cmd + "' as " + player.getName(); String alert = "Running command '" + cmd + "' as " + user.getName();
addon.getLogger().info(alert); addon.getLogger().info(alert);
cmd = cmd.substring(6,cmd.length()).replace("[player]", player.getName()).trim(); cmd = cmd.substring(6,cmd.length()).replace("[player]", user.getName()).trim();
try { try {
if (!player.performCommand(cmd)) { if (!user.performCommand(cmd)) {
showError(cmd); showError(cmd);
} }
} catch (Exception e) { } catch (Exception e) {
@ -243,7 +251,7 @@ public class TryToComplete {
} }
// Substitute in any references to player // Substitute in any references to player
try { try {
if (!addon.getServer().dispatchCommand(addon.getServer().getConsoleSender(), cmd.replace("[player]", player.getName()))) { if (!addon.getServer().dispatchCommand(addon.getServer().getConsoleSender(), cmd.replace("[player]", user.getName()))) {
showError(cmd); showError(cmd);
} }
} catch (Exception e) { } catch (Exception e) {