improve placeholders & add group requirement

removed:
%rankup_rank_requirement_<rank>_<requirement>_left%
%rankup_rank_requirement_<rank>_<requirement>_percent_left%
%rankup_rank_requirement_<rank>_<requirement>_percent_done%
This commit is contained in:
okx-code
2018-08-29 12:49:17 +01:00
parent 7b6a25d66e
commit b28842b43e
15 changed files with 131 additions and 90 deletions
+1 -1
View File
@@ -4,7 +4,7 @@ plugins {
} }
group 'sh.okx' group 'sh.okx'
version '3.0-alpha.14' version '3.0-alpha.15'
sourceCompatibility = 1.8 sourceCompatibility = 1.8
+9 -4
View File
@@ -26,6 +26,7 @@ import sh.okx.rankup.ranks.Rank;
import sh.okx.rankup.ranks.Rankups; import sh.okx.rankup.ranks.Rankups;
import sh.okx.rankup.ranks.requirements.MoneyRequirement; import sh.okx.rankup.ranks.requirements.MoneyRequirement;
import sh.okx.rankup.ranks.requirements.PlaytimeMinutesRequirement; import sh.okx.rankup.ranks.requirements.PlaytimeMinutesRequirement;
import sh.okx.rankup.ranks.requirements.GroupRequirement;
import sh.okx.rankup.ranks.requirements.Requirement; import sh.okx.rankup.ranks.requirements.Requirement;
import sh.okx.rankup.ranks.requirements.RequirementRegistry; import sh.okx.rankup.ranks.requirements.RequirementRegistry;
import sh.okx.rankup.ranks.requirements.XpLevelRequirement; import sh.okx.rankup.ranks.requirements.XpLevelRequirement;
@@ -144,6 +145,7 @@ public class Rankup extends JavaPlugin {
requirementRegistry.addRequirement(new MoneyRequirement(this, "money")); requirementRegistry.addRequirement(new MoneyRequirement(this, "money"));
requirementRegistry.addRequirement(new XpLevelRequirement(this, "xp-level")); requirementRegistry.addRequirement(new XpLevelRequirement(this, "xp-level"));
requirementRegistry.addRequirement(new PlaytimeMinutesRequirement(this, "playtime-minutes")); requirementRegistry.addRequirement(new PlaytimeMinutesRequirement(this, "playtime-minutes"));
requirementRegistry.addRequirement(new GroupRequirement(this, "group"));
} }
private void setupPermissions() { private void setupPermissions() {
@@ -244,7 +246,7 @@ public class Rankup extends JavaPlugin {
.replaceAll(player, rank, rankups.nextRank(rank)); .replaceAll(player, rank, rankups.nextRank(rank));
if (economy != null) { if (economy != null) {
double balance = economy.getBalance(player); double balance = economy.getBalance(player);
double amount = rank.getRequirement("money").getAmount(); double amount = rank.getRequirement("money").getValueDouble();
builder = builder builder = builder
.replace(Variable.MONEY, formatMoney(amount)) .replace(Variable.MONEY, formatMoney(amount))
.replace(Variable.MONEY_NEEDED, formatMoney(Math.max(0, amount - balance))); .replace(Variable.MONEY_NEEDED, formatMoney(Math.max(0, amount - balance)));
@@ -276,10 +278,13 @@ public class Rankup extends JavaPlugin {
DecimalFormat simpleFormat = placeholders.getSimpleFormat(); DecimalFormat simpleFormat = placeholders.getSimpleFormat();
DecimalFormat percentFormat = placeholders.getPercentFormat(); DecimalFormat percentFormat = placeholders.getPercentFormat();
for (Requirement requirement : rank.getRequirements()) { for (Requirement requirement : rank.getRequirements()) {
replaceRequirements(builder, Variable.AMOUNT, requirement, () -> simpleFormat.format(requirement.getAmount())); try {
replaceRequirements(builder, Variable.AMOUNT, requirement, () -> simpleFormat.format(requirement.getValueDouble()));
replaceRequirements(builder, Variable.AMOUNT_NEEDED, requirement, () -> simpleFormat.format(requirement.getRemaining(player))); replaceRequirements(builder, Variable.AMOUNT_NEEDED, requirement, () -> simpleFormat.format(requirement.getRemaining(player)));
replaceRequirements(builder, Variable.PERCENT_LEFT, requirement, () -> percentFormat.format(Math.max(0, (requirement.getRemaining(player) / requirement.getAmount()) * 100))); replaceRequirements(builder, Variable.PERCENT_LEFT, requirement, () -> percentFormat.format(Math.max(0, (requirement.getRemaining(player) / requirement.getValueDouble()) * 100)));
replaceRequirements(builder, Variable.PERCENT_DONE, requirement, () -> percentFormat.format(Math.min(100, (1 - (requirement.getRemaining(player) / requirement.getAmount())) * 100))); replaceRequirements(builder, Variable.PERCENT_DONE, requirement, () -> percentFormat.format(Math.min(100, (1 - (requirement.getRemaining(player) / requirement.getValueDouble())) * 100)));
} catch(NumberFormatException ignored) {
}
} }
} }
@@ -70,11 +70,11 @@ public class RankListCommand implements CommandExecutor {
} }
plugin.replaceRequirements((Player) sender, builder, rank); plugin.replaceRequirements((Player) sender, builder, rank);
} else { } else {
amount = money.getAmount(); amount = money.getValueDouble();
} }
if(amount != null && plugin.getEconomy() != null) { if(amount != null && plugin.getEconomy() != null) {
builder.replace(Variable.MONEY_NEEDED, plugin.formatMoney(amount)); builder.replace(Variable.MONEY_NEEDED, plugin.formatMoney(amount));
builder.replace(Variable.MONEY, plugin.formatMoney(money.getAmount())); builder.replace(Variable.MONEY, plugin.formatMoney(money.getValueDouble()));
} }
return builder; return builder;
@@ -36,67 +36,49 @@ public class Placeholders extends PlaceholderExpansion {
Rankups rankups = plugin.getRankups(); Rankups rankups = plugin.getRankups();
Rank rank = rankups.getRank(player); Rank rank = rankups.getRank(player);
Rank next = null; Rank next = rank == null ? null : rankups.nextRank(rank);
if (rank != null) {
next = rankups.nextRank(rank);
}
if (params.startsWith("requirement_")) { if (params.startsWith("requirement_")) {
String[] parts = params.split("_", 3); String[] parts = params.split("_", 3);
return getPlaceholderRequirement(player, rank, return getPlaceholderRequirement(player, rank,
parts[1], parts.length > 2 ? parts[2] : ""); parts[1], parts.length > 2 ? parts[2] : "");
} else if (params.startsWith("rank_requirement_")) { } else if (params.startsWith("rank_requirement_")) {
String[] parts = params.split("_", 5); String[] parts = params.split("_", 4);
return getPlaceholderRequirement(player, rankups.getRank(parts[2]), return simpleFormat.format(orElse(rankups.getRank(parts[2]).getRequirement(parts[3]), Requirement::getValueDouble, 0));
parts[3], parts.length > 4 ? parts[4] : "");
} else if(params.startsWith("rank_money_")) { } else if(params.startsWith("rank_money_")) {
String[] parts = params.split("_", 3); String[] parts = params.split("_", 3);
return moneyFormat.format(rankups.getRank(parts[2]).getRequirement("money").getAmount()); return moneyFormat.format(rankups.getRank(parts[2]).getRequirement("money").getValueDouble());
} else {
} }
switch (params) { switch (params) {
case "current_rank": case "current_rank":
return orElsePlaceholder(rank, Rank::getRank, "not-in-ladder"); return orElsePlaceholder(rank, Rank::getRank, "not-in-ladder");
case "current_rank_name": case "current_rank_name":
return orElsePlaceholder(rank, Rank::getRank, "not-in-ladder"); return orElsePlaceholder(rank, Rank::getName, "not-in-ladder");
case "current_rank_money": case "current_rank_money":
return String.valueOf(orElse(rank, r -> simplify(r.getRequirement("money").getAmount()), 0)); return String.valueOf(orElse(rank, r -> simplify(r.getRequirement("money").getValueDouble()), 0));
case "current_rank_money_formatted": case "current_rank_money_formatted":
return moneyFormat.format(orElse(rank, r -> r.getRequirement("money").getAmount(), 0)); return moneyFormat.format(orElse(rank, r -> r.getRequirement("money").getValueDouble(), 0));
case "next_rank": case "next_rank":
if (rank == null) { return orElsePlaceholder(rank, r -> orElsePlaceholder(next, Rank::getRank, "highest-rank"), "not-in-ladder");
return getPlaceholder("not-in-ladder");
} else if (next == null) {
return getPlaceholder("highest-rank");
} else {
return next.getRank();
}
case "next_rank_name": case "next_rank_name":
if (rank == null) { return orElsePlaceholder(rank, r -> orElsePlaceholder(next, Rank::getName, "highest-rank"), "not-in-ladder");
return getPlaceholder("not-in-ladder");
} else if (next == null) {
return getPlaceholder("highest-rank");
} else {
return next.getName();
}
case "money": case "money":
return String.valueOf(orElse(rank, r -> simplify(r.getRequirement("money").getAmount()), 0)); return String.valueOf(orElse(rank, r -> simplify(r.getRequirement("money").getValueDouble()), 0));
case "money_formatted": case "money_formatted":
return plugin.formatMoney(orElse(rank, r -> r.getRequirement("money").getAmount(), 0D)); return plugin.formatMoney(orElse(rank, r -> r.getRequirement("money").getValueDouble(), 0D));
case "money_left": case "money_left":
return String.valueOf(Math.max(0, orElse(rank, r -> simplify(plugin.getEconomy().getBalance(player) - r.getRequirement("money").getAmount()), 0).doubleValue())); return String.valueOf(Math.max(0, orElse(rank, r -> simplify(plugin.getEconomy().getBalance(player) - r.getRequirement("money").getValueDouble()), 0).doubleValue()));
case "money_left_formatted": case "money_left_formatted":
return plugin.formatMoney(Math.max(0D, orElse(rank, r -> plugin.getEconomy().getBalance(player) - r.getRequirement("money").getAmount(), 0D))); return plugin.formatMoney(Math.max(0D, orElse(rank, r -> plugin.getEconomy().getBalance(player) - r.getRequirement("money").getValueDouble(), 0D)));
case "percent_left": case "percent_left":
return String.valueOf(Math.max(0D, orElse(rank, r -> (1 - (plugin.getEconomy().getBalance(player) / r.getRequirement("money").getAmount())) * 100, 0).doubleValue())); return String.valueOf(Math.max(0D, orElse(rank, r -> (1 - (plugin.getEconomy().getBalance(player) / r.getRequirement("money").getValueDouble())) * 100, 0).doubleValue()));
case "percent_left_formatted": case "percent_left_formatted":
return percentFormat.format(Math.max(0D, orElse(rank, r -> (1 - (plugin.getEconomy().getBalance(player) / r.getRequirement("money").getAmount())) * 100, 0).doubleValue())); return percentFormat.format(Math.max(0D, orElse(rank, r -> (1 - (plugin.getEconomy().getBalance(player) / r.getRequirement("money").getValueDouble())) * 100, 0).doubleValue()));
case "percent_done": case "percent_done":
return String.valueOf(Math.min(100D, orElse(rank, r -> (plugin.getEconomy().getBalance(player) / r.getRequirement("money").getAmount()) * 100, 0).doubleValue())); return String.valueOf(Math.min(100D, orElse(rank, r -> (plugin.getEconomy().getBalance(player) / r.getRequirement("money").getValueDouble()) * 100, 0).doubleValue()));
case "percent_done_formatted": case "percent_done_formatted":
return percentFormat.format(Math.min(100D, orElse(rank, r -> (plugin.getEconomy().getBalance(player) / r.getRequirement("money").getAmount()) * 100, 0).doubleValue())); return percentFormat.format(Math.min(100D, orElse(rank, r -> (plugin.getEconomy().getBalance(player) / r.getRequirement("money").getValueDouble()) * 100, 0).doubleValue()));
default: default:
return null; return null;
} }
@@ -109,13 +91,13 @@ public class Placeholders extends PlaceholderExpansion {
Requirement requirement = rank.getRequirement(requirementName); Requirement requirement = rank.getRequirement(requirementName);
switch (params) { switch (params) {
case "": case "":
return simpleFormat.format(orElse(requirement, Requirement::getAmount, 0)); return simpleFormat.format(orElse(requirement, Requirement::getValueDouble, 0));
case "left": case "left":
return simpleFormat.format(orElse(requirement, r -> r.getRemaining(player), 0)); return simpleFormat.format(orElse(requirement, r -> r.getRemaining(player), 0));
case "percent_left": case "percent_left":
return percentFormat.format(orElse(requirement, r -> (r.getRemaining(player) / r.getAmount()) * 100, 0)); return percentFormat.format(orElse(requirement, r -> (r.getRemaining(player) / r.getValueDouble()) * 100, 0));
case "percent_done": case "percent_done":
return percentFormat.format(orElse(requirement, r -> (1 - (r.getRemaining(player) / r.getAmount())) * 100, 100)); return percentFormat.format(orElse(requirement, r -> (1 - (r.getRemaining(player) / r.getValueDouble())) * 100, 100));
default: default:
return null; return null;
} }
+6 -4
View File
@@ -9,6 +9,7 @@ import org.bukkit.entity.Player;
import sh.okx.rankup.Rankup; import sh.okx.rankup.Rankup;
import sh.okx.rankup.messages.MessageBuilder; import sh.okx.rankup.messages.MessageBuilder;
import sh.okx.rankup.messages.Variable; import sh.okx.rankup.messages.Variable;
import sh.okx.rankup.ranks.requirements.DeductibleRequirement;
import sh.okx.rankup.ranks.requirements.Requirement; import sh.okx.rankup.ranks.requirements.Requirement;
import java.util.HashSet; import java.util.HashSet;
@@ -40,9 +41,8 @@ public class Rank {
if(requirementsSection != null) { if(requirementsSection != null) {
for (Map.Entry<String, Object> entry : requirementsSection.getValues(false).entrySet()) { for (Map.Entry<String, Object> entry : requirementsSection.getValues(false).entrySet()) {
String name = entry.getKey(); String name = entry.getKey();
double amount = Double.parseDouble(String.valueOf(entry.getValue()).replace(",", "")); String value = String.valueOf(entry.getValue());
Requirement requirement = plugin.getRequirementRegistry().newRequirement(name, value);
Requirement requirement = plugin.getRequirementRegistry().newRequirement(name, amount);
if (requirement == null) { if (requirement == null) {
plugin.getLogger().warning("Unknown requirement " + name); plugin.getLogger().warning("Unknown requirement " + name);
} else { } else {
@@ -113,7 +113,9 @@ public class Rank {
public void applyRequirements(Player player) { public void applyRequirements(Player player) {
for(Requirement requirement : requirements) { for(Requirement requirement : requirements) {
requirement.apply(player); if(requirement instanceof DeductibleRequirement) {
((DeductibleRequirement) requirement).apply(player);
}
} }
} }
@@ -0,0 +1,23 @@
package sh.okx.rankup.ranks.requirements;
import org.bukkit.entity.Player;
import sh.okx.rankup.Rankup;
public abstract class DeductibleRequirement extends Requirement {
public DeductibleRequirement(Rankup plugin, String name) {
super(plugin, name);
}
protected DeductibleRequirement(Requirement clone) {
super(clone);
}
/**
* Apply the effect of this requirement to the player.
* For money, this could be taking money away from the player.
* You can assume that <code>Requirement#check(Player)</code> has been called,
* and has returned true immediately prior to this.
* @param player the player to take from
*/
public abstract void apply(Player player);
}
@@ -0,0 +1,33 @@
package sh.okx.rankup.ranks.requirements;
import org.bukkit.entity.Player;
import sh.okx.rankup.Rankup;
public class GroupRequirement extends Requirement {
public GroupRequirement(Rankup plugin, String name) {
super(plugin, name);
}
protected GroupRequirement(Requirement clone) {
super(clone);
}
@Override
public boolean check(Player player) {
OUTER:
for(String requiredGroup : getValueString().split(" ")) {
for(String group : plugin.getPermissions().getPlayerGroups(player)) {
if(group.equalsIgnoreCase(requiredGroup)) {
continue OUTER;
}
}
return false;
}
return true;
}
@Override
public Requirement clone() {
return new GroupRequirement(this);
}
}
@@ -4,7 +4,7 @@ import net.milkbowl.vault.economy.Economy;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import sh.okx.rankup.Rankup; import sh.okx.rankup.Rankup;
public class MoneyRequirement extends Requirement { public class MoneyRequirement extends DeductibleRequirement {
public MoneyRequirement(Rankup plugin, String name) { public MoneyRequirement(Rankup plugin, String name) {
super(plugin, name); super(plugin, name);
} }
@@ -17,18 +17,18 @@ public class MoneyRequirement extends Requirement {
public boolean check(Player player) { public boolean check(Player player) {
Economy economy = plugin.getEconomy(); Economy economy = plugin.getEconomy();
double balance = economy.getBalance(player); double balance = economy.getBalance(player);
return balance >= amount; return balance >= getValueDouble();
} }
@Override @Override
public void apply(Player player) { public void apply(Player player) {
Economy economy = plugin.getEconomy(); Economy economy = plugin.getEconomy();
economy.withdrawPlayer(player, amount); economy.withdrawPlayer(player, getValueDouble());
} }
@Override @Override
public double getRemaining(Player player) { public double getRemaining(Player player) {
return Math.max(0, amount - plugin.getEconomy().getBalance(player)); return Math.max(0, getValueDouble() - plugin.getEconomy().getBalance(player));
} }
@Override @Override
@@ -25,17 +25,12 @@ public class PlaytimeMinutesRequirement extends Requirement {
@Override @Override
public boolean check(Player player) { public boolean check(Player player) {
return player.getStatistic(playOneTick) * TICKS_PER_MINUTE >= amount; return player.getStatistic(playOneTick) * TICKS_PER_MINUTE >= getValueDouble();
}
@Override
public void apply(Player player) {
// well, we can't really take hours of playtime away, can we?
} }
@Override @Override
public double getRemaining(Player player) { public double getRemaining(Player player) {
return Math.max(0, amount - (player.getStatistic(playOneTick) * TICKS_PER_MINUTE)); return Math.max(0, getValueDouble() - (player.getStatistic(playOneTick) * TICKS_PER_MINUTE));
} }
@Override @Override
@@ -9,9 +9,7 @@ public abstract class Requirement implements Cloneable {
protected Rankup plugin; protected Rankup plugin;
@Getter @Getter
protected String name; protected String name;
@Getter private String value;
@Setter
protected double amount;
public Requirement(Rankup plugin, String name) { public Requirement(Rankup plugin, String name) {
this.plugin = plugin; this.plugin = plugin;
@@ -22,10 +20,27 @@ public abstract class Requirement implements Cloneable {
if (clone != null) { if (clone != null) {
this.plugin = clone.plugin; this.plugin = clone.plugin;
this.name = clone.name; this.name = clone.name;
this.amount = clone.amount; this.value = clone.value;
} }
} }
public void setValue(String value) {
this.value = value;
}
public String getValueString() {
return value;
}
public double getValueDouble() {
return Double.parseDouble(value);
}
public int getValueInt() {
return Integer.parseInt(value);
}
/** /**
* Check if a player meets this requirement * Check if a player meets this requirement
* @param player the player to check * @param player the player to check
@@ -33,15 +48,6 @@ public abstract class Requirement implements Cloneable {
*/ */
public abstract boolean check(Player player); public abstract boolean check(Player player);
/**
* Apply the effect of this requirement to the player.
* For money, this could be taking money away from the player.
* You can assume that <code>Requirement#check(Player)</code> has been called,
* and has returned true immediately prior to this.
* @param player the player to take from
*/
public abstract void apply(Player player);
/** /**
* Get the remaining amount needed for <code>Requirement#check(Player)</code> to yield true. * Get the remaining amount needed for <code>Requirement#check(Player)</code> to yield true.
* This is not required and is only used in placeholders. * This is not required and is only used in placeholders.
@@ -49,7 +55,7 @@ public abstract class Requirement implements Cloneable {
* @return the remaining amount needed. Should be non-negative. * @return the remaining amount needed. Should be non-negative.
*/ */
public double getRemaining(Player player) { public double getRemaining(Player player) {
return amount; return getValueDouble();
} }
public abstract Requirement clone(); public abstract Requirement clone();
} }
@@ -10,11 +10,11 @@ public class RequirementRegistry {
requirements.add(requirement); requirements.add(requirement);
} }
public Requirement newRequirement(String name, double amount) { public Requirement newRequirement(String name, String value) {
for(Requirement requirement : requirements) { for(Requirement requirement : requirements) {
if(requirement.getName().equalsIgnoreCase(name)) { if(requirement.getName().equalsIgnoreCase(name)) {
Requirement newRequirement = requirement.clone(); Requirement newRequirement = requirement.clone();
newRequirement.setAmount(amount); newRequirement.setValue(value);
return newRequirement; return newRequirement;
} }
} }
@@ -3,7 +3,7 @@ package sh.okx.rankup.ranks.requirements;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import sh.okx.rankup.Rankup; import sh.okx.rankup.Rankup;
public class XpLevelRequirement extends Requirement { public class XpLevelRequirement extends DeductibleRequirement {
public XpLevelRequirement(Rankup plugin, String name) { public XpLevelRequirement(Rankup plugin, String name) {
super(plugin, name); super(plugin, name);
} }
@@ -12,25 +12,19 @@ public class XpLevelRequirement extends Requirement {
super(clone); super(clone);
} }
@Override
public void setAmount(double amount) {
// experience level should be a whole number
super.setAmount(Math.round(amount));
}
@Override @Override
public boolean check(Player player) { public boolean check(Player player) {
return player.getLevel() >= amount; return player.getLevel() >= getValueInt();
} }
@Override @Override
public void apply(Player player) { public void apply(Player player) {
player.setLevel(player.getLevel() - (int) amount); player.setLevel(player.getLevel() - getValueInt());
} }
@Override @Override
public double getRemaining(Player player) { public double getRemaining(Player player) {
return Math.max(0, amount - player.getLevel()); return Math.max(0, getValueInt() - player.getLevel());
} }
@Override @Override
+1 -1
View File
@@ -49,7 +49,7 @@ placeholders:
percent-format: "0.##" percent-format: "0.##"
# the format used for requirements # the format used for requirements
simple-format: "#.##" simple-format: "#.##"
# used for current_rank and next_rank placeholders when a player not in anything in rankups.yml # used for current_rank and next_rank placeholders when a player is not in anything in rankups.yml
not-in-ladder: "None" not-in-ladder: "None"
# used in next_rank placeholders when there is no rankup # used in next_rank placeholders when there is no rankup
highest-rank: "None" highest-rank: "None"
+1 -1
View File
@@ -1,5 +1,5 @@
name: Rankup name: Rankup
version: 3.0-alpha.14 version: 3.0-alpha.15
main: sh.okx.rankup.Rankup main: sh.okx.rankup.Rankup
author: Okx author: Okx
depend: [Vault] depend: [Vault]
+1
View File
@@ -11,6 +11,7 @@ Aexample:
# money: money from the server economy # money: money from the server economy
# xp-level: amount of experience levels # xp-level: amount of experience levels
# playtime-minutes: minutes a player has played # playtime-minutes: minutes a player has played
# group: requires a player to have a certain group - separate by spaces to require multiple. note that the group is not removed.
# custom requirements can also be added by other plugins. # custom requirements can also be added by other plugins.
requirements: requirements:
money: 1000 money: 1000