mirror of
https://github.com/BentoBoxWorld/Challenges.git
synced 2025-02-22 15:21:58 +01:00
Enable challenges to have multiple statistic requirements
This enables things like a challenge to kill 10 creepers, 10 zombies, and 10 skeletons.
This commit is contained in:
parent
cf4dcaf630
commit
c5334acc87
@ -2,11 +2,16 @@
|
||||
// Created by BONNe
|
||||
// Copyright - 2021
|
||||
//
|
||||
// Enhanced by tastybento
|
||||
|
||||
|
||||
package world.bentobox.challenges.database.object.requirements;
|
||||
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.Statistic;
|
||||
import org.bukkit.entity.EntityType;
|
||||
@ -15,8 +20,69 @@ import org.eclipse.jdt.annotation.Nullable;
|
||||
import com.google.gson.annotations.Expose;
|
||||
|
||||
|
||||
/**
|
||||
* Requirements for statistics based challenges
|
||||
*/
|
||||
public class StatisticRequirements extends Requirements
|
||||
{
|
||||
/**
|
||||
* Record for this requirement
|
||||
* @param Statistic statistic
|
||||
* @param EntityType entity
|
||||
* @param Material material
|
||||
* @param Integer amount
|
||||
* @param Boolean reduceStatistic
|
||||
*/
|
||||
public record StatisticRec(@Expose Statistic statistic, @Expose EntityType entity, @Expose Material material,
|
||||
@Expose Integer amount, @Expose Boolean reduceStatistic) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Type of the statistic field.
|
||||
* @deprecated Shifting to a list
|
||||
*/
|
||||
@Expose
|
||||
@Nullable
|
||||
private Statistic statistic;
|
||||
|
||||
/**
|
||||
* Type of entity for entity related statistics.
|
||||
* @deprecated Shifting to a list
|
||||
*/
|
||||
@Expose
|
||||
@Nullable
|
||||
private EntityType entity;
|
||||
|
||||
/**
|
||||
* Type of material for block and item related statistics.
|
||||
* @deprecated Shifting to a list
|
||||
*/
|
||||
@Expose
|
||||
@Nullable
|
||||
private Material material;
|
||||
|
||||
/**
|
||||
* Amount of the stats.
|
||||
* @deprecated Shifting to a list
|
||||
*/
|
||||
@Expose
|
||||
private Integer amount;
|
||||
|
||||
/**
|
||||
* Indicate that player statistic fields must be adjusted after completing challenges.
|
||||
* @deprecated Shifting to a list
|
||||
*/
|
||||
@Expose
|
||||
private Boolean reduceStatistic;
|
||||
|
||||
/**
|
||||
* List of statistics that must be done for this challenge
|
||||
*/
|
||||
@Expose
|
||||
@Nullable
|
||||
private List<StatisticRec> statisticList;
|
||||
|
||||
|
||||
/**
|
||||
* Constructor Requirements creates a new Requirements instance.
|
||||
*/
|
||||
@ -34,12 +100,7 @@ public class StatisticRequirements extends Requirements
|
||||
public Requirements copy()
|
||||
{
|
||||
StatisticRequirements requirements = new StatisticRequirements();
|
||||
requirements.setStatistic(this.statistic);
|
||||
requirements.setEntity(this.entity);
|
||||
requirements.setMaterial(this.material);
|
||||
requirements.setAmount(this.amount);
|
||||
requirements.setReduceStatistic(this.reduceStatistic);
|
||||
|
||||
requirements.setStatisticList(this.getRequiredStatistics());
|
||||
return requirements;
|
||||
}
|
||||
|
||||
@ -47,183 +108,33 @@ public class StatisticRequirements extends Requirements
|
||||
@Override
|
||||
public boolean isValid()
|
||||
{
|
||||
if (!super.isValid())
|
||||
{
|
||||
return false;
|
||||
// TODO - do something here?
|
||||
return super.isValid();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the statisticList
|
||||
*/
|
||||
public List<StatisticRec> getRequiredStatistics() {
|
||||
if (statisticList == null) {
|
||||
statisticList = new ArrayList<>();
|
||||
// Convert old single statistic entries to new list of records
|
||||
if (statistic != null) {
|
||||
StatisticRec rec = new StatisticRec(this.statistic, this.entity, this.material, this.amount,
|
||||
this.reduceStatistic);
|
||||
statisticList.add(rec);
|
||||
}
|
||||
}
|
||||
return statisticList;
|
||||
}
|
||||
|
||||
if (this.statistic == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return switch (this.statistic.getType())
|
||||
{
|
||||
case ITEM -> this.material != null && this.material.isItem();
|
||||
|
||||
case BLOCK -> this.material != null && this.material.isBlock();
|
||||
|
||||
case ENTITY -> this.entity != null;
|
||||
|
||||
case UNTYPED -> true;
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
* @param value the statisticList to set
|
||||
*/
|
||||
public void setStatisticList(Collection<StatisticRec> value) {
|
||||
// If value is null, assign null; otherwise, create a new ArrayList from value.
|
||||
this.statisticList = (value == null) ? null : new ArrayList<>(value);
|
||||
}
|
||||
|
||||
|
||||
// ---------------------------------------------------------------------
|
||||
// Section: Getters and setters
|
||||
// ---------------------------------------------------------------------
|
||||
|
||||
|
||||
/**
|
||||
* Gets statistic.
|
||||
*
|
||||
* @return the statistic
|
||||
*/
|
||||
@Nullable
|
||||
public Statistic getStatistic()
|
||||
{
|
||||
return statistic;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Sets statistic.
|
||||
*
|
||||
* @param statistic the statistic
|
||||
*/
|
||||
public void setStatistic(@Nullable Statistic statistic)
|
||||
{
|
||||
this.statistic = statistic;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Gets entity.
|
||||
*
|
||||
* @return the entity
|
||||
*/
|
||||
@Nullable
|
||||
public EntityType getEntity()
|
||||
{
|
||||
return entity;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Sets entity.
|
||||
*
|
||||
* @param entity the entity
|
||||
*/
|
||||
public void setEntity(@Nullable EntityType entity)
|
||||
{
|
||||
this.entity = entity;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Gets material.
|
||||
*
|
||||
* @return the material
|
||||
*/
|
||||
@Nullable
|
||||
public Material getMaterial()
|
||||
{
|
||||
return material;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Sets material.
|
||||
*
|
||||
* @param material the material
|
||||
*/
|
||||
public void setMaterial(@Nullable Material material)
|
||||
{
|
||||
this.material = material;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Gets amount.
|
||||
*
|
||||
* @return the amount
|
||||
*/
|
||||
public int getAmount()
|
||||
{
|
||||
return amount;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Sets amount.
|
||||
*
|
||||
* @param amount the amount
|
||||
*/
|
||||
public void setAmount(int amount)
|
||||
{
|
||||
this.amount = amount;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Is reduce statistic boolean.
|
||||
*
|
||||
* @return the boolean
|
||||
*/
|
||||
public boolean isReduceStatistic()
|
||||
{
|
||||
return reduceStatistic;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Sets reduce statistic.
|
||||
*
|
||||
* @param reduceStatistic the reduce statistic
|
||||
*/
|
||||
public void setReduceStatistic(boolean reduceStatistic)
|
||||
{
|
||||
this.reduceStatistic = reduceStatistic;
|
||||
}
|
||||
|
||||
|
||||
// ---------------------------------------------------------------------
|
||||
// Section: Variables
|
||||
// ---------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Type of the statistic field.
|
||||
*/
|
||||
@Expose
|
||||
@Nullable
|
||||
private Statistic statistic;
|
||||
|
||||
/**
|
||||
* Type of entity for entity related statistics.
|
||||
*/
|
||||
@Expose
|
||||
@Nullable
|
||||
private EntityType entity;
|
||||
|
||||
/**
|
||||
* Type of material for block and item related statistics.
|
||||
*/
|
||||
@Expose
|
||||
@Nullable
|
||||
private Material material;
|
||||
|
||||
/**
|
||||
* Amount of the stats.
|
||||
*/
|
||||
@Expose
|
||||
private int amount;
|
||||
|
||||
/**
|
||||
* Indicate that player statistic fields must be adjusted after completing challenges.
|
||||
*/
|
||||
@Expose
|
||||
private boolean reduceStatistic;
|
||||
}
|
||||
|
@ -50,6 +50,7 @@ import world.bentobox.challenges.database.object.requirements.InventoryRequireme
|
||||
import world.bentobox.challenges.database.object.requirements.IslandRequirements;
|
||||
import world.bentobox.challenges.database.object.requirements.OtherRequirements;
|
||||
import world.bentobox.challenges.database.object.requirements.StatisticRequirements;
|
||||
import world.bentobox.challenges.database.object.requirements.StatisticRequirements.StatisticRec;
|
||||
import world.bentobox.challenges.utils.Constants;
|
||||
import world.bentobox.challenges.utils.Utils;
|
||||
|
||||
@ -356,13 +357,12 @@ public class ChallengesImportManager
|
||||
case STATISTIC_TYPE -> {
|
||||
StatisticRequirements requirements = new StatisticRequirements();
|
||||
challenge.setRequirements(requirements);
|
||||
|
||||
requirements.setAmount(section.getInt("amount", 0));
|
||||
requirements.setReduceStatistic(section.getBoolean("reduce", false));
|
||||
|
||||
requirements.setStatistic(matchStatistic(section.getString("statistic")));
|
||||
requirements.setEntity(matchEntity(section.getString("entity")));
|
||||
requirements.setMaterial(matchMaterial(section.getString("material")));
|
||||
List<StatisticRec> list = new ArrayList<>();
|
||||
list.add(new StatisticRec(matchStatistic(section.getString("statistic")),
|
||||
matchEntity(section.getString("entity")), matchMaterial(section.getString("material")),
|
||||
section.getInt("amount", 0), section.getBoolean("reduce", false)));
|
||||
// TODO: Add support for multiple stat challenge
|
||||
requirements.setStatisticList(list);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -13,6 +13,7 @@ import java.util.Map;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.Statistic;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.eclipse.jdt.annotation.NonNull;
|
||||
@ -29,6 +30,7 @@ import world.bentobox.challenges.database.object.requirements.InventoryRequireme
|
||||
import world.bentobox.challenges.database.object.requirements.IslandRequirements;
|
||||
import world.bentobox.challenges.database.object.requirements.OtherRequirements;
|
||||
import world.bentobox.challenges.database.object.requirements.StatisticRequirements;
|
||||
import world.bentobox.challenges.database.object.requirements.StatisticRequirements.StatisticRec;
|
||||
import world.bentobox.challenges.managers.ChallengesManager;
|
||||
import world.bentobox.challenges.utils.Constants;
|
||||
import world.bentobox.challenges.utils.LevelStatus;
|
||||
@ -467,7 +469,7 @@ public abstract class CommonPanel {
|
||||
}
|
||||
|
||||
/**
|
||||
* This method generates lore message for Statistic requirement.
|
||||
* This method generates lore message for Statistic requirements.
|
||||
*
|
||||
* @param requirement Statistic Requirement.
|
||||
* @return Requirement lore message.
|
||||
@ -475,48 +477,49 @@ public abstract class CommonPanel {
|
||||
private String generateStatisticChallenge(StatisticRequirements requirement) {
|
||||
final String reference = Constants.DESCRIPTIONS + "challenge.requirements.statistic.";
|
||||
|
||||
String statistic;
|
||||
|
||||
if (requirement.getStatistic() == null) {
|
||||
if (requirement.getRequiredStatistics().isEmpty()) {
|
||||
// Challenges by default comes with empty statistic field.
|
||||
return "";
|
||||
}
|
||||
|
||||
switch (requirement.getStatistic().getType()) {
|
||||
case UNTYPED -> statistic = this.user.getTranslationOrNothing(reference + "statistic", "[statistic]",
|
||||
Utils.prettifyObject(requirement.getStatistic(), this.user), "[number]",
|
||||
String.valueOf(requirement.getAmount()));
|
||||
StringBuilder statistics = new StringBuilder();
|
||||
for (StatisticRec s : requirement.getRequiredStatistics()) {
|
||||
String statistic = switch (s.statistic().getType()) {
|
||||
case UNTYPED -> this.user.getTranslationOrNothing(reference + "statistic", "[statistic]",
|
||||
Utils.prettifyObject(s.statistic(), this.user), "[number]", String.valueOf(s.amount()));
|
||||
case ITEM, BLOCK -> {
|
||||
if (requirement.getAmount() > 1) {
|
||||
statistic = this.user.getTranslationOrNothing(reference + "multiple-target", "[statistic]",
|
||||
Utils.prettifyObject(requirement.getStatistic(), this.user), "[number]",
|
||||
String.valueOf(requirement.getAmount()), "[target]",
|
||||
Utils.prettifyObject(requirement.getMaterial(), this.user));
|
||||
if (s.amount() > 1) {
|
||||
yield this.user.getTranslationOrNothing(reference + "multiple-target", "[statistic]",
|
||||
Utils.prettifyObject(s.statistic(), this.user), "[number]", String.valueOf(s.amount()),
|
||||
"[target]", Utils.prettifyObject(s.material(), this.user));
|
||||
} else {
|
||||
statistic = this.user.getTranslationOrNothing(reference + "single-target", "[statistic]",
|
||||
Utils.prettifyObject(requirement.getStatistic(), this.user), "[target]",
|
||||
Utils.prettifyObject(requirement.getMaterial(), this.user));
|
||||
yield this.user.getTranslationOrNothing(reference + "single-target", "[statistic]",
|
||||
Utils.prettifyObject(s.statistic(), this.user), "[target]",
|
||||
Utils.prettifyObject(s.material(), this.user));
|
||||
}
|
||||
}
|
||||
case ENTITY -> {
|
||||
if (requirement.getAmount() > 1) {
|
||||
statistic = this.user.getTranslationOrNothing(reference + "multiple-target", "[statistic]",
|
||||
Utils.prettifyObject(requirement.getStatistic(), this.user), "[number]",
|
||||
String.valueOf(requirement.getAmount()), "[target]",
|
||||
Utils.prettifyObject(requirement.getEntity(), this.user));
|
||||
if (s.amount() > 1) {
|
||||
yield this.user.getTranslationOrNothing(reference + "multiple-target", "[statistic]",
|
||||
Utils.prettifyObject(s.statistic(), this.user), "[number]", String.valueOf(s.amount()),
|
||||
"[target]", Utils.prettifyObject(s.entity(), this.user));
|
||||
} else {
|
||||
statistic = this.user.getTranslationOrNothing(reference + "single-target", "[statistic]",
|
||||
Utils.prettifyObject(requirement.getStatistic(), this.user), "[target]",
|
||||
Utils.prettifyObject(requirement.getEntity(), this.user));
|
||||
yield this.user.getTranslationOrNothing(reference + "single-target", "[statistic]",
|
||||
Utils.prettifyObject(s.statistic(), this.user), "[target]",
|
||||
Utils.prettifyObject(s.entity(), this.user));
|
||||
}
|
||||
}
|
||||
default -> statistic = "";
|
||||
default -> "";
|
||||
};
|
||||
|
||||
String warning = s.reduceStatistic() ? this.user.getTranslationOrNothing(reference + "warning")
|
||||
: "";
|
||||
statistics.append(this.user.getTranslationOrNothing(reference + "lore", "[statistic]", statistic, "[warning]",
|
||||
warning));
|
||||
statistics.append("\n");
|
||||
|
||||
}
|
||||
|
||||
String warning = requirement.isReduceStatistic() ? this.user.getTranslationOrNothing(reference + "warning")
|
||||
: "";
|
||||
|
||||
return this.user.getTranslationOrNothing(reference + "lore", "[statistic]", statistic, "[warning]", warning);
|
||||
return statistics.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -35,9 +35,6 @@ import world.bentobox.challenges.panel.ConversationUtils;
|
||||
import world.bentobox.challenges.panel.util.EnvironmentSelector;
|
||||
import world.bentobox.challenges.panel.util.ItemSelector;
|
||||
import world.bentobox.challenges.panel.util.MultiBlockSelector;
|
||||
import world.bentobox.challenges.panel.util.SingleBlockSelector;
|
||||
import world.bentobox.challenges.panel.util.SingleEntitySelector;
|
||||
import world.bentobox.challenges.panel.util.StatisticSelector;
|
||||
import world.bentobox.challenges.utils.Constants;
|
||||
import world.bentobox.challenges.utils.Utils;
|
||||
|
||||
@ -229,24 +226,8 @@ public class EditChallengePanel extends CommonPanel {
|
||||
* @param panelBuilder PanelBuilder where icons must be added.
|
||||
*/
|
||||
private void buildStatisticRequirementsPanel(PanelBuilder panelBuilder) {
|
||||
panelBuilder.item(10, this.createRequirementButton(RequirementButton.STATISTIC));
|
||||
panelBuilder.item(19, this.createRequirementButton(RequirementButton.REMOVE_STATISTIC));
|
||||
|
||||
panelBuilder.item(11, this.createRequirementButton(RequirementButton.STATISTIC_AMOUNT));
|
||||
|
||||
StatisticRequirements requirements = this.challenge.getRequirements();
|
||||
|
||||
if (requirements.getStatistic() != null) {
|
||||
switch (requirements.getStatistic().getType()) {
|
||||
case ITEM -> panelBuilder.item(13, this.createRequirementButton(RequirementButton.STATISTIC_ITEMS));
|
||||
case BLOCK -> panelBuilder.item(13, this.createRequirementButton(RequirementButton.STATISTIC_BLOCKS));
|
||||
case ENTITY -> panelBuilder.item(13, this.createRequirementButton(RequirementButton.STATISTIC_ENTITIES));
|
||||
default -> {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
panelBuilder.item(25, this.createRequirementButton(RequirementButton.REQUIRED_PERMISSIONS));
|
||||
// Give user the ability to add or remove statistics
|
||||
panelBuilder.item(10, this.createRequirementButton(RequirementButton.REQUIRED_STATISTICS));
|
||||
}
|
||||
|
||||
/**
|
||||
@ -627,9 +608,9 @@ public class EditChallengePanel extends CommonPanel {
|
||||
case REQUIRED_EXPERIENCE, REMOVE_EXPERIENCE, REQUIRED_LEVEL, REQUIRED_MONEY, REMOVE_MONEY -> {
|
||||
return this.createOtherRequirementButton(button);
|
||||
}
|
||||
// Buttons for Statistic Requirements
|
||||
case STATISTIC, STATISTIC_BLOCKS, STATISTIC_ITEMS, STATISTIC_ENTITIES, STATISTIC_AMOUNT, REMOVE_STATISTIC -> {
|
||||
return this.createStatisticRequirementButton(button);
|
||||
// Statistics
|
||||
case REQUIRED_STATISTICS -> {
|
||||
return this.createStatisticsRequirementButton(button);
|
||||
}
|
||||
// Default behaviour.
|
||||
default -> {
|
||||
@ -702,8 +683,8 @@ public class EditChallengePanel extends CommonPanel {
|
||||
description.add(this.user.getTranslation(reference + "title"));
|
||||
// Add Material Tags only
|
||||
requirements.getRequiredMaterialTags()
|
||||
.forEach((block, count) -> description.add(this.user.getTranslation(reference + "list",
|
||||
"[tag]", Utils.prettifyObject(block, this.user), "[number]", String.valueOf(count))));
|
||||
.forEach((block, count) -> description.add(this.user.getTranslation(reference + "list", "[tag]",
|
||||
Utils.prettifyObject(block, this.user), "[number]", String.valueOf(count))));
|
||||
}
|
||||
|
||||
icon = new ItemStack(Material.STONE_BRICKS);
|
||||
@ -724,8 +705,8 @@ public class EditChallengePanel extends CommonPanel {
|
||||
description.add(this.user.getTranslation(reference + "title"));
|
||||
// Add Material Tags only
|
||||
requirements.getRequiredEntityTypeTags()
|
||||
.forEach((block, count) -> description.add(this.user.getTranslation(reference + "list",
|
||||
"[tag]", Utils.prettifyObject(block, this.user), "[number]", String.valueOf(count))));
|
||||
.forEach((block, count) -> description.add(this.user.getTranslation(reference + "list", "[tag]",
|
||||
Utils.prettifyObject(block, this.user), "[number]", String.valueOf(count))));
|
||||
}
|
||||
|
||||
icon = new ItemStack(Material.ZOMBIE_HEAD);
|
||||
@ -811,6 +792,62 @@ public class EditChallengePanel extends CommonPanel {
|
||||
.clickHandler(clickHandler).build();
|
||||
}
|
||||
|
||||
/**
|
||||
* This method creates buttons for inventory requirements menu.
|
||||
*
|
||||
* @param button Button which panel item must be created.
|
||||
* @return PanelItem that represents given button.
|
||||
*/
|
||||
private PanelItem createStatisticsRequirementButton(RequirementButton button) {
|
||||
final String reference = Constants.BUTTON + button.name().toLowerCase() + ".";
|
||||
|
||||
final String name = this.user.getTranslation(reference + "name");
|
||||
final List<String> description = new ArrayList<>(3);
|
||||
description.add(this.user.getTranslation(reference + "description"));
|
||||
|
||||
ItemStack icon;
|
||||
boolean glow;
|
||||
PanelItem.ClickHandler clickHandler;
|
||||
|
||||
final StatisticRequirements requirements = this.challenge.getRequirements();
|
||||
switch (button) {
|
||||
// Just one special statistic button right now
|
||||
case REQUIRED_STATISTICS -> {
|
||||
// TODO rename getStaticicList() to getRequiredStatistics()
|
||||
if (requirements.getRequiredStatistics().isEmpty()) {
|
||||
description.add(this.user.getTranslation(reference + "none"));
|
||||
} else {
|
||||
description.add(this.user.getTranslation(reference + "title"));
|
||||
|
||||
requirements.getRequiredStatistics().stream()
|
||||
.sorted(Comparator.comparing(r -> r.statistic().getKey().getKey()))
|
||||
// Just list the name of the statistic
|
||||
.forEach(sr -> description.add(this.user.getTranslationOrNothing(reference + "list", "[name]",
|
||||
Utils.prettifyObject(sr.statistic(), user))));
|
||||
}
|
||||
|
||||
icon = new ItemStack(Material.CHEST);
|
||||
clickHandler = (panel, user, clickType, slot) -> {
|
||||
// Deal with adding and removing statistics in the MultiStatisticSelector class
|
||||
ManageStatisticsPanel.open(this, requirements.getRequiredStatistics());
|
||||
return true;
|
||||
};
|
||||
glow = false;
|
||||
}
|
||||
default -> {
|
||||
// This should never need to be shown. Just for future expansion.
|
||||
glow = false;
|
||||
icon = new ItemStack(Material.PAPER);
|
||||
clickHandler = null;
|
||||
}
|
||||
}
|
||||
|
||||
description.add("");
|
||||
description.add(this.user.getTranslation(Constants.TIPS + "click-to-change"));
|
||||
return new PanelItemBuilder().icon(icon).name(name).description(description).glow(glow)
|
||||
.clickHandler(clickHandler).build();
|
||||
}
|
||||
|
||||
/**
|
||||
* This method creates buttons for inventory requirements menu.
|
||||
*
|
||||
@ -1085,163 +1122,6 @@ public class EditChallengePanel extends CommonPanel {
|
||||
.clickHandler(clickHandler).build();
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a button for statistic requirements.
|
||||
*
|
||||
* @param button Button that must be created.
|
||||
* @return PanelItem button.
|
||||
*/
|
||||
private PanelItem createStatisticRequirementButton(RequirementButton button) {
|
||||
final String reference = Constants.BUTTON + button.name().toLowerCase() + ".";
|
||||
|
||||
final String name = this.user.getTranslation(reference + "name");
|
||||
final List<String> description = new ArrayList<>(3);
|
||||
description.add(this.user.getTranslation(reference + "description"));
|
||||
|
||||
ItemStack icon;
|
||||
boolean glow;
|
||||
PanelItem.ClickHandler clickHandler;
|
||||
|
||||
final StatisticRequirements requirements = this.challenge.getRequirements();
|
||||
|
||||
switch (button) {
|
||||
case STATISTIC -> {
|
||||
description.add(this.user.getTranslation(reference + "value", "[statistic]",
|
||||
Utils.prettifyObject(requirements.getStatistic(), this.user)));
|
||||
|
||||
icon = new ItemStack(requirements.getStatistic() == null ? Material.BARRIER : Material.PAPER);
|
||||
clickHandler = (panel, user, clickType, slot) -> {
|
||||
StatisticSelector.open(this.user, (status, statistic) -> {
|
||||
if (status) {
|
||||
requirements.setStatistic(statistic);
|
||||
requirements.setMaterial(null);
|
||||
requirements.setEntity(null);
|
||||
requirements.setAmount(0);
|
||||
}
|
||||
|
||||
this.build();
|
||||
});
|
||||
return true;
|
||||
};
|
||||
glow = false;
|
||||
|
||||
description.add("");
|
||||
description.add(this.user.getTranslation(Constants.TIPS + "click-to-change"));
|
||||
}
|
||||
case STATISTIC_AMOUNT -> {
|
||||
description.add(this.user.getTranslation(reference + "value", Constants.PARAMETER_NUMBER,
|
||||
String.valueOf(requirements.getAmount())));
|
||||
icon = new ItemStack(Material.CHEST);
|
||||
clickHandler = (panel, user, clickType, i) -> {
|
||||
Consumer<Number> numberConsumer = number -> {
|
||||
if (number != null) {
|
||||
requirements.setAmount(number.intValue());
|
||||
}
|
||||
|
||||
// reopen panel
|
||||
this.build();
|
||||
};
|
||||
ConversationUtils.createNumericInput(numberConsumer, this.user,
|
||||
this.user.getTranslation(Constants.CONVERSATIONS + "input-number"), 0, Integer.MAX_VALUE);
|
||||
|
||||
return true;
|
||||
};
|
||||
glow = false;
|
||||
|
||||
description.add("");
|
||||
description.add(this.user.getTranslation(Constants.TIPS + "click-to-change"));
|
||||
}
|
||||
case REMOVE_STATISTIC -> {
|
||||
description.add(
|
||||
this.user.getTranslation(reference + (requirements.isReduceStatistic() ? "enabled" : "disabled")));
|
||||
|
||||
icon = new ItemStack(Material.LEVER);
|
||||
clickHandler = (panel, user, clickType, slot) -> {
|
||||
requirements.setReduceStatistic(!requirements.isReduceStatistic());
|
||||
this.build();
|
||||
return true;
|
||||
};
|
||||
glow = requirements.isReduceStatistic();
|
||||
|
||||
description.add("");
|
||||
description.add(this.user.getTranslation(Constants.TIPS + "click-to-toggle"));
|
||||
}
|
||||
case STATISTIC_BLOCKS -> {
|
||||
description.add(this.user.getTranslation(reference + "value", "[block]",
|
||||
Utils.prettifyObject(requirements.getMaterial(), this.user)));
|
||||
|
||||
icon = requirements.getMaterial() == null ? new ItemStack(Material.BARRIER)
|
||||
: new ItemStack(requirements.getMaterial());
|
||||
clickHandler = (panel, user, clickType, slot) -> {
|
||||
SingleBlockSelector.open(this.user, SingleBlockSelector.Mode.BLOCKS, (status, block) -> {
|
||||
if (status) {
|
||||
requirements.setMaterial(block);
|
||||
}
|
||||
|
||||
this.build();
|
||||
});
|
||||
|
||||
return true;
|
||||
};
|
||||
glow = false;
|
||||
|
||||
description.add("");
|
||||
description.add(this.user.getTranslation(Constants.TIPS + "click-to-change"));
|
||||
}
|
||||
case STATISTIC_ITEMS -> {
|
||||
description.add(this.user.getTranslation(reference + "value", "[item]",
|
||||
Utils.prettifyObject(requirements.getMaterial(), this.user)));
|
||||
|
||||
icon = requirements.getMaterial() == null ? new ItemStack(Material.BARRIER)
|
||||
: new ItemStack(requirements.getMaterial());
|
||||
clickHandler = (panel, user, clickType, slot) -> {
|
||||
SingleBlockSelector.open(this.user, SingleBlockSelector.Mode.ITEMS, (status, block) -> {
|
||||
if (status) {
|
||||
requirements.setMaterial(block);
|
||||
}
|
||||
|
||||
this.build();
|
||||
});
|
||||
|
||||
return true;
|
||||
};
|
||||
glow = false;
|
||||
|
||||
description.add("");
|
||||
description.add(this.user.getTranslation(Constants.TIPS + "click-to-change"));
|
||||
}
|
||||
case STATISTIC_ENTITIES -> {
|
||||
description.add(this.user.getTranslation(reference + "value", "[entity]",
|
||||
Utils.prettifyObject(requirements.getEntity(), this.user)));
|
||||
|
||||
icon = requirements.getEntity() == null ? new ItemStack(Material.BARRIER)
|
||||
: new ItemStack(PanelUtils.getEntityEgg(requirements.getEntity()));
|
||||
clickHandler = (panel, user, clickType, slot) -> {
|
||||
SingleEntitySelector.open(this.user, true, (status, entity) -> {
|
||||
if (status) {
|
||||
requirements.setEntity(entity);
|
||||
}
|
||||
|
||||
this.build();
|
||||
});
|
||||
|
||||
return true;
|
||||
};
|
||||
glow = false;
|
||||
|
||||
description.add("");
|
||||
description.add(this.user.getTranslation(Constants.TIPS + "click-to-change"));
|
||||
}
|
||||
default -> {
|
||||
icon = new ItemStack(Material.PAPER);
|
||||
clickHandler = null;
|
||||
glow = false;
|
||||
}
|
||||
}
|
||||
return new PanelItemBuilder().icon(icon).name(name).description(description).glow(glow)
|
||||
.clickHandler(clickHandler).build();
|
||||
}
|
||||
|
||||
/**
|
||||
* This method creates buttons for rewards menu.
|
||||
*
|
||||
@ -1791,11 +1671,13 @@ public class EditChallengePanel extends CommonPanel {
|
||||
/**
|
||||
* Represents different requirement buttons that are used in menus.
|
||||
*/
|
||||
private enum RequirementButton {
|
||||
public enum RequirementButton {
|
||||
REQUIRED_ENTITIES, REMOVE_ENTITIES, REQUIRED_BLOCKS, REMOVE_BLOCKS, SEARCH_RADIUS, REQUIRED_PERMISSIONS,
|
||||
REQUIRED_ITEMS, REMOVE_ITEMS, ADD_IGNORED_META, REMOVE_IGNORED_META, REQUIRED_EXPERIENCE, REMOVE_EXPERIENCE,
|
||||
REQUIRED_LEVEL, REQUIRED_MONEY, REMOVE_MONEY, STATISTIC, STATISTIC_BLOCKS, STATISTIC_ITEMS, STATISTIC_ENTITIES,
|
||||
STATISTIC_AMOUNT, REMOVE_STATISTIC, REQUIRED_MATERIALTAGS, REQUIRED_ENTITYTAGS,
|
||||
REQUIRED_LEVEL, REQUIRED_MONEY, REMOVE_MONEY, STATISTIC_SHOW, STATISTIC, STATISTIC_BLOCKS, STATISTIC_ITEMS,
|
||||
STATISTIC_ENTITIES, NEW_STATISTIC,
|
||||
STATISTIC_AMOUNT, REMOVE_STATISTIC, REQUIRED_MATERIALTAGS, REQUIRED_ENTITYTAGS, REQUIRED_STATISTICS,
|
||||
REMOVE_STATISTICS,
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------
|
||||
|
@ -0,0 +1,616 @@
|
||||
package world.bentobox.challenges.panel.admin;
|
||||
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Comparator;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Objects;
|
||||
import java.util.Set;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.Statistic;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.eclipse.jdt.annotation.Nullable;
|
||||
|
||||
import lv.id.bonne.panelutils.PanelUtils;
|
||||
import world.bentobox.bentobox.BentoBox;
|
||||
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.challenges.database.object.requirements.StatisticRequirements.StatisticRec;
|
||||
import world.bentobox.challenges.panel.CommonPagedPanel;
|
||||
import world.bentobox.challenges.panel.CommonPanel;
|
||||
import world.bentobox.challenges.panel.ConversationUtils;
|
||||
import world.bentobox.challenges.panel.admin.EditChallengePanel.RequirementButton;
|
||||
import world.bentobox.challenges.panel.util.SingleBlockSelector;
|
||||
import world.bentobox.challenges.panel.util.SingleEntitySelector;
|
||||
import world.bentobox.challenges.panel.util.StatisticSelector;
|
||||
import world.bentobox.challenges.utils.Constants;
|
||||
import world.bentobox.challenges.utils.Utils;
|
||||
|
||||
|
||||
/**
|
||||
* This class allows to edit material that are in required material map.
|
||||
*/
|
||||
public class ManageStatisticsPanel extends CommonPagedPanel<StatisticRec>
|
||||
{
|
||||
|
||||
// ---------------------------------------------------------------------
|
||||
// Section: Enums
|
||||
// ---------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Functional buttons in current GUI.
|
||||
*/
|
||||
private enum Button {
|
||||
ADD_STATISTIC, REMOVE_STATISTIC
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------
|
||||
// Section: Variables
|
||||
// ---------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Contains selected stats.
|
||||
*/
|
||||
private final Set<StatisticRec> selectedStats;
|
||||
|
||||
/**
|
||||
* List of required statistics
|
||||
*/
|
||||
private final List<StatisticRec> statisticsList;
|
||||
|
||||
/**
|
||||
* Stores filtered items.
|
||||
*/
|
||||
private List<StatisticRec> filterElements;
|
||||
|
||||
private ManageStatisticsPanel(CommonPanel parentGUI, List<StatisticRec> statisticsList)
|
||||
{
|
||||
super(parentGUI);
|
||||
this.statisticsList = statisticsList;
|
||||
|
||||
// Sort tags by their ordinal value.
|
||||
this.statisticsList.sort(Comparator.comparing(tag -> tag.statistic().getKey().getKey()));
|
||||
|
||||
this.selectedStats = new HashSet<>();
|
||||
|
||||
// Init without filters applied.
|
||||
this.filterElements = this.statisticsList;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Open the Challenges Admin GUI.
|
||||
*/
|
||||
public static void open(CommonPanel parentGUI, List<StatisticRec> statisticsList) {
|
||||
new ManageStatisticsPanel(parentGUI, statisticsList).build();
|
||||
}
|
||||
|
||||
|
||||
// ---------------------------------------------------------------------
|
||||
// Section: Methods
|
||||
// ---------------------------------------------------------------------
|
||||
|
||||
|
||||
/**
|
||||
* This method is called when filter value is updated.
|
||||
*/
|
||||
@Override
|
||||
protected void updateFilters()
|
||||
{
|
||||
if (this.searchString == null || this.searchString.isBlank())
|
||||
{
|
||||
this.filterElements = this.statisticsList;
|
||||
}
|
||||
else
|
||||
{
|
||||
this.filterElements = this.statisticsList.stream().
|
||||
filter(element -> {
|
||||
// If element name is set and name contains search field, then do not filter out.
|
||||
return element.statistic().getKey().getKey().toLowerCase(Locale.ENGLISH)
|
||||
.contains(this.searchString.toLowerCase(Locale.ENGLISH));
|
||||
}).
|
||||
distinct().
|
||||
collect(Collectors.toList());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* This method builds all necessary elements in GUI panel.
|
||||
*/
|
||||
@Override
|
||||
protected void build()
|
||||
{
|
||||
PanelBuilder panelBuilder = new PanelBuilder().user(this.user).
|
||||
name(this.user.getTranslation(Constants.TITLE + "manage-statistics"));
|
||||
|
||||
// Create nice border.
|
||||
PanelUtils.fillBorder(panelBuilder);
|
||||
|
||||
panelBuilder.item(3, this.createButton(Button.ADD_STATISTIC));
|
||||
panelBuilder.item(5, this.createButton(Button.REMOVE_STATISTIC));
|
||||
// Fill the box with what is selected
|
||||
this.populateElements(panelBuilder, this.filterElements);
|
||||
|
||||
// Add return button.
|
||||
panelBuilder.item(44, this.returnButton);
|
||||
|
||||
panelBuilder.build();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* This method creates PanelItem button of requested type.
|
||||
* @param button Button which must be created.
|
||||
* @return new PanelItem with requested functionality.
|
||||
*/
|
||||
private PanelItem createButton(Button button)
|
||||
{
|
||||
final String reference = Constants.BUTTON + button.name().toLowerCase() + ".";
|
||||
|
||||
final String name = this.user.getTranslation(reference + "name");
|
||||
final List<String> description = new ArrayList<>(3);
|
||||
description.add(this.user.getTranslation(reference + "description"));
|
||||
|
||||
ItemStack icon;
|
||||
PanelItem.ClickHandler clickHandler;
|
||||
boolean glow;
|
||||
|
||||
switch (button)
|
||||
{
|
||||
case ADD_STATISTIC -> {
|
||||
icon = new ItemStack(Material.BUCKET);
|
||||
clickHandler = (panel, user1, clickType, slot) ->
|
||||
{
|
||||
StatisticSelector.open(this.user, (status, statistic) ->
|
||||
{
|
||||
if (status)
|
||||
{
|
||||
StatisticRec newItem = new StatisticRec(statistic, null, null, 0, false);
|
||||
this.statisticsList.add(newItem);
|
||||
|
||||
}
|
||||
|
||||
this.build();
|
||||
});
|
||||
return true;
|
||||
};
|
||||
glow = false;
|
||||
|
||||
description.add("");
|
||||
description.add(this.user.getTranslation(Constants.TIPS + "click-to-add"));
|
||||
}
|
||||
case REMOVE_STATISTIC -> {
|
||||
|
||||
if (!this.selectedStats.isEmpty())
|
||||
{
|
||||
description.add(this.user.getTranslation(reference + "title"));
|
||||
this.selectedStats.forEach(stat ->
|
||||
description.add(this.user.getTranslation(reference + "statistic_element", "[statistic]",
|
||||
Utils.prettifyObject(stat.statistic(), this.user))));
|
||||
}
|
||||
|
||||
icon = new ItemStack(Material.LAVA_BUCKET);
|
||||
|
||||
clickHandler = (panel, user1, clickType, slot) ->
|
||||
{
|
||||
if (!this.selectedStats.isEmpty())
|
||||
{
|
||||
this.statisticsList.removeAll(this.selectedStats);
|
||||
this.selectedStats.clear();
|
||||
this.build();
|
||||
}
|
||||
|
||||
return true;
|
||||
};
|
||||
|
||||
glow = !this.selectedStats.isEmpty();
|
||||
|
||||
description.add("");
|
||||
description.add(this.user.getTranslation(Constants.TIPS + "click-to-remove"));
|
||||
}
|
||||
default -> {
|
||||
icon = new ItemStack(Material.PAPER);
|
||||
clickHandler = null;
|
||||
glow = false;
|
||||
}
|
||||
}
|
||||
|
||||
return new PanelItemBuilder().
|
||||
icon(icon).
|
||||
name(name).
|
||||
description(description).
|
||||
clickHandler(clickHandler).
|
||||
glow(glow).
|
||||
build();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* This method creates button for given stat.
|
||||
* @param rec material which button must be created.
|
||||
* @return new Button for material.
|
||||
*/
|
||||
@Override
|
||||
protected PanelItem createElementButton(StatisticRec rec)
|
||||
{
|
||||
final String reference = Constants.BUTTON + "statistic_element.";
|
||||
|
||||
List<String> description = new ArrayList<>();
|
||||
|
||||
// Show everything about this statistic
|
||||
// Type is not shown to the user, just used to decide what to show
|
||||
switch (rec.statistic().getType()) {
|
||||
case BLOCK:
|
||||
description.add(this.user.getTranslation(reference + "block", "[block]",
|
||||
Utils.prettifyObject(rec.material(), this.user)));
|
||||
break;
|
||||
case ENTITY:
|
||||
description.add(this.user.getTranslation(reference + "entity", "[entity]",
|
||||
Utils.prettifyObject(rec.entity(), this.user)));
|
||||
break;
|
||||
case ITEM:
|
||||
description.add(this.user.getTranslation(reference + "item", "[item]",
|
||||
Utils.prettifyObject(rec.material(), this.user)));
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
// Amount
|
||||
description.add(this.user.getTranslation(reference + "amount", Constants.PARAMETER_NUMBER,
|
||||
String.valueOf(Objects.requireNonNullElse(rec.amount(), 0))));
|
||||
// Removal
|
||||
description.add(this.user.getTranslation(reference + "remove.name", "[value]",
|
||||
this.user.getTranslation(reference + "remove.value."
|
||||
+ (Objects.requireNonNullElse(rec.reduceStatistic(), false) ? "enabled" : "disabled"))));
|
||||
|
||||
if (this.selectedStats.contains(rec))
|
||||
{
|
||||
description.add(this.user.getTranslation(reference + "selected"));
|
||||
}
|
||||
|
||||
description.add("");
|
||||
description.add(this.user.getTranslation(Constants.TIPS + "left-click-to-choose"));
|
||||
|
||||
if (this.selectedStats.contains(rec))
|
||||
{
|
||||
description.add(this.user.getTranslation(Constants.TIPS + "right-click-to-deselect"));
|
||||
}
|
||||
else
|
||||
{
|
||||
description.add(this.user.getTranslation(Constants.TIPS + "right-click-to-select"));
|
||||
}
|
||||
|
||||
return new PanelItemBuilder().
|
||||
name(this.user.getTranslation(reference + "name", "[statistic]",
|
||||
Utils.prettifyObject(rec.statistic(), this.user)))
|
||||
.icon(getStatisticIcon(rec.statistic())).
|
||||
description(description).
|
||||
clickHandler((panel, user1, clickType, slot) -> {
|
||||
// On right click change which entities are selected for deletion.
|
||||
if (clickType.isRightClick())
|
||||
{
|
||||
if (!this.selectedStats.add(rec))
|
||||
{
|
||||
// Remove material if it is already selected
|
||||
this.selectedStats.remove(rec);
|
||||
}
|
||||
|
||||
this.build();
|
||||
}
|
||||
else
|
||||
{
|
||||
// Left click
|
||||
this.buildStatisticPanel(rec);
|
||||
}
|
||||
return true;
|
||||
}).
|
||||
glow(this.selectedStats.contains(rec)).
|
||||
build();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get an icon for a Statistic. Hand selected!
|
||||
* @param stat Statistic
|
||||
* @return ItemStack icon
|
||||
*/
|
||||
public static ItemStack getStatisticIcon(Statistic stat) {
|
||||
return switch (stat) {
|
||||
case ANIMALS_BRED -> new ItemStack(Material.WHEAT);
|
||||
case ARMOR_CLEANED -> new ItemStack(Material.LEATHER_CHESTPLATE);
|
||||
case AVIATE_ONE_CM -> new ItemStack(Material.ELYTRA);
|
||||
case BANNER_CLEANED -> new ItemStack(Material.RED_BANNER);
|
||||
case BEACON_INTERACTION -> new ItemStack(Material.BEACON);
|
||||
case BELL_RING -> new ItemStack(Material.BELL);
|
||||
case BOAT_ONE_CM -> new ItemStack(Material.OAK_BOAT);
|
||||
case BREAK_ITEM -> new ItemStack(Material.AMETHYST_SHARD);
|
||||
case BREWINGSTAND_INTERACTION -> new ItemStack(Material.BREWING_STAND);
|
||||
case CAKE_SLICES_EATEN -> new ItemStack(Material.CAKE);
|
||||
case CAULDRON_FILLED -> new ItemStack(Material.CAULDRON);
|
||||
case CAULDRON_USED -> new ItemStack(Material.CAULDRON);
|
||||
case CHEST_OPENED -> new ItemStack(Material.CHEST);
|
||||
case CLEAN_SHULKER_BOX -> new ItemStack(Material.SHULKER_BOX);
|
||||
case CLIMB_ONE_CM -> new ItemStack(Material.LADDER);
|
||||
case CRAFTING_TABLE_INTERACTION -> new ItemStack(Material.CRAFTING_TABLE);
|
||||
case CRAFT_ITEM -> new ItemStack(Material.CRAFTING_TABLE);
|
||||
case CROUCH_ONE_CM -> new ItemStack(Material.PAPER);
|
||||
case DAMAGE_ABSORBED -> new ItemStack(Material.IRON_SWORD);
|
||||
case DAMAGE_BLOCKED_BY_SHIELD -> new ItemStack(Material.SHIELD);
|
||||
case DAMAGE_DEALT -> new ItemStack(Material.DIAMOND_SWORD);
|
||||
case DAMAGE_DEALT_ABSORBED -> new ItemStack(Material.GOLDEN_SWORD);
|
||||
case DAMAGE_DEALT_RESISTED -> new ItemStack(Material.WOODEN_SWORD);
|
||||
case DAMAGE_RESISTED -> new ItemStack(Material.IRON_HELMET);
|
||||
case DAMAGE_TAKEN -> new ItemStack(Material.IRON_LEGGINGS);
|
||||
case DEATHS -> new ItemStack(Material.OBSIDIAN);
|
||||
case DISPENSER_INSPECTED -> new ItemStack(Material.DISPENSER);
|
||||
case DROP -> new ItemStack(Material.PAPER);
|
||||
case DROPPER_INSPECTED -> new ItemStack(Material.DROPPER);
|
||||
case DROP_COUNT -> new ItemStack(Material.PAPER);
|
||||
case ENDERCHEST_OPENED -> new ItemStack(Material.ENDER_CHEST);
|
||||
case ENTITY_KILLED_BY -> new ItemStack(Material.BOW);
|
||||
case FALL_ONE_CM -> new ItemStack(Material.PAPER);
|
||||
case FISH_CAUGHT -> new ItemStack(Material.FISHING_ROD);
|
||||
case FLOWER_POTTED -> new ItemStack(Material.FLOWER_POT);
|
||||
case FLY_ONE_CM -> new ItemStack(Material.ELYTRA);
|
||||
case FURNACE_INTERACTION -> new ItemStack(Material.FURNACE);
|
||||
case HOPPER_INSPECTED -> new ItemStack(Material.HOPPER);
|
||||
case HORSE_ONE_CM -> new ItemStack(Material.IRON_HORSE_ARMOR);
|
||||
case INTERACT_WITH_ANVIL -> new ItemStack(Material.ANVIL);
|
||||
case INTERACT_WITH_BLAST_FURNACE -> new ItemStack(Material.BLAST_FURNACE);
|
||||
case INTERACT_WITH_CAMPFIRE -> new ItemStack(Material.CAMPFIRE);
|
||||
case INTERACT_WITH_CARTOGRAPHY_TABLE -> new ItemStack(Material.CARTOGRAPHY_TABLE);
|
||||
case INTERACT_WITH_GRINDSTONE -> new ItemStack(Material.GRINDSTONE);
|
||||
case INTERACT_WITH_LECTERN -> new ItemStack(Material.LECTERN);
|
||||
case INTERACT_WITH_LOOM -> new ItemStack(Material.LOOM);
|
||||
case INTERACT_WITH_SMITHING_TABLE -> new ItemStack(Material.SMITHING_TABLE);
|
||||
case INTERACT_WITH_SMOKER -> new ItemStack(Material.SMOKER);
|
||||
case INTERACT_WITH_STONECUTTER -> new ItemStack(Material.STONECUTTER);
|
||||
case ITEM_ENCHANTED -> new ItemStack(Material.ENCHANTED_GOLDEN_APPLE);
|
||||
case JUMP -> new ItemStack(Material.RABBIT_FOOT);
|
||||
case KILL_ENTITY -> new ItemStack(Material.DIAMOND_SWORD);
|
||||
case LEAVE_GAME -> new ItemStack(Material.PAPER);
|
||||
case MINECART_ONE_CM -> new ItemStack(Material.MINECART);
|
||||
case MINE_BLOCK -> new ItemStack(Material.STONE);
|
||||
case MOB_KILLS -> new ItemStack(Material.PAPER);
|
||||
case NOTEBLOCK_PLAYED -> new ItemStack(Material.NOTE_BLOCK);
|
||||
case NOTEBLOCK_TUNED -> new ItemStack(Material.NOTE_BLOCK);
|
||||
case OPEN_BARREL -> new ItemStack(Material.BARREL);
|
||||
case PICKUP -> new ItemStack(Material.PAPER);
|
||||
case PIG_ONE_CM -> new ItemStack(Material.PIG_SPAWN_EGG);
|
||||
case PLAYER_KILLS -> new ItemStack(Material.PLAYER_HEAD);
|
||||
case PLAY_ONE_MINUTE -> new ItemStack(Material.CLOCK);
|
||||
case RAID_TRIGGER -> new ItemStack(Material.OMINOUS_BOTTLE);
|
||||
case RAID_WIN -> new ItemStack(Material.GOLD_INGOT);
|
||||
case RECORD_PLAYED -> new ItemStack(Material.MUSIC_DISC_BLOCKS);
|
||||
case SHULKER_BOX_OPENED -> new ItemStack(Material.SHULKER_BOX);
|
||||
case SLEEP_IN_BED -> new ItemStack(Material.RED_BED);
|
||||
case SNEAK_TIME -> new ItemStack(Material.PAPER);
|
||||
case SPRINT_ONE_CM -> new ItemStack(Material.PAPER);
|
||||
case STRIDER_ONE_CM -> new ItemStack(Material.STRIDER_SPAWN_EGG);
|
||||
case SWIM_ONE_CM -> new ItemStack(Material.WATER_BUCKET);
|
||||
case TALKED_TO_VILLAGER -> new ItemStack(Material.EMERALD);
|
||||
case TARGET_HIT -> new ItemStack(Material.TARGET);
|
||||
case TIME_SINCE_DEATH -> new ItemStack(Material.CLOCK);
|
||||
case TIME_SINCE_REST -> new ItemStack(Material.CLOCK);
|
||||
case TOTAL_WORLD_TIME -> new ItemStack(Material.CLOCK);
|
||||
case TRADED_WITH_VILLAGER -> new ItemStack(Material.EMERALD);
|
||||
case TRAPPED_CHEST_TRIGGERED -> new ItemStack(Material.TRAPPED_CHEST);
|
||||
case USE_ITEM -> new ItemStack(Material.STICK);
|
||||
case WALK_ONE_CM -> new ItemStack(Material.LEATHER_BOOTS);
|
||||
case WALK_ON_WATER_ONE_CM -> new ItemStack(Material.LILY_PAD);
|
||||
case WALK_UNDER_WATER_ONE_CM -> new ItemStack(Material.WATER_BUCKET);
|
||||
default -> new ItemStack(Material.PAPER);
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
private Panel buildStatisticPanel(StatisticRec req) {
|
||||
|
||||
PanelBuilder panelBuilder = new PanelBuilder().user(this.user);
|
||||
|
||||
panelBuilder.name(this.user.getTranslation(Constants.TITLE + "statistic-selector"));
|
||||
|
||||
PanelUtils.fillBorder(panelBuilder);
|
||||
|
||||
panelBuilder.item(10, this.createStatisticRequirementButton(RequirementButton.STATISTIC, req));
|
||||
panelBuilder.item(19, this.createStatisticRequirementButton(RequirementButton.REMOVE_STATISTIC, req));
|
||||
|
||||
panelBuilder.item(11, this.createStatisticRequirementButton(RequirementButton.STATISTIC_AMOUNT, req));
|
||||
switch (req.statistic().getType()) {
|
||||
case BLOCK:
|
||||
panelBuilder.item(13, this.createStatisticRequirementButton(RequirementButton.STATISTIC_BLOCKS, req));
|
||||
break;
|
||||
case ENTITY:
|
||||
panelBuilder.item(13, this.createStatisticRequirementButton(RequirementButton.STATISTIC_ENTITIES, req));
|
||||
break;
|
||||
case ITEM:
|
||||
panelBuilder.item(13, this.createStatisticRequirementButton(RequirementButton.STATISTIC_ITEMS, req));
|
||||
break;
|
||||
case UNTYPED:
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
|
||||
}
|
||||
panelBuilder.item(25, this.createStatisticRequirementButton(RequirementButton.REQUIRED_PERMISSIONS, req));
|
||||
panelBuilder.item(44, this.returnButton);
|
||||
return panelBuilder.build();
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a button for statistic requirements.
|
||||
*
|
||||
* @param button Button that must be created.
|
||||
* @param req
|
||||
* @return PanelItem button.
|
||||
*/
|
||||
private PanelItem createStatisticRequirementButton(RequirementButton button, StatisticRec req) {
|
||||
|
||||
final String reference = Constants.BUTTON + button.name().toLowerCase(Locale.ENGLISH) + ".";
|
||||
final String name = this.user.getTranslation(reference + "name");
|
||||
final List<String> description = new ArrayList<>(3);
|
||||
description.add(this.user.getTranslation(reference + "description"));
|
||||
|
||||
ItemStack icon;
|
||||
boolean glow;
|
||||
PanelItem.ClickHandler clickHandler;
|
||||
|
||||
switch (button) {
|
||||
case STATISTIC -> {
|
||||
description.add(this.user.getTranslation(reference + "value", "[statistic]",
|
||||
Utils.prettifyObject(req.statistic(), this.user)));
|
||||
|
||||
icon = new ItemStack(req.statistic() == null ? Material.BARRIER : Material.PAPER);
|
||||
clickHandler = (panel, user, clickType, slot) -> {
|
||||
StatisticSelector.open(this.user, (status, statistic) -> {
|
||||
if (status) {
|
||||
// Replace the old with the new
|
||||
statisticsList.removeIf(sr -> sr.equals(req));
|
||||
statisticsList.add(new StatisticRec(statistic, null, null, 0, false));
|
||||
}
|
||||
this.build();
|
||||
});
|
||||
return true;
|
||||
};
|
||||
glow = false;
|
||||
|
||||
description.add("");
|
||||
description.add(this.user.getTranslation(Constants.TIPS + "click-to-change"));
|
||||
}
|
||||
case STATISTIC_AMOUNT -> {
|
||||
description.add(this.user.getTranslation(reference + "value", Constants.PARAMETER_NUMBER,
|
||||
String.valueOf(req.amount())));
|
||||
icon = new ItemStack(Material.CHEST);
|
||||
clickHandler = (panel, user, clickType, i) -> {
|
||||
Consumer<Number> numberConsumer = number -> {
|
||||
if (number != null) {
|
||||
// Replace the old with the new
|
||||
statisticsList.removeIf(sr -> sr.equals(req));
|
||||
statisticsList.add(new StatisticRec(req.statistic(), req.entity(), req.material(),
|
||||
number.intValue(), req.reduceStatistic()));
|
||||
}
|
||||
|
||||
// reopen panel
|
||||
this.build();
|
||||
};
|
||||
ConversationUtils.createNumericInput(numberConsumer, this.user,
|
||||
this.user.getTranslation(Constants.CONVERSATIONS + "input-number"), 0, Integer.MAX_VALUE);
|
||||
|
||||
return true;
|
||||
};
|
||||
glow = false;
|
||||
|
||||
description.add("");
|
||||
description.add(this.user.getTranslation(Constants.TIPS + "click-to-change"));
|
||||
}
|
||||
case REMOVE_STATISTIC -> {
|
||||
description.add(this.user.getTranslation(reference + (req.reduceStatistic() ? "enabled" : "disabled")));
|
||||
|
||||
icon = new ItemStack(Material.LEVER);
|
||||
clickHandler = (panel, user, clickType, slot) -> {
|
||||
// Replace the old with the new
|
||||
statisticsList.removeIf(sr -> sr.equals(req));
|
||||
statisticsList.add(new StatisticRec(req.statistic(), req.entity(), req.material(), req.amount(),
|
||||
!req.reduceStatistic()));
|
||||
|
||||
this.build();
|
||||
return true;
|
||||
};
|
||||
glow = req.reduceStatistic();
|
||||
|
||||
description.add("");
|
||||
description.add(this.user.getTranslation(Constants.TIPS + "click-to-toggle"));
|
||||
}
|
||||
case STATISTIC_BLOCKS -> {
|
||||
description.add(this.user.getTranslation(reference + "value", "[block]",
|
||||
Utils.prettifyObject(req.material(), this.user)));
|
||||
|
||||
icon = req.material() == null ? new ItemStack(Material.BARRIER) : new ItemStack(req.material());
|
||||
clickHandler = (panel, user, clickType, slot) -> {
|
||||
SingleBlockSelector.open(this.user, SingleBlockSelector.Mode.BLOCKS, (status, block) -> {
|
||||
if (status) {
|
||||
// Replace the old with the new
|
||||
statisticsList.removeIf(sr -> sr.equals(req));
|
||||
statisticsList.add(new StatisticRec(req.statistic(), req.entity(), block, req.amount(),
|
||||
req.reduceStatistic()));
|
||||
|
||||
}
|
||||
|
||||
this.build();
|
||||
});
|
||||
|
||||
return true;
|
||||
};
|
||||
glow = false;
|
||||
|
||||
description.add("");
|
||||
description.add(this.user.getTranslation(Constants.TIPS + "click-to-change"));
|
||||
}
|
||||
case STATISTIC_ITEMS -> {
|
||||
description.add(this.user.getTranslation(reference + "value", "[item]",
|
||||
Utils.prettifyObject(req.material(), this.user)));
|
||||
|
||||
icon = req.material() == null ? new ItemStack(Material.BARRIER) : new ItemStack(req.material());
|
||||
clickHandler = (panel, user, clickType, slot) -> {
|
||||
SingleBlockSelector.open(this.user, SingleBlockSelector.Mode.ITEMS, (status, block) -> {
|
||||
if (status) {
|
||||
// Replace the old with the new
|
||||
statisticsList.removeIf(sr -> sr.equals(req));
|
||||
statisticsList.add(new StatisticRec(req.statistic(), req.entity(), block, req.amount(),
|
||||
req.reduceStatistic()));
|
||||
}
|
||||
|
||||
this.build();
|
||||
});
|
||||
|
||||
return true;
|
||||
};
|
||||
glow = false;
|
||||
|
||||
description.add("");
|
||||
description.add(this.user.getTranslation(Constants.TIPS + "click-to-change"));
|
||||
}
|
||||
case STATISTIC_ENTITIES -> {
|
||||
description.add(this.user.getTranslation(reference + "value", "[entity]",
|
||||
Utils.prettifyObject(req.entity(), this.user)));
|
||||
|
||||
icon = req.entity() == null ? new ItemStack(Material.BARRIER)
|
||||
: new ItemStack(PanelUtils.getEntityEgg(req.entity()));
|
||||
clickHandler = (panel, user, clickType, slot) -> {
|
||||
SingleEntitySelector.open(this.user, true, (status, entity) -> {
|
||||
if (status) {
|
||||
// Replace the old with the new
|
||||
statisticsList.removeIf(sr -> sr.equals(req));
|
||||
statisticsList.add(new StatisticRec(req.statistic(), entity, req.material(), req.amount(),
|
||||
req.reduceStatistic()));
|
||||
}
|
||||
|
||||
this.build();
|
||||
});
|
||||
|
||||
return true;
|
||||
};
|
||||
glow = false;
|
||||
|
||||
description.add("");
|
||||
description.add(this.user.getTranslation(Constants.TIPS + "click-to-change"));
|
||||
}
|
||||
default -> {
|
||||
icon = new ItemStack(Material.PAPER);
|
||||
clickHandler = null;
|
||||
glow = false;
|
||||
}
|
||||
}
|
||||
return new PanelItemBuilder().icon(icon).name(name).description(description).glow(glow)
|
||||
.clickHandler(clickHandler).build();
|
||||
}
|
||||
|
||||
|
||||
}
|
@ -17,6 +17,7 @@ import world.bentobox.bentobox.api.panels.PanelItem;
|
||||
import world.bentobox.bentobox.api.panels.builders.PanelBuilder;
|
||||
import world.bentobox.bentobox.api.panels.builders.PanelItemBuilder;
|
||||
import world.bentobox.bentobox.api.user.User;
|
||||
import world.bentobox.challenges.panel.admin.ManageStatisticsPanel;
|
||||
import world.bentobox.challenges.utils.Constants;
|
||||
import world.bentobox.challenges.utils.Utils;
|
||||
|
||||
@ -132,13 +133,11 @@ public class StatisticSelector extends PagedSelector<Statistic>
|
||||
return new PanelItemBuilder().
|
||||
name(this.user.getTranslation(reference + "name", "[statistic]",
|
||||
Utils.prettifyObject(statistic, this.user))).
|
||||
icon(Material.PAPER).
|
||||
description(description).
|
||||
clickHandler((panel, user1, clickType, slot) -> {
|
||||
this.consumer.accept(true, statistic);
|
||||
return true;
|
||||
}).
|
||||
build();
|
||||
icon(ManageStatisticsPanel.getStatisticIcon(statistic)).description(description)
|
||||
.clickHandler((panel, user1, clickType, slot) -> {
|
||||
this.consumer.accept(true, statistic);
|
||||
return true;
|
||||
}).build();
|
||||
}
|
||||
|
||||
|
||||
|
@ -57,6 +57,20 @@ public abstract class UnifiedMultiSelector<T> extends PagedSelector<T> {
|
||||
this.filterElements = this.elements;
|
||||
}
|
||||
|
||||
protected UnifiedMultiSelector(User user, Mode mode, List<T> elements,
|
||||
BiConsumer<Boolean, Collection<T>> consumer) {
|
||||
super(user);
|
||||
this.mode = mode;
|
||||
this.consumer = consumer;
|
||||
this.selectedElements = new HashSet<>();
|
||||
//If the elements are passed to the subclass in the constructor
|
||||
this.elements = elements;
|
||||
// Sort elements using the provided string representation.
|
||||
this.elements.sort(Comparator.comparing(this::elementToString));
|
||||
// Start with the full list as the filtered list.
|
||||
this.filterElements = this.elements;
|
||||
}
|
||||
|
||||
/**
|
||||
* Subclasses must return the complete list of available elements.
|
||||
*/
|
||||
|
@ -3,6 +3,7 @@ package world.bentobox.challenges.tasks;
|
||||
|
||||
|
||||
import java.time.Duration;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
@ -48,6 +49,7 @@ import world.bentobox.challenges.database.object.requirements.InventoryRequireme
|
||||
import world.bentobox.challenges.database.object.requirements.IslandRequirements;
|
||||
import world.bentobox.challenges.database.object.requirements.OtherRequirements;
|
||||
import world.bentobox.challenges.database.object.requirements.StatisticRequirements;
|
||||
import world.bentobox.challenges.database.object.requirements.StatisticRequirements.StatisticRec;
|
||||
import world.bentobox.challenges.managers.ChallengesManager;
|
||||
import world.bentobox.challenges.utils.Constants;
|
||||
import world.bentobox.challenges.utils.Utils;
|
||||
@ -475,63 +477,58 @@ public class TryToComplete
|
||||
}
|
||||
case STATISTIC_TYPE -> {
|
||||
StatisticRequirements requirements = this.challenge.getRequirements();
|
||||
for (StatisticRec s : requirements.getRequiredStatistics()) {
|
||||
if (s.reduceStatistic() && s.statistic() != null) {
|
||||
int removeAmount = result.getFactor() * s.amount();
|
||||
|
||||
if (requirements.isReduceStatistic() && requirements.getStatistic() != null) {
|
||||
int removeAmount = result.getFactor() * requirements.getAmount();
|
||||
|
||||
// Start to remove from player who called the completion.
|
||||
switch (requirements.getStatistic().getType())
|
||||
{
|
||||
case UNTYPED -> {
|
||||
int statistic = this.user.getPlayer().getStatistic(requirements.getStatistic());
|
||||
|
||||
if (removeAmount >= statistic) {
|
||||
this.user.getPlayer().setStatistic(requirements.getStatistic(), 0);
|
||||
removeAmount -= statistic;
|
||||
} else {
|
||||
this.user.getPlayer().setStatistic(requirements.getStatistic(), statistic - removeAmount);
|
||||
removeAmount = 0;
|
||||
}
|
||||
}
|
||||
case ITEM, BLOCK -> {
|
||||
if (requirements.getMaterial() == null) {
|
||||
// Just a sanity check. Material cannot be null at this point of code.
|
||||
removeAmount = 0;
|
||||
} else {
|
||||
int statistic = this.user.getPlayer().getStatistic(requirements.getStatistic(),
|
||||
requirements.getMaterial());
|
||||
// Start to remove from player who called the completion.
|
||||
switch (s.statistic().getType())
|
||||
{
|
||||
case UNTYPED -> {
|
||||
int statistic = this.user.getPlayer().getStatistic(s.statistic());
|
||||
|
||||
if (removeAmount >= statistic) {
|
||||
this.user.getPlayer().setStatistic(requirements.getStatistic(), requirements.getMaterial(),
|
||||
0);
|
||||
this.user.getPlayer().setStatistic(s.statistic(), 0);
|
||||
removeAmount -= statistic;
|
||||
} else {
|
||||
this.user.getPlayer().setStatistic(requirements.getStatistic(), requirements.getMaterial(),
|
||||
statistic - removeAmount);
|
||||
this.user.getPlayer().setStatistic(s.statistic(), statistic - removeAmount);
|
||||
removeAmount = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
case ENTITY -> {
|
||||
if (requirements.getEntity() == null) {
|
||||
// Just a sanity check. Entity cannot be null at this point of code.
|
||||
removeAmount = 0;
|
||||
} else {
|
||||
int statistic = this.user.getPlayer().getStatistic(requirements.getStatistic(),
|
||||
requirements.getEntity());
|
||||
|
||||
if (removeAmount >= statistic) {
|
||||
this.user.getPlayer().setStatistic(requirements.getStatistic(), requirements.getEntity(),
|
||||
0);
|
||||
removeAmount -= statistic;
|
||||
} else {
|
||||
this.user.getPlayer().setStatistic(requirements.getStatistic(), requirements.getEntity(),
|
||||
statistic - removeAmount);
|
||||
case ITEM, BLOCK -> {
|
||||
if (s.material() == null) {
|
||||
// Just a sanity check. Material cannot be null at this point of code.
|
||||
removeAmount = 0;
|
||||
} else {
|
||||
int statistic = this.user.getPlayer().getStatistic(s.statistic(), s.material());
|
||||
|
||||
if (removeAmount >= statistic) {
|
||||
this.user.getPlayer().setStatistic(s.statistic(), s.material(), 0);
|
||||
removeAmount -= statistic;
|
||||
} else {
|
||||
this.user.getPlayer().setStatistic(s.statistic(), s.material(),
|
||||
statistic - removeAmount);
|
||||
removeAmount = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
case ENTITY -> {
|
||||
if (s.entity() == null) {
|
||||
// Just a sanity check. Entity cannot be null at this point of code.
|
||||
removeAmount = 0;
|
||||
} else {
|
||||
int statistic = this.user.getPlayer().getStatistic(s.statistic(), s.entity());
|
||||
|
||||
if (removeAmount >= statistic) {
|
||||
this.user.getPlayer().setStatistic(s.statistic(), s.entity(), 0);
|
||||
removeAmount -= statistic;
|
||||
} else {
|
||||
this.user.getPlayer().setStatistic(s.statistic(), s.entity(), statistic - removeAmount);
|
||||
removeAmount = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// If challenges are in sync with all island members, then punish others too.
|
||||
if (this.addon.getChallengesSettings().isStoreAsIslandData())
|
||||
@ -553,64 +550,62 @@ public class TryToComplete
|
||||
continue;
|
||||
}
|
||||
|
||||
switch (Objects.requireNonNull(requirements.getStatistic()).getType()) {
|
||||
switch (Objects.requireNonNull(s.statistic()).getType()) {
|
||||
case UNTYPED -> {
|
||||
int statistic = player.getStatistic(requirements.getStatistic());
|
||||
int statistic = player.getStatistic(s.statistic());
|
||||
|
||||
if (removeAmount >= statistic)
|
||||
{
|
||||
removeAmount -= statistic;
|
||||
player.setStatistic(requirements.getStatistic(), 0);
|
||||
player.setStatistic(s.statistic(), 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
player.setStatistic(requirements.getStatistic(), statistic - removeAmount);
|
||||
player.setStatistic(s.statistic(), statistic - removeAmount);
|
||||
removeAmount = 0;
|
||||
}
|
||||
}
|
||||
case ITEM, BLOCK -> {
|
||||
if (requirements.getMaterial() == null)
|
||||
if (s.material() == null)
|
||||
{
|
||||
// Just a sanity check. Entity cannot be null at this point of code.
|
||||
removeAmount = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
int statistic = player.getStatistic(requirements.getStatistic(),
|
||||
requirements.getMaterial());
|
||||
int statistic = player.getStatistic(s.statistic(), s.material());
|
||||
|
||||
if (removeAmount >= statistic)
|
||||
{
|
||||
removeAmount -= statistic;
|
||||
player.setStatistic(requirements.getStatistic(), requirements.getMaterial(), 0);
|
||||
player.setStatistic(s.statistic(), s.material(), 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
player.setStatistic(requirements.getStatistic(), requirements.getMaterial(),
|
||||
player.setStatistic(s.statistic(), s.material(),
|
||||
statistic - removeAmount);
|
||||
removeAmount = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
case ENTITY -> {
|
||||
if (requirements.getEntity() == null)
|
||||
if (s.entity() == null)
|
||||
{
|
||||
// Just a sanity check. Entity cannot be null at this point of code.
|
||||
removeAmount = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
int statistic = player.getStatistic(requirements.getStatistic(),
|
||||
requirements.getEntity());
|
||||
int statistic = player.getStatistic(s.statistic(), s.entity());
|
||||
|
||||
if (removeAmount >= statistic)
|
||||
{
|
||||
removeAmount -= statistic;
|
||||
player.setStatistic(requirements.getStatistic(), requirements.getEntity(), 0);
|
||||
player.setStatistic(s.statistic(), s.entity(), 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
player.setStatistic(requirements.getStatistic(), requirements.getEntity(),
|
||||
player.setStatistic(s.statistic(), s.entity(),
|
||||
statistic - removeAmount);
|
||||
removeAmount = 0;
|
||||
}
|
||||
@ -619,6 +614,7 @@ public class TryToComplete
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1470,54 +1466,58 @@ public class TryToComplete
|
||||
|
||||
int currentValue;
|
||||
|
||||
if (requirements.getStatistic() == null) {
|
||||
if (requirements.getRequiredStatistics().isEmpty()) {
|
||||
// Sanity check.
|
||||
return EMPTY_RESULT;
|
||||
}
|
||||
List<ChallengeResult> cr = new ArrayList<>();
|
||||
// Check all requirements
|
||||
for (StatisticRec s : requirements.getRequiredStatistics()) {
|
||||
|
||||
switch (Objects.requireNonNull(requirements.getStatistic()).getType())
|
||||
{
|
||||
case UNTYPED ->
|
||||
currentValue = this.manager.getStatisticData(this.user, this.world, requirements.getStatistic());
|
||||
case ITEM, BLOCK -> currentValue = this.manager.getStatisticData(this.user, this.world,
|
||||
requirements.getStatistic(), requirements.getMaterial());
|
||||
case ENTITY -> currentValue = this.manager.getStatisticData(this.user, this.world, requirements.getStatistic(),
|
||||
requirements.getEntity());
|
||||
default -> currentValue = 0;
|
||||
}
|
||||
|
||||
if (currentValue < requirements.getAmount()) {
|
||||
switch (Objects.requireNonNull(requirements.getStatistic()).getType())
|
||||
switch (Objects.requireNonNull(s.statistic()).getType())
|
||||
{
|
||||
case ITEM, BLOCK -> {
|
||||
Utils.sendMessage(this.user, this.world, Constants.ERRORS + "requirement-not-met-material",
|
||||
TextVariables.NUMBER, String.valueOf(requirements.getAmount()), "[statistic]",
|
||||
Utils.prettifyObject(requirements.getStatistic(), this.user), "[material]",
|
||||
Utils.prettifyObject(requirements.getMaterial(), this.user), Constants.PARAMETER_VALUE,
|
||||
String.valueOf(currentValue));
|
||||
case UNTYPED -> currentValue = this.manager.getStatisticData(this.user, this.world, s.statistic());
|
||||
case ITEM, BLOCK ->
|
||||
currentValue = this.manager.getStatisticData(this.user, this.world, s.statistic(), s.material());
|
||||
case ENTITY ->
|
||||
currentValue = this.manager.getStatisticData(this.user, this.world, s.statistic(), s.entity());
|
||||
default -> currentValue = 0;
|
||||
}
|
||||
case ENTITY -> {
|
||||
Utils.sendMessage(this.user,
|
||||
this.world, Constants.ERRORS + "requirement-not-met-entity", TextVariables.NUMBER,
|
||||
String.valueOf(requirements.getAmount()), "[statistic]",
|
||||
Utils.prettifyObject(requirements.getStatistic(), this.user), "[entity]",
|
||||
Utils.prettifyObject(requirements.getEntity(), this.user), Constants.PARAMETER_VALUE,
|
||||
String.valueOf(currentValue));
|
||||
}
|
||||
default -> {
|
||||
Utils.sendMessage(this.user,
|
||||
this.world, Constants.ERRORS + "requirement-not-met", TextVariables.NUMBER,
|
||||
String.valueOf(requirements.getAmount()), "[statistic]",
|
||||
Utils.prettifyObject(requirements.getStatistic(), this.user), Constants.PARAMETER_VALUE,
|
||||
String.valueOf(currentValue));
|
||||
}
|
||||
}
|
||||
} else {
|
||||
factor = requirements.getAmount() == 0 ? factor : Math.min(factor, currentValue / requirements.getAmount());
|
||||
|
||||
return new ChallengeResult().setMeetsRequirements().setCompleteFactor(factor);
|
||||
if (currentValue < s.amount()) {
|
||||
switch (Objects.requireNonNull(s.statistic()).getType()) {
|
||||
case ITEM, BLOCK -> {
|
||||
Utils.sendMessage(this.user, this.world, Constants.ERRORS + "requirement-not-met-material",
|
||||
TextVariables.NUMBER, String.valueOf(s.amount()), "[statistic]",
|
||||
Utils.prettifyObject(s.statistic(), this.user), "[material]",
|
||||
Utils.prettifyObject(s.material(), this.user), Constants.PARAMETER_VALUE,
|
||||
String.valueOf(currentValue));
|
||||
}
|
||||
case ENTITY -> {
|
||||
Utils.sendMessage(this.user, this.world, Constants.ERRORS + "requirement-not-met-entity",
|
||||
TextVariables.NUMBER, String.valueOf(s.amount()), "[statistic]",
|
||||
Utils.prettifyObject(s.statistic(), this.user), "[entity]",
|
||||
Utils.prettifyObject(s.entity(), this.user), Constants.PARAMETER_VALUE,
|
||||
String.valueOf(currentValue));
|
||||
}
|
||||
default -> {
|
||||
Utils.sendMessage(this.user, this.world, Constants.ERRORS + "requirement-not-met",
|
||||
TextVariables.NUMBER, String.valueOf(s.amount()), "[statistic]",
|
||||
Utils.prettifyObject(s.statistic(), this.user), Constants.PARAMETER_VALUE,
|
||||
String.valueOf(currentValue));
|
||||
}
|
||||
}
|
||||
} else {
|
||||
factor = s.amount() == 0 ? factor : Math.min(factor, currentValue / s.amount());
|
||||
// Store result
|
||||
cr.add(new ChallengeResult().setMeetsRequirements().setCompleteFactor(factor));
|
||||
}
|
||||
}
|
||||
// Check results -- all must pass
|
||||
if (cr.stream().allMatch(result -> result.meetsRequirements)) {
|
||||
// Return any of them, because they pass
|
||||
return cr.getFirst();
|
||||
}
|
||||
|
||||
return EMPTY_RESULT;
|
||||
}
|
||||
|
||||
|
@ -63,6 +63,7 @@ challenges:
|
||||
manage-block-groups: "&0&l Manage Block Groups"
|
||||
manage-entity-groups: "&0&l Manage Entity Groups"
|
||||
manage-entities: "&0&l Manage Entities"
|
||||
manage-statistics: "&0&l Manage Statistics"
|
||||
type-selector: "&0&l Challenge Type Selector"
|
||||
item-selector: "&0&l Item Selector"
|
||||
block-selector: "&0&l Block Selector"
|
||||
@ -212,7 +213,8 @@ challenges:
|
||||
name: "&f&l Deployment"
|
||||
description: |-
|
||||
&7 Toggle whether the challenge is
|
||||
&7 deployed and can be completed by users.
|
||||
&7 deployed and can be completed
|
||||
&7 by users.
|
||||
enabled: "&2 Enabled"
|
||||
disabled: "&c Disabled"
|
||||
name:
|
||||
@ -265,7 +267,8 @@ challenges:
|
||||
name: "&f&l Required Permissions"
|
||||
description: |-
|
||||
&7 Allows you to change the required
|
||||
&7 permissions for this challenge to be completed.
|
||||
&7 permissions for this challenge to
|
||||
&7 be completed.
|
||||
title: "&7 Permissions: "
|
||||
permission: " &8 - [permission]"
|
||||
none: "&7 No permissions are set."
|
||||
@ -273,15 +276,16 @@ challenges:
|
||||
name: "&f&l Remove Entities"
|
||||
description: |-
|
||||
&7 Toggle whether required entities will
|
||||
&7 be removed from the world after completing
|
||||
&7 the challenge.
|
||||
&7 be removed from the world after
|
||||
&7 completing the challenge.
|
||||
enabled: "&2 Enabled"
|
||||
disabled: "&c Disabled"
|
||||
required_entities:
|
||||
name: "&f&l Required Entities"
|
||||
description: |-
|
||||
&7 Allows you to change the required
|
||||
&7 entities for this challenge to be completed.
|
||||
&7 entities for this challenge to be
|
||||
&7 completed.
|
||||
title: "&7 Entities: "
|
||||
list: " &8 - [number] x [entity]"
|
||||
none: "&7 No entities have been added."
|
||||
@ -289,18 +293,28 @@ challenges:
|
||||
name: "&f&l Remove Blocks"
|
||||
description: |-
|
||||
&7 Toggle whether required blocks will
|
||||
&7 be removed from the world after completing
|
||||
&7 the challenge.
|
||||
&7 be removed from the world after
|
||||
&7 completing the challenge.
|
||||
enabled: "&2 Enabled"
|
||||
disabled: "&c Disabled"
|
||||
required_blocks:
|
||||
name: "&f&l Required Blocks"
|
||||
description: |-
|
||||
&7 Allows you to change the required
|
||||
&7 blocks for this challenge to be completed.
|
||||
&7 blocks for this challenge to be
|
||||
&7 completed.
|
||||
title: "&7 Blocks: "
|
||||
list: " &8 - [number] x [block]"
|
||||
none: "&7 No blocks have been added."
|
||||
required_statistics:
|
||||
name: "&f&l Required Statistics"
|
||||
description: |-
|
||||
&7 Allows you to change the required
|
||||
&7 statistics for this challenge to be
|
||||
&7 completed.
|
||||
title: "&7 Statistics: "
|
||||
list: " &8 - [name]"
|
||||
none: "&7 No statistics have been added."
|
||||
search_radius:
|
||||
name: "&f&l Search Radius"
|
||||
description: |-
|
||||
@ -312,8 +326,8 @@ challenges:
|
||||
name: "&f&l Remove Items"
|
||||
description: |-
|
||||
&7 Toggle whether required items will
|
||||
&7 be removed from the inventory after completing
|
||||
&7 the challenge.
|
||||
&7 be removed from the inventory after
|
||||
&7 completing the challenge.
|
||||
enabled: "&2 Enabled"
|
||||
disabled: "&c Disabled"
|
||||
required_items:
|
||||
@ -327,8 +341,9 @@ challenges:
|
||||
add_ignored_meta:
|
||||
name: "&f&l Add Ignore Metadata"
|
||||
description: |-
|
||||
&7 Allows you to specify which items should ignore
|
||||
&7 any metadata assigned to them.
|
||||
&7 Allows you to specify which items
|
||||
&7 should ignore any metadata
|
||||
&7 assigned to them.
|
||||
title: "&7 Items: "
|
||||
list: " &8 - [number] x [item]"
|
||||
none: "&7 No items have been added."
|
||||
@ -340,28 +355,31 @@ challenges:
|
||||
remove_experience:
|
||||
name: "&f&l Remove Experience"
|
||||
description: |-
|
||||
&7 Toggle whether the required experience will
|
||||
&7 be removed from the player after completing
|
||||
&7 Toggle whether the required
|
||||
&7 experience will be removed
|
||||
&7 from the player after completing
|
||||
&7 the challenge.
|
||||
enabled: "&2 Enabled"
|
||||
disabled: "&c Disabled"
|
||||
required_experience:
|
||||
name: "&f&l Required Experience"
|
||||
description: |-
|
||||
&7 Allows you to change the required experience for
|
||||
&7 the player.
|
||||
&7 Allows you to change the required
|
||||
&7 experience for the player.
|
||||
value: "&7 Current experience: &e [number]"
|
||||
required_level:
|
||||
name: "&f&l Required Island Level"
|
||||
description: |-
|
||||
&7 Allows you to change the required island level
|
||||
&7 Allows you to change the
|
||||
&7 required island level
|
||||
&7 for the challenge.
|
||||
value: "&7 Current level: &e [number]"
|
||||
required_materialtags:
|
||||
name: "&f&l Required Block Groups"
|
||||
description: |-
|
||||
&7 Allows you to change the required
|
||||
&7 block groups for this challenge to be completed.
|
||||
&7 block groups for this challenge to
|
||||
&7 be completed.
|
||||
title: "&7 Block group: "
|
||||
list: " &8 - [number] x [tag]"
|
||||
none: "&7 No block groups have been added."
|
||||
@ -369,57 +387,71 @@ challenges:
|
||||
name: "&f&l Required Entity Groups"
|
||||
description: |-
|
||||
&7 Allows you to change the required
|
||||
&7 entity groups for this challenge to be completed.
|
||||
&7 entity groups for this challenge to
|
||||
&7 be completed.
|
||||
title: "&7 Entity group: "
|
||||
list: " &8 - [number] x [tag]"
|
||||
none: "&7 No entity groups have been added."
|
||||
remove_money:
|
||||
name: "&f&l Remove Money"
|
||||
description: |-
|
||||
&7 Toggle whether the required money will
|
||||
&7 be removed from the player's account after completing
|
||||
&7 the challenge.
|
||||
&7 Toggle whether the required
|
||||
&7 money will be removed from
|
||||
&7 the player's account after
|
||||
&7 completing the challenge.
|
||||
enabled: "&2 Enabled"
|
||||
disabled: "&c Disabled"
|
||||
required_money:
|
||||
name: "&f&l Required Money"
|
||||
description: |-
|
||||
&7 Allows you to change the required money on the player's
|
||||
&7 Allows you to change the required
|
||||
&7 money on the player's
|
||||
&7 account for the challenge.
|
||||
value: "&7 Current value: &e [number]"
|
||||
statistic:
|
||||
name: "&f&l Statistic"
|
||||
description: |-
|
||||
&7 Allows you to change the statistic type that is
|
||||
&7 checked for this challenge.
|
||||
&7 Allows you to change the statistic
|
||||
&7 type that is checked for
|
||||
&7 this challenge.
|
||||
value: "&7 Current value: &e [statistic]"
|
||||
statistic_amount:
|
||||
name: "&f&l Target Value"
|
||||
description: |-
|
||||
&7 Allows you to change the target statistic value
|
||||
&7 Allows you to change the target
|
||||
&7 statistic value
|
||||
&7 that must be met.
|
||||
value: "&7 Current value: &e [number]"
|
||||
remove_statistic:
|
||||
name: "&f&l Reduce Statistic"
|
||||
add_statistic:
|
||||
name: "&f&l Add Statistic"
|
||||
description: |-
|
||||
&7 Toggle whether the statistic value will
|
||||
&7 be reduced after completing the challenge.
|
||||
&7 Allows you to add a new
|
||||
&7 statistic to the list.
|
||||
remove_statistic:
|
||||
name: "&f&l Remove Statistic"
|
||||
description: |-
|
||||
&7 Allows you to remove
|
||||
&7 selected statistics
|
||||
&7 from the list.
|
||||
enabled: "&2 Enabled"
|
||||
disabled: "&c Disabled"
|
||||
statistic_blocks:
|
||||
name: "&f&l Target Block"
|
||||
description: |-
|
||||
&7 Allows you to change the target block for the statistic.
|
||||
&7 Allows you to change the target
|
||||
&7 block for the statistic.
|
||||
value: "&7 Current block: &e [block]"
|
||||
statistic_items:
|
||||
name: "&f&l Target Item"
|
||||
description: |-
|
||||
&7 Allows you to change the target item for the statistic.
|
||||
&7 Allows you to change the target
|
||||
&7 item for the statistic.
|
||||
value: "&7 Current item: &e [item]"
|
||||
statistic_entities:
|
||||
name: "&f&l Target Entity"
|
||||
description: |-
|
||||
&7 Allows you to change the target entity for the statistic.
|
||||
&7 Allows you to change the target
|
||||
&7 entity for the statistic.
|
||||
value: "&7 Current entity: &e [entity]"
|
||||
reward_text:
|
||||
name: "&f&l Reward Text"
|
||||
@ -430,7 +462,8 @@ challenges:
|
||||
repeat_reward_text:
|
||||
name: "&f&l Repeat Reward Text"
|
||||
description: |-
|
||||
&7 Specifies the repeat reward text for the challenge.
|
||||
&7 Specifies the repeat reward
|
||||
&7 text for the challenge.
|
||||
&7 Color codes must be applied.
|
||||
value: "&7 Current text:"
|
||||
reward_items:
|
||||
@ -443,21 +476,22 @@ challenges:
|
||||
repeat_reward_items:
|
||||
name: "&f&l Repeat Reward Items"
|
||||
description: |-
|
||||
&7 Allows you to change the repeat reward items for this challenge.
|
||||
&7 Allows you to change the repeat
|
||||
&7 reward items for this challenge.
|
||||
title: "&7 Items: "
|
||||
list: " &8 - [number] x [item]"
|
||||
none: "&7 No items have been added."
|
||||
reward_experience:
|
||||
name: "&f&l Reward Experience"
|
||||
description: |-
|
||||
&7 Allows you to change the reward experience for
|
||||
&7 the player.
|
||||
&7 Allows you to change the reward
|
||||
& experience for the player.
|
||||
value: "&7 Reward experience: &e [number]"
|
||||
repeat_reward_experience:
|
||||
name: "&f&l Repeat Reward Experience"
|
||||
description: |-
|
||||
&7 Allows you to change the repeat reward experience
|
||||
&7 for the player.
|
||||
&7 Allows you to change the repeat
|
||||
&7 reward experience for the player.
|
||||
value: "&7 Reward experience: &e [number]"
|
||||
reward_money:
|
||||
name: "&f&l Reward Money"
|
||||
@ -467,8 +501,8 @@ challenges:
|
||||
repeat_reward_money:
|
||||
name: "&f&l Repeat Reward Money"
|
||||
description: |-
|
||||
&7 Allows you to change the repeat reward money
|
||||
&7 for the challenge.
|
||||
&7 Allows you to change the repeat
|
||||
&7 reward money for the challenge.
|
||||
value: "&7 Current value: &e [number]"
|
||||
reward_commands:
|
||||
name: "&f&l Reward Commands"
|
||||
@ -511,8 +545,9 @@ challenges:
|
||||
cool_down:
|
||||
name: "&f&l Cool Down"
|
||||
description: |-
|
||||
&7 Allows you to change the cooldown period (in seconds)
|
||||
&7 that must elapse between repeatable challenge completions.
|
||||
&7 Allows you to change the cooldown
|
||||
&7 period (in seconds) that must elapse
|
||||
&7 between repeatable challenge completions.
|
||||
value: "&7 Current value: &e [time]"
|
||||
challenges:
|
||||
name: "&f&l Challenges"
|
||||
@ -522,66 +557,79 @@ challenges:
|
||||
waiver_amount:
|
||||
name: "&f&l Waiver Amount"
|
||||
description: |-
|
||||
&7 Allows you to set the number of challenges that can
|
||||
&7 be left uncompleted to unlock the next level.
|
||||
&7 Allows you to set the number of challenges
|
||||
&7 that can be left uncompleted to unlock
|
||||
&7 the next level.
|
||||
value: "&7 Current value: &e [number]"
|
||||
add_challenges:
|
||||
name: "&f&l Add Challenge(-s)"
|
||||
description: |-
|
||||
&7 Allows you to select and add challenges to the level.
|
||||
&7 Allows you to select and add
|
||||
&7 challenges to the level.
|
||||
remove_challenges:
|
||||
name: "&f&l Remove Challenge(-s)"
|
||||
description: |-
|
||||
&7 Allows you to select and remove challenges from the level.
|
||||
&7 Allows you to select and remove
|
||||
&7 challenges from the level.
|
||||
reset_on_new:
|
||||
name: "&f&l Reset On New"
|
||||
description: |-
|
||||
&7 Toggle whether challenges should be reset when a user leaves
|
||||
&7 Toggle whether challenges should
|
||||
& be reset when a user leaves
|
||||
&7 their island or creates a new one.
|
||||
enabled: "&2 Enabled"
|
||||
disabled: "&c Disabled"
|
||||
broadcast:
|
||||
name: "&f&l Broadcast"
|
||||
description: |-
|
||||
&7 Broadcasts the first-time completion of a challenge or level to everyone.
|
||||
&7 Broadcasts the first-time completion
|
||||
&7 of a challenge or level to everyone.
|
||||
enabled: "&2 Enabled"
|
||||
disabled: "&c Disabled"
|
||||
remove_completed:
|
||||
name: "&f&l Hide Completed"
|
||||
description: |-
|
||||
&7 Hides completed challenges from the menu.
|
||||
&7 Hides completed challenges
|
||||
&7 from the menu.
|
||||
enabled: "&2 Enabled"
|
||||
disabled: "&c Disabled"
|
||||
glow_completed:
|
||||
name: "&f&l Glow Completed"
|
||||
description: |-
|
||||
&7 Applies an enchantment glow to completed challenges.
|
||||
&7 Applies an enchantment glow
|
||||
&7 to completed challenges.
|
||||
enabled: "&2 Enabled"
|
||||
disabled: "&c Disabled"
|
||||
store_history:
|
||||
name: "&f&l Store History"
|
||||
description: |-
|
||||
&7 Stores internal history each time a challenge is completed.
|
||||
&7 Currently viewable only in the database.
|
||||
&7 Stores internal history each time
|
||||
&7 a challenge is completed.
|
||||
&7 Currently viewable only in the
|
||||
&7 database.
|
||||
enabled: "&2 Enabled"
|
||||
disabled: "&c Disabled"
|
||||
data_per_island:
|
||||
name: "&f&l Store Per Island"
|
||||
description: |-
|
||||
&7 Stores completed challenges on a per-island basis.
|
||||
&7 Progress will be shared with all team members.
|
||||
&7 Stores completed challenges
|
||||
&7 on a per-island basis.
|
||||
&7 Progress will be shared
|
||||
&7 with all team members.
|
||||
enabled: "&2 Enabled"
|
||||
disabled: "&c Disabled"
|
||||
show_title:
|
||||
name: "&f&l Show Title"
|
||||
description: |-
|
||||
&7 Displays a title when a challenge or level is completed.
|
||||
&7 Displays a title when a challenge
|
||||
&7 or level is completed.
|
||||
enabled: "&2 Enabled"
|
||||
disabled: "&c Disabled"
|
||||
gamemode_gui:
|
||||
name: "&f&l GameMode Selection GUI"
|
||||
description: |-
|
||||
&7 Enables a single GUI accessible via the /challenges command.
|
||||
&7 Enables a single GUI accessible
|
||||
&7 via the /challenges command.
|
||||
&7 (Requires server restart.)
|
||||
enabled: "&2 Enabled"
|
||||
disabled: "&c Disabled"
|
||||
@ -593,20 +641,26 @@ challenges:
|
||||
purge_history:
|
||||
name: "&f&l History Lifetime"
|
||||
description: |-
|
||||
&7 Specifies the number of days that history data is stored
|
||||
&7 Specifies the number of days
|
||||
&7 that history data is stored
|
||||
&7 in user data.
|
||||
&7 A value of 0 means the data will not be removed.
|
||||
&7 A value of 0 means the data will
|
||||
&7 not be removed.
|
||||
value: "&7 Current value: &e [number]"
|
||||
title_showtime:
|
||||
name: "&f&l Title Showtime"
|
||||
description: |-
|
||||
&7 Number of ticks the title will be displayed to the player.
|
||||
&7 Number of ticks the title will
|
||||
& be displayed to the player.
|
||||
value: "&7 Current value: &e [number]"
|
||||
active_world_list:
|
||||
name: "&f&l Show Only Active World"
|
||||
description: |-
|
||||
&7 If the GameMode Selection GUI is enabled, this setting determines
|
||||
&7 whether the GUI displays the GameMode selection or challenges for the current world.
|
||||
&7 If the GameMode Selection GUI is
|
||||
&7 enabled, this setting determines
|
||||
&7 whether the GUI displays the
|
||||
&7 GameMode selection or challenges
|
||||
&7 for the current world.
|
||||
&7 (Requires server restart.)
|
||||
enabled: "&2 Enabled"
|
||||
disabled: "&c Disabled"
|
||||
@ -622,13 +676,15 @@ challenges:
|
||||
include_undeployed:
|
||||
name: "&f&l Include Undeployed Challenges"
|
||||
description: |-
|
||||
&7 Indicates whether undeployed challenges should be counted towards level completion.
|
||||
&7 Indicates whether undeployed challenges
|
||||
&7 should be counted towards level completion.
|
||||
enabled: "&2 Enabled"
|
||||
disabled: "&c Disabled"
|
||||
download:
|
||||
name: "&f&l Download Libraries"
|
||||
description: |-
|
||||
&7 Manually updates the available challenges libraries.
|
||||
&7 Manually updates the available
|
||||
&7 challenges libraries.
|
||||
enabled: "&2 With cache clear"
|
||||
disabled: "&c Without cache clear"
|
||||
player:
|
||||
@ -728,20 +784,24 @@ challenges:
|
||||
inventory_type:
|
||||
name: "&f&l Inventory Type"
|
||||
description: |-
|
||||
&7 Challenge that checks items in the player's inventory.
|
||||
&7 Challenge that checks items
|
||||
&7 in the player's inventory.
|
||||
island_type:
|
||||
name: "&f&l Island Type"
|
||||
description: |-
|
||||
&7 Challenge that checks blocks or entities around the player.
|
||||
&7 Challenge that checks blocks
|
||||
&7 or entities around the player.
|
||||
other_type:
|
||||
name: "&f&l Other Type"
|
||||
description: |-
|
||||
&7 Challenge that utilizes plugins or add-on features,
|
||||
&7 Challenge that utilizes plugins
|
||||
&7 or add-on features,
|
||||
&7 such as level and money.
|
||||
statistic_type:
|
||||
name: "&f&l Statistic Type"
|
||||
description: |-
|
||||
&7 Challenge that checks the player's statistic data.
|
||||
&7 Challenge that checks the
|
||||
&7 player's statistic data.
|
||||
save:
|
||||
name: "&f&l Save"
|
||||
description: |-
|
||||
@ -761,7 +821,17 @@ challenges:
|
||||
element: "&8 - [element]"
|
||||
statistic_element:
|
||||
name: "&f&l [statistic]"
|
||||
amount: "&7 Target Value: &e [number]"
|
||||
remove:
|
||||
name: "&7 Reduce Statistic: [value]"
|
||||
value:
|
||||
enabled: "&c Enabled"
|
||||
disabled: "&2 Disabled"
|
||||
block: "&7 Target Block: &e [block]"
|
||||
item: "&7 Target Item: &e [item]"
|
||||
entity: "&7 Target Entity: &e [entity]"
|
||||
description: "[description]"
|
||||
selected: "&2 Selected"
|
||||
environment_element:
|
||||
name: "&f&l [environment]"
|
||||
description: "[description]"
|
||||
|
Loading…
Reference in New Issue
Block a user