mirror of https://github.com/mcMMO-Dev/mcMMO.git
Compare commits
17 Commits
1127dfe553
...
1bcca99c2d
Author | SHA1 | Date |
---|---|---|
Prestley | 1bcca99c2d | |
nossr50 | 4d98d25215 | |
nossr50 | ffc6061f8b | |
nossr50 | 0363ee2e90 | |
nossr50 | b6e512b09e | |
nossr50 | aecf17a2a2 | |
nossr50 | c769813892 | |
nossr50 | e509876658 | |
nossr50 | a047bca94c | |
nossr50 | b5a50da09b | |
nossr50 | 2d79b364db | |
Robert Alan Chapton | 657d7cafa7 | |
nossr50 | d92c60fc84 | |
nossr50 | b56ddebde8 | |
nossr50 | cf49fc7599 | |
cj89898 | 618dfa94fc | |
cj89898 | 6fd4dd1403 |
|
@ -1,3 +1,39 @@
|
||||||
|
Version 2.2.006
|
||||||
|
Updated outdated wiki URLs in commands to point to the new wiki
|
||||||
|
Removed the msg about skills being migrated to a new system when using /mmoinfo command
|
||||||
|
Added new config custom_item_support.yml
|
||||||
|
Added setting to disable repair on items with custom models, this is not on by default
|
||||||
|
Added new locale entry 'Anvil.Repair.Reject.CustomModelData'
|
||||||
|
Added new locale entry 'Anvil.Salvage.Reject.CustomModelData'
|
||||||
|
|
||||||
|
NOTES:
|
||||||
|
Let me know in detail what kind of support you'd like to see in mcMMO regarding custom items, I'm open to suggestions.
|
||||||
|
This update adds a new config file to allow server owners to disable repair or salvage on items with custom models,
|
||||||
|
This prevention mechanism is not enabled by default, change the settings in custom_item_support.yml if you want to enable it.
|
||||||
|
This feature is off by default for now to keep compatibility with existing servers, but it may be enabled by default in the future if feedback suggests it should be.
|
||||||
|
As a reminder, anyone can update the wiki by clicking on the "edit on github" link on various pages, this will take you to the wiki's source code on GitHub, submit a PR to make changes
|
||||||
|
|
||||||
|
Version 2.2.005
|
||||||
|
Fixed a bug where certain skills such as Dodge/Arrow Deflect had no skill cap and would continue improving forever
|
||||||
|
Reduced messages on startup for SQL DB
|
||||||
|
(API) Constructor for ProbabilityImpl now takes a raw value between 0 and 1 instead of an inflated percentage
|
||||||
|
(API) Added some convenience methods to Probability, and ProbabilityUtil classes
|
||||||
|
(Codebase) Added more unit tests revolving around Probability/RNG
|
||||||
|
|
||||||
|
Version 2.2.004
|
||||||
|
Fixed bug where values from Experience_Formula.Skill_Multiplier were not functioning
|
||||||
|
|
||||||
|
NOTES:
|
||||||
|
A reminder that these values are multipliers and no longer divisors, if you want 10x lower XP, a value of .1 would do the job.
|
||||||
|
|
||||||
|
Version 2.2.003
|
||||||
|
(SQLDB) Fixed a bug where lastlogin was using a value that was too large
|
||||||
|
(SQLDB) Fixed bug where crossbows was not getting added to SQL schema for some users
|
||||||
|
|
||||||
|
Version 2.2.002
|
||||||
|
Fixed bug where thrown tridents did not grant XP or benefit from subskills
|
||||||
|
Fixed bug where trickshot marked bounced arrows as being shot from a bow instead of being shot from a crossbow
|
||||||
|
|
||||||
Version 2.2.001
|
Version 2.2.001
|
||||||
Fixed Crossbow's Powered shot showing the text for the wrong skill from the locale when using /crossbows command
|
Fixed Crossbow's Powered shot showing the text for the wrong skill from the locale when using /crossbows command
|
||||||
|
|
||||||
|
|
16
README.md
16
README.md
|
@ -10,6 +10,22 @@ Spigot Resource: https://spigot.mcmmo.org
|
||||||
|
|
||||||
I plan to post links to our new wiki (its still under development), downloads, and dev blogs there.
|
I plan to post links to our new wiki (its still under development), downloads, and dev blogs there.
|
||||||
|
|
||||||
|
## API
|
||||||
|
If you are using maven, you can add mcMMO API to your plugin by adding it to pom.xml like so...
|
||||||
|
|
||||||
|
```
|
||||||
|
<repository>
|
||||||
|
<id>neetgames</id>
|
||||||
|
<url>https://nexus.neetgames.com/repository/maven-releases/</url>
|
||||||
|
</repository>
|
||||||
|
```
|
||||||
|
```
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.gmail.nossr50.mcMMO</groupId>
|
||||||
|
<artifactId>mcMMO</artifactId>
|
||||||
|
<version>2.2.004</version>
|
||||||
|
</dependency>
|
||||||
|
```
|
||||||
### Builds
|
### Builds
|
||||||
Currently, you can obtain our builds via the Spigot or Polymart:
|
Currently, you can obtain our builds via the Spigot or Polymart:
|
||||||
|
|
||||||
|
|
2
pom.xml
2
pom.xml
|
@ -2,7 +2,7 @@
|
||||||
<modelVersion>4.0.0</modelVersion>
|
<modelVersion>4.0.0</modelVersion>
|
||||||
<groupId>com.gmail.nossr50.mcMMO</groupId>
|
<groupId>com.gmail.nossr50.mcMMO</groupId>
|
||||||
<artifactId>mcMMO</artifactId>
|
<artifactId>mcMMO</artifactId>
|
||||||
<version>2.2.001</version>
|
<version>2.2.006-SNAPSHOT</version>
|
||||||
<name>mcMMO</name>
|
<name>mcMMO</name>
|
||||||
<url>https://github.com/mcMMO-Dev/mcMMO</url>
|
<url>https://github.com/mcMMO-Dev/mcMMO</url>
|
||||||
<scm>
|
<scm>
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
package com.gmail.nossr50.commands.skills;
|
package com.gmail.nossr50.commands.skills;
|
||||||
|
|
||||||
import com.gmail.nossr50.datatypes.skills.SubSkillType;
|
import com.gmail.nossr50.datatypes.skills.SubSkillType;
|
||||||
import com.gmail.nossr50.listeners.InteractionManager;
|
|
||||||
import com.gmail.nossr50.locale.LocaleLoader;
|
import com.gmail.nossr50.locale.LocaleLoader;
|
||||||
import com.gmail.nossr50.mcMMO;
|
import com.gmail.nossr50.mcMMO;
|
||||||
import com.gmail.nossr50.util.Permissions;
|
import com.gmail.nossr50.util.Permissions;
|
||||||
|
@ -29,14 +28,11 @@ public class MmoInfoCommand implements TabExecutor {
|
||||||
*/
|
*/
|
||||||
if(commandSender instanceof Player player)
|
if(commandSender instanceof Player player)
|
||||||
{
|
{
|
||||||
if(args.length < 1)
|
if(args == null || args.length < 1 || args[0] == null || args[0].isEmpty())
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if(Permissions.mmoinfo(player))
|
if(Permissions.mmoinfo(player))
|
||||||
{
|
{
|
||||||
if(args == null || args[0] == null)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
if(args[0].equalsIgnoreCase( "???"))
|
if(args[0].equalsIgnoreCase( "???"))
|
||||||
{
|
{
|
||||||
player.sendMessage(LocaleLoader.getString("Commands.MmoInfo.Header"));
|
player.sendMessage(LocaleLoader.getString("Commands.MmoInfo.Header"));
|
||||||
|
@ -44,14 +40,15 @@ public class MmoInfoCommand implements TabExecutor {
|
||||||
player.sendMessage(LocaleLoader.getString("Commands.MmoInfo.DetailsHeader"));
|
player.sendMessage(LocaleLoader.getString("Commands.MmoInfo.DetailsHeader"));
|
||||||
player.sendMessage(LocaleLoader.getString("Commands.MmoInfo.Mystery"));
|
player.sendMessage(LocaleLoader.getString("Commands.MmoInfo.Mystery"));
|
||||||
return true;
|
return true;
|
||||||
} else if(InteractionManager.getAbstractByName(args[0]) != null || mcMMO.p.getSkillTools().EXACT_SUBSKILL_NAMES.contains(args[0]))
|
|
||||||
{
|
|
||||||
displayInfo(player, args[0]);
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//Not a real skill
|
final SubSkillType subSkillType = matchSubSkill(args[0]);
|
||||||
player.sendMessage(LocaleLoader.getString("Commands.MmoInfo.NoMatch"));
|
if (subSkillType != null) {
|
||||||
|
displayInfo(player, subSkillType);
|
||||||
|
} else {
|
||||||
|
//Not a real skill
|
||||||
|
player.sendMessage(LocaleLoader.getString("Commands.MmoInfo.NoMatch"));
|
||||||
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -59,6 +56,16 @@ public class MmoInfoCommand implements TabExecutor {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public SubSkillType matchSubSkill(String name) {
|
||||||
|
for(SubSkillType subSkillType : SubSkillType.values())
|
||||||
|
{
|
||||||
|
if(subSkillType.getNiceNameNoSpaces(subSkillType).equalsIgnoreCase(name)
|
||||||
|
|| subSkillType.name().equalsIgnoreCase(name))
|
||||||
|
return subSkillType;
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<String> onTabComplete(@NotNull CommandSender sender, @NotNull Command command, @NotNull String alias, String[] args) {
|
public List<String> onTabComplete(@NotNull CommandSender sender, @NotNull Command command, @NotNull String alias, String[] args) {
|
||||||
if (args.length == 1) {
|
if (args.length == 1) {
|
||||||
|
@ -67,20 +74,13 @@ public class MmoInfoCommand implements TabExecutor {
|
||||||
return ImmutableList.of();
|
return ImmutableList.of();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void displayInfo(Player player, String subSkillName)
|
private void displayInfo(Player player, SubSkillType subSkillType)
|
||||||
{
|
{
|
||||||
player.sendMessage(LocaleLoader.getString("Commands.MmoInfo.Header"));
|
player.sendMessage(LocaleLoader.getString("Commands.MmoInfo.Header"));
|
||||||
player.sendMessage(LocaleLoader.getString("Commands.MmoInfo.SubSkillHeader", subSkillName));
|
player.sendMessage(LocaleLoader.getString("Commands.MmoInfo.SubSkillHeader", subSkillType.getLocaleName()));
|
||||||
player.sendMessage(LocaleLoader.getString("Commands.MmoInfo.DetailsHeader"));
|
player.sendMessage(LocaleLoader.getString("Commands.MmoInfo.DetailsHeader"));
|
||||||
player.sendMessage(LocaleLoader.getString("Commands.MmoInfo.OldSkill"));
|
|
||||||
|
|
||||||
for(SubSkillType subSkillType : SubSkillType.values())
|
|
||||||
{
|
|
||||||
if(subSkillType.getNiceNameNoSpaces(subSkillType).equalsIgnoreCase(subSkillName))
|
|
||||||
subSkillName = subSkillType.getWikiName(subSkillType.toString());
|
|
||||||
}
|
|
||||||
|
|
||||||
//Send Player Wiki Link
|
//Send Player Wiki Link
|
||||||
TextComponentFactory.sendPlayerSubSkillWikiLink(player, subSkillName);
|
TextComponentFactory.sendPlayerSubSkillWikiLink(player, subSkillType.getLocaleName(), subSkillType);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,23 @@
|
||||||
|
package com.gmail.nossr50.config;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
|
||||||
|
public class CustomItemSupportConfig extends BukkitConfig {
|
||||||
|
public CustomItemSupportConfig(File dataFolder) {
|
||||||
|
super("custom_item_support.yml", dataFolder);
|
||||||
|
validate();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void loadKeys() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isCustomRepairAllowed() {
|
||||||
|
return config.getBoolean("Custom_Item_Support.Repair.Allow_Repair_On_Items_With_Custom_Model_Data", true);
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isCustomSalvageAllowed() {
|
||||||
|
return config.getBoolean("Custom_Item_Support.Salvage.Allow_Salvage_On_Items_With_Custom_Model_Data", true);
|
||||||
|
}
|
||||||
|
}
|
|
@ -260,7 +260,7 @@ public class ExperienceConfig extends BukkitConfig {
|
||||||
|
|
||||||
/* Skill modifiers */
|
/* Skill modifiers */
|
||||||
public double getFormulaSkillModifier(PrimarySkillType skill) {
|
public double getFormulaSkillModifier(PrimarySkillType skill) {
|
||||||
return config.getDouble("Experience_Formula.Modifier." + StringUtils.getCapitalized(skill.toString()), 1);
|
return config.getDouble("Experience_Formula.Skill_Multiplier." + StringUtils.getCapitalized(skill.toString()), 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Custom XP perk */
|
/* Custom XP perk */
|
||||||
|
|
|
@ -578,13 +578,9 @@ public final class SQLDatabaseManager implements DatabaseManager {
|
||||||
statement.executeUpdate();
|
statement.executeUpdate();
|
||||||
statement.close();
|
statement.close();
|
||||||
|
|
||||||
long currentTimeMillis = System.currentTimeMillis();
|
statement = connection.prepareStatement("INSERT INTO " + tablePrefix + "users (user, uuid, lastlogin) VALUES (?, ?, UNIX_TIMESTAMP())", Statement.RETURN_GENERATED_KEYS);
|
||||||
|
|
||||||
String sql = "INSERT INTO " + tablePrefix + "users (`user`, uuid, lastlogin) VALUES (?, ?, ?)";
|
|
||||||
statement = connection.prepareStatement(sql, Statement.RETURN_GENERATED_KEYS);
|
|
||||||
statement.setString(1, playerName);
|
statement.setString(1, playerName);
|
||||||
statement.setString(2, uuid != null ? uuid.toString() : null);
|
statement.setString(2, uuid != null ? uuid.toString() : null);
|
||||||
statement.setLong(3, currentTimeMillis);
|
|
||||||
statement.executeUpdate();
|
statement.executeUpdate();
|
||||||
|
|
||||||
resultSet = statement.getGeneratedKeys();
|
resultSet = statement.getGeneratedKeys();
|
||||||
|
@ -1038,19 +1034,41 @@ public final class SQLDatabaseManager implements DatabaseManager {
|
||||||
}
|
}
|
||||||
|
|
||||||
private void updateStructure(String tableName, String columnName, String columnSize) {
|
private void updateStructure(String tableName, String columnName, String columnSize) {
|
||||||
try (Connection connection = getConnection(PoolIdentifier.MISC);
|
try (Connection connection = getConnection(PoolIdentifier.MISC)) {
|
||||||
Statement createStatement = connection.createStatement()) {
|
if (!columnExists(connection, mcMMO.p.getGeneralConfig().getMySQLDatabaseName(), tablePrefix+tableName, columnName)) {
|
||||||
|
try (Statement createStatement = connection.createStatement()) {
|
||||||
String startingLevel = "'" + mcMMO.p.getAdvancedConfig().getStartingLevel() + "'";
|
// logger.info("[SQLDB Check] Adding column '" + columnName + "' to table '" + tablePrefix + tableName + "'...");
|
||||||
createStatement.executeUpdate("ALTER TABLE `" + tablePrefix + tableName + "` "
|
String startingLevel = "'" + mcMMO.p.getAdvancedConfig().getStartingLevel() + "'";
|
||||||
+ "ADD COLUMN IF NOT EXISTS `" + columnName + "` int(" + columnSize + ") unsigned NOT NULL DEFAULT " + startingLevel);
|
createStatement.executeUpdate("ALTER TABLE `" + tablePrefix + tableName + "` "
|
||||||
|
+ "ADD COLUMN `" + columnName + "` int(" + columnSize + ") unsigned NOT NULL DEFAULT " + startingLevel);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// logger.info("[SQLDB Check] Column '" + columnName + "' already exists in table '" + tablePrefix + tableName + "', looks good!");
|
||||||
|
}
|
||||||
} catch (SQLException e) {
|
} catch (SQLException e) {
|
||||||
e.printStackTrace(); // Consider more robust logging
|
e.printStackTrace(); // Consider more robust logging
|
||||||
throw new RuntimeException(e);
|
throw new RuntimeException(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private boolean columnExists(Connection connection, String database, String tableName, String columnName) throws SQLException {
|
||||||
|
// logger.info("[SQLDB Check] Checking if column '" + columnName + "' exists in table '" + tableName + "'");
|
||||||
|
try (Statement createStatement = connection.createStatement()) {
|
||||||
|
String sql = "SELECT `COLUMN_NAME`\n" +
|
||||||
|
"FROM `INFORMATION_SCHEMA`.`COLUMNS`\n" +
|
||||||
|
"WHERE `TABLE_SCHEMA`='" + database + "'\n" +
|
||||||
|
" AND `TABLE_NAME`='" + tableName + "'\n" +
|
||||||
|
" AND `COLUMN_NAME`='" + columnName + "'";
|
||||||
|
var resultSet = createStatement.executeQuery(sql);
|
||||||
|
return resultSet.next();
|
||||||
|
} catch (SQLException e) {
|
||||||
|
logger.info("Failed to check if column exists in table " + tableName + " for column " + columnName);
|
||||||
|
e.printStackTrace();
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
private void setStatementQuery(PreparedStatement statement, String tableName) throws SQLException {
|
private void setStatementQuery(PreparedStatement statement, String tableName) throws SQLException {
|
||||||
if (!this.h2) {
|
if (!this.h2) {
|
||||||
// Set schema name for MySQL
|
// Set schema name for MySQL
|
||||||
|
|
|
@ -65,6 +65,7 @@ import org.bukkit.plugin.Plugin;
|
||||||
import org.checkerframework.checker.nullness.qual.NonNull;
|
import org.checkerframework.checker.nullness.qual.NonNull;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
import org.jetbrains.annotations.VisibleForTesting;
|
||||||
|
|
||||||
import java.util.EnumMap;
|
import java.util.EnumMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
@ -840,14 +841,15 @@ public class McMMOPlayer implements Identified {
|
||||||
* @param xp Experience amount to process
|
* @param xp Experience amount to process
|
||||||
* @return Modified experience
|
* @return Modified experience
|
||||||
*/
|
*/
|
||||||
private float modifyXpGain(PrimarySkillType primarySkillType, float xp) {
|
@VisibleForTesting
|
||||||
|
float modifyXpGain(PrimarySkillType primarySkillType, float xp) {
|
||||||
//TODO: A rare situation can occur where the default Power Level cap can prevent a player with one skill edited to something silly like Integer.MAX_VALUE from gaining XP in any skill, we may need to represent power level with another data type
|
//TODO: A rare situation can occur where the default Power Level cap can prevent a player with one skill edited to something silly like Integer.MAX_VALUE from gaining XP in any skill, we may need to represent power level with another data type
|
||||||
if ((mcMMO.p.getSkillTools().getLevelCap(primarySkillType) <= getSkillLevel(primarySkillType))
|
if ((mcMMO.p.getSkillTools().getLevelCap(primarySkillType) <= getSkillLevel(primarySkillType))
|
||||||
|| (mcMMO.p.getGeneralConfig().getPowerLevelCap() <= getPowerLevel())) {
|
|| (mcMMO.p.getGeneralConfig().getPowerLevelCap() <= getPowerLevel())) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
xp = (float) (xp * ExperienceConfig.getInstance().getFormulaSkillModifier(primarySkillType) * ExperienceConfig.getInstance().getExperienceGainsGlobalMultiplier());
|
xp = (float) ((xp * ExperienceConfig.getInstance().getFormulaSkillModifier(primarySkillType)) * ExperienceConfig.getInstance().getExperienceGainsGlobalMultiplier());
|
||||||
|
|
||||||
if (mcMMO.p.getGeneralConfig().getToolModsEnabled()) {
|
if (mcMMO.p.getGeneralConfig().getToolModsEnabled()) {
|
||||||
CustomTool tool = mcMMO.getModManager().getTool(player.getInventory().getItemInMainHand());
|
CustomTool tool = mcMMO.getModManager().getTool(player.getInventory().getItemInMainHand());
|
||||||
|
|
|
@ -132,12 +132,12 @@ public enum PrimarySkillType {
|
||||||
/**
|
/**
|
||||||
* WARNING: Being removed in an upcoming update, you should be using mcMMO.getSkillTools() instead
|
* WARNING: Being removed in an upcoming update, you should be using mcMMO.getSkillTools() instead
|
||||||
* @return the max level of this skill
|
* @return the max level of this skill
|
||||||
* @see SkillTools#getXpModifier(com.gmail.nossr50.datatypes.skills.PrimarySkillType)
|
* @see SkillTools#getXpMultiplier(com.gmail.nossr50.datatypes.skills.PrimarySkillType)
|
||||||
* @deprecated this is being removed in an upcoming update, you should be using mcMMO.getSkillTools() instead
|
* @deprecated this is being removed in an upcoming update, you should be using mcMMO.getSkillTools() instead
|
||||||
*/
|
*/
|
||||||
@Deprecated
|
@Deprecated
|
||||||
public double getXpModifier() {
|
public double getXpModifier() {
|
||||||
return mcMMO.p.getSkillTools().getXpModifier(this);
|
return mcMMO.p.getSkillTools().getXpMultiplier(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -213,35 +213,12 @@ public enum SubSkillType {
|
||||||
return endResult.toString();
|
return endResult.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getWikiName(String subSkillName) {
|
public String getWikiUrl() {
|
||||||
/*
|
// remove the text before the first underscore
|
||||||
* Find where to begin our substring (after the prefix)
|
int subStringIndex = getSubStringIndex(name());
|
||||||
*/
|
String afterPrefix = name().substring(subStringIndex);
|
||||||
StringBuilder endResult = new StringBuilder();
|
// replace _ or spaces with -
|
||||||
int subStringIndex = getSubStringIndex(subSkillName);
|
return afterPrefix.replace("_", "-").replace(" ", "-").toLowerCase(Locale.ENGLISH);
|
||||||
|
|
||||||
/*
|
|
||||||
* Split the string up so we can capitalize each part
|
|
||||||
*/
|
|
||||||
String subskillNameWithoutPrefix = subSkillName.substring(subStringIndex);
|
|
||||||
if(subskillNameWithoutPrefix.contains("_"))
|
|
||||||
{
|
|
||||||
String[] splitStrings = subskillNameWithoutPrefix.split("_");
|
|
||||||
|
|
||||||
for(int i = 0; i < splitStrings.length; i++)
|
|
||||||
{
|
|
||||||
if(i+1 >= splitStrings.length)
|
|
||||||
endResult.append(StringUtils.getCapitalized(splitStrings[i]));
|
|
||||||
else {
|
|
||||||
endResult.append(StringUtils.getCapitalized(splitStrings[i]));
|
|
||||||
endResult.append("_");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
endResult.append(StringUtils.getCapitalized(subskillNameWithoutPrefix));
|
|
||||||
}
|
|
||||||
|
|
||||||
return endResult.toString();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -140,6 +140,7 @@ public class mcMMO extends JavaPlugin {
|
||||||
private GeneralConfig generalConfig;
|
private GeneralConfig generalConfig;
|
||||||
private AdvancedConfig advancedConfig;
|
private AdvancedConfig advancedConfig;
|
||||||
private PartyConfig partyConfig;
|
private PartyConfig partyConfig;
|
||||||
|
private CustomItemSupportConfig customItemSupportConfig;
|
||||||
|
|
||||||
private FoliaLib foliaLib;
|
private FoliaLib foliaLib;
|
||||||
private PartyManager partyManager;
|
private PartyManager partyManager;
|
||||||
|
@ -185,6 +186,7 @@ public class mcMMO extends JavaPlugin {
|
||||||
//Init configs
|
//Init configs
|
||||||
advancedConfig = new AdvancedConfig(getDataFolder());
|
advancedConfig = new AdvancedConfig(getDataFolder());
|
||||||
partyConfig = new PartyConfig(getDataFolder());
|
partyConfig = new PartyConfig(getDataFolder());
|
||||||
|
customItemSupportConfig = new CustomItemSupportConfig(getDataFolder());
|
||||||
|
|
||||||
//Store this value so other plugins can check it
|
//Store this value so other plugins can check it
|
||||||
isRetroModeEnabled = generalConfig.getIsRetroMode();
|
isRetroModeEnabled = generalConfig.getIsRetroMode();
|
||||||
|
@ -806,6 +808,10 @@ public class mcMMO extends JavaPlugin {
|
||||||
return partyManager;
|
return partyManager;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public CustomItemSupportConfig getCustomItemSupportConfig() {
|
||||||
|
return customItemSupportConfig;
|
||||||
|
}
|
||||||
|
|
||||||
public @NotNull FoliaLib getFoliaLib() {
|
public @NotNull FoliaLib getFoliaLib() {
|
||||||
return foliaLib;
|
return foliaLib;
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,14 +15,26 @@ import org.bukkit.entity.Player;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.TreeMap;
|
|
||||||
|
|
||||||
public class PapiExpansion extends PlaceholderExpansion {
|
public class PapiExpansion extends PlaceholderExpansion {
|
||||||
private final Map<String, Placeholder> placeholders = new TreeMap<>(String.CASE_INSENSITIVE_ORDER);
|
|
||||||
|
public static final String SKILL_LEVEL = "level_";
|
||||||
|
public static final String SKILL_EXP_NEEDED = "xp_needed_";
|
||||||
|
public static final String SKILL_EXP_REMAINING = "xp_remaining_";
|
||||||
|
public static final String SKILL_EXP = "xp_";
|
||||||
|
public static final String SKILL_RANK = "rank_";
|
||||||
|
public static final String SKILL_EXP_RATE = "xprate_";
|
||||||
|
public static final String POWER_LEVEL = "power_level";
|
||||||
|
public static final String POWER_LEVEL_CAP = "power_level_cap";
|
||||||
|
public static final String IN_PARTY = "in_party";
|
||||||
|
public static final String PARTY_NAME = "party_name";
|
||||||
|
public static final String IS_PARTY_LEADER = "is_party_leader";
|
||||||
|
public static final String PARTY_LEADER = "party_leader";
|
||||||
|
public static final String PARTY_SIZE = "party_size";
|
||||||
|
public static final String EXP_RATE = "xprate";
|
||||||
|
public static final String IS_EXP_EVENT_ACTIVE = "is_xp_event_active";
|
||||||
|
|
||||||
public PapiExpansion() {
|
public PapiExpansion() {
|
||||||
init();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -37,8 +49,7 @@ public class PapiExpansion extends PlaceholderExpansion {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getVersion() {
|
public String getVersion() {
|
||||||
//grab version from pom.xml
|
return mcMMO.p.getDescription().getVersion();
|
||||||
return "1.0,0";
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -54,105 +65,41 @@ public class PapiExpansion extends PlaceholderExpansion {
|
||||||
@Override
|
@Override
|
||||||
@Nullable
|
@Nullable
|
||||||
public String onPlaceholderRequest(final Player player, @NotNull final String params) {
|
public String onPlaceholderRequest(final Player player, @NotNull final String params) {
|
||||||
String token;
|
|
||||||
String data = null;
|
// Non player-specific placeholders
|
||||||
int dataPosition = params.indexOf(":");
|
if (params.equalsIgnoreCase(IS_EXP_EVENT_ACTIVE)) {
|
||||||
|
return mcMMO.p.isXPEventEnabled() ? PlaceholderAPIPlugin.booleanTrue() : PlaceholderAPIPlugin.booleanFalse();
|
||||||
if (dataPosition != -1) {
|
} else if (params.equalsIgnoreCase(EXP_RATE)) {
|
||||||
token = params.substring(0, dataPosition);
|
|
||||||
data = params.substring(dataPosition + 1);
|
|
||||||
} else {
|
|
||||||
token = params;
|
|
||||||
}
|
|
||||||
|
|
||||||
Placeholder placeholder = placeholders.get(token);
|
|
||||||
|
|
||||||
if (placeholder != null) {
|
|
||||||
return placeholder.process(player, data);
|
|
||||||
} else {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public Integer getSkillLevel(PrimarySkillType skill, Player player) {
|
|
||||||
final McMMOPlayer user = UserManager.getPlayer(player);
|
|
||||||
if (user == null) return null;
|
|
||||||
return user.getSkillLevel(skill);
|
|
||||||
}
|
|
||||||
|
|
||||||
public Integer getExpNeeded(PrimarySkillType skill, Player player) {
|
|
||||||
final McMMOPlayer user = UserManager.getPlayer(player);
|
|
||||||
if (user == null) return null;
|
|
||||||
return user.getXpToLevel(skill);
|
|
||||||
}
|
|
||||||
|
|
||||||
public Integer getExp(PrimarySkillType skill, Player player) {
|
|
||||||
final McMMOPlayer user = UserManager.getPlayer(player);
|
|
||||||
if (user == null) return null;
|
|
||||||
|
|
||||||
return user.getSkillXpLevel(skill);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public Integer getExpRemaining(PrimarySkillType skill, Player player) {
|
|
||||||
final McMMOPlayer user = UserManager.getPlayer(player);
|
|
||||||
if (user == null) return null;
|
|
||||||
int current = user.getSkillXpLevel(skill);
|
|
||||||
int needed = user.getXpToLevel(skill);
|
|
||||||
|
|
||||||
return needed - current;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Integer getRank(PrimarySkillType skill, Player player) {
|
|
||||||
try {
|
|
||||||
return ExperienceAPI.getPlayerRankSkill(player.getUniqueId(), StringUtils.getCapitalized(skill.toString()));
|
|
||||||
} catch (Exception ex) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public Integer getPowerLevel(Player player) {
|
|
||||||
final McMMOPlayer user = UserManager.getPlayer(player);
|
|
||||||
if (user == null) return null;
|
|
||||||
return user.getPowerLevel();
|
|
||||||
}
|
|
||||||
|
|
||||||
public Integer getPowerCap(Player player) {
|
|
||||||
return mcMMO.p.getGeneralConfig().getPowerLevelCap();
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getPartyName(Player player) {
|
|
||||||
final McMMOPlayer user = UserManager.getPlayer(player);
|
|
||||||
if (user == null) return null;
|
|
||||||
final Party party = user.getParty();
|
|
||||||
|
|
||||||
return (party == null) ? null : party.getName();
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getPartyLeader(Player player) {
|
|
||||||
final McMMOPlayer user = UserManager.getPlayer(player);
|
|
||||||
if (user == null) return null;
|
|
||||||
final Party party = user.getParty();
|
|
||||||
return (party == null) ? null : party.getLeader().getPlayerName();
|
|
||||||
}
|
|
||||||
|
|
||||||
public Integer getPartySize(Player player) {
|
|
||||||
final McMMOPlayer user = UserManager.getPlayer(player);
|
|
||||||
if (user == null) return null;
|
|
||||||
final Party party = user.getParty();
|
|
||||||
return (party == null) ? null : party.getMembers().size();
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getXpRate(Player player) {
|
|
||||||
return String.valueOf(ExperienceConfig.getInstance().getExperienceGainsGlobalMultiplier());
|
return String.valueOf(ExperienceConfig.getInstance().getExperienceGainsGlobalMultiplier());
|
||||||
}
|
} else if (params.equalsIgnoreCase(POWER_LEVEL_CAP)) {
|
||||||
|
return String.valueOf(mcMMO.p.getGeneralConfig().getPowerLevelCap());
|
||||||
public String getSkillXpRate(PrimarySkillType skill, Player player) {
|
}
|
||||||
final McMMOPlayer user = UserManager.getPlayer(player);
|
|
||||||
if (user == null) return null;
|
final McMMOPlayer user = UserManager.getPlayer(player);
|
||||||
|
if (user == null) return null;
|
||||||
|
|
||||||
|
if (params.startsWith(SKILL_LEVEL)) {
|
||||||
|
PrimarySkillType skill = PrimarySkillType.valueOf(params.substring(SKILL_LEVEL.length()).toUpperCase());
|
||||||
|
return skill == null ? null : String.valueOf(user.getSkillLevel(skill));
|
||||||
|
} else if (params.startsWith(SKILL_EXP_NEEDED)) {
|
||||||
|
PrimarySkillType skill = PrimarySkillType.valueOf(params.substring(SKILL_EXP_NEEDED.length()).toUpperCase());
|
||||||
|
return skill == null ? null : String.valueOf(user.getXpToLevel(skill));
|
||||||
|
} else if (params.startsWith(SKILL_EXP_REMAINING)) {
|
||||||
|
PrimarySkillType skill = PrimarySkillType.valueOf(params.substring(SKILL_EXP_REMAINING.length()).toUpperCase());
|
||||||
|
return skill == null ? null : String.valueOf(user.getXpToLevel(skill) - user.getSkillXpLevel(skill));
|
||||||
|
} else if (params.startsWith(SKILL_EXP)) {
|
||||||
|
PrimarySkillType skill = PrimarySkillType.valueOf(params.substring(SKILL_EXP.length()).toUpperCase());
|
||||||
|
return skill == null ? null : String.valueOf(user.getSkillXpLevel(skill));
|
||||||
|
} else if (params.startsWith(SKILL_RANK)) {
|
||||||
|
try {
|
||||||
|
return String.valueOf(ExperienceAPI.getPlayerRankSkill(player.getUniqueId(), StringUtils.getCapitalized(params.substring(SKILL_RANK.length()))));
|
||||||
|
} catch (Exception ex) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
} else if (params.startsWith(SKILL_EXP_RATE)) {
|
||||||
|
PrimarySkillType skill = PrimarySkillType.valueOf(params.substring(SKILL_EXP_RATE.length()).toUpperCase());
|
||||||
|
if (skill == null) return null;
|
||||||
double modifier = 1.0F;
|
double modifier = 1.0F;
|
||||||
|
|
||||||
if (Permissions.customXpBoost(player, skill))
|
if (Permissions.customXpBoost(player, skill))
|
||||||
modifier = ExperienceConfig.getInstance().getCustomXpPerkBoost();
|
modifier = ExperienceConfig.getInstance().getCustomXpPerkBoost();
|
||||||
else if (Permissions.quadrupleXp(player, skill))
|
else if (Permissions.quadrupleXp(player, skill))
|
||||||
|
@ -167,69 +114,29 @@ public class PapiExpansion extends PlaceholderExpansion {
|
||||||
modifier = 1.5;
|
modifier = 1.5;
|
||||||
else if (Permissions.oneAndOneTenthXp(player, skill))
|
else if (Permissions.oneAndOneTenthXp(player, skill))
|
||||||
modifier = 1.1;
|
modifier = 1.1;
|
||||||
|
|
||||||
return String.valueOf(modifier);
|
return String.valueOf(modifier);
|
||||||
|
} else if (params.equalsIgnoreCase(POWER_LEVEL)) {
|
||||||
|
return String.valueOf(user.getPowerLevel());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//Party placeholders
|
||||||
|
final Party party = user.getParty();
|
||||||
|
|
||||||
|
if (params.equalsIgnoreCase(IN_PARTY)) {
|
||||||
|
return (party==null) ? PlaceholderAPIPlugin.booleanFalse() : PlaceholderAPIPlugin.booleanTrue();
|
||||||
|
} else if (params.equalsIgnoreCase(PARTY_NAME)) {
|
||||||
|
return (party == null) ? "" : party.getName();
|
||||||
|
} else if (params.equalsIgnoreCase(IS_PARTY_LEADER)) {
|
||||||
|
if (party == null) return "";
|
||||||
|
return party.getLeader().getPlayerName().equals(player.getName()) ? PlaceholderAPIPlugin.booleanTrue() : PlaceholderAPIPlugin.booleanFalse();
|
||||||
|
} else if (params.equalsIgnoreCase(PARTY_LEADER)) {
|
||||||
|
return (party == null) ? "" : party.getLeader().getPlayerName();
|
||||||
|
} else if (params.equalsIgnoreCase(PARTY_SIZE)) {
|
||||||
|
return (party == null) ? "" : String.valueOf(party.getMembers().size());
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String isExpEventActive(Player player) {
|
|
||||||
return mcMMO.p.isXPEventEnabled() ? PlaceholderAPIPlugin.booleanTrue() : PlaceholderAPIPlugin.booleanFalse();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void registerPlaceholder(Placeholder placeholder) {
|
|
||||||
final Placeholder registered = placeholders.get(placeholder.getName());
|
|
||||||
if (registered != null)
|
|
||||||
throw new IllegalStateException("Placeholder " + placeholder.getName() + " is already registered!");
|
|
||||||
|
|
||||||
placeholders.put(placeholder.getName(), placeholder);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected void init() {
|
|
||||||
|
|
||||||
for (PrimarySkillType skill : PrimarySkillType.values()) {
|
|
||||||
// %mcmmo_level_<skillname>%
|
|
||||||
registerPlaceholder(new SkillLevelPlaceholder(this, skill));
|
|
||||||
|
|
||||||
//%mcmmo_xp_needed_<skillname>%
|
|
||||||
registerPlaceholder(new SkillExpNeededPlaceholder(this, skill));
|
|
||||||
|
|
||||||
//%mcmmo_xp_<skillname>%
|
|
||||||
registerPlaceholder(new SkillExpPlaceholder(this, skill));
|
|
||||||
|
|
||||||
//%mcmmo_xp_remaining_<skillname>%
|
|
||||||
registerPlaceholder(new SkillExpRemainingPlaceholder(this, skill));
|
|
||||||
|
|
||||||
//%mcmmo_rank_<skillname>%
|
|
||||||
registerPlaceholder(new SkillRankPlaceholder(this, skill));
|
|
||||||
|
|
||||||
//%mcmmo_xprate_<skillname>%
|
|
||||||
registerPlaceholder(new SkillXpRatePlaceholder(this, skill));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
//%mcmmo_power_level%
|
|
||||||
registerPlaceholder(new PowerLevelPlaceholder(this));
|
|
||||||
|
|
||||||
// %mcmmo_power_level_cap%
|
|
||||||
registerPlaceholder(new PowerLevelCapPlaceholder(this));
|
|
||||||
|
|
||||||
// %mcmmo_in_party%
|
|
||||||
registerPlaceholder(new PartyIsMemberPlaceholder(this));
|
|
||||||
|
|
||||||
/// %mcmmo_party_name%
|
|
||||||
registerPlaceholder(new PartyNamePlaceholder(this));
|
|
||||||
|
|
||||||
// %mcmmo_is_party_leader%
|
|
||||||
registerPlaceholder(new PartyIsLeaderPlaceholder(this));
|
|
||||||
|
|
||||||
// %mcmmo_party_leader%
|
|
||||||
registerPlaceholder(new PartyLeaderPlaceholder(this));
|
|
||||||
|
|
||||||
// %mcmmo_party_size%
|
|
||||||
registerPlaceholder(new PartySizePlaceholder(this));
|
|
||||||
|
|
||||||
// %mcmmo_is_xp_event_active%
|
|
||||||
registerPlaceholder(new XpEventActivePlaceholder(this));
|
|
||||||
// %mcmmo_xprate%
|
|
||||||
registerPlaceholder(new XpRatePlaceholder(this));
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,29 +0,0 @@
|
||||||
package com.gmail.nossr50.placeholders;
|
|
||||||
|
|
||||||
import org.bukkit.entity.Player;
|
|
||||||
|
|
||||||
public class PartyIsLeaderPlaceholder implements Placeholder {
|
|
||||||
|
|
||||||
private final PapiExpansion papiExpansion;
|
|
||||||
|
|
||||||
public PartyIsLeaderPlaceholder(PapiExpansion papiExpansion) {
|
|
||||||
this.papiExpansion = papiExpansion;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* {@inheritDoc}
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public String process(Player player, String params) {
|
|
||||||
String leader = papiExpansion.getPartyLeader(player);
|
|
||||||
return (leader.equals(player.getName())) ? "true" : "false";
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* {@inheritDoc}
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public String getName() {
|
|
||||||
return "is_party_leader";
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,21 +0,0 @@
|
||||||
package com.gmail.nossr50.placeholders;
|
|
||||||
|
|
||||||
import org.bukkit.entity.Player;
|
|
||||||
|
|
||||||
public class PartyIsMemberPlaceholder implements Placeholder {
|
|
||||||
|
|
||||||
private final PapiExpansion papiExpansion;
|
|
||||||
public PartyIsMemberPlaceholder(PapiExpansion papiExpansion) {
|
|
||||||
this.papiExpansion = papiExpansion;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String process(Player player, String params) {
|
|
||||||
return (papiExpansion.getPartyName(player) == null) ? "false" : "true";
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getName() {
|
|
||||||
return "in_party";
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,22 +0,0 @@
|
||||||
package com.gmail.nossr50.placeholders;
|
|
||||||
|
|
||||||
import org.apache.commons.lang.StringUtils;
|
|
||||||
import org.bukkit.entity.Player;
|
|
||||||
|
|
||||||
public class PartyLeaderPlaceholder implements Placeholder {
|
|
||||||
private final PapiExpansion papiExpansion;
|
|
||||||
|
|
||||||
public PartyLeaderPlaceholder(PapiExpansion papiExpansion) {
|
|
||||||
this.papiExpansion = papiExpansion;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String process(Player player, String params) {
|
|
||||||
return StringUtils.stripToEmpty(papiExpansion.getPartyLeader(player));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getName() {
|
|
||||||
return "party_leader";
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,22 +0,0 @@
|
||||||
package com.gmail.nossr50.placeholders;
|
|
||||||
|
|
||||||
import org.apache.commons.lang.StringUtils;
|
|
||||||
import org.bukkit.entity.Player;
|
|
||||||
|
|
||||||
public class PartyNamePlaceholder implements Placeholder {
|
|
||||||
private final PapiExpansion papiExpansion;
|
|
||||||
|
|
||||||
public PartyNamePlaceholder(PapiExpansion papiExpansion) {
|
|
||||||
this.papiExpansion = papiExpansion;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String process(Player player, String params) {
|
|
||||||
return StringUtils.stripToEmpty(papiExpansion.getPartyName(player));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getName() {
|
|
||||||
return "party_name";
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,22 +0,0 @@
|
||||||
package com.gmail.nossr50.placeholders;
|
|
||||||
|
|
||||||
import org.bukkit.entity.Player;
|
|
||||||
|
|
||||||
public class PartySizePlaceholder implements Placeholder {
|
|
||||||
private final PapiExpansion papiExpansion;
|
|
||||||
|
|
||||||
public PartySizePlaceholder(PapiExpansion papiExpansion) {
|
|
||||||
this.papiExpansion = papiExpansion;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String process(Player player, String params) {
|
|
||||||
Integer partySize = papiExpansion.getPartySize(player);
|
|
||||||
return (partySize == null) ? "" : partySize.toString();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getName() {
|
|
||||||
return "party_size";
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,18 +0,0 @@
|
||||||
package com.gmail.nossr50.placeholders;
|
|
||||||
|
|
||||||
import org.bukkit.entity.Player;
|
|
||||||
|
|
||||||
public interface Placeholder {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param player the player to process the placeholder for
|
|
||||||
* @param params the paramaters to be passed to the placeholder
|
|
||||||
* @return the value of the placeholder
|
|
||||||
*/
|
|
||||||
String process(Player player, String params);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return the name of the placeholder
|
|
||||||
*/
|
|
||||||
String getName();
|
|
||||||
}
|
|
|
@ -1,22 +0,0 @@
|
||||||
package com.gmail.nossr50.placeholders;
|
|
||||||
|
|
||||||
import org.bukkit.entity.Player;
|
|
||||||
|
|
||||||
public class PowerLevelCapPlaceholder implements Placeholder {
|
|
||||||
private final PapiExpansion papiExpansion;
|
|
||||||
|
|
||||||
public PowerLevelCapPlaceholder(PapiExpansion papiExpansion) {
|
|
||||||
this.papiExpansion = papiExpansion;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String process(Player player, String params) {
|
|
||||||
Integer cap = papiExpansion.getPowerCap(player);
|
|
||||||
return (cap == null) ? "" : cap.toString();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getName() {
|
|
||||||
return "power_level_cap";
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,22 +0,0 @@
|
||||||
package com.gmail.nossr50.placeholders;
|
|
||||||
|
|
||||||
import org.bukkit.entity.Player;
|
|
||||||
|
|
||||||
public class PowerLevelPlaceholder implements Placeholder {
|
|
||||||
private final PapiExpansion papiExpansion;
|
|
||||||
|
|
||||||
public PowerLevelPlaceholder(PapiExpansion papiExpansion) {
|
|
||||||
this.papiExpansion = papiExpansion;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String process(Player player, String params) {
|
|
||||||
Integer powerLevel = papiExpansion.getPowerLevel(player);
|
|
||||||
return (powerLevel == null) ? "" : powerLevel.toString();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getName() {
|
|
||||||
return "power_level";
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,26 +0,0 @@
|
||||||
package com.gmail.nossr50.placeholders;
|
|
||||||
|
|
||||||
import com.gmail.nossr50.datatypes.skills.PrimarySkillType;
|
|
||||||
import org.bukkit.entity.Player;
|
|
||||||
|
|
||||||
public class SkillExpNeededPlaceholder implements Placeholder {
|
|
||||||
|
|
||||||
private final PapiExpansion papiExpansion;
|
|
||||||
private final PrimarySkillType skillType;
|
|
||||||
|
|
||||||
public SkillExpNeededPlaceholder(PapiExpansion papiExpansion, PrimarySkillType skillType) {
|
|
||||||
this.papiExpansion = papiExpansion;
|
|
||||||
this.skillType = skillType;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String process(Player player, String params) {
|
|
||||||
final Integer expNeeded = papiExpansion.getExpNeeded(skillType, player);
|
|
||||||
return (expNeeded == null) ? "" : expNeeded.toString();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getName() {
|
|
||||||
return "xp_needed_" + skillType.toString().toLowerCase();
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,26 +0,0 @@
|
||||||
package com.gmail.nossr50.placeholders;
|
|
||||||
|
|
||||||
import com.gmail.nossr50.datatypes.skills.PrimarySkillType;
|
|
||||||
import org.bukkit.entity.Player;
|
|
||||||
|
|
||||||
public class SkillExpPlaceholder implements Placeholder {
|
|
||||||
private final PapiExpansion papiExpansion;
|
|
||||||
private final PrimarySkillType skill;
|
|
||||||
|
|
||||||
public SkillExpPlaceholder(PapiExpansion papiExpansion, PrimarySkillType skill) {
|
|
||||||
this.papiExpansion = papiExpansion;
|
|
||||||
this.skill = skill;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String process(Player player, String params) {
|
|
||||||
Integer exp = papiExpansion.getExp(skill, player);
|
|
||||||
return (exp == null) ? "" : exp.toString();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getName() {
|
|
||||||
return "xp_" + skill.toString().toLowerCase();
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,25 +0,0 @@
|
||||||
package com.gmail.nossr50.placeholders;
|
|
||||||
|
|
||||||
import com.gmail.nossr50.datatypes.skills.PrimarySkillType;
|
|
||||||
import org.bukkit.entity.Player;
|
|
||||||
|
|
||||||
public class SkillExpRemainingPlaceholder implements Placeholder {
|
|
||||||
private final PapiExpansion papiExpansion;
|
|
||||||
private final PrimarySkillType skill;
|
|
||||||
|
|
||||||
public SkillExpRemainingPlaceholder(PapiExpansion papiExpansion, PrimarySkillType skill) {
|
|
||||||
this.papiExpansion = papiExpansion;
|
|
||||||
this.skill = skill;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String process(Player player, String params) {
|
|
||||||
final Integer expRemaining = papiExpansion.getExpRemaining(skill, player);
|
|
||||||
return (expRemaining == null) ? "" : expRemaining.toString();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getName() {
|
|
||||||
return "xp_remaining_" + skill.toString().toLowerCase();
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,25 +0,0 @@
|
||||||
package com.gmail.nossr50.placeholders;
|
|
||||||
|
|
||||||
import com.gmail.nossr50.datatypes.skills.PrimarySkillType;
|
|
||||||
import org.bukkit.entity.Player;
|
|
||||||
|
|
||||||
public class SkillLevelPlaceholder implements Placeholder {
|
|
||||||
private final PapiExpansion papiExpansion;
|
|
||||||
private final PrimarySkillType skillType;
|
|
||||||
|
|
||||||
public SkillLevelPlaceholder(PapiExpansion papiExpansion, PrimarySkillType skillType) {
|
|
||||||
this.papiExpansion = papiExpansion;
|
|
||||||
this.skillType = skillType;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String process(Player p, String params) {
|
|
||||||
final Integer skillLevel = papiExpansion.getSkillLevel(skillType, p);
|
|
||||||
return (skillLevel == null) ? "" : skillLevel.toString();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getName() {
|
|
||||||
return "level_" + skillType.toString().toLowerCase();
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,25 +0,0 @@
|
||||||
package com.gmail.nossr50.placeholders;
|
|
||||||
|
|
||||||
import com.gmail.nossr50.datatypes.skills.PrimarySkillType;
|
|
||||||
import org.bukkit.entity.Player;
|
|
||||||
|
|
||||||
public class SkillRankPlaceholder implements Placeholder {
|
|
||||||
private final PapiExpansion papiExpansion;
|
|
||||||
private final PrimarySkillType skill;
|
|
||||||
|
|
||||||
public SkillRankPlaceholder(PapiExpansion papiExpansion, PrimarySkillType skill) {
|
|
||||||
this.papiExpansion = papiExpansion;
|
|
||||||
this.skill = skill;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String process(Player player, String params) {
|
|
||||||
Integer rank = papiExpansion.getRank(skill, player);
|
|
||||||
return (rank == null) ? "" : rank.toString();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getName() {
|
|
||||||
return "rank_" + skill.toString().toLowerCase();
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,25 +0,0 @@
|
||||||
package com.gmail.nossr50.placeholders;
|
|
||||||
|
|
||||||
import com.gmail.nossr50.datatypes.skills.PrimarySkillType;
|
|
||||||
import org.bukkit.entity.Player;
|
|
||||||
|
|
||||||
public class SkillXpRatePlaceholder implements Placeholder {
|
|
||||||
private final PapiExpansion papiExpansion;
|
|
||||||
private final PrimarySkillType skillType;
|
|
||||||
|
|
||||||
public SkillXpRatePlaceholder(PapiExpansion papiExpansion, PrimarySkillType skillType) {
|
|
||||||
this.papiExpansion = papiExpansion;
|
|
||||||
this.skillType = skillType;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String process(Player p, String params) {
|
|
||||||
final String skillLevel = papiExpansion.getSkillXpRate(skillType, p);
|
|
||||||
return (skillLevel == null) ? "" : skillLevel;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getName() {
|
|
||||||
return "xprate_" + skillType.toString().toLowerCase();
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,22 +0,0 @@
|
||||||
package com.gmail.nossr50.placeholders;
|
|
||||||
|
|
||||||
import com.gmail.nossr50.datatypes.skills.PrimarySkillType;
|
|
||||||
import org.bukkit.entity.Player;
|
|
||||||
|
|
||||||
public class XpEventActivePlaceholder implements Placeholder {
|
|
||||||
private final PapiExpansion papiExpansion;
|
|
||||||
|
|
||||||
public <S extends PrimarySkillType> XpEventActivePlaceholder(PapiExpansion papiExpansion) {
|
|
||||||
this.papiExpansion = papiExpansion;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String process(Player player, String params) {
|
|
||||||
return papiExpansion.isExpEventActive(player);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getName() {
|
|
||||||
return "is_xp_event_active";
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,22 +0,0 @@
|
||||||
package com.gmail.nossr50.placeholders;
|
|
||||||
|
|
||||||
import com.gmail.nossr50.datatypes.skills.PrimarySkillType;
|
|
||||||
import org.bukkit.entity.Player;
|
|
||||||
|
|
||||||
public class XpRatePlaceholder implements Placeholder {
|
|
||||||
private final PapiExpansion papiExpansion;
|
|
||||||
|
|
||||||
public <S extends PrimarySkillType> XpRatePlaceholder(PapiExpansion papiExpansion) {
|
|
||||||
this.papiExpansion = papiExpansion;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String process(Player player, String params) {
|
|
||||||
return papiExpansion.getXpRate(player);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getName() {
|
|
||||||
return "xprate";
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -72,6 +72,7 @@ public class CrossbowsManager extends SkillManager {
|
||||||
new FixedMetadataValue(pluginRef, bounceCount + 1));
|
new FixedMetadataValue(pluginRef, bounceCount + 1));
|
||||||
spawnedArrow.setMetadata(MetadataConstants.METADATA_KEY_SPAWNED_ARROW,
|
spawnedArrow.setMetadata(MetadataConstants.METADATA_KEY_SPAWNED_ARROW,
|
||||||
new FixedMetadataValue(pluginRef, originalArrowShooter));
|
new FixedMetadataValue(pluginRef, originalArrowShooter));
|
||||||
|
spawnedArrow.setShotFromCrossbow(true);
|
||||||
|
|
||||||
// Don't allow multi-shot or infinite arrows to be picked up
|
// Don't allow multi-shot or infinite arrows to be picked up
|
||||||
if (spawnedArrow.hasMetadata(MetadataConstants.METADATA_KEY_MULTI_SHOT_ARROW)
|
if (spawnedArrow.hasMetadata(MetadataConstants.METADATA_KEY_MULTI_SHOT_ARROW)
|
||||||
|
|
|
@ -65,10 +65,19 @@ public class RepairManager extends SkillManager {
|
||||||
public void handleRepair(ItemStack item) {
|
public void handleRepair(ItemStack item) {
|
||||||
Player player = getPlayer();
|
Player player = getPlayer();
|
||||||
Repairable repairable = mcMMO.getRepairableManager().getRepairable(item.getType());
|
Repairable repairable = mcMMO.getRepairableManager().getRepairable(item.getType());
|
||||||
|
if (item.getItemMeta() != null) {
|
||||||
|
if(item.getItemMeta().hasCustomModelData()) {
|
||||||
|
if(!mcMMO.p.getCustomItemSupportConfig().isCustomRepairAllowed()) {
|
||||||
|
NotificationManager.sendPlayerInformation(player, NotificationType.SUBSKILL_MESSAGE_FAILED,
|
||||||
|
"Anvil.Repair.Reject.CustomModelData");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (item.getItemMeta().isUnbreakable()) {
|
if (item.getItemMeta().isUnbreakable()) {
|
||||||
NotificationManager.sendPlayerInformation(player, NotificationType.SUBSKILL_MESSAGE_FAILED, "Anvil.Unbreakable");
|
NotificationManager.sendPlayerInformation(player, NotificationType.SUBSKILL_MESSAGE_FAILED, "Anvil.Unbreakable");
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Permissions checks on material and item types
|
// Permissions checks on material and item types
|
||||||
|
|
|
@ -62,14 +62,19 @@ public class SalvageManager extends SkillManager {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void handleSalvage(Location location, ItemStack item) {
|
public void handleSalvage(Location location, ItemStack item) {
|
||||||
Player player = getPlayer();
|
final Player player = getPlayer();
|
||||||
|
|
||||||
Salvageable salvageable = mcMMO.getSalvageableManager().getSalvageable(item.getType());
|
final Salvageable salvageable = mcMMO.getSalvageableManager().getSalvageable(item.getType());
|
||||||
ItemMeta meta = item.getItemMeta();
|
final ItemMeta meta = item.getItemMeta();
|
||||||
|
if (meta != null) {
|
||||||
if (meta != null && meta.isUnbreakable()) {
|
if (meta.hasCustomModelData() && !mcMMO.p.getCustomItemSupportConfig().isCustomSalvageAllowed()) {
|
||||||
NotificationManager.sendPlayerInformation(player, NotificationType.SUBSKILL_MESSAGE_FAILED, "Anvil.Unbreakable");
|
NotificationManager.sendPlayerInformation(player, NotificationType.SUBSKILL_MESSAGE_FAILED, "Anvil.Salvage.Reject.CustomModelData");
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
if (meta.isUnbreakable()) {
|
||||||
|
NotificationManager.sendPlayerInformation(player, NotificationType.SUBSKILL_MESSAGE_FAILED, "Anvil.Unbreakable");
|
||||||
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Permissions checks on material and item types
|
// Permissions checks on material and item types
|
||||||
|
@ -190,30 +195,6 @@ public class SalvageManager extends SkillManager {
|
||||||
return RankUtils.getRank(getPlayer(), SubSkillType.SALVAGE_ARCANE_SALVAGE);
|
return RankUtils.getRank(getPlayer(), SubSkillType.SALVAGE_ARCANE_SALVAGE);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*public double getExtractFullEnchantChance() {
|
|
||||||
int skillLevel = getSkillLevel();
|
|
||||||
|
|
||||||
for (Tier tier : Tier.values()) {
|
|
||||||
if (skillLevel >= tier.getLevel()) {
|
|
||||||
return tier.getExtractFullEnchantChance();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
public double getExtractPartialEnchantChance() {
|
|
||||||
int skillLevel = getSkillLevel();
|
|
||||||
|
|
||||||
for (Tier tier : Tier.values()) {
|
|
||||||
if (skillLevel >= tier.getLevel()) {
|
|
||||||
return tier.getExtractPartialEnchantChance();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}*/
|
|
||||||
|
|
||||||
public double getExtractFullEnchantChance() {
|
public double getExtractFullEnchantChance() {
|
||||||
if(Permissions.hasSalvageEnchantBypassPerk(getPlayer()))
|
if(Permissions.hasSalvageEnchantBypassPerk(getPlayer()))
|
||||||
return 100.0D;
|
return 100.0D;
|
||||||
|
|
|
@ -1,10 +1,21 @@
|
||||||
package com.gmail.nossr50.util.random;
|
package com.gmail.nossr50.util.random;
|
||||||
|
|
||||||
|
import com.gmail.nossr50.api.exceptions.ValueOutOfBoundsException;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
import java.util.concurrent.ThreadLocalRandom;
|
import java.util.concurrent.ThreadLocalRandom;
|
||||||
|
|
||||||
public interface Probability {
|
public interface Probability {
|
||||||
|
/**
|
||||||
|
* A Probability that always fails.
|
||||||
|
*/
|
||||||
|
Probability ALWAYS_FAILS = () -> 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A Probability that always succeeds.
|
||||||
|
*/
|
||||||
|
Probability ALWAYS_SUCCEEDS = () -> 1;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The value of this Probability
|
* The value of this Probability
|
||||||
* Should return a result between 0 and 1 (inclusive)
|
* Should return a result between 0 and 1 (inclusive)
|
||||||
|
@ -17,19 +28,40 @@ public interface Probability {
|
||||||
double getValue();
|
double getValue();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a new Probability with the given value
|
* Create a new Probability of a percentage.
|
||||||
* A value of 100 would represent 100% chance of success
|
* This method takes a percentage and creates a Probability of equivalent odds.
|
||||||
* A value of 50 would represent 50% chance of success
|
*
|
||||||
* A value of 0 would represent 0% chance of success
|
* A value of 100 would represent 100% chance of success,
|
||||||
* A value of 1 would represent 1% chance of success
|
* A value of 50 would represent 50% chance of success,
|
||||||
* A value of 0.5 would represent 0.5% chance of success
|
* A value of 0 would represent 0% chance of success,
|
||||||
* A value of 0.01 would represent 0.01% chance of success
|
* A value of 1 would represent 1% chance of success,
|
||||||
|
* A value of 0.5 would represent 0.5% chance of success,
|
||||||
|
* A value of 0.01 would represent 0.01% chance of success.
|
||||||
*
|
*
|
||||||
* @param percentage the value of the probability
|
* @param percentage the value of the probability
|
||||||
* @return a new Probability with the given value
|
* @return a new Probability with the given value
|
||||||
*/
|
*/
|
||||||
static @NotNull Probability ofPercent(double percentage) {
|
static @NotNull Probability ofPercent(double percentage) {
|
||||||
return new ProbabilityImpl(percentage);
|
if (percentage < 0) {
|
||||||
|
throw new ValueOutOfBoundsException("Value should never be negative for Probability! This suggests a coding mistake, contact the devs!");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Convert to a 0-1 floating point representation
|
||||||
|
double probabilityValue = percentage / 100.0D;
|
||||||
|
return new ProbabilityImpl(probabilityValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new Probability of a value.
|
||||||
|
* This method takes a value between 0 and 1 and creates a Probability of equivalent odds.
|
||||||
|
* A value of 1 or greater represents something that will always succeed.
|
||||||
|
* A value of around 0.5 represents something that succeeds around half the time.
|
||||||
|
* A value of 0 represents something that will always fail.
|
||||||
|
* @param value the value of the probability
|
||||||
|
* @return a new Probability with the given value
|
||||||
|
*/
|
||||||
|
static @NotNull Probability ofValue(double value) {
|
||||||
|
return new ProbabilityImpl(value);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -8,31 +8,22 @@ public class ProbabilityImpl implements Probability {
|
||||||
private final double probabilityValue;
|
private final double probabilityValue;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a probability with a static value
|
* Create a probability from a static value.
|
||||||
|
* A value of 0 represents a 0% chance of success,
|
||||||
|
* A value of 1 represents a 100% chance of success.
|
||||||
|
* A value of 0.5 represents a 50% chance of success.
|
||||||
|
* A value of 0.01 represents a 1% chance of success.
|
||||||
|
* And so on.
|
||||||
*
|
*
|
||||||
* @param percentage the percentage value of the probability
|
* @param value the value of the probability between 0 and 100
|
||||||
*/
|
*/
|
||||||
ProbabilityImpl(double percentage) throws ValueOutOfBoundsException {
|
public ProbabilityImpl(double value) throws ValueOutOfBoundsException {
|
||||||
if (percentage < 0) {
|
if (value < 0) {
|
||||||
throw new ValueOutOfBoundsException("Value should never be negative for Probability! This suggests a coding mistake, contact the devs!");
|
throw new ValueOutOfBoundsException("Value should never be negative for Probability!" +
|
||||||
|
" This suggests a coding mistake, contact the devs!");
|
||||||
}
|
}
|
||||||
|
|
||||||
// Convert to a 0-1 floating point representation
|
probabilityValue = value;
|
||||||
probabilityValue = percentage / 100.0D;
|
|
||||||
}
|
|
||||||
|
|
||||||
ProbabilityImpl(double xPos, double xCeiling, double probabilityCeiling) throws ValueOutOfBoundsException {
|
|
||||||
if(probabilityCeiling > 100) {
|
|
||||||
throw new ValueOutOfBoundsException("Probability Ceiling should never be above 100!");
|
|
||||||
} else if (probabilityCeiling < 0) {
|
|
||||||
throw new ValueOutOfBoundsException("Probability Ceiling should never be below 0!");
|
|
||||||
}
|
|
||||||
|
|
||||||
//Get the percent success, this will be from 0-100
|
|
||||||
double probabilityPercent = (probabilityCeiling * (xPos / xCeiling));
|
|
||||||
|
|
||||||
//Convert to a 0-1 floating point representation
|
|
||||||
this.probabilityValue = probabilityPercent / 100.0D;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -79,24 +79,24 @@ public class ProbabilityUtil {
|
||||||
switch (getProbabilityType(subSkillType)) {
|
switch (getProbabilityType(subSkillType)) {
|
||||||
case DYNAMIC_CONFIGURABLE:
|
case DYNAMIC_CONFIGURABLE:
|
||||||
double probabilityCeiling;
|
double probabilityCeiling;
|
||||||
double xCeiling;
|
double skillLevel;
|
||||||
double xPos;
|
double maxBonusLevel; // If a skill level is equal to the cap, it has the full probability
|
||||||
|
|
||||||
if (player != null) {
|
if (player != null) {
|
||||||
McMMOPlayer mmoPlayer = UserManager.getPlayer(player);
|
McMMOPlayer mmoPlayer = UserManager.getPlayer(player);
|
||||||
if (mmoPlayer == null) {
|
if (mmoPlayer == null) {
|
||||||
return Probability.ofPercent(0);
|
return Probability.ofPercent(0);
|
||||||
}
|
}
|
||||||
xPos = mmoPlayer.getSkillLevel(subSkillType.getParentSkill());
|
skillLevel = mmoPlayer.getSkillLevel(subSkillType.getParentSkill());
|
||||||
} else {
|
} else {
|
||||||
xPos = 0;
|
skillLevel = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
//Probability ceiling is configurable in this type
|
//Probability ceiling is configurable in this type
|
||||||
probabilityCeiling = mcMMO.p.getAdvancedConfig().getMaximumProbability(subSkillType);
|
probabilityCeiling = mcMMO.p.getAdvancedConfig().getMaximumProbability(subSkillType);
|
||||||
//The xCeiling is configurable in this type
|
//The xCeiling is configurable in this type
|
||||||
xCeiling = mcMMO.p.getAdvancedConfig().getMaxBonusLevel(subSkillType);
|
maxBonusLevel = mcMMO.p.getAdvancedConfig().getMaxBonusLevel(subSkillType);
|
||||||
return new ProbabilityImpl(xPos, xCeiling, probabilityCeiling);
|
return calculateCurrentSkillProbability(skillLevel, 0, probabilityCeiling, maxBonusLevel);
|
||||||
case STATIC_CONFIGURABLE:
|
case STATIC_CONFIGURABLE:
|
||||||
try {
|
try {
|
||||||
return getStaticRandomChance(subSkillType);
|
return getStaticRandomChance(subSkillType);
|
||||||
|
@ -127,22 +127,7 @@ public class ProbabilityUtil {
|
||||||
* @return true if the Skill RNG succeeds, false if it fails
|
* @return true if the Skill RNG succeeds, false if it fails
|
||||||
*/
|
*/
|
||||||
public static boolean isSkillRNGSuccessful(@NotNull SubSkillType subSkillType, @NotNull Player player) {
|
public static boolean isSkillRNGSuccessful(@NotNull SubSkillType subSkillType, @NotNull Player player) {
|
||||||
//Process probability
|
final Probability probability = getSkillProbability(subSkillType, player);
|
||||||
Probability probability = getSubSkillProbability(subSkillType, player);
|
|
||||||
|
|
||||||
//Send out event
|
|
||||||
SubSkillEvent subSkillEvent = EventUtils.callSubSkillEvent(player, subSkillType);
|
|
||||||
|
|
||||||
if(subSkillEvent.isCancelled()) {
|
|
||||||
return false; //Event got cancelled so this doesn't succeed
|
|
||||||
}
|
|
||||||
|
|
||||||
//Result modifier
|
|
||||||
double resultModifier = subSkillEvent.getResultModifier();
|
|
||||||
|
|
||||||
//Mutate probability
|
|
||||||
if(resultModifier != 1.0D)
|
|
||||||
probability = Probability.ofPercent(probability.getValue() * resultModifier);
|
|
||||||
|
|
||||||
//Luck
|
//Luck
|
||||||
boolean isLucky = Permissions.lucky(player, subSkillType.getParentSkill());
|
boolean isLucky = Permissions.lucky(player, subSkillType.getParentSkill());
|
||||||
|
@ -154,12 +139,42 @@ public class ProbabilityUtil {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the {@link Probability} for a specific {@link SubSkillType} for a specific {@link Player}.
|
||||||
|
* This does not take into account perks such as lucky for the player.
|
||||||
|
* This is affected by other plugins who can listen to the {@link SubSkillEvent} and cancel it or mutate it.
|
||||||
|
*
|
||||||
|
* @param subSkillType the target subskill
|
||||||
|
* @param player the target player
|
||||||
|
* @return the probability for this skill
|
||||||
|
*/
|
||||||
|
public static Probability getSkillProbability(@NotNull SubSkillType subSkillType, @NotNull Player player) {
|
||||||
|
//Process probability
|
||||||
|
Probability probability = getSubSkillProbability(subSkillType, player);
|
||||||
|
|
||||||
|
//Send out event
|
||||||
|
SubSkillEvent subSkillEvent = EventUtils.callSubSkillEvent(player, subSkillType);
|
||||||
|
|
||||||
|
if(subSkillEvent.isCancelled()) {
|
||||||
|
return Probability.ALWAYS_FAILS;
|
||||||
|
}
|
||||||
|
|
||||||
|
//Result modifier
|
||||||
|
double resultModifier = subSkillEvent.getResultModifier();
|
||||||
|
|
||||||
|
//Mutate probability
|
||||||
|
if(resultModifier != 1.0D)
|
||||||
|
probability = Probability.ofPercent(probability.getValue() * resultModifier);
|
||||||
|
|
||||||
|
return probability;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This is one of several Skill RNG check methods
|
* This is one of several Skill RNG check methods
|
||||||
* This helper method is specific to static value RNG, which can be influenced by a player's Luck
|
* This helper method is specific to static value RNG, which can be influenced by a player's Luck
|
||||||
*
|
*
|
||||||
* @param primarySkillType the related primary skill
|
* @param primarySkillType the related primary skill
|
||||||
* @param player the target player, can be null (null players have the worst odds)
|
* @param player the target player can be null (null players have the worst odds)
|
||||||
* @param probabilityPercentage the probability of this player succeeding in "percentage" format (0-100 inclusive)
|
* @param probabilityPercentage the probability of this player succeeding in "percentage" format (0-100 inclusive)
|
||||||
* @return true if the RNG succeeds, false if it fails
|
* @return true if the RNG succeeds, false if it fails
|
||||||
*/
|
*/
|
||||||
|
@ -223,4 +238,31 @@ public class ProbabilityUtil {
|
||||||
|
|
||||||
return new String[]{percent.format(firstValue), percent.format(secondValue)};
|
return new String[]{percent.format(firstValue), percent.format(secondValue)};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Helper function to calculate what probability a given skill has at a certain level
|
||||||
|
* @param skillLevel the skill level currently between the floor and the ceiling
|
||||||
|
* @param floor the minimum odds this skill can have
|
||||||
|
* @param ceiling the maximum odds this skill can have
|
||||||
|
* @param maxBonusLevel the maximum level this skill can have to reach the ceiling
|
||||||
|
*
|
||||||
|
* @return the probability of success for this skill at this level
|
||||||
|
*/
|
||||||
|
public static Probability calculateCurrentSkillProbability(double skillLevel, double floor,
|
||||||
|
double ceiling, double maxBonusLevel) {
|
||||||
|
// The odds of success are between the value of the floor and the value of the ceiling.
|
||||||
|
// If the skill has a maxBonusLevel of 500 on this skill, then at skill level 500 you would have the full odds,
|
||||||
|
// at skill level 250 it would be half odds.
|
||||||
|
|
||||||
|
if (skillLevel >= maxBonusLevel || maxBonusLevel <= 0) {
|
||||||
|
// Avoid divide by zero bugs
|
||||||
|
// Max benefit has been reached, should always succeed
|
||||||
|
return Probability.ofPercent(ceiling);
|
||||||
|
}
|
||||||
|
|
||||||
|
double odds = (skillLevel / maxBonusLevel) * 100D;
|
||||||
|
|
||||||
|
// make sure the odds aren't lower or higher than the floor or ceiling
|
||||||
|
return Probability.ofPercent(Math.min(Math.max(floor, odds), ceiling));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -111,7 +111,7 @@ public final class CombatUtils {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
private static void processTridentCombat(@NotNull LivingEntity target, @NotNull Player player, @NotNull EntityDamageByEntityEvent event) {
|
private static void processTridentCombatMelee(@NotNull LivingEntity target, @NotNull Player player, @NotNull EntityDamageByEntityEvent event) {
|
||||||
if (event.getCause() == DamageCause.THORNS) {
|
if (event.getCause() == DamageCause.THORNS) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -127,10 +127,40 @@ public final class CombatUtils {
|
||||||
|
|
||||||
TridentsManager tridentsManager = mcMMOPlayer.getTridentsManager();
|
TridentsManager tridentsManager = mcMMOPlayer.getTridentsManager();
|
||||||
|
|
||||||
if (tridentsManager.canActivateAbility()) {
|
// if (tridentsManager.canActivateAbility()) {
|
||||||
mcMMOPlayer.checkAbilityActivation(PrimarySkillType.TRIDENTS);
|
// mcMMOPlayer.checkAbilityActivation(PrimarySkillType.TRIDENTS);
|
||||||
|
// }
|
||||||
|
|
||||||
|
if (SkillUtils.canUseSubskill(player, SubSkillType.TRIDENTS_IMPALE)) {
|
||||||
|
boostedDamage += (tridentsManager.impaleDamageBonus() * mcMMOPlayer.getAttackStrength());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(canUseLimitBreak(player, target, SubSkillType.TRIDENTS_TRIDENTS_LIMIT_BREAK)) {
|
||||||
|
boostedDamage += (getLimitBreakDamage(player, target, SubSkillType.TRIDENTS_TRIDENTS_LIMIT_BREAK) * mcMMOPlayer.getAttackStrength());
|
||||||
|
}
|
||||||
|
|
||||||
|
event.setDamage(boostedDamage);
|
||||||
|
processCombatXP(mcMMOPlayer, target, PrimarySkillType.TRIDENTS);
|
||||||
|
|
||||||
|
printFinalDamageDebug(player, event, mcMMOPlayer);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void processTridentCombatRanged(@NotNull Trident trident, @NotNull LivingEntity target, @NotNull Player player, @NotNull EntityDamageByEntityEvent event) {
|
||||||
|
if (event.getCause() == DamageCause.THORNS) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
double boostedDamage = event.getDamage();
|
||||||
|
|
||||||
|
McMMOPlayer mcMMOPlayer = UserManager.getPlayer(player);
|
||||||
|
|
||||||
|
//Make sure the profiles been loaded
|
||||||
|
if(mcMMOPlayer == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
TridentsManager tridentsManager = mcMMOPlayer.getTridentsManager();
|
||||||
|
|
||||||
if (SkillUtils.canUseSubskill(player, SubSkillType.TRIDENTS_IMPALE)) {
|
if (SkillUtils.canUseSubskill(player, SubSkillType.TRIDENTS_IMPALE)) {
|
||||||
boostedDamage += (tridentsManager.impaleDamageBonus() * mcMMOPlayer.getAttackStrength());
|
boostedDamage += (tridentsManager.impaleDamageBonus() * mcMMOPlayer.getAttackStrength());
|
||||||
}
|
}
|
||||||
|
@ -465,7 +495,7 @@ public final class CombatUtils {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mcMMO.p.getSkillTools().doesPlayerHaveSkillPermission(player, PrimarySkillType.TRIDENTS)) {
|
if (mcMMO.p.getSkillTools().doesPlayerHaveSkillPermission(player, PrimarySkillType.TRIDENTS)) {
|
||||||
processTridentCombat(target, player, event);
|
processTridentCombatMelee(target, player, event);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -481,6 +511,17 @@ public final class CombatUtils {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else if (painSource instanceof Trident trident) {
|
||||||
|
ProjectileSource projectileSource = trident.getShooter();
|
||||||
|
|
||||||
|
if (projectileSource instanceof Player player) {
|
||||||
|
if (!Misc.isNPCEntityExcludingVillagers(player)) {
|
||||||
|
if(mcMMO.p.getSkillTools().canCombatSkillsTrigger(PrimarySkillType.TRIDENTS, target)) {
|
||||||
|
processTridentCombatRanged(trident, target, player, event);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
else if (painSource instanceof Arrow arrow) {
|
else if (painSource instanceof Arrow arrow) {
|
||||||
ProjectileSource projectileSource = arrow.getShooter();
|
ProjectileSource projectileSource = arrow.getShooter();
|
||||||
boolean isCrossbow = arrow.isShotFromCrossbow();
|
boolean isCrossbow = arrow.isShotFromCrossbow();
|
||||||
|
|
|
@ -331,7 +331,7 @@ public class SkillTools {
|
||||||
return primarySkillChildrenMap.get(primarySkillType);
|
return primarySkillChildrenMap.get(primarySkillType);
|
||||||
}
|
}
|
||||||
|
|
||||||
public double getXpModifier(PrimarySkillType primarySkillType) {
|
public double getXpMultiplier(PrimarySkillType primarySkillType) {
|
||||||
return ExperienceConfig.getInstance().getFormulaSkillModifier(primarySkillType);
|
return ExperienceConfig.getInstance().getFormulaSkillModifier(primarySkillType);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -34,8 +34,6 @@ import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
|
|
||||||
import static java.util.Objects.requireNonNull;
|
|
||||||
|
|
||||||
public final class SkillUtils {
|
public final class SkillUtils {
|
||||||
/**
|
/**
|
||||||
* This is a static utility class, therefore we don't want any instances of
|
* This is a static utility class, therefore we don't want any instances of
|
||||||
|
|
|
@ -56,18 +56,23 @@ public class TextComponentFactory {
|
||||||
return Component.text(text);
|
return Component.text(text);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void sendPlayerSubSkillWikiLink(Player player, String subskillformatted) {
|
public static String getSubSkillWikiLink(SubSkillType subSkillType) {
|
||||||
|
return "https://wiki.mcmmo.org/en/skills/"
|
||||||
|
+ subSkillType.getParentSkill().toString().toLowerCase(Locale.ENGLISH) + "#"
|
||||||
|
+ subSkillType.getWikiUrl().toLowerCase(Locale.ENGLISH);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void sendPlayerSubSkillWikiLink(Player player, String subskillformatted, SubSkillType subSkillType) {
|
||||||
if (!mcMMO.p.getGeneralConfig().getUrlLinksEnabled())
|
if (!mcMMO.p.getGeneralConfig().getUrlLinksEnabled())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
TextComponent.Builder wikiLinkComponent = Component.text().content(LocaleLoader.getString("Overhaul.mcMMO.MmoInfo.Wiki"));
|
TextComponent.Builder wikiLinkComponent = Component.text().content(LocaleLoader.getString("Overhaul.mcMMO.MmoInfo.Wiki"));
|
||||||
wikiLinkComponent.decoration(TextDecoration.UNDERLINED, true);
|
wikiLinkComponent.decoration(TextDecoration.UNDERLINED, true);
|
||||||
|
|
||||||
String wikiUrl = "https://wiki.mcmmo.org/" + subskillformatted;
|
final String subSkillWikiLink = getSubSkillWikiLink(subSkillType);
|
||||||
|
wikiLinkComponent.clickEvent(ClickEvent.openUrl(subSkillWikiLink));
|
||||||
|
|
||||||
wikiLinkComponent.clickEvent(ClickEvent.openUrl(wikiUrl));
|
TextComponent.Builder componentBuilder = Component.text().content(subskillformatted).append(Component.newline()).append(Component.text(subSkillWikiLink)).color(NamedTextColor.GRAY).decoration(TextDecoration.ITALIC, true);
|
||||||
|
|
||||||
TextComponent.Builder componentBuilder = Component.text().content(subskillformatted).append(Component.newline()).append(Component.text(wikiUrl)).color(NamedTextColor.GRAY).decoration(TextDecoration.ITALIC, true);
|
|
||||||
|
|
||||||
wikiLinkComponent.hoverEvent(HoverEvent.showText(componentBuilder.build()));
|
wikiLinkComponent.hoverEvent(HoverEvent.showText(componentBuilder.build()));
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,11 @@
|
||||||
|
# This is meant to be a general config for allowing mcMMO to allow interaction with custom items.
|
||||||
|
# In the future, I would like to add configs to be specific about certain custom items.
|
||||||
|
# For now, support is generalized to whether the custom item has a custom model.
|
||||||
|
# This is an easy solution to implement for now, but not the most ideal.
|
||||||
|
Custom_Item_Support:
|
||||||
|
Repair:
|
||||||
|
# Turn this off to disable repair on any items with custom model data
|
||||||
|
Allow_Repair_On_Items_With_Custom_Model_Data: true
|
||||||
|
Salvage:
|
||||||
|
# Turn this off to disable salvage on any items with custom model data
|
||||||
|
Allow_Salvage_On_Items_With_Custom_Model_Data: true
|
|
@ -423,6 +423,8 @@ Salvage.Skills.Lottery.Perfect=&a&lPerfect!&r&6 You salvaged &3{1}&6 effortlessl
|
||||||
Salvage.Skills.Lottery.Untrained=&7You aren't properly trained in salvaging. You were only able to recover &c{0}&7 materials from &a{1}&7.
|
Salvage.Skills.Lottery.Untrained=&7You aren't properly trained in salvaging. You were only able to recover &c{0}&7 materials from &a{1}&7.
|
||||||
#Anvil (Shared between SALVAGE and REPAIR)
|
#Anvil (Shared between SALVAGE and REPAIR)
|
||||||
Anvil.Unbreakable=This item is unbreakable!
|
Anvil.Unbreakable=This item is unbreakable!
|
||||||
|
Anvil.Repair.Reject.CustomModelData=A mysterious force prevents you from repairing this item...
|
||||||
|
Anvil.Salvage.Reject.CustomModelData=A mysterious force prevents you from salvaging this item...
|
||||||
#CROSSBOWS
|
#CROSSBOWS
|
||||||
Crossbows.SkillName=CROSSBOWS
|
Crossbows.SkillName=CROSSBOWS
|
||||||
Crossbows.Ability.Lower=&7You lower your crossbow.
|
Crossbows.Ability.Lower=&7You lower your crossbow.
|
||||||
|
|
|
@ -1,245 +1,245 @@
|
||||||
package com.gmail.nossr50.database;
|
//package com.gmail.nossr50.database;
|
||||||
|
//
|
||||||
import com.gmail.nossr50.config.AdvancedConfig;
|
//import com.gmail.nossr50.config.AdvancedConfig;
|
||||||
import com.gmail.nossr50.config.GeneralConfig;
|
//import com.gmail.nossr50.config.GeneralConfig;
|
||||||
import com.gmail.nossr50.datatypes.MobHealthbarType;
|
//import com.gmail.nossr50.datatypes.MobHealthbarType;
|
||||||
import com.gmail.nossr50.datatypes.player.PlayerProfile;
|
//import com.gmail.nossr50.datatypes.player.PlayerProfile;
|
||||||
import com.gmail.nossr50.datatypes.skills.PrimarySkillType;
|
//import com.gmail.nossr50.datatypes.skills.PrimarySkillType;
|
||||||
import com.gmail.nossr50.mcMMO;
|
//import com.gmail.nossr50.mcMMO;
|
||||||
import com.gmail.nossr50.util.compat.CompatibilityManager;
|
//import com.gmail.nossr50.util.compat.CompatibilityManager;
|
||||||
import com.gmail.nossr50.util.platform.MinecraftGameVersion;
|
//import com.gmail.nossr50.util.platform.MinecraftGameVersion;
|
||||||
import com.gmail.nossr50.util.skills.SkillTools;
|
//import com.gmail.nossr50.util.skills.SkillTools;
|
||||||
import com.gmail.nossr50.util.upgrade.UpgradeManager;
|
//import com.gmail.nossr50.util.upgrade.UpgradeManager;
|
||||||
import org.bukkit.entity.Player;
|
//import org.bukkit.entity.Player;
|
||||||
import org.jetbrains.annotations.NotNull;
|
//import org.jetbrains.annotations.NotNull;
|
||||||
import org.junit.jupiter.api.*;
|
//import org.junit.jupiter.api.*;
|
||||||
import org.mockito.MockedStatic;
|
//import org.mockito.MockedStatic;
|
||||||
import org.mockito.Mockito;
|
//import org.mockito.Mockito;
|
||||||
|
//
|
||||||
import java.util.logging.Logger;
|
//import java.util.logging.Logger;
|
||||||
|
//
|
||||||
import static org.junit.jupiter.api.Assertions.*;
|
//import static org.junit.jupiter.api.Assertions.*;
|
||||||
import static org.mockito.ArgumentMatchers.any;
|
//import static org.mockito.ArgumentMatchers.any;
|
||||||
import static org.mockito.Mockito.when;
|
//import static org.mockito.Mockito.when;
|
||||||
|
//
|
||||||
class SQLDatabaseManagerTest {
|
//class SQLDatabaseManagerTest {
|
||||||
private final static @NotNull Logger logger = Logger.getLogger(Logger.GLOBAL_LOGGER_NAME);
|
// private final static @NotNull Logger logger = Logger.getLogger(Logger.GLOBAL_LOGGER_NAME);
|
||||||
static MockedStatic<mcMMO> mockedMcMMO;
|
// static MockedStatic<mcMMO> mockedMcMMO;
|
||||||
SQLDatabaseManager sqlDatabaseManager;
|
// SQLDatabaseManager sqlDatabaseManager;
|
||||||
static GeneralConfig generalConfig;
|
// static GeneralConfig generalConfig;
|
||||||
static AdvancedConfig advancedConfig;
|
// static AdvancedConfig advancedConfig;
|
||||||
static UpgradeManager upgradeManager;
|
// static UpgradeManager upgradeManager;
|
||||||
static CompatibilityManager compatibilityManager;
|
// static CompatibilityManager compatibilityManager;
|
||||||
static SkillTools skillTools;
|
// static SkillTools skillTools;
|
||||||
|
//
|
||||||
@BeforeAll
|
// @BeforeAll
|
||||||
static void setUpAll() {
|
// static void setUpAll() {
|
||||||
// stub mcMMO.p
|
// // stub mcMMO.p
|
||||||
mockedMcMMO = Mockito.mockStatic(mcMMO.class);
|
// mockedMcMMO = Mockito.mockStatic(mcMMO.class);
|
||||||
mcMMO.p = Mockito.mock(mcMMO.class);
|
// mcMMO.p = Mockito.mock(mcMMO.class);
|
||||||
when(mcMMO.p.getLogger()).thenReturn(logger);
|
// when(mcMMO.p.getLogger()).thenReturn(logger);
|
||||||
|
//
|
||||||
// general config mock
|
// // general config mock
|
||||||
mockGeneralConfig();
|
// mockGeneralConfig();
|
||||||
|
//
|
||||||
// advanced config mock
|
// // advanced config mock
|
||||||
advancedConfig = Mockito.mock(AdvancedConfig.class);
|
// advancedConfig = Mockito.mock(AdvancedConfig.class);
|
||||||
when(mcMMO.p.getAdvancedConfig()).thenReturn(advancedConfig);
|
// when(mcMMO.p.getAdvancedConfig()).thenReturn(advancedConfig);
|
||||||
|
//
|
||||||
// starting level
|
// // starting level
|
||||||
when(mcMMO.p.getAdvancedConfig().getStartingLevel()).thenReturn(0);
|
// when(mcMMO.p.getAdvancedConfig().getStartingLevel()).thenReturn(0);
|
||||||
|
//
|
||||||
// wire skill tools
|
// // wire skill tools
|
||||||
skillTools = new SkillTools(mcMMO.p);
|
// skillTools = new SkillTools(mcMMO.p);
|
||||||
when(mcMMO.p.getSkillTools()).thenReturn(skillTools);
|
// when(mcMMO.p.getSkillTools()).thenReturn(skillTools);
|
||||||
|
//
|
||||||
// compatibility manager mock
|
// // compatibility manager mock
|
||||||
compatibilityManager = Mockito.mock(CompatibilityManager.class);
|
// compatibilityManager = Mockito.mock(CompatibilityManager.class);
|
||||||
when(mcMMO.getCompatibilityManager()).thenReturn(compatibilityManager);
|
// when(mcMMO.getCompatibilityManager()).thenReturn(compatibilityManager);
|
||||||
when(compatibilityManager.getMinecraftGameVersion()).thenReturn(new MinecraftGameVersion(1, 20, 4));
|
// when(compatibilityManager.getMinecraftGameVersion()).thenReturn(new MinecraftGameVersion(1, 20, 4));
|
||||||
|
//
|
||||||
// upgrade manager mock
|
// // upgrade manager mock
|
||||||
upgradeManager = Mockito.mock(UpgradeManager.class);
|
// upgradeManager = Mockito.mock(UpgradeManager.class);
|
||||||
when(mcMMO.getUpgradeManager()).thenReturn(upgradeManager);
|
// when(mcMMO.getUpgradeManager()).thenReturn(upgradeManager);
|
||||||
|
//
|
||||||
// don't trigger upgrades
|
// // don't trigger upgrades
|
||||||
when(mcMMO.getUpgradeManager().shouldUpgrade(any())).thenReturn(false);
|
// when(mcMMO.getUpgradeManager().shouldUpgrade(any())).thenReturn(false);
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
private static void mockGeneralConfig() {
|
// private static void mockGeneralConfig() {
|
||||||
generalConfig = Mockito.mock(GeneralConfig.class);
|
// generalConfig = Mockito.mock(GeneralConfig.class);
|
||||||
when(generalConfig.getLocale()).thenReturn("en_US");
|
// when(generalConfig.getLocale()).thenReturn("en_US");
|
||||||
when(mcMMO.p.getGeneralConfig()).thenReturn(generalConfig);
|
// when(mcMMO.p.getGeneralConfig()).thenReturn(generalConfig);
|
||||||
|
//
|
||||||
// max pool size
|
// // max pool size
|
||||||
when(mcMMO.p.getGeneralConfig().getMySQLMaxPoolSize(SQLDatabaseManager.PoolIdentifier.MISC))
|
// when(mcMMO.p.getGeneralConfig().getMySQLMaxPoolSize(SQLDatabaseManager.PoolIdentifier.MISC))
|
||||||
.thenReturn(10);
|
// .thenReturn(10);
|
||||||
when(mcMMO.p.getGeneralConfig().getMySQLMaxPoolSize(SQLDatabaseManager.PoolIdentifier.LOAD))
|
// when(mcMMO.p.getGeneralConfig().getMySQLMaxPoolSize(SQLDatabaseManager.PoolIdentifier.LOAD))
|
||||||
.thenReturn(20);
|
// .thenReturn(20);
|
||||||
when(mcMMO.p.getGeneralConfig().getMySQLMaxPoolSize(SQLDatabaseManager.PoolIdentifier.SAVE))
|
// when(mcMMO.p.getGeneralConfig().getMySQLMaxPoolSize(SQLDatabaseManager.PoolIdentifier.SAVE))
|
||||||
.thenReturn(20);
|
// .thenReturn(20);
|
||||||
|
//
|
||||||
// max connections
|
// // max connections
|
||||||
when(mcMMO.p.getGeneralConfig().getMySQLMaxConnections(SQLDatabaseManager.PoolIdentifier.MISC))
|
// when(mcMMO.p.getGeneralConfig().getMySQLMaxConnections(SQLDatabaseManager.PoolIdentifier.MISC))
|
||||||
.thenReturn(30);
|
// .thenReturn(30);
|
||||||
when(mcMMO.p.getGeneralConfig().getMySQLMaxConnections(SQLDatabaseManager.PoolIdentifier.LOAD))
|
// when(mcMMO.p.getGeneralConfig().getMySQLMaxConnections(SQLDatabaseManager.PoolIdentifier.LOAD))
|
||||||
.thenReturn(30);
|
// .thenReturn(30);
|
||||||
when(mcMMO.p.getGeneralConfig().getMySQLMaxConnections(SQLDatabaseManager.PoolIdentifier.SAVE))
|
// when(mcMMO.p.getGeneralConfig().getMySQLMaxConnections(SQLDatabaseManager.PoolIdentifier.SAVE))
|
||||||
.thenReturn(30);
|
// .thenReturn(30);
|
||||||
|
//
|
||||||
// table prefix
|
// // table prefix
|
||||||
when(mcMMO.p.getGeneralConfig().getMySQLTablePrefix()).thenReturn("mcmmo_");
|
// when(mcMMO.p.getGeneralConfig().getMySQLTablePrefix()).thenReturn("mcmmo_");
|
||||||
|
//
|
||||||
// public key retrieval
|
// // public key retrieval
|
||||||
when(mcMMO.p.getGeneralConfig().getMySQLPublicKeyRetrieval()).thenReturn(true);
|
// when(mcMMO.p.getGeneralConfig().getMySQLPublicKeyRetrieval()).thenReturn(true);
|
||||||
|
//
|
||||||
// debug
|
// // debug
|
||||||
when(mcMMO.p.getGeneralConfig().getMySQLDebug()).thenReturn(true);
|
// when(mcMMO.p.getGeneralConfig().getMySQLDebug()).thenReturn(true);
|
||||||
|
//
|
||||||
// use mysql
|
// // use mysql
|
||||||
when(mcMMO.p.getGeneralConfig().getUseMySQL()).thenReturn(true);
|
// when(mcMMO.p.getGeneralConfig().getUseMySQL()).thenReturn(true);
|
||||||
|
//
|
||||||
// use ssl
|
// // use ssl
|
||||||
when(mcMMO.p.getGeneralConfig().getMySQLSSL()).thenReturn(true);
|
// when(mcMMO.p.getGeneralConfig().getMySQLSSL()).thenReturn(true);
|
||||||
|
//
|
||||||
// username
|
// // username
|
||||||
when(mcMMO.p.getGeneralConfig().getMySQLUserName()).thenReturn("sa");
|
// when(mcMMO.p.getGeneralConfig().getMySQLUserName()).thenReturn("sa");
|
||||||
|
//
|
||||||
// password
|
// // password
|
||||||
when(mcMMO.p.getGeneralConfig().getMySQLUserPassword()).thenReturn("");
|
// when(mcMMO.p.getGeneralConfig().getMySQLUserPassword()).thenReturn("");
|
||||||
|
//
|
||||||
// host
|
// // host
|
||||||
when(mcMMO.p.getGeneralConfig().getMySQLServerName()).thenReturn("localhost");
|
// when(mcMMO.p.getGeneralConfig().getMySQLServerName()).thenReturn("localhost");
|
||||||
|
//
|
||||||
// unused mob health bar thingy
|
// // unused mob health bar thingy
|
||||||
when(mcMMO.p.getGeneralConfig().getMobHealthbarDefault()).thenReturn(MobHealthbarType.HEARTS);
|
// when(mcMMO.p.getGeneralConfig().getMobHealthbarDefault()).thenReturn(MobHealthbarType.HEARTS);
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
@BeforeEach
|
// @BeforeEach
|
||||||
void setUp() {
|
// void setUp() {
|
||||||
assertNull(sqlDatabaseManager);
|
// assertNull(sqlDatabaseManager);
|
||||||
sqlDatabaseManager = new SQLDatabaseManager(logger, "org.h2.Driver", true);
|
// sqlDatabaseManager = new SQLDatabaseManager(logger, "org.h2.Driver", true);
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
@AfterEach
|
// @AfterEach
|
||||||
void tearDown() {
|
// void tearDown() {
|
||||||
sqlDatabaseManager = null;
|
// sqlDatabaseManager = null;
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
@AfterAll
|
// @AfterAll
|
||||||
static void tearDownAll() {
|
// static void tearDownAll() {
|
||||||
mockedMcMMO.close();
|
// mockedMcMMO.close();
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
@Test
|
// @Test
|
||||||
void testGetConnectionMisc() throws Exception {
|
// void testGetConnectionMisc() throws Exception {
|
||||||
assertNotNull(sqlDatabaseManager.getConnection(SQLDatabaseManager.PoolIdentifier.MISC));
|
// assertNotNull(sqlDatabaseManager.getConnection(SQLDatabaseManager.PoolIdentifier.MISC));
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
@Test
|
// @Test
|
||||||
void testGetConnectionLoad() throws Exception {
|
// void testGetConnectionLoad() throws Exception {
|
||||||
assertNotNull(sqlDatabaseManager.getConnection(SQLDatabaseManager.PoolIdentifier.LOAD));
|
// assertNotNull(sqlDatabaseManager.getConnection(SQLDatabaseManager.PoolIdentifier.LOAD));
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
@Test
|
// @Test
|
||||||
void testGetConnectionSave() throws Exception {
|
// void testGetConnectionSave() throws Exception {
|
||||||
assertNotNull(sqlDatabaseManager.getConnection(SQLDatabaseManager.PoolIdentifier.SAVE));
|
// assertNotNull(sqlDatabaseManager.getConnection(SQLDatabaseManager.PoolIdentifier.SAVE));
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
@Test
|
// @Test
|
||||||
void testNewUser() {
|
// void testNewUser() {
|
||||||
Player player = Mockito.mock(Player.class);
|
// Player player = Mockito.mock(Player.class);
|
||||||
when(player.getUniqueId()).thenReturn(java.util.UUID.randomUUID());
|
// when(player.getUniqueId()).thenReturn(java.util.UUID.randomUUID());
|
||||||
when(player.getName()).thenReturn("nossr50");
|
// when(player.getName()).thenReturn("nossr50");
|
||||||
sqlDatabaseManager.newUser(player);
|
// sqlDatabaseManager.newUser(player);
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
@Test
|
// @Test
|
||||||
void testNewUserGetSkillLevel() {
|
// void testNewUserGetSkillLevel() {
|
||||||
Player player = Mockito.mock(Player.class);
|
// Player player = Mockito.mock(Player.class);
|
||||||
when(player.getUniqueId()).thenReturn(java.util.UUID.randomUUID());
|
// when(player.getUniqueId()).thenReturn(java.util.UUID.randomUUID());
|
||||||
when(player.getName()).thenReturn("nossr50");
|
// when(player.getName()).thenReturn("nossr50");
|
||||||
PlayerProfile playerProfile = sqlDatabaseManager.newUser(player);
|
// PlayerProfile playerProfile = sqlDatabaseManager.newUser(player);
|
||||||
|
//
|
||||||
for (PrimarySkillType primarySkillType : PrimarySkillType.values()) {
|
// for (PrimarySkillType primarySkillType : PrimarySkillType.values()) {
|
||||||
assertEquals(0, playerProfile.getSkillLevel(primarySkillType));
|
// assertEquals(0, playerProfile.getSkillLevel(primarySkillType));
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
@Test
|
// @Test
|
||||||
void testNewUserGetSkillXpLevel() {
|
// void testNewUserGetSkillXpLevel() {
|
||||||
Player player = Mockito.mock(Player.class);
|
// Player player = Mockito.mock(Player.class);
|
||||||
when(player.getUniqueId()).thenReturn(java.util.UUID.randomUUID());
|
// when(player.getUniqueId()).thenReturn(java.util.UUID.randomUUID());
|
||||||
when(player.getName()).thenReturn("nossr50");
|
// when(player.getName()).thenReturn("nossr50");
|
||||||
PlayerProfile playerProfile = sqlDatabaseManager.newUser(player);
|
// PlayerProfile playerProfile = sqlDatabaseManager.newUser(player);
|
||||||
|
//
|
||||||
for (PrimarySkillType primarySkillType : PrimarySkillType.values()) {
|
// for (PrimarySkillType primarySkillType : PrimarySkillType.values()) {
|
||||||
assertEquals(0, playerProfile.getSkillXpLevel(primarySkillType));
|
// assertEquals(0, playerProfile.getSkillXpLevel(primarySkillType));
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
@Test
|
// @Test
|
||||||
void testSaveSkillLevelValues() {
|
// void testSaveSkillLevelValues() {
|
||||||
Player player = Mockito.mock(Player.class);
|
// Player player = Mockito.mock(Player.class);
|
||||||
when(player.getUniqueId()).thenReturn(java.util.UUID.randomUUID());
|
// when(player.getUniqueId()).thenReturn(java.util.UUID.randomUUID());
|
||||||
when(player.getName()).thenReturn("nossr50");
|
// when(player.getName()).thenReturn("nossr50");
|
||||||
PlayerProfile playerProfile = sqlDatabaseManager.newUser(player);
|
// PlayerProfile playerProfile = sqlDatabaseManager.newUser(player);
|
||||||
|
//
|
||||||
// Validate values are starting from zero
|
// // Validate values are starting from zero
|
||||||
for (PrimarySkillType primarySkillType : PrimarySkillType.values()) {
|
// for (PrimarySkillType primarySkillType : PrimarySkillType.values()) {
|
||||||
assertEquals(0, playerProfile.getSkillXpLevel(primarySkillType));
|
// assertEquals(0, playerProfile.getSkillXpLevel(primarySkillType));
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
// Change values
|
// // Change values
|
||||||
for (PrimarySkillType primarySkillType : PrimarySkillType.values()) {
|
// for (PrimarySkillType primarySkillType : PrimarySkillType.values()) {
|
||||||
playerProfile.modifySkill(primarySkillType, 1 + primarySkillType.ordinal());
|
// playerProfile.modifySkill(primarySkillType, 1 + primarySkillType.ordinal());
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
boolean saveSuccess = sqlDatabaseManager.saveUser(playerProfile);
|
// boolean saveSuccess = sqlDatabaseManager.saveUser(playerProfile);
|
||||||
assertTrue(saveSuccess);
|
// assertTrue(saveSuccess);
|
||||||
|
//
|
||||||
PlayerProfile retrievedUser = sqlDatabaseManager.loadPlayerProfile(player.getName());
|
// PlayerProfile retrievedUser = sqlDatabaseManager.loadPlayerProfile(player.getName());
|
||||||
|
//
|
||||||
// Check that values got saved
|
// // Check that values got saved
|
||||||
for (PrimarySkillType primarySkillType : PrimarySkillType.values()) {
|
// for (PrimarySkillType primarySkillType : PrimarySkillType.values()) {
|
||||||
if (primarySkillType == PrimarySkillType.SALVAGE || primarySkillType == PrimarySkillType.SMELTING) {
|
// if (primarySkillType == PrimarySkillType.SALVAGE || primarySkillType == PrimarySkillType.SMELTING) {
|
||||||
// Child skills are not saved, but calculated
|
// // Child skills are not saved, but calculated
|
||||||
continue;
|
// continue;
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
assertEquals(1 + primarySkillType.ordinal(), retrievedUser.getSkillLevel(primarySkillType));
|
// assertEquals(1 + primarySkillType.ordinal(), retrievedUser.getSkillLevel(primarySkillType));
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
@Test
|
// @Test
|
||||||
void testSaveSkillXpValues() {
|
// void testSaveSkillXpValues() {
|
||||||
Player player = Mockito.mock(Player.class);
|
// Player player = Mockito.mock(Player.class);
|
||||||
when(player.getUniqueId()).thenReturn(java.util.UUID.randomUUID());
|
// when(player.getUniqueId()).thenReturn(java.util.UUID.randomUUID());
|
||||||
when(player.getName()).thenReturn("nossr50");
|
// when(player.getName()).thenReturn("nossr50");
|
||||||
PlayerProfile playerProfile = sqlDatabaseManager.newUser(player);
|
// PlayerProfile playerProfile = sqlDatabaseManager.newUser(player);
|
||||||
|
//
|
||||||
// Validate values are starting from zero
|
// // Validate values are starting from zero
|
||||||
for (PrimarySkillType primarySkillType : PrimarySkillType.values()) {
|
// for (PrimarySkillType primarySkillType : PrimarySkillType.values()) {
|
||||||
assertEquals(0, playerProfile.getSkillXpLevel(primarySkillType));
|
// assertEquals(0, playerProfile.getSkillXpLevel(primarySkillType));
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
// Change values
|
// // Change values
|
||||||
for (PrimarySkillType primarySkillType : PrimarySkillType.values()) {
|
// for (PrimarySkillType primarySkillType : PrimarySkillType.values()) {
|
||||||
playerProfile.setSkillXpLevel(primarySkillType, 1 + primarySkillType.ordinal());
|
// playerProfile.setSkillXpLevel(primarySkillType, 1 + primarySkillType.ordinal());
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
sqlDatabaseManager.saveUser(playerProfile);
|
// sqlDatabaseManager.saveUser(playerProfile);
|
||||||
|
//
|
||||||
PlayerProfile retrievedUser = sqlDatabaseManager.loadPlayerProfile(player.getName());
|
// PlayerProfile retrievedUser = sqlDatabaseManager.loadPlayerProfile(player.getName());
|
||||||
|
//
|
||||||
// Check that values got saved
|
// // Check that values got saved
|
||||||
for (PrimarySkillType primarySkillType : PrimarySkillType.values()) {
|
// for (PrimarySkillType primarySkillType : PrimarySkillType.values()) {
|
||||||
if (primarySkillType == PrimarySkillType.SALVAGE || primarySkillType == PrimarySkillType.SMELTING) {
|
// if (primarySkillType == PrimarySkillType.SALVAGE || primarySkillType == PrimarySkillType.SMELTING) {
|
||||||
// Child skills are not saved, but calculated
|
// // Child skills are not saved, but calculated
|
||||||
continue;
|
// continue;
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
assertEquals(1 + primarySkillType.ordinal(), retrievedUser.getSkillXpLevel(primarySkillType));
|
// assertEquals(1 + primarySkillType.ordinal(), retrievedUser.getSkillXpLevel(primarySkillType));
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
}
|
//}
|
||||||
|
|
|
@ -73,8 +73,9 @@ class WoodcuttingTest extends MMOTestEnvironment {
|
||||||
woodcuttingManager.processBonusDropCheck(blockState);
|
woodcuttingManager.processBonusDropCheck(blockState);
|
||||||
|
|
||||||
// verify bonus drops were spawned
|
// verify bonus drops were spawned
|
||||||
// TODO: Can fail if triple drops happen, need to update test
|
// TODO: using at least once since triple drops can also happen
|
||||||
Mockito.verify(woodcuttingManager, Mockito.times(1)).spawnHarvestLumberBonusDrops(blockState);
|
// TODO: Change the test env to disallow triple drop in the future
|
||||||
|
Mockito.verify(woodcuttingManager, Mockito.atLeastOnce()).spawnHarvestLumberBonusDrops(blockState);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
|
|
@ -14,19 +14,19 @@ class ProbabilityTest {
|
||||||
private static Stream<Arguments> provideProbabilitiesForWithinExpectations() {
|
private static Stream<Arguments> provideProbabilitiesForWithinExpectations() {
|
||||||
return Stream.of(
|
return Stream.of(
|
||||||
// static probability, % of time for success
|
// static probability, % of time for success
|
||||||
Arguments.of(new ProbabilityImpl(5), 5),
|
Arguments.of(new ProbabilityImpl(.05), 5),
|
||||||
Arguments.of(new ProbabilityImpl(10), 10),
|
Arguments.of(new ProbabilityImpl(.10), 10),
|
||||||
Arguments.of(new ProbabilityImpl(15), 15),
|
Arguments.of(new ProbabilityImpl(.15), 15),
|
||||||
Arguments.of(new ProbabilityImpl(20), 20),
|
Arguments.of(new ProbabilityImpl(.20), 20),
|
||||||
Arguments.of(new ProbabilityImpl(25), 25),
|
Arguments.of(new ProbabilityImpl(.25), 25),
|
||||||
Arguments.of(new ProbabilityImpl(50), 50),
|
Arguments.of(new ProbabilityImpl(.50), 50),
|
||||||
Arguments.of(new ProbabilityImpl(75), 75),
|
Arguments.of(new ProbabilityImpl(.75), 75),
|
||||||
Arguments.of(new ProbabilityImpl(90), 90),
|
Arguments.of(new ProbabilityImpl(.90), 90),
|
||||||
Arguments.of(new ProbabilityImpl(99.9), 99.9),
|
Arguments.of(new ProbabilityImpl(.999), 99.9),
|
||||||
Arguments.of(new ProbabilityImpl(0.05), 0.05),
|
Arguments.of(new ProbabilityImpl(0.0005), 0.05),
|
||||||
Arguments.of(new ProbabilityImpl(0.1), 0.1),
|
Arguments.of(new ProbabilityImpl(0.001), 0.1),
|
||||||
Arguments.of(new ProbabilityImpl(500), 100),
|
Arguments.of(new ProbabilityImpl(50.0), 100),
|
||||||
Arguments.of(new ProbabilityImpl(1000), 100)
|
Arguments.of(new ProbabilityImpl(100.0), 100)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,22 @@
|
||||||
|
package com.gmail.nossr50.util.random;
|
||||||
|
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||||
|
|
||||||
|
public class ProbabilityTestUtils {
|
||||||
|
public static void assertProbabilityExpectations(double expectedWinPercent, Probability probability) {
|
||||||
|
double iterations = 2.0e7; //20 million
|
||||||
|
double winCount = 0;
|
||||||
|
for (int i = 0; i < iterations; i++) {
|
||||||
|
if(probability.evaluate()) {
|
||||||
|
winCount++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
double successPercent = (winCount / iterations) * 100;
|
||||||
|
System.out.println("Wins: " + winCount);
|
||||||
|
System.out.println("Fails: " + (iterations - winCount));
|
||||||
|
System.out.println("Percentage succeeded: " + successPercent + ", Expected: " + expectedWinPercent);
|
||||||
|
assertEquals(expectedWinPercent, successPercent, 0.025D);
|
||||||
|
System.out.println("Variance is within tolerance levels!");
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,39 +1,44 @@
|
||||||
package com.gmail.nossr50.util.random;
|
package com.gmail.nossr50.util.random;
|
||||||
|
|
||||||
import com.gmail.nossr50.config.AdvancedConfig;
|
import com.gmail.nossr50.MMOTestEnvironment;
|
||||||
import com.gmail.nossr50.datatypes.skills.SubSkillType;
|
import com.gmail.nossr50.datatypes.skills.SubSkillType;
|
||||||
import com.gmail.nossr50.mcMMO;
|
import org.junit.jupiter.api.AfterEach;
|
||||||
import org.junit.jupiter.api.BeforeEach;
|
import org.junit.jupiter.api.BeforeEach;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
import org.junit.jupiter.params.ParameterizedTest;
|
import org.junit.jupiter.params.ParameterizedTest;
|
||||||
import org.junit.jupiter.params.provider.Arguments;
|
import org.junit.jupiter.params.provider.Arguments;
|
||||||
import org.junit.jupiter.params.provider.MethodSource;
|
import org.junit.jupiter.params.provider.MethodSource;
|
||||||
|
|
||||||
|
import java.util.logging.Logger;
|
||||||
import java.util.stream.Stream;
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
import static com.gmail.nossr50.datatypes.skills.SubSkillType.*;
|
import static com.gmail.nossr50.datatypes.skills.SubSkillType.*;
|
||||||
|
import static com.gmail.nossr50.util.random.ProbabilityTestUtils.assertProbabilityExpectations;
|
||||||
|
import static com.gmail.nossr50.util.random.ProbabilityUtil.calculateCurrentSkillProbability;
|
||||||
|
import static java.util.logging.Logger.getLogger;
|
||||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||||
import static org.mockito.Mockito.mock;
|
|
||||||
import static org.mockito.Mockito.when;
|
import static org.mockito.Mockito.when;
|
||||||
|
|
||||||
class ProbabilityUtilTest {
|
class ProbabilityUtilTest extends MMOTestEnvironment {
|
||||||
mcMMO mmoInstance;
|
private static final Logger logger = getLogger(ProbabilityUtilTest.class.getName());
|
||||||
AdvancedConfig advancedConfig;
|
|
||||||
|
|
||||||
final static double impactChance = 11D;
|
final static double impactChance = 11D;
|
||||||
final static double greaterImpactChance = 0.007D;
|
final static double greaterImpactChance = 0.007D;
|
||||||
final static double fastFoodChance = 45.5D;
|
final static double fastFoodChance = 45.5D;
|
||||||
|
|
||||||
@BeforeEach
|
@BeforeEach
|
||||||
public void setupMocks() throws NoSuchFieldException, IllegalAccessException {
|
public void setupMocks() {
|
||||||
this.mmoInstance = mock(mcMMO.class);
|
mockBaseEnvironment(logger);
|
||||||
mcMMO.class.getField("p").set(null, mmoInstance);
|
|
||||||
this.advancedConfig = mock(AdvancedConfig.class);
|
|
||||||
when(mmoInstance.getAdvancedConfig()).thenReturn(advancedConfig);
|
|
||||||
when(advancedConfig.getImpactChance()).thenReturn(impactChance);
|
when(advancedConfig.getImpactChance()).thenReturn(impactChance);
|
||||||
when(advancedConfig.getGreaterImpactChance()).thenReturn(greaterImpactChance);
|
when(advancedConfig.getGreaterImpactChance()).thenReturn(greaterImpactChance);
|
||||||
when(advancedConfig.getFastFoodChance()).thenReturn(fastFoodChance);
|
when(advancedConfig.getFastFoodChance()).thenReturn(fastFoodChance);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@AfterEach
|
||||||
|
public void tearDown() {
|
||||||
|
cleanupBaseEnvironment();
|
||||||
|
}
|
||||||
|
|
||||||
private static Stream<Arguments> staticChanceSkills() {
|
private static Stream<Arguments> staticChanceSkills() {
|
||||||
return Stream.of(
|
return Stream.of(
|
||||||
// static probability, % of time for success
|
// static probability, % of time for success
|
||||||
|
@ -45,22 +50,26 @@ class ProbabilityUtilTest {
|
||||||
|
|
||||||
@ParameterizedTest
|
@ParameterizedTest
|
||||||
@MethodSource("staticChanceSkills")
|
@MethodSource("staticChanceSkills")
|
||||||
void testStaticChanceSkills(SubSkillType subSkillType, double expectedWinPercent) throws InvalidStaticChance {
|
void staticChanceSkillsShouldSucceedAsExpected(SubSkillType subSkillType, double expectedWinPercent)
|
||||||
|
throws InvalidStaticChance {
|
||||||
Probability staticRandomChance = ProbabilityUtil.getStaticRandomChance(subSkillType);
|
Probability staticRandomChance = ProbabilityUtil.getStaticRandomChance(subSkillType);
|
||||||
assertProbabilityExpectations(expectedWinPercent, staticRandomChance);
|
assertProbabilityExpectations(expectedWinPercent, staticRandomChance);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void assertProbabilityExpectations(double expectedWinPercent, Probability probability) {
|
@Test
|
||||||
double iterations = 2.0e7;
|
public void isSkillRNGSuccessfulShouldBehaveAsExpected() {
|
||||||
double winCount = 0;
|
// Given
|
||||||
for (int i = 0; i < iterations; i++) {
|
when(advancedConfig.getMaximumProbability(UNARMED_ARROW_DEFLECT)).thenReturn(20D);
|
||||||
if(probability.evaluate()) {
|
when(advancedConfig.getMaxBonusLevel(UNARMED_ARROW_DEFLECT)).thenReturn(0);
|
||||||
winCount++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
double successPercent = (winCount / iterations) * 100;
|
final Probability probability = ProbabilityUtil.getSkillProbability(UNARMED_ARROW_DEFLECT, player);
|
||||||
System.out.println(successPercent + ", " + expectedWinPercent);
|
assertEquals(0.2D, probability.getValue());
|
||||||
assertEquals(expectedWinPercent, successPercent, 0.05D);
|
assertProbabilityExpectations(20, probability);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void calculateCurrentSkillProbabilityShouldBeTwenty() {
|
||||||
|
final Probability probability = calculateCurrentSkillProbability(1000, 0, 20, 1000);
|
||||||
|
assertEquals(0.2D, probability.getValue());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue