Add single method that generates level description.

This commit is contained in:
BONNe 2019-02-12 15:36:16 +02:00
parent 0317d057ab
commit d33a763cbe
9 changed files with 280 additions and 15 deletions

View File

@ -495,9 +495,22 @@ public class ChallengesManager
* @return - true if completed
*/
public boolean isChallengeComplete(UUID user, Challenge challenge)
{
return this.isChallengeComplete(user, challenge.getUniqueId());
}
/**
* Checks if a challenge is complete or not
*
* @param user - User who must be checked.
* @param challenge - Challenge
* @return - true if completed
*/
public boolean isChallengeComplete(UUID user, String challenge)
{
this.addPlayer(user);
return this.playerCacheData.get(user).isChallengeDone(challenge.getUniqueId());
return this.playerCacheData.get(user).isChallengeDone(challenge);
}
@ -509,9 +522,22 @@ public class ChallengesManager
* @return Level status - how many challenges still to do on which level
*/
public List<LevelStatus> getChallengeLevelStatus(User user, World world)
{
return this.getChallengeLevelStatus(user.getUniqueId(), Util.getWorld(world).getName());
}
/**
* Get the status on every level
*
* @param user - user
* @param world - world
* @return Level status - how many challenges still to do on which level
*/
public List<LevelStatus> getChallengeLevelStatus(UUID user, String world)
{
this.addPlayer(user);
ChallengesPlayerData playerData = this.playerCacheData.get(user.getUniqueId());
ChallengesPlayerData playerData = this.playerCacheData.get(user);
List<ChallengeLevel> challengeLevelList = this.getLevels(world);
@ -552,17 +578,29 @@ public class ChallengesManager
* Check is user can see given level.
*
* @param user - user
* @param world - world
* @param level - level
* @return true if level is unlocked
*/
public boolean isLevelUnlocked(User user, World world, ChallengeLevel level)
public boolean isLevelUnlocked(User user, ChallengeLevel level)
{
return this.isLevelUnlocked(user.getUniqueId(), level);
}
/**
* Check is user can see given level.
*
* @param user - user
* @param level - level
* @return true if level is unlocked
*/
public boolean isLevelUnlocked(UUID user, ChallengeLevel level)
{
this.addPlayer(user);
return this.getChallengeLevelStatus(user, world).stream().
filter(LevelStatus::isUnlocked).
anyMatch(lv -> lv.getLevel().equals(level));
return this.getChallengeLevelStatus(user, level.getWorld()).stream().
filter(LevelStatus::isUnlocked).
anyMatch(lv -> lv.getLevel().equals(level));
}
@ -667,6 +705,28 @@ public class ChallengesManager
}
/**
* This method returns LevelStatus object for given challenge level.
* @param user User which level status must be acquired.
* @param level Level which status must be calculated.
* @return LevelStatus fof given level.
*/
public LevelStatus getChallengeLevelStatus(UUID user, ChallengeLevel level)
{
List<LevelStatus> statusList = this.getChallengeLevelStatus(user, level.getWorld());
for (LevelStatus status : statusList)
{
if (status.getLevel().equals(level))
{
return status;
}
}
return null;
}
// ---------------------------------------------------------------------
// Section: Challenges related methods
// ---------------------------------------------------------------------
@ -841,11 +901,21 @@ public class ChallengesManager
*/
public List<ChallengeLevel> getLevels(World world)
{
String worldName = Util.getWorld(world).getName();
return this.getLevels(Util.getWorld(world).getName());
}
/**
* This method returns list of challenge levels in given world.
* @param world for which levels must be searched.
* @return List with challenges in given world.
*/
public List<ChallengeLevel> getLevels(String world)
{
// TODO: Probably need to check also database.
return this.levelCacheData.values().stream().
sorted(ChallengeLevel::compareTo).
filter(challenge -> challenge.getUniqueId().startsWith(worldName)).
filter(challenge -> challenge.getUniqueId().startsWith(world)).
collect(Collectors.toList());
}

View File

@ -71,6 +71,22 @@ public class Settings implements DataObject
@ConfigEntry(path = "challenge-lore-message")
private String challengeLoreMessage = "LSTDEQiWRi";
@ConfigComment("")
@ConfigComment("This string allows to change element order in Level description. Each letter represents")
@ConfigComment("one object from level description. If letter is not used, then its represented part")
@ConfigComment("will not be in description. If use any letter that is not recognized, then it will be")
@ConfigComment("ignored. Some strings can be customized via lang file under 'challenges.gui.level-description'.")
@ConfigComment("List of letters and their meaning: ")
@ConfigComment(" - S - Status String: '*.completed'")
@ConfigComment(" - T - Count of completed challenges String: '*.completed-challenges-of'")
@ConfigComment(" - D - Description String: defined in level object - challengeLevel.unlockMessage")
@ConfigComment(" - A - WaiverAmount String: '*.waver-amount'")
@ConfigComment(" - R - Reward String: '*.experience-reward', '*.money-reward', '*.not-repeatable'")
@ConfigComment("By adding 'i' after R (rewards) will display list of items that are defined in challenge")
@ConfigComment("and can be customized under 'challenges.gui.description.*'")
@ConfigEntry(path = "challenge-lore-message")
private String levelLoreMessage = "STDARi";
@ConfigComment("")
@ConfigComment("This list stores GameModes in which Challenges addon should not work.")
@ConfigComment("To disable addon it is necessary to write its name in new line that starts with -. Example:")
@ -187,6 +203,16 @@ public class Settings implements DataObject
}
/**
* This method returns the levelLoreMessage object.
* @return the levelLoreMessage object.
*/
public String getLevelLoreMessage()
{
return levelLoreMessage;
}
/**
* This method sets the configVersion object value.
* @param configVersion the configVersion object new value.
@ -214,6 +240,16 @@ public class Settings implements DataObject
}
/**
* This method sets the levelLoreMessage object value.
* @param levelLoreMessage the levelLoreMessage object new value.
*/
public void setLevelLoreMessage(String levelLoreMessage)
{
this.levelLoreMessage = levelLoreMessage;
}
/**
* @param resetChallenges new resetChallenges value.
*/

View File

@ -55,7 +55,7 @@ public class ChallengesPanels {
}
this.level = this.manager.getLevel(level);
// Check if level is valid
if (!manager.isLevelUnlocked(user, world, this.level)) {
if (!manager.isLevelUnlocked(user, this.level)) {
return;
}
PanelBuilder panelBuilder = new PanelBuilder()

View File

@ -65,7 +65,7 @@ public class ChallengesPanels2 {
}
this.level = manager.getLevel(level);
// Check if level is valid
if (mode.equals(Mode.PLAYER) && !manager.isLevelUnlocked(requester, world, this.level)) {
if (mode.equals(Mode.PLAYER) && !manager.isLevelUnlocked(requester, this.level)) {
return;
}
PanelBuilder panelBuilder = new PanelBuilder();

View File

@ -1,6 +1,7 @@
package world.bentobox.challenges.panel;
import org.bukkit.Bukkit;
import org.bukkit.Material;
import org.bukkit.World;
import org.bukkit.enchantments.Enchantment;
@ -18,6 +19,8 @@ import world.bentobox.bentobox.api.user.User;
import world.bentobox.challenges.ChallengesAddon;
import world.bentobox.challenges.ChallengesManager;
import world.bentobox.challenges.database.object.Challenge;
import world.bentobox.challenges.database.object.ChallengeLevel;
import world.bentobox.challenges.utils.LevelStatus;
/**
@ -250,6 +253,11 @@ public abstract class CommonGUI
}
// ---------------------------------------------------------------------
// Section: Generate Challenge Description
// ---------------------------------------------------------------------
/**
* This method generates and returns given challenge description. It is used here to avoid multiple
* duplicates, as it would be nice to have single place where challenge could be generated.
@ -651,5 +659,147 @@ public abstract class CommonGUI
return result;
}
// ---------------------------------------------------------------------
// Section: Generate Level Description
// ---------------------------------------------------------------------
/**
* This method generates level description string.
* @param level Level which string must be generated.
* @param user User who calls generation.
* @return List with generated description.
*/
protected List<String> generateLevelDescription(ChallengeLevel level, Player user)
{
List<String> result = new ArrayList<>();
ChallengesManager manager = this.addon.getChallengesManager();
LevelStatus status = manager.getChallengeLevelStatus(user.getUniqueId(), level);
// Used to know if blocks, entities, items should be added after requirements and rewards.
char prevChar = ' ';
for (char c : this.addon.getChallengesSettings().getChallengeLoreMessage().toLowerCase().toCharArray())
{
switch (c)
{
case 's':
{
if (status.isComplete())
{
result.add(this.user.getTranslation("challenges.gui.level-description.completed"));
}
break;
}
case 't':
{
if (!status.isComplete())
{
int doneChallengeCount = (int) level.getChallenges().stream().
filter(challenge -> this.addon.getChallengesManager().isChallengeComplete(user.getUniqueId(), challenge)).
count();
result.add(this.user.getTranslation("challenges.gui.level-description.completed-challenges-of",
"[number]", Integer.toString(doneChallengeCount),
"[max]", Integer.toString(level.getChallenges().size())));
}
break;
}
case 'd':
{
if (!status.isUnlocked())
{
result.add(level.getUnlockMessage());
}
break;
}
case 'a':
{
if (!status.isUnlocked() && !status.isComplete())
{
result.add(this.user.getTranslation("challenges.gui.level-description.waver-amount",
"[value]", Integer.toString(level.getWaiverAmount())));
}
break;
}
case 'r':
{
if (status.isUnlocked() && !status.isComplete())
{
if (level.getRewardExperience() > 0)
{
result.add(this.user
.getTranslation("challenges.gui.level-description.experience-reward",
"[value]", Integer.toString(level.getWaiverAmount())));
}
if (this.addon.isEconomyProvided() && level.getRewardMoney() > 0)
{
result.add(this.user.getTranslation("challenges.gui.level-description.money-reward",
"[value]", Integer.toString(level.getRewardMoney())));
}
}
break;
}
case 'i':
{
if (status.isUnlocked() && !status.isComplete() && prevChar == 'r')
{
// Add message about reward items
if (!level.getRewardItems().isEmpty())
{
result.add(this.user.getTranslation("challenges.gui.level-description.reward-items"));
for (ItemStack itemStack : level.getRewardItems())
{
result.add(this.user.getTranslation("challenges.gui.descriptions.item",
"[item]", itemStack.getType().name(),
"[count]", Integer.toString(itemStack.getAmount())));
if (itemStack.hasItemMeta() && itemStack.getEnchantments().isEmpty())
{
result.add(this.user.getTranslation("challenges.gui.descriptions.item-meta",
"[meta]", itemStack.getItemMeta().toString()));
}
for (Map.Entry<Enchantment, Integer> entry : itemStack.getEnchantments().entrySet())
{
result.add(this.user.getTranslation("challenges.gui.descriptions.item-enchant",
"[enchant]", entry.getKey().getKey().getKey(), "[level]", Integer.toString(entry.getValue())));
}
}
}
// Add message about reward commands
if (!level.getRewardCommands().isEmpty())
{
result.add(this.user.getTranslation("challenges.gui.level-description.reward-commands"));
for (String command : level.getRewardCommands())
{
result.add(this.user.getTranslation("challenges.gui.descriptions.command",
"[command]", command.replace("[player]", user.getName()).replace("[SELF]", "")));
}
}
}
break;
}
default:
{
break;
}
}
prevChar = c;
}
result.replaceAll(x -> x.replace("[label]", this.topLabel));
return result;
}
}

View File

@ -350,7 +350,7 @@ public class TryToComplete
}
// Check if user has unlocked challenges level.
else if (!this.challenge.getLevel().equals(ChallengesManager.FREE) &&
!this.manager.isLevelUnlocked(this.user, this.world, this.manager.getLevel(this.challenge.getLevel())))
!this.manager.isLevelUnlocked(this.user, this.manager.getLevel(this.challenge.getLevel())))
{
this.user.sendMessage("challenges.errors.challenge-level-not-available");
result = EMPTY_RESULT;

View File

@ -134,7 +134,8 @@ public class ListLevelsGUI extends CommonGUI
{
PanelItemBuilder itemBuilder = new PanelItemBuilder().
name(challengeLevel.getFriendlyName()).
description(GuiUtils.stringSplit(challengeLevel.getUnlockMessage(),
description(GuiUtils.stringSplit(
this.generateLevelDescription(challengeLevel, this.user.getPlayer()),
this.addon.getChallengesSettings().getLoreLineLength())).
icon(challengeLevel.getIcon()).
glow(false);

View File

@ -384,7 +384,7 @@ public class ChallengesGUI extends CommonGUI
{
icon = level.getLevel().getIcon();
description = GuiUtils.stringSplit(
this.user.getTranslation("challenges.gui.descriptions.level-unlocked", "[level]", name),
this.generateLevelDescription(level.getLevel(), user.getPlayer()),
this.addon.getChallengesSettings().getLoreLineLength());
clickHandler = (panel, user1, clickType, slot) -> {
this.lastSelectedLevel = level;

View File

@ -253,6 +253,14 @@ challenges:
required-items: 'Required Items:'
required-entities: 'Required Entities:'
required-blocks: 'Required Blocks:'
level-description:
completed: '&BCompleted'
completed-challenges-of: '&3You have completed [number] of [max] challenges in this level.'
waver-amount: '&6Can skip [value] challenges to unlock next level.'
experience-reward: '&6Exp reward: [value]'
money-reward: '&6Money reward: $[value]'
reward-items: '&6Reward Items:'
reward-commands: '&6Reward Commands:'
messages:
admin:
hit-things: 'Hit things to add them to the list of things required. Right click when done.'
@ -293,4 +301,4 @@ challenges:
import-no-file: '&cCould not find challenges.yml file to import!'
no-load: '&cError: Could not load challenges.yml. [message]'
load-error: '&cError: Cannot load [value].'
version: 3
version: 4