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

View File

@ -5,6 +5,7 @@ import org.bukkit.Bukkit;
import bskyblock.addon.challenges.commands.ChallengesCommand;
import bskyblock.addon.challenges.commands.admin.ChallengesAdminCommand;
import us.tastybento.bskyblock.api.addons.Addon;
import us.tastybento.bskyblock.api.commands.CompositeCommand;
/**
* Add-on to BSkyBlock that enables challenges
@ -14,6 +15,7 @@ import us.tastybento.bskyblock.api.addons.Addon;
public class ChallengesAddon extends Addon {
private ChallengesManager challengesManager;
private String permissionPrefix = "addon";
@Override
public void onEnable() {
@ -29,9 +31,22 @@ public class ChallengesAddon extends Addon {
// First time challenges creation
new FreshSqueezedChallenges(this);
// Register commands
new ChallengesCommand(this);
new ChallengesAdminCommand(this);
// Register commands - run one tick later to allow all addons to load
// AcidIsland hook in
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
}
@ -46,4 +61,8 @@ public class ChallengesAddon extends Addon {
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.bukkit.ChatColor;
import org.bukkit.Material;
import org.bukkit.World;
import org.bukkit.inventory.Inventory;
import org.bukkit.inventory.ItemStack;
@ -50,8 +51,6 @@ public class ChallengesManager {
players = new BSBDatabase<>(addon, PlayerData.class);
// Cache of challenges
challengeMap = new LinkedHashMap<>();
// Start panels
challengesPanels = new ChallengesPanels(addon, this);
// Cache of player data
playerData = new HashMap<>();
load();
@ -87,9 +86,9 @@ public class ChallengesManager {
* @param challenge - challenge
* @return - number of times
*/
public long checkChallengeTimes(User user, Challenges challenge) {
public long checkChallengeTimes(User user, Challenges challenge, World world) {
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
* @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) {
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(name)).findFirst();
Optional<Challenges> challenge = ch.stream().filter(c -> c.getUniqueId().equalsIgnoreCase(worldName + name)).findFirst();
if (challenge.isPresent()) {
return challenge.get();
}
@ -210,9 +211,10 @@ public class ChallengesManager {
/**
* 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) {
public List<LevelStatus> getChallengeLevelStatus(User user, World world) {
addPlayer(user);
PlayerData pd = playerData.get(user.getUniqueId());
List<LevelStatus> result = new ArrayList<>();
@ -223,7 +225,7 @@ public class ChallengesManager {
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(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);
boolean complete = challsToDo > 0 ? false : true;
// Create result class with the data
@ -236,20 +238,27 @@ public class ChallengesManager {
}
/**
* 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
* 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) {
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();
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
* @return - true if completed
*/
public boolean isChallengeComplete(User user, String challengeName) {
public boolean isChallengeComplete(User user, String challengeName, World world) {
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
* @return true if level is unlocked
*/
public boolean isLevelUnlocked(User user, String level) {
public boolean isLevelUnlocked(User user, String level, World world) {
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
* @param user
* @param uniqueId
* @param user - user
* @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);
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 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.user.User;
@ -11,17 +11,16 @@ public class ChallengesCommand extends CompositeCommand {
public static final String CHALLENGE_COMMAND = "challenges";
private ChallengesAddon addon;
public ChallengesCommand(ChallengesAddon addon) {
super(CHALLENGE_COMMAND, "c", "challenge");
public ChallengesCommand(ChallengesAddon addon, CompositeCommand cmd) {
super(cmd, CHALLENGE_COMMAND, "c", "challenge");
this.addon = addon;
// Set up commands
}
@Override
public boolean execute(User user, List<String> args) {
// Open up the challenges GUI
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 false;
@ -30,7 +29,7 @@ public class ChallengesCommand extends CompositeCommand {
@Override
public void setup() {
this.setOnlyPlayer(true);
this.setPermission(Constants.PERMPREFIX + CHALLENGE_COMMAND);
this.setPermission(getPermissionPrefix() + CHALLENGE_COMMAND);
this.setParameters(CHALLENGE_COMMAND + ".parameters");
this.setDescription(CHALLENGE_COMMAND + ".description");
this.setOnlyPlayer(true);

View File

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

View File

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

View File

@ -49,7 +49,7 @@ public class SetIcon extends CompositeCommand {
user.sendMessage("challenges.admin.seticon.description");
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
if (challenge == null) {
user.sendMessage("challenges.admin.seticon.error.no-such-challenge");

View File

@ -19,6 +19,9 @@ public class ChallengeLevels implements DataObject, Comparable<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<>();
@ -52,7 +55,7 @@ public class ChallengeLevels implements DataObject, Comparable<ChallengeLevels>
}
public List<String> getRewardCommands() {
return rewardCommands;
return rewardCommands = new ArrayList<>();
}
@Override
@ -168,6 +171,20 @@ public class ChallengeLevels implements DataObject, Comparable<ChallengeLevels>
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()
*/

View File

@ -41,6 +41,9 @@ public class Challenges implements DataObject {
@ConfigComment("Whether this challenge is deployed or not")
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
@ConfigComment("Name of the icon and challenge. May include color codes. Single line.")
private String friendlyName = "";
@ -196,7 +199,7 @@ public class Challenges implements DataObject {
* @return the icon
*/
public ItemStack getIcon() {
return icon;
return icon.clone();
}
/**
@ -559,6 +562,20 @@ public class Challenges implements DataObject {
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
*/

View File

@ -8,9 +8,12 @@ import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import org.bukkit.World;
import com.google.gson.annotations.Expose;
import us.tastybento.bskyblock.database.objects.DataObject;
import us.tastybento.bskyblock.util.Util;
/**
* 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
* @param challengeName - unique challenge name
*/
public void setChallengeDone(String challengeName) {
int times = challengeStatus.getOrDefault(challengeName, 0) + 1;
challengeStatus.put(challengeName, times);
challengesTimestamp.put(challengeName, System.currentTimeMillis());
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());
}
/**
@ -49,8 +53,8 @@ public class PlayerData implements DataObject {
* @param challengeName - unique challenge name
* @return true if done at least once
*/
public boolean isChallengeDone(String challengeName) {
return getTimes(challengeName) > 0 ? true : false;
public boolean isChallengeDone(World world, String challengeName) {
return getTimes(world, challengeName) > 0;
}
/**
@ -58,8 +62,8 @@ public class PlayerData implements DataObject {
* @param challengeName - unique challenge name
* @return - number of times
*/
public int getTimes(String challengeName) {
return challengeStatus.getOrDefault(challengeName, 0);
public int getTimes(World world, String challengeName) {
return challengeStatus.getOrDefault(Util.getWorld(world).getName() + challengeName, 0);
}
/**
@ -75,7 +79,6 @@ public class PlayerData implements DataObject {
*/
@Override
public String getUniqueId() {
// TODO Auto-generated method stub
return uniqueId;
}
@ -85,7 +88,6 @@ public class PlayerData implements DataObject {
@Override
public void setUniqueId(String uniqueId) {
this.uniqueId = uniqueId;
}
/**

View File

@ -6,6 +6,7 @@ import java.util.List;
import java.util.Set;
import org.bukkit.Material;
import org.bukkit.World;
import org.bukkit.inventory.ItemStack;
import bskyblock.addon.challenges.ChallengesAddon;
@ -14,7 +15,6 @@ import bskyblock.addon.challenges.LevelStatus;
import bskyblock.addon.challenges.commands.ChallengesCommand;
import bskyblock.addon.challenges.database.object.Challenges;
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.PanelItem;
import us.tastybento.bskyblock.api.panels.builders.PanelBuilder;
@ -25,26 +25,20 @@ import us.tastybento.bskyblock.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 plugin, ChallengesManager manager){
this.addon = plugin;
this.manager = manager;
}
/**
* @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) {
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");
@ -53,24 +47,33 @@ public class ChallengesPanels {
if (level.isEmpty()) {
level = manager.getChallengeList().keySet().iterator().next().getUniqueId();
}
this.level = level;
// Check if level is valid
if (!manager.isLevelUnlocked(user, level)) {
if (!manager.isLevelUnlocked(user, level, world)) {
return;
}
PanelBuilder panelBuilder = new PanelBuilder()
.name(user.getTranslation("challenges.gui-title"));
addChallengeItems(panelBuilder, user, level);
addNavigation(panelBuilder, user, level);
addFreeChallanges(panelBuilder, user);
addChallengeItems(panelBuilder);
addNavigation(panelBuilder);
addFreeChallanges(panelBuilder);
// Create the panel
Panel panel = panelBuilder.build();
panel.open(user);
}
private void addFreeChallanges(PanelBuilder panelBuilder, User user) {
manager.getChallenges(ChallengesManager.FREE).forEach(challenge -> createItem(panelBuilder, challenge, 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));
}
@ -80,9 +83,9 @@ public class ChallengesPanels {
* @param challenge
* @param user
*/
private void createItem(PanelBuilder panelBuilder, Challenges challenge, User user) {
private void createItem(PanelBuilder panelBuilder, Challenges challenge) {
// 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 (completed && challenge.isRemoveWhenCompleted()) {
return;
@ -90,11 +93,11 @@ public class ChallengesPanels {
PanelItem item = new PanelItemBuilder()
.icon(challenge.getIcon())
.name(challenge.getFriendlyName().isEmpty() ? challenge.getUniqueId() : challenge.getFriendlyName())
.description(challengeDescription(challenge, user))
.description(challengeDescription(challenge))
.glow(completed)
.clickHandler((panel, player, c, s) -> {
if (!challenge.getChallengeType().equals(ChallengeType.ICON)) {
new TryToComplete(addon, player, manager, challenge);
new TryToComplete(addon, player, manager, challenge, world, permPrefix, label);
}
return true;
})
@ -106,17 +109,9 @@ public class ChallengesPanels {
}
}
private void addChallengeItems(PanelBuilder panelBuilder, User user, String level) {
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) {
private void addNavigation(PanelBuilder panelBuilder) {
// Add navigation to other levels
for (LevelStatus status: manager.getChallengeLevelStatus(user)) {
for (LevelStatus status: manager.getChallengeLevelStatus(user, world)) {
if (status.getLevel().getUniqueId().equals(level)) {
// Skip if this is the current level
continue;
@ -132,7 +127,7 @@ public class ChallengesPanels {
.description(manager.stringSplit(user.getTranslation("challenges.navigation","[level]",name)))
.clickHandler((p, u, c, s) -> {
u.closeInventory();
u.performCommand(ChallengesCommand.CHALLENGE_COMMAND + " " + status.getLevel().getUniqueId());
u.performCommand(label + " " + ChallengesCommand.CHALLENGE_COMMAND + " " + status.getLevel().getUniqueId());
return true;
})
.build();
@ -157,7 +152,7 @@ public class ChallengesPanels {
* @param player
* @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>();
String level = challenge.getLevel();
if (!level.isEmpty()) {
@ -165,9 +160,9 @@ public class ChallengesPanels {
}
// 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();
long doneTimes = addon.getChallengesManager().checkChallengeTimes(user, challenge);
long doneTimes = addon.getChallengesManager().checkChallengeTimes(user, challenge, world);
if (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)));
}
// Final placeholder change for [label]
result.replaceAll(x -> x.replace("[label]", Constants.ISLANDCOMMAND));
result.replaceAll(x -> x.replace("[label]", label));
return result;
}

View File

@ -9,6 +9,7 @@ import java.util.List;
import java.util.Map;
import org.bukkit.Material;
import org.bukkit.World;
import org.bukkit.entity.EntityType;
import org.bukkit.inventory.ItemStack;
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.ChallengeType;
import bskyblock.addon.level.Level;
import us.tastybento.bskyblock.Constants;
import us.tastybento.bskyblock.api.user.User;
import us.tastybento.bskyblock.util.Util;
@ -31,22 +31,30 @@ import us.tastybento.bskyblock.util.Util;
public class TryToComplete {
private ChallengesAddon addon;
private World world;
private String permPrefix;
private User user;
private ChallengesManager manager;
private Challenges challenge;
/**
* @param addon
* @param user
* @param manager
* @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;
// Check if user is in the worlds
if (!Util.inWorld(user.getLocation())) {
user.sendMessage("general.errors.wrong-world");
return;
}
this.world = world;
this.permPrefix = permPrefix;
this.user = user;
this.manager = manager;
this.challenge = challenge;
// Check if can complete challenge
ChallengeResult result = checkIfCanCompleteChallenge(user, manager, challenge);
ChallengeResult result = checkIfCanCompleteChallenge();
if (!result.meetsRequirements) {
return;
}
@ -60,7 +68,7 @@ public class TryToComplete {
// Give exp
user.getPlayer().giveExp(challenge.getExpReward());
// Run commands
runCommands(user, challenge.getRewardCommands());
runCommands(challenge.getRewardCommands());
user.sendMessage("challenges.you-completed", "[challenge]", challenge.getFriendlyName());
} else {
// Give rewards
@ -72,31 +80,31 @@ public class TryToComplete {
// Give exp
user.getPlayer().giveExp(challenge.getRepeatExpReward());
// Run commands
runCommands(user, challenge.getRepeatRewardCommands());
runCommands(challenge.getRepeatRewardCommands());
user.sendMessage("challenges.you-repeated", "[challenge]", challenge.getFriendlyName());
}
// Mark as complete
manager.setChallengeComplete(user, challenge.getUniqueId());
manager.setChallengeComplete(user, challenge.getUniqueId(), world);
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
*/
private ChallengeResult checkIfCanCompleteChallenge(User user, ChallengesManager manager, Challenges challenge) {
private ChallengeResult checkIfCanCompleteChallenge() {
// 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");
return new ChallengeResult();
}
// 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");
return new ChallengeResult();
}
// Check repeatability
if (manager.isChallengeComplete(user, challenge.getUniqueId())
if (manager.isChallengeComplete(user, challenge.getUniqueId(), world)
&& (!challenge.isRepeatable() || challenge.getChallengeType().equals(ChallengeType.LEVEL)
|| challenge.getChallengeType().equals(ChallengeType.ISLAND))) {
user.sendMessage("challenges.not-repeatable");
@ -104,17 +112,17 @@ public class TryToComplete {
}
switch (challenge.getChallengeType()) {
case INVENTORY:
return checkInventory(user, manager, challenge);
return checkInventory();
case LEVEL:
return checkLevel(user, challenge);
return checkLevel();
case ISLAND:
return checkSurrounding(user, challenge);
return checkSurrounding();
default:
return new ChallengeResult();
}
}
private ChallengeResult checkInventory(User user, ChallengesManager manager, Challenges challenge) {
private ChallengeResult checkInventory() {
// Run through inventory
List<ItemStack> required = new ArrayList<>(challenge.getRequiredItems());
for (ItemStack req : required) {
@ -130,32 +138,32 @@ public class TryToComplete {
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
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());
}
private ChallengeResult checkSurrounding(User user, Challenges challenge) {
if (!addon.getIslands().userIsOnIsland(user)) {
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(user, challenge.getRequiredEntities(), challenge.getSearchRadius());
ChallengeResult result = searchForEntities(challenge.getRequiredEntities(), challenge.getSearchRadius());
if (result.meetsRequirements) {
// Search for items only if entities found
result = searchForBlocks(user, challenge.getRequiredBlocks(), challenge.getSearchRadius());
result = searchForBlocks(challenge.getRequiredBlocks(), challenge.getSearchRadius());
}
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);
for (int x = -searchRadius; x <= searchRadius; x++) {
for (int y = -searchRadius; y <= searchRadius; y++) {
@ -179,7 +187,7 @@ public class TryToComplete {
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);
user.getPlayer().getNearbyEntities(searchRadius, searchRadius, searchRadius).forEach(entity -> {
// 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
if (player.hasPermission(Constants.PERMPREFIX + "command.challengeexempt") && !player.isOp()) {
if (user.hasPermission(permPrefix + "command.challengeexempt") && !user.isOp()) {
return;
}
for (String cmd : commands) {
if (cmd.startsWith("[SELF]")) {
String alert = "Running command '" + cmd + "' as " + player.getName();
String alert = "Running command '" + cmd + "' as " + user.getName();
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 {
if (!player.performCommand(cmd)) {
if (!user.performCommand(cmd)) {
showError(cmd);
}
} catch (Exception e) {
@ -243,7 +251,7 @@ public class TryToComplete {
}
// Substitute in any references to player
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);
}
} catch (Exception e) {