mirror of
https://github.com/mcMMO-Dev/mcMMO.git
synced 2024-11-24 14:16:45 +01:00
Merge branch 'master' of https://github.com/mcMMO-Dev/mcMMO into tridentsxbows
This commit is contained in:
commit
fc10243d6f
@ -99,6 +99,15 @@ Version 2.2.000
|
||||
Parties got unnecessarily complex in my absence, I have removed many party features in order to simplify parties and bring them closer to my vision. I have also added new features which should improve parties where it matters.
|
||||
About the removed party features, all the features I removed I consider poor quality features and I don't think they belong in mcMMO. Feel free to yell at me in discord if you disagree.
|
||||
I don't know what genius decided to make parties public by default, when I found out that parties had been changed to such a system I could barely contain my disgust. Parties are back to being private, you get invited by a party leader or party officer. That is the only way to join a party.
|
||||
Version 2.1.170
|
||||
Reverted a change that broke compatibility with the mcMMO papi ecloud thingy
|
||||
|
||||
Version 2.1.169
|
||||
Fixed a few memory leaks involving arrows
|
||||
Fixed mcMMO inappropriately assigning metadata to projectiles not fired from players
|
||||
Fix mctop not working if locale was set to something other than en_US
|
||||
mcMMO will now always emulate lure in order to stack it correctly and avoid vanilla bugs
|
||||
|
||||
Version 2.1.168
|
||||
Fixed an IndexOutOfBoundsException error when trying to access UserBlockTracker from an invalid range (thanks t00thpick1)
|
||||
(API) UserBlockTracker is now the interface by which our block-tracker will be known (thanks t00thpick1)
|
||||
|
@ -45,6 +45,6 @@ public class AddlevelsCommand extends ExperienceCommand {
|
||||
if(isSilent)
|
||||
return;
|
||||
|
||||
player.sendMessage(LocaleLoader.getString("Commands.addlevels.AwardSkill.1", value, rootSkill.getLocalizedName()));
|
||||
player.sendMessage(LocaleLoader.getString("Commands.addlevels.AwardSkill.1", value, rootSkill.getName()));
|
||||
}
|
||||
}
|
||||
|
@ -46,6 +46,6 @@ public class AddxpCommand extends ExperienceCommand {
|
||||
if(isSilent)
|
||||
return;
|
||||
|
||||
player.sendMessage(LocaleLoader.getString("Commands.addxp.AwardSkill", value, rootSkill.getLocalizedName()));
|
||||
player.sendMessage(LocaleLoader.getString("Commands.addxp.AwardSkill", value, rootSkill.getName()));
|
||||
}
|
||||
}
|
||||
|
@ -161,7 +161,7 @@ public abstract class ExperienceCommand implements TabExecutor {
|
||||
sender.sendMessage(LocaleLoader.getString("Commands.addlevels.AwardAll.2", playerName));
|
||||
}
|
||||
else {
|
||||
sender.sendMessage(LocaleLoader.getString("Commands.addlevels.AwardSkill.2", rootSkill.getLocalizedName(), playerName));
|
||||
sender.sendMessage(LocaleLoader.getString("Commands.addlevels.AwardSkill.2", rootSkill.getName(), playerName));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -51,6 +51,6 @@ public class MmoeditCommand extends ExperienceCommand {
|
||||
if(isSilent)
|
||||
return;
|
||||
|
||||
player.sendMessage(LocaleLoader.getString("Commands.mmoedit.Modified.1", rootSkill.getLocalizedName(), value));
|
||||
player.sendMessage(LocaleLoader.getString("Commands.mmoedit.Modified.1", rootSkill.getName(), value));
|
||||
}
|
||||
}
|
||||
|
@ -142,7 +142,7 @@ public class SkillresetCommand implements TabExecutor {
|
||||
}
|
||||
|
||||
protected void handlePlayerMessageSkill(Player player, RootSkill rootSkill) {
|
||||
player.sendMessage(LocaleLoader.getString("Commands.Reset.Single", rootSkill.getLocalizedName()));
|
||||
player.sendMessage(LocaleLoader.getString("Commands.Reset.Single", rootSkill.getName()));
|
||||
}
|
||||
|
||||
private boolean validateArguments(CommandSender sender, String skillName) {
|
||||
@ -154,7 +154,7 @@ public class SkillresetCommand implements TabExecutor {
|
||||
sender.sendMessage(LocaleLoader.getString("Commands.addlevels.AwardAll.2", playerName));
|
||||
}
|
||||
else {
|
||||
sender.sendMessage(LocaleLoader.getString("Commands.addlevels.AwardSkill.2", rootSkill.getLocalizedName(), playerName));
|
||||
sender.sendMessage(LocaleLoader.getString("Commands.addlevels.AwardSkill.2", rootSkill.getName(), playerName));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -59,6 +59,6 @@ public class HardcoreCommand extends HardcoreModeCommand {
|
||||
rootSkill.setHardcoreStatLossEnabled(enable);
|
||||
}
|
||||
|
||||
mcMMO.p.getServer().broadcastMessage(LocaleLoader.getString("Hardcore.Mode." + (enable ? "Enabled" : "Disabled"), LocaleLoader.getString("Hardcore.DeathStatLoss.Name"), (rootSkill == null ? "all skills" : rootSkill.getLocalizedName())));
|
||||
mcMMO.p.getServer().broadcastMessage(LocaleLoader.getString("Hardcore.Mode." + (enable ? "Enabled" : "Disabled"), LocaleLoader.getString("Hardcore.DeathStatLoss.Name"), (rootSkill == null ? "all skills" : rootSkill.getName())));
|
||||
}
|
||||
}
|
@ -49,7 +49,7 @@ public abstract class SkillCommand implements TabExecutor {
|
||||
public SkillCommand(@NotNull RootSkill rootSkill) {
|
||||
this.rootSkill = CoreSkills.getSkill(primarySkillType);
|
||||
this.primarySkillType = primarySkillType;
|
||||
skillName = rootSkill.getLocalizedName();
|
||||
skillName = rootSkill.getName();
|
||||
skillGuideCommand = new SkillGuideCommand(rootSkill);
|
||||
}
|
||||
|
||||
@ -177,10 +177,10 @@ public abstract class SkillCommand implements TabExecutor {
|
||||
{
|
||||
if(i+1 < parentList.size())
|
||||
{
|
||||
parentMessage.append(LocaleLoader.getString("Effects.Child.ParentList", parentList.get(i).getLocalizedName(), mcMMOPlayer.getSkillLevel(parentList.get(i))));
|
||||
parentMessage.append(LocaleLoader.getString("Effects.Child.ParentList", parentList.get(i).getName(), mcMMOPlayer.getSkillLevel(parentList.get(i))));
|
||||
parentMessage.append(ChatColor.GRAY).append(", ");
|
||||
} else {
|
||||
parentMessage.append(LocaleLoader.getString("Effects.Child.ParentList", parentList.get(i).getLocalizedName(), mcMMOPlayer.getSkillLevel(parentList.get(i))));
|
||||
parentMessage.append(LocaleLoader.getString("Effects.Child.ParentList", parentList.get(i).getName(), mcMMOPlayer.getSkillLevel(parentList.get(i))));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -22,7 +22,7 @@ public class SkillGuideCommand implements CommandExecutor {
|
||||
|
||||
public SkillGuideCommand(@NotNull RootSkill rootSkill) {
|
||||
this.rootSkill = rootSkill;
|
||||
header = LocaleLoader.getString("Guides.Header", rootSkill.getLocalizedName());
|
||||
header = LocaleLoader.getString("Guides.Header", rootSkill.getName());
|
||||
guide = getGuide(rootSkill);
|
||||
}
|
||||
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -99,10 +99,10 @@ public enum PrimarySkillType {
|
||||
nonChildSkills.add(skill);
|
||||
}
|
||||
|
||||
for(SubSkillType subSkillType : skill.subSkillTypes)
|
||||
{
|
||||
for(SubSkillType subSkillType : skill.subSkillTypes) {
|
||||
subSkillNames.add(subSkillType.getNiceNameNoSpaces(subSkillType));
|
||||
}
|
||||
|
||||
names.add(skill.getName());
|
||||
}
|
||||
|
||||
@ -234,13 +234,13 @@ public enum PrimarySkillType {
|
||||
return null;
|
||||
}
|
||||
|
||||
public String getLocalizedName() {
|
||||
public String getName() {
|
||||
return StringUtils.getCapitalized(LocaleLoader.getString(StringUtils.getCapitalized(this.toString()) + ".SkillName"));
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return StringUtils.getCapitalized(StringUtils.getCapitalized(this.toString()));
|
||||
}
|
||||
// public String getName() {
|
||||
// return StringUtils.getCapitalized(StringUtils.getCapitalized(this.toString()));
|
||||
// }
|
||||
|
||||
public boolean getPermissions(Player player) {
|
||||
return Permissions.skillEnabled(player, this);
|
||||
|
@ -124,24 +124,26 @@ public class EntityListener implements Listener {
|
||||
if(!WorldGuardManager.getInstance().hasMainFlag(player))
|
||||
return;
|
||||
}
|
||||
|
||||
Entity projectile = event.getProjectile();
|
||||
|
||||
//Should be noted that there are API changes regarding Arrow from 1.13.2 to current versions of the game
|
||||
if (!(projectile instanceof Arrow)) {
|
||||
return;
|
||||
}
|
||||
|
||||
ItemStack bow = event.getBow();
|
||||
|
||||
if (bow != null
|
||||
&& bow.containsEnchantment(Enchantment.ARROW_INFINITE)) {
|
||||
projectile.setMetadata(mcMMO.infiniteArrowKey, mcMMO.metadataValue);
|
||||
}
|
||||
|
||||
projectile.setMetadata(mcMMO.bowForceKey, new FixedMetadataValue(pluginRef, Math.min(event.getForce() * AdvancedConfig.getInstance().getForceMultiplier(), 1.0)));
|
||||
projectile.setMetadata(mcMMO.arrowDistanceKey, new FixedMetadataValue(pluginRef, projectile.getLocation()));
|
||||
//Cleanup metadata in 1 minute in case normal collection falls through
|
||||
CombatUtils.cleanupArrowMetadata((Projectile) projectile);
|
||||
}
|
||||
|
||||
Entity projectile = event.getProjectile();
|
||||
|
||||
//Should be noted that there are API changes regarding Arrow from 1.13.2 to current versions of the game
|
||||
if (!(projectile instanceof Arrow)) {
|
||||
return;
|
||||
}
|
||||
|
||||
ItemStack bow = event.getBow();
|
||||
|
||||
if (bow != null
|
||||
&& bow.containsEnchantment(Enchantment.ARROW_INFINITE)) {
|
||||
projectile.setMetadata(mcMMO.infiniteArrowKey, mcMMO.metadataValue);
|
||||
}
|
||||
|
||||
projectile.setMetadata(mcMMO.bowForceKey, new FixedMetadataValue(pluginRef, Math.min(event.getForce() * AdvancedConfig.getInstance().getForceMultiplier(), 1.0)));
|
||||
projectile.setMetadata(mcMMO.arrowDistanceKey, new FixedMetadataValue(pluginRef, projectile.getLocation()));
|
||||
}
|
||||
|
||||
@EventHandler(ignoreCancelled = true, priority = EventPriority.LOWEST)
|
||||
@ -169,6 +171,8 @@ public class EntityListener implements Listener {
|
||||
EntityType entityType = projectile.getType();
|
||||
|
||||
if (entityType == EntityType.ARROW || entityType == EntityType.SPECTRAL_ARROW) {
|
||||
CombatUtils.delayArrowMetaCleanup(projectile); //Cleans up metadata 1 minute from now in case other collection methods fall through
|
||||
|
||||
if (!projectile.hasMetadata(mcMMO.bowForceKey))
|
||||
projectile.setMetadata(mcMMO.bowForceKey, new FixedMetadataValue(pluginRef, 1.0));
|
||||
|
||||
@ -244,7 +248,6 @@ public class EntityListener implements Listener {
|
||||
Entity entity = event.getEntity();
|
||||
Material notYetReplacedType = block.getState().getType(); //because its from getState() this is the block that hasn't been changed yet, which is likely air/lava/water etc
|
||||
|
||||
|
||||
// When the event is fired for the falling block that changes back to a
|
||||
// normal block
|
||||
// event.getBlock().getType() returns AIR
|
||||
@ -463,13 +466,14 @@ public class EntityListener implements Listener {
|
||||
LivingEntity livingEntity = (LivingEntity) entityDamageEvent.getEntity();
|
||||
|
||||
if(entityDamageEvent.getFinalDamage() >= livingEntity.getHealth()) {
|
||||
|
||||
/*
|
||||
* This sets entity names back to whatever they are supposed to be
|
||||
*/
|
||||
//This sets entity names back to whatever they are supposed to be
|
||||
CombatUtils.fixNames(livingEntity);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(entityDamageEvent.getDamager() instanceof Projectile) {
|
||||
CombatUtils.cleanupArrowMetadata((Projectile) entityDamageEvent.getDamager());
|
||||
}
|
||||
}
|
||||
|
||||
public boolean checkParties(Cancellable event, Player defendingPlayer, Player attackingPlayer) {
|
||||
|
@ -839,7 +839,7 @@ public class PlayerListener implements Listener {
|
||||
// Do these ACTUALLY have to be lower case to work properly?
|
||||
for (PrimarySkillType skill : PrimarySkillType.values()) {
|
||||
String skillName = skill.toString().toLowerCase(Locale.ENGLISH);
|
||||
String localizedName = skill.getLocalizedName().toLowerCase(Locale.ENGLISH);
|
||||
String localizedName = skill.getName().toLowerCase(Locale.ENGLISH);
|
||||
|
||||
if (lowerCaseCommand.equals(localizedName)) {
|
||||
event.setMessage(message.replace(command, skillName));
|
||||
|
@ -53,7 +53,7 @@ public class McrankCommandDisplayTask extends BukkitRunnable {
|
||||
// }
|
||||
|
||||
rank = skills.get(skill);
|
||||
sender.sendMessage(LocaleLoader.getString("Commands.mcrank.Skill", skill.getLocalizedName(), (rank == null ? LocaleLoader.getString("Commands.mcrank.Unranked") : rank)));
|
||||
sender.sendMessage(LocaleLoader.getString("Commands.mcrank.Skill", skill.getName(), (rank == null ? LocaleLoader.getString("Commands.mcrank.Unranked") : rank)));
|
||||
}
|
||||
|
||||
rank = skills.get(null);
|
||||
|
@ -63,10 +63,10 @@ public class MctopCommandDisplayTask extends BukkitRunnable {
|
||||
}
|
||||
else {
|
||||
if(sender instanceof Player) {
|
||||
sender.sendMessage(LocaleLoader.getString("Commands.Skill.Leaderboard", skill.getLocalizedName()));
|
||||
sender.sendMessage(LocaleLoader.getString("Commands.Skill.Leaderboard", skill.getName()));
|
||||
}
|
||||
else {
|
||||
sender.sendMessage(ChatColor.stripColor(LocaleLoader.getString("Commands.Skill.Leaderboard", skill.getLocalizedName())));
|
||||
sender.sendMessage(ChatColor.stripColor(LocaleLoader.getString("Commands.Skill.Leaderboard", skill.getName())));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -56,8 +56,7 @@ public class ArcheryManager extends SkillManager {
|
||||
public double distanceXpBonusMultiplier(@NotNull LivingEntity target, @NotNull Entity arrow) {
|
||||
//Hacky Fix - some plugins spawn arrows and assign them to players after the ProjectileLaunchEvent fires
|
||||
if(!arrow.hasMetadata(mcMMO.arrowDistanceKey))
|
||||
return arrow.getLocation().distance(target.getLocation());
|
||||
|
||||
return 1;
|
||||
|
||||
Location firedLocation = (Location) arrow.getMetadata(mcMMO.arrowDistanceKey).get(0).value();
|
||||
Location targetLocation = target.getLocation();
|
||||
|
@ -265,7 +265,7 @@ public class FishingManager extends SkillManager {
|
||||
int convertedLureBonus = 0;
|
||||
|
||||
//This avoids a Minecraft bug where lure levels above 3 break fishing
|
||||
if(lureLevel > 3) {
|
||||
if(lureLevel > 0) {
|
||||
masterAnglerCompatibilityLayer.setApplyLure(fishHook, false);
|
||||
convertedLureBonus = lureLevel * 100;
|
||||
}
|
||||
|
@ -37,7 +37,7 @@ public final class CommandRegistrationManager {
|
||||
private static void registerSkillCommands() {
|
||||
for (PrimarySkillType skill : PrimarySkillType.values()) {
|
||||
String commandName = skill.toString().toLowerCase(Locale.ENGLISH);
|
||||
String localizedName = skill.getLocalizedName().toLowerCase(Locale.ENGLISH);
|
||||
String localizedName = skill.getName().toLowerCase(Locale.ENGLISH);
|
||||
|
||||
PluginCommand command;
|
||||
|
||||
|
@ -94,7 +94,7 @@ public class ScoreboardManager {
|
||||
int i = 0;
|
||||
for (PrimarySkillType type : PrimarySkillType.values()) {
|
||||
// Include child skills
|
||||
skillLabelBuilder.put(type, getShortenedName(colors.get(i) + type.getLocalizedName(), false));
|
||||
skillLabelBuilder.put(type, getShortenedName(colors.get(i) + type.getName(), false));
|
||||
|
||||
if (type.getSuperAbilityType() != null) {
|
||||
abilityLabelBuilder.put(type.getSuperAbilityType(), getShortenedName(colors.get(i) + type.getSuperAbilityType().getLocalizedName()));
|
||||
@ -116,7 +116,7 @@ public class ScoreboardManager {
|
||||
else {
|
||||
for (PrimarySkillType type : PrimarySkillType.values()) {
|
||||
// Include child skills
|
||||
skillLabelBuilder.put(type, getShortenedName(ChatColor.GREEN + type.getLocalizedName()));
|
||||
skillLabelBuilder.put(type, getShortenedName(ChatColor.GREEN + type.getName()));
|
||||
|
||||
if (type.getSuperAbilityType() != null) {
|
||||
abilityLabelBuilder.put(type.getSuperAbilityType(), formatAbility(type.getSuperAbilityType().getLocalizedName()));
|
||||
|
@ -24,16 +24,19 @@ import com.gmail.nossr50.util.compat.layers.persistentdata.AbstractPersistentDat
|
||||
import com.gmail.nossr50.util.compat.layers.persistentdata.MobMetaFlagType;
|
||||
import com.gmail.nossr50.util.player.NotificationManager;
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.GameMode;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.attribute.Attribute;
|
||||
import org.bukkit.attribute.AttributeInstance;
|
||||
import org.bukkit.enchantments.Enchantment;
|
||||
import org.bukkit.entity.*;
|
||||
import org.bukkit.event.entity.EntityDamageByEntityEvent;
|
||||
import org.bukkit.event.entity.EntityDamageEvent;
|
||||
import org.bukkit.event.entity.EntityDamageEvent.DamageCause;
|
||||
import org.bukkit.event.entity.EntityDamageEvent.DamageModifier;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.metadata.FixedMetadataValue;
|
||||
import org.bukkit.metadata.MetadataValue;
|
||||
import org.bukkit.potion.PotionEffectType;
|
||||
import org.bukkit.projectiles.ProjectileSource;
|
||||
@ -288,6 +291,7 @@ public final class CombatUtils {
|
||||
|
||||
//Make sure the profiles been loaded
|
||||
if(mmoPlayer == null) {
|
||||
cleanupArrowMetadata(arrow);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -326,8 +330,10 @@ public final class CombatUtils {
|
||||
"Force Multiplier: "+forceMultiplier,
|
||||
"Initial Damage: "+initialDamage,
|
||||
"Final Damage: "+finalDamage);
|
||||
|
||||
processCombatXP(mmoPlayer, target, PrimarySkillType.ARCHERY, distanceMultiplier);
|
||||
|
||||
//Clean data
|
||||
cleanupArrowMetadata(arrow);
|
||||
}
|
||||
|
||||
private static void processCrossbowCombat(LivingEntity target, Player player, EntityDamageByEntityEvent event, Projectile arrow) {
|
||||
@ -499,19 +505,22 @@ public final class CombatUtils {
|
||||
|
||||
//Has metadata
|
||||
if(arrow.getMetadata(mcMMO.PROJECTILE_ORIGIN_METAKEY).size() > 0) {
|
||||
if(isProjectileFromBow(arrow)) {
|
||||
if(PrimarySkillType.ARCHERY.shouldProcess(target)) {
|
||||
if (isProjectileFromBow(arrow)) {
|
||||
if (PrimarySkillType.ARCHERY.shouldProcess(target)) {
|
||||
if (!Misc.isNPCEntityExcludingVillagers(player) && PrimarySkillType.ARCHERY.getPermissions(player)) {
|
||||
processArcheryCombat(target, player, event, arrow);
|
||||
}
|
||||
}
|
||||
} else if(isProjectileFromCrossbow(arrow)) {
|
||||
if(PrimarySkillType.CROSSBOWS.shouldProcess(target)) {
|
||||
} else if (isProjectileFromCrossbow(arrow)) {
|
||||
if (PrimarySkillType.CROSSBOWS.shouldProcess(target)) {
|
||||
if (!Misc.isNPCEntityExcludingVillagers(player) && PrimarySkillType.CROSSBOWS.getPermissions(player)) {
|
||||
processCrossbowCombat(target, player, event, arrow);
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
//Cleanup Arrow
|
||||
cleanupArrowMetadata(arrow);
|
||||
}
|
||||
|
||||
if (target.getType() != EntityType.CREEPER && !Misc.isNPCEntityExcludingVillagers(player) && PrimarySkillType.TAMING.getPermissions(player)) {
|
||||
@ -1122,4 +1131,32 @@ public final class CombatUtils {
|
||||
attributeInstance.setBaseValue(normalSpeed * multiplier);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Clean up metadata from a projectile
|
||||
*
|
||||
* @param entity projectile
|
||||
*/
|
||||
public static void cleanupArrowMetadata(@NotNull Projectile entity) {
|
||||
if(entity.hasMetadata(mcMMO.infiniteArrowKey)) {
|
||||
entity.removeMetadata(mcMMO.infiniteArrowKey, mcMMO.p);
|
||||
}
|
||||
|
||||
if(entity.hasMetadata(mcMMO.bowForceKey)) {
|
||||
entity.removeMetadata(mcMMO.bowForceKey, mcMMO.p);
|
||||
}
|
||||
|
||||
if(entity.hasMetadata(mcMMO.arrowDistanceKey)) {
|
||||
entity.removeMetadata(mcMMO.arrowDistanceKey, mcMMO.p);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Clean up metadata from a projectile after a minute has passed
|
||||
*
|
||||
* @param entity the projectile
|
||||
*/
|
||||
public static void delayArrowMetaCleanup(@NotNull Projectile entity) {
|
||||
Bukkit.getServer().getScheduler().runTaskLater(mcMMO.p, () -> { cleanupArrowMetadata(entity);}, 20*60);
|
||||
}
|
||||
}
|
||||
|
@ -1,116 +1,116 @@
|
||||
package com.gmail.nossr50.util.random;
|
||||
|
||||
import com.gmail.nossr50.datatypes.player.McMMOPlayer;
|
||||
import com.gmail.nossr50.datatypes.skills.PrimarySkillType;
|
||||
import com.gmail.nossr50.datatypes.skills.SubSkillType;
|
||||
import com.gmail.nossr50.util.Permissions;
|
||||
import com.gmail.nossr50.util.player.UserManager;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.Mockito;
|
||||
import org.powermock.api.mockito.PowerMockito;
|
||||
import org.powermock.core.classloader.annotations.PrepareForTest;
|
||||
import org.powermock.modules.junit4.PowerMockRunner;
|
||||
|
||||
import static org.mockito.Mockito.mock;
|
||||
|
||||
//TODO: Rewrite the entire com.gmail.nossr50.util.random package, it was written in haste and it disgusts me
|
||||
//TODO: Add more tests for the other types of random dice rolls
|
||||
@RunWith(PowerMockRunner.class)
|
||||
@PrepareForTest({RandomChanceUtil.class, UserManager.class})
|
||||
public class RandomChanceTest {
|
||||
|
||||
private Player luckyPlayer;
|
||||
private McMMOPlayer mmoPlayerLucky;
|
||||
|
||||
private Player normalPlayer;
|
||||
private McMMOPlayer mmoPlayerNormal;
|
||||
|
||||
private SubSkillType subSkillType;
|
||||
private PrimarySkillType primarySkillType;
|
||||
|
||||
private final String testASCIIHeader = "---- mcMMO Tests ----";
|
||||
|
||||
@Before
|
||||
public void setUpMock() {
|
||||
primarySkillType = PrimarySkillType.HERBALISM;
|
||||
subSkillType = SubSkillType.HERBALISM_GREEN_THUMB;
|
||||
|
||||
//TODO: Likely needs to be changed per skill if more tests were added
|
||||
PowerMockito.stub(PowerMockito.method(RandomChanceUtil.class, "getMaximumProbability", subSkillType.getClass())).toReturn(100D);
|
||||
PowerMockito.stub(PowerMockito.method(RandomChanceUtil.class, "getMaxBonusLevelCap", subSkillType.getClass())).toReturn(1000D);
|
||||
|
||||
normalPlayer = mock(Player.class);
|
||||
luckyPlayer = mock(Player.class);
|
||||
|
||||
mmoPlayerNormal = mock(McMMOPlayer.class);
|
||||
mmoPlayerLucky = mock(McMMOPlayer.class);
|
||||
|
||||
PowerMockito.mockStatic(UserManager.class);
|
||||
Mockito.when(UserManager.getPlayer(normalPlayer)).thenReturn(mmoPlayerNormal);
|
||||
Mockito.when(UserManager.getPlayer(luckyPlayer)).thenReturn(mmoPlayerLucky);
|
||||
|
||||
Mockito.when(mmoPlayerNormal.getPlayer()).thenReturn(normalPlayer);
|
||||
Mockito.when(mmoPlayerLucky.getPlayer()).thenReturn(luckyPlayer);
|
||||
|
||||
//Lucky player has the lucky permission
|
||||
//Normal player doesn't have any lucky permission
|
||||
Mockito.when(Permissions.lucky(luckyPlayer, primarySkillType)).thenReturn(true);
|
||||
Mockito.when(Permissions.lucky(normalPlayer, primarySkillType)).thenReturn(false);
|
||||
|
||||
Mockito.when(mmoPlayerNormal.getSkillLevel(primarySkillType)).thenReturn(800);
|
||||
Mockito.when(mmoPlayerLucky.getSkillLevel(primarySkillType)).thenReturn(800);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testLuckyChance() {
|
||||
System.out.println(testASCIIHeader);
|
||||
System.out.println("Testing success odds to fall within expected values...");
|
||||
assertEquals(80D, getSuccessChance(mmoPlayerNormal),0D);
|
||||
assertEquals(80D * RandomChanceUtil.LUCKY_MODIFIER, getSuccessChance(mmoPlayerLucky),0D);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNeverFailsSuccessLuckyPlayer() {
|
||||
System.out.println(testASCIIHeader);
|
||||
System.out.println("Test - Lucky Player with 80% base success should never fail (10,000 iterations)");
|
||||
for(int x = 0; x < 10000; x++) {
|
||||
Assert.assertTrue(RandomChanceUtil.checkRandomChanceExecutionSuccess(luckyPlayer, SubSkillType.HERBALISM_GREEN_THUMB, true));
|
||||
if(x == 10000-1)
|
||||
System.out.println("They never failed!");
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testFailsAboutExpected() {
|
||||
System.out.println(testASCIIHeader);
|
||||
System.out.println("Test - Player with 800 skill should fail about 20% of the time (100,000 iterations)");
|
||||
double ratioDivisor = 1000; //1000 because we run the test 100,000 times
|
||||
double expectedFailRate = 20D;
|
||||
|
||||
double win = 0, loss = 0;
|
||||
for(int x = 0; x < 100000; x++) {
|
||||
if(RandomChanceUtil.checkRandomChanceExecutionSuccess(normalPlayer, SubSkillType.HERBALISM_GREEN_THUMB, true)) {
|
||||
win++;
|
||||
} else {
|
||||
loss++;
|
||||
}
|
||||
}
|
||||
|
||||
double lossRatio = (loss / ratioDivisor);
|
||||
Assert.assertEquals(lossRatio, expectedFailRate, 1D);
|
||||
}
|
||||
|
||||
private double getSuccessChance(@NotNull McMMOPlayer mmoPlayer) {
|
||||
RandomChanceSkill randomChanceSkill = new RandomChanceSkill(mmoPlayer.getPlayer(), subSkillType, true);
|
||||
return RandomChanceUtil.calculateChanceOfSuccess(randomChanceSkill);
|
||||
}
|
||||
|
||||
private void assertEquals(double expected, double actual, double delta) {
|
||||
Assert.assertEquals(expected, actual, delta);
|
||||
}
|
||||
}
|
||||
//package com.gmail.nossr50.util.random;
|
||||
//
|
||||
//import com.gmail.nossr50.datatypes.player.McMMOPlayer;
|
||||
//import com.gmail.nossr50.datatypes.skills.PrimarySkillType;
|
||||
//import com.gmail.nossr50.datatypes.skills.SubSkillType;
|
||||
//import com.gmail.nossr50.util.Permissions;
|
||||
//import com.gmail.nossr50.util.player.UserManager;
|
||||
//import org.bukkit.entity.Player;
|
||||
//import org.jetbrains.annotations.NotNull;
|
||||
//import org.junit.Assert;
|
||||
//import org.junit.Before;
|
||||
//import org.junit.Test;
|
||||
//import org.junit.runner.RunWith;
|
||||
//import org.mockito.Mockito;
|
||||
//import org.powermock.api.mockito.PowerMockito;
|
||||
//import org.powermock.core.classloader.annotations.PrepareForTest;
|
||||
//import org.powermock.modules.junit4.PowerMockRunner;
|
||||
//
|
||||
//import static org.mockito.Mockito.mock;
|
||||
//
|
||||
////TODO: Rewrite the entire com.gmail.nossr50.util.random package, it was written in haste and it disgusts me
|
||||
////TODO: Add more tests for the other types of random dice rolls
|
||||
//@RunWith(PowerMockRunner.class)
|
||||
//@PrepareForTest({RandomChanceUtil.class, UserManager.class})
|
||||
//public class RandomChanceTest {
|
||||
//
|
||||
// private Player luckyPlayer;
|
||||
// private McMMOPlayer mmoPlayerLucky;
|
||||
//
|
||||
// private Player normalPlayer;
|
||||
// private McMMOPlayer mmoPlayerNormal;
|
||||
//
|
||||
// private SubSkillType subSkillType;
|
||||
// private PrimarySkillType primarySkillType;
|
||||
//
|
||||
// private final String testASCIIHeader = "---- mcMMO Tests ----";
|
||||
//
|
||||
// @Before
|
||||
// public void setUpMock() {
|
||||
// primarySkillType = PrimarySkillType.HERBALISM;
|
||||
// subSkillType = SubSkillType.HERBALISM_GREEN_THUMB;
|
||||
//
|
||||
// //TODO: Likely needs to be changed per skill if more tests were added
|
||||
// PowerMockito.stub(PowerMockito.method(RandomChanceUtil.class, "getMaximumProbability", subSkillType.getClass())).toReturn(100D);
|
||||
// PowerMockito.stub(PowerMockito.method(RandomChanceUtil.class, "getMaxBonusLevelCap", subSkillType.getClass())).toReturn(1000D);
|
||||
//
|
||||
// normalPlayer = mock(Player.class);
|
||||
// luckyPlayer = mock(Player.class);
|
||||
//
|
||||
// mmoPlayerNormal = mock(McMMOPlayer.class);
|
||||
// mmoPlayerLucky = mock(McMMOPlayer.class);
|
||||
//
|
||||
// PowerMockito.mockStatic(UserManager.class);
|
||||
// Mockito.when(UserManager.getPlayer(normalPlayer)).thenReturn(mmoPlayerNormal);
|
||||
// Mockito.when(UserManager.getPlayer(luckyPlayer)).thenReturn(mmoPlayerLucky);
|
||||
//
|
||||
// Mockito.when(mmoPlayerNormal.getPlayer()).thenReturn(normalPlayer);
|
||||
// Mockito.when(mmoPlayerLucky.getPlayer()).thenReturn(luckyPlayer);
|
||||
//
|
||||
// //Lucky player has the lucky permission
|
||||
// //Normal player doesn't have any lucky permission
|
||||
// Mockito.when(Permissions.lucky(luckyPlayer, primarySkillType)).thenReturn(true);
|
||||
// Mockito.when(Permissions.lucky(normalPlayer, primarySkillType)).thenReturn(false);
|
||||
//
|
||||
// Mockito.when(mmoPlayerNormal.getSkillLevel(primarySkillType)).thenReturn(800);
|
||||
// Mockito.when(mmoPlayerLucky.getSkillLevel(primarySkillType)).thenReturn(800);
|
||||
// }
|
||||
//
|
||||
// @Test
|
||||
// public void testLuckyChance() {
|
||||
// System.out.println(testASCIIHeader);
|
||||
// System.out.println("Testing success odds to fall within expected values...");
|
||||
// assertEquals(80D, getSuccessChance(mmoPlayerNormal),0D);
|
||||
// assertEquals(80D * RandomChanceUtil.LUCKY_MODIFIER, getSuccessChance(mmoPlayerLucky),0D);
|
||||
// }
|
||||
//
|
||||
// @Test
|
||||
// public void testNeverFailsSuccessLuckyPlayer() {
|
||||
// System.out.println(testASCIIHeader);
|
||||
// System.out.println("Test - Lucky Player with 80% base success should never fail (10,000 iterations)");
|
||||
// for(int x = 0; x < 10000; x++) {
|
||||
// Assert.assertTrue(RandomChanceUtil.checkRandomChanceExecutionSuccess(luckyPlayer, SubSkillType.HERBALISM_GREEN_THUMB, true));
|
||||
// if(x == 10000-1)
|
||||
// System.out.println("They never failed!");
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// @Test
|
||||
// public void testFailsAboutExpected() {
|
||||
// System.out.println(testASCIIHeader);
|
||||
// System.out.println("Test - Player with 800 skill should fail about 20% of the time (100,000 iterations)");
|
||||
// double ratioDivisor = 1000; //1000 because we run the test 100,000 times
|
||||
// double expectedFailRate = 20D;
|
||||
//
|
||||
// double win = 0, loss = 0;
|
||||
// for(int x = 0; x < 100000; x++) {
|
||||
// if(RandomChanceUtil.checkRandomChanceExecutionSuccess(normalPlayer, SubSkillType.HERBALISM_GREEN_THUMB, true)) {
|
||||
// win++;
|
||||
// } else {
|
||||
// loss++;
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// double lossRatio = (loss / ratioDivisor);
|
||||
// Assert.assertEquals(lossRatio, expectedFailRate, 1D);
|
||||
// }
|
||||
//
|
||||
// private double getSuccessChance(@NotNull McMMOPlayer mmoPlayer) {
|
||||
// RandomChanceSkill randomChanceSkill = new RandomChanceSkill(mmoPlayer.getPlayer(), subSkillType, true);
|
||||
// return RandomChanceUtil.calculateChanceOfSuccess(randomChanceSkill);
|
||||
// }
|
||||
//
|
||||
// private void assertEquals(double expected, double actual, double delta) {
|
||||
// Assert.assertEquals(expected, actual, delta);
|
||||
// }
|
||||
//}
|
||||
|
Loading…
Reference in New Issue
Block a user