mirror of
https://github.com/mcMMO-Dev/mcMMO.git
synced 2024-11-25 14:46:46 +01:00
CompatibilityLayer framework
This commit is contained in:
parent
f82ad99c82
commit
5984230bf3
@ -1,3 +1,12 @@
|
|||||||
|
Version 2.1.126
|
||||||
|
mcMMO now relies on NMS for some of its features, if NMS cannot properly be wired up when initializing mcMMO behaviours relying on NMS will either be partially supported or disabled
|
||||||
|
mcMMO now has a compatibility mode, any features that require specific versions of Minecraft for full functionality will be disabled if your server is not running a compatible version, mcMMO will still function in compatibility mode, but either the feature will be modified or disabled depending on the version of the server software
|
||||||
|
New command /mmocompat - Shows information about whether or not mcMMO is fully functional or if some features are disabled due to the server software not being fully supported. Can be used by players or console.
|
||||||
|
Fixed an exploit involving fishing rods
|
||||||
|
|
||||||
|
Notes:
|
||||||
|
There are no features that rely on NMS in this version, it took a lot of work to write the NMS framework and I'm going to delay implementation for future versions.
|
||||||
|
|
||||||
Version 2.1.125
|
Version 2.1.125
|
||||||
*Fixed a bug where you could not place blocks on top of certain repair/salvage anvils
|
*Fixed a bug where you could not place blocks on top of certain repair/salvage anvils
|
||||||
|
|
||||||
@ -5,7 +14,7 @@ Version 2.1.125
|
|||||||
|
|
||||||
Version 2.1.124
|
Version 2.1.124
|
||||||
Repair/Salvage can now be set to use vanilla blocks that already do something and that vanilla functionality will be disabled by mcMMO (you could use vanilla-anvils instead of iron_blocks for repair now)
|
Repair/Salvage can now be set to use vanilla blocks that already do something and that vanilla functionality will be disabled by mcMMO (you could use vanilla-anvils instead of iron_blocks for repair now)
|
||||||
Added Gold_Nugget to Mining's Bonus_Drops in config.yml (edit your config)
|
Added Gold_Nugget to Mining's Bonus_Drops in config.yml (edit your config)g
|
||||||
Added Piglin to experience.yml combat XP tables with a value of 2.0 (edit your config)
|
Added Piglin to experience.yml combat XP tables with a value of 2.0 (edit your config)
|
||||||
Added Hoglin to experience.yml combat XP tables with a value of 4.0 (edit your config)
|
Added Hoglin to experience.yml combat XP tables with a value of 4.0 (edit your config)
|
||||||
Added Zombified_Piglin & Zombie_Pigman to experience.yml combat XP tables with a value of 3.0 (edit your config)
|
Added Zombified_Piglin & Zombie_Pigman to experience.yml combat XP tables with a value of 3.0 (edit your config)
|
||||||
|
7
pom.xml
7
pom.xml
@ -167,7 +167,7 @@
|
|||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.spigotmc</groupId>
|
<groupId>org.spigotmc</groupId>
|
||||||
<artifactId>spigot-api</artifactId>
|
<artifactId>spigot-api</artifactId>
|
||||||
<version>1.15.1-R0.1-SNAPSHOT</version>
|
<version>1.15.2-R0.1-SNAPSHOT</version>
|
||||||
<scope>provided</scope>
|
<scope>provided</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
@ -198,6 +198,11 @@
|
|||||||
<version>7.0.52</version>
|
<version>7.0.52</version>
|
||||||
<scope>compile</scope>
|
<scope>compile</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.jetbrains</groupId>
|
||||||
|
<artifactId>annotations</artifactId>
|
||||||
|
<version>19.0.0</version>
|
||||||
|
</dependency>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
<properties>
|
<properties>
|
||||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||||
|
@ -0,0 +1,28 @@
|
|||||||
|
package com.gmail.nossr50.commands.admin;
|
||||||
|
|
||||||
|
import com.gmail.nossr50.mcMMO;
|
||||||
|
import org.bukkit.command.Command;
|
||||||
|
import org.bukkit.command.CommandExecutor;
|
||||||
|
import org.bukkit.command.CommandSender;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
|
public class CompatibilityCommand implements CommandExecutor {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Executes the given command, returning its success.
|
||||||
|
* <br>
|
||||||
|
* If false is returned, then the "usage" plugin.yml entry for this command
|
||||||
|
* (if defined) will be sent to the player.
|
||||||
|
*
|
||||||
|
* @param commandSender Source of the command
|
||||||
|
* @param command Command which was executed
|
||||||
|
* @param s Alias of the command which was used
|
||||||
|
* @param strings Passed command arguments
|
||||||
|
* @return true if a valid command, otherwise false
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public boolean onCommand(@NotNull CommandSender commandSender, @NotNull Command command, @NotNull String s, @NotNull String[] strings) {
|
||||||
|
mcMMO.getCompatibilityManager().reportCompatibilityStatus(commandSender);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
@ -96,6 +96,7 @@ public class McMMOPlayer {
|
|||||||
private int respawnATS;
|
private int respawnATS;
|
||||||
private int teleportATS;
|
private int teleportATS;
|
||||||
private long databaseATS;
|
private long databaseATS;
|
||||||
|
private double attackStrength; //captured during arm swing events
|
||||||
//private int chimeraWingLastUse;
|
//private int chimeraWingLastUse;
|
||||||
private Location teleportCommence;
|
private Location teleportCommence;
|
||||||
|
|
||||||
@ -142,12 +143,21 @@ public class McMMOPlayer {
|
|||||||
experienceBarManager = new ExperienceBarManager(this);
|
experienceBarManager = new ExperienceBarManager(this);
|
||||||
|
|
||||||
debugMode = false; //Debug mode helps solve support issues, players can toggle it on or off
|
debugMode = false; //Debug mode helps solve support issues, players can toggle it on or off
|
||||||
|
attackStrength = 1.0D;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getPlayerName() {
|
public String getPlayerName() {
|
||||||
return playerName;
|
return playerName;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public double getAttackStrength() {
|
||||||
|
return attackStrength;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setAttackStrength(double attackStrength) {
|
||||||
|
this.attackStrength = attackStrength;
|
||||||
|
}
|
||||||
|
|
||||||
/*public void hideXpBar(PrimarySkillType primarySkillType)
|
/*public void hideXpBar(PrimarySkillType primarySkillType)
|
||||||
{
|
{
|
||||||
experienceBarManager.hideExperienceBar(primarySkillType);
|
experienceBarManager.hideExperienceBar(primarySkillType);
|
||||||
|
@ -10,6 +10,7 @@ import org.bukkit.event.Cancellable;
|
|||||||
public class SubSkillEvent extends McMMOPlayerSkillEvent implements Cancellable {
|
public class SubSkillEvent extends McMMOPlayerSkillEvent implements Cancellable {
|
||||||
private SubSkillType subSkillType;
|
private SubSkillType subSkillType;
|
||||||
private boolean cancelled = false;
|
private boolean cancelled = false;
|
||||||
|
private double resultModifier = 1.0D;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Only skills using the old system will fire this event
|
* Only skills using the old system will fire this event
|
||||||
@ -23,11 +24,33 @@ public class SubSkillEvent extends McMMOPlayerSkillEvent implements Cancellable
|
|||||||
this.subSkillType = subSkillType;
|
this.subSkillType = subSkillType;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Only skills using the old system will fire this event
|
||||||
|
* @param player target player
|
||||||
|
* @param subSkillType target subskill
|
||||||
|
* @param resultModifier a value multiplied against the final result of the dice roll, typically between 0-1.0
|
||||||
|
* @Deprecated Skills will be using a new system stemming from the AbstractSubSkill class so make sure you check for both events, this event will be removed eventually.
|
||||||
|
*/
|
||||||
|
@Deprecated
|
||||||
|
public SubSkillEvent(Player player, SubSkillType subSkillType, double resultModifier) {
|
||||||
|
super(player, PrimarySkillType.bySecondaryAbility(subSkillType));
|
||||||
|
this.subSkillType = subSkillType;
|
||||||
|
this.resultModifier = resultModifier;
|
||||||
|
}
|
||||||
|
|
||||||
public SubSkillEvent(Player player, AbstractSubSkill abstractSubSkill)
|
public SubSkillEvent(Player player, AbstractSubSkill abstractSubSkill)
|
||||||
{
|
{
|
||||||
super(player, abstractSubSkill.getPrimarySkill());
|
super(player, abstractSubSkill.getPrimarySkill());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public double getResultModifier() {
|
||||||
|
return resultModifier;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setResultModifier(double resultModifier) {
|
||||||
|
this.resultModifier = resultModifier;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the SubSkillType involved in the event
|
* Gets the SubSkillType involved in the event
|
||||||
* @return the SubSkillType
|
* @return the SubSkillType
|
||||||
|
@ -28,6 +28,7 @@ import com.gmail.nossr50.util.skills.CombatUtils;
|
|||||||
import com.gmail.nossr50.util.skills.SkillActivationType;
|
import com.gmail.nossr50.util.skills.SkillActivationType;
|
||||||
import com.gmail.nossr50.worldguard.WorldGuardManager;
|
import com.gmail.nossr50.worldguard.WorldGuardManager;
|
||||||
import com.gmail.nossr50.worldguard.WorldGuardUtils;
|
import com.gmail.nossr50.worldguard.WorldGuardUtils;
|
||||||
|
import org.bukkit.Bukkit;
|
||||||
import org.bukkit.Material;
|
import org.bukkit.Material;
|
||||||
import org.bukkit.OfflinePlayer;
|
import org.bukkit.OfflinePlayer;
|
||||||
import org.bukkit.block.Block;
|
import org.bukkit.block.Block;
|
||||||
@ -289,6 +290,7 @@ public class EntityListener implements Listener {
|
|||||||
if(WorldGuardUtils.isWorldGuardLoaded())
|
if(WorldGuardUtils.isWorldGuardLoaded())
|
||||||
{
|
{
|
||||||
if(attacker instanceof Player) {
|
if(attacker instanceof Player) {
|
||||||
|
Bukkit.broadcastMessage("(Player attacked something) EntityDamageEvent fired!");
|
||||||
|
|
||||||
if(!WorldGuardManager.getInstance().hasMainFlag((Player) attacker))
|
if(!WorldGuardManager.getInstance().hasMainFlag((Player) attacker))
|
||||||
return;
|
return;
|
||||||
|
@ -38,7 +38,10 @@ import com.gmail.nossr50.util.*;
|
|||||||
import com.gmail.nossr50.util.blockmeta.chunkmeta.ChunkManager;
|
import com.gmail.nossr50.util.blockmeta.chunkmeta.ChunkManager;
|
||||||
import com.gmail.nossr50.util.blockmeta.chunkmeta.ChunkManagerFactory;
|
import com.gmail.nossr50.util.blockmeta.chunkmeta.ChunkManagerFactory;
|
||||||
import com.gmail.nossr50.util.commands.CommandRegistrationManager;
|
import com.gmail.nossr50.util.commands.CommandRegistrationManager;
|
||||||
|
import com.gmail.nossr50.util.compat.CompatibilityManager;
|
||||||
import com.gmail.nossr50.util.experience.FormulaManager;
|
import com.gmail.nossr50.util.experience.FormulaManager;
|
||||||
|
import com.gmail.nossr50.util.platform.PlatformManager;
|
||||||
|
import com.gmail.nossr50.util.platform.ServerSoftwareType;
|
||||||
import com.gmail.nossr50.util.player.PlayerLevelUtils;
|
import com.gmail.nossr50.util.player.PlayerLevelUtils;
|
||||||
import com.gmail.nossr50.util.player.UserManager;
|
import com.gmail.nossr50.util.player.UserManager;
|
||||||
import com.gmail.nossr50.util.scoreboards.ScoreboardManager;
|
import com.gmail.nossr50.util.scoreboards.ScoreboardManager;
|
||||||
@ -62,10 +65,10 @@ import java.io.InputStreamReader;
|
|||||||
import java.lang.reflect.Method;
|
import java.lang.reflect.Method;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Locale;
|
|
||||||
|
|
||||||
public class mcMMO extends JavaPlugin {
|
public class mcMMO extends JavaPlugin {
|
||||||
/* Managers */
|
/* Managers */
|
||||||
|
private static PlatformManager platformManager;
|
||||||
private static ChunkManager placeStore;
|
private static ChunkManager placeStore;
|
||||||
private static RepairableManager repairableManager;
|
private static RepairableManager repairableManager;
|
||||||
private static SalvageableManager salvageableManager;
|
private static SalvageableManager salvageableManager;
|
||||||
@ -141,6 +144,10 @@ public class mcMMO extends JavaPlugin {
|
|||||||
public void onEnable() {
|
public void onEnable() {
|
||||||
try {
|
try {
|
||||||
p = this;
|
p = this;
|
||||||
|
|
||||||
|
//Platform Manager
|
||||||
|
platformManager = new PlatformManager();
|
||||||
|
|
||||||
getLogger().setFilter(new LogFilter(this));
|
getLogger().setFilter(new LogFilter(this));
|
||||||
metadataValue = new FixedMetadataValue(this, true);
|
metadataValue = new FixedMetadataValue(this, true);
|
||||||
|
|
||||||
@ -188,10 +195,10 @@ public class mcMMO extends JavaPlugin {
|
|||||||
Bukkit
|
Bukkit
|
||||||
.getScheduler()
|
.getScheduler()
|
||||||
.scheduleSyncRepeatingTask(this,
|
.scheduleSyncRepeatingTask(this,
|
||||||
() -> getLogger().severe("You are running an outdated version of "+getServerSoftware()+", mcMMO will not work unless you update to a newer version!"),
|
() -> getLogger().severe("You are running an outdated version of "+platformManager.getServerSoftware()+", mcMMO will not work unless you update to a newer version!"),
|
||||||
20, 20*60*30);
|
20, 20*60*30);
|
||||||
|
|
||||||
if(getServerSoftware() == ServerSoftwareType.CRAFTBUKKIT)
|
if(platformManager.getServerSoftware() == ServerSoftwareType.CRAFT_BUKKIT)
|
||||||
{
|
{
|
||||||
Bukkit.getScheduler()
|
Bukkit.getScheduler()
|
||||||
.scheduleSyncRepeatingTask(this,
|
.scheduleSyncRepeatingTask(this,
|
||||||
@ -275,40 +282,11 @@ public class mcMMO extends JavaPlugin {
|
|||||||
Class<?> checkForClassBaseComponent = Class.forName("net.md_5.bungee.api.chat.BaseComponent");
|
Class<?> checkForClassBaseComponent = Class.forName("net.md_5.bungee.api.chat.BaseComponent");
|
||||||
} catch (ClassNotFoundException | NoSuchMethodException e) {
|
} catch (ClassNotFoundException | NoSuchMethodException e) {
|
||||||
serverAPIOutdated = true;
|
serverAPIOutdated = true;
|
||||||
String software = getServerSoftwareStr();
|
String software = platformManager.getServerSoftwareStr();
|
||||||
getLogger().severe("You are running an older version of " + software + " that is not compatible with mcMMO, update your server software!");
|
getLogger().severe("You are running an older version of " + software + " that is not compatible with mcMMO, update your server software!");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private enum ServerSoftwareType {
|
|
||||||
PAPER,
|
|
||||||
SPIGOT,
|
|
||||||
CRAFTBUKKIT
|
|
||||||
}
|
|
||||||
|
|
||||||
private ServerSoftwareType getServerSoftware()
|
|
||||||
{
|
|
||||||
if(Bukkit.getVersion().toLowerCase(Locale.ENGLISH).contains("paper"))
|
|
||||||
return ServerSoftwareType.PAPER;
|
|
||||||
else if(Bukkit.getVersion().toLowerCase(Locale.ENGLISH).contains("spigot"))
|
|
||||||
return ServerSoftwareType.SPIGOT;
|
|
||||||
else
|
|
||||||
return ServerSoftwareType.CRAFTBUKKIT;
|
|
||||||
}
|
|
||||||
|
|
||||||
private String getServerSoftwareStr()
|
|
||||||
{
|
|
||||||
switch(getServerSoftware())
|
|
||||||
{
|
|
||||||
case PAPER:
|
|
||||||
return "Paper";
|
|
||||||
case SPIGOT:
|
|
||||||
return "Spigot";
|
|
||||||
default:
|
|
||||||
return "CraftBukkit";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onLoad()
|
public void onLoad()
|
||||||
{
|
{
|
||||||
@ -436,6 +414,10 @@ public class mcMMO extends JavaPlugin {
|
|||||||
return upgradeManager;
|
return upgradeManager;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static CompatibilityManager getCompatibilityManager() {
|
||||||
|
return platformManager.getCompatibilityManager();
|
||||||
|
}
|
||||||
|
|
||||||
@Deprecated
|
@Deprecated
|
||||||
public static void setDatabaseManager(DatabaseManager databaseManager) {
|
public static void setDatabaseManager(DatabaseManager databaseManager) {
|
||||||
mcMMO.databaseManager = databaseManager;
|
mcMMO.databaseManager = databaseManager;
|
||||||
@ -684,4 +666,8 @@ public class mcMMO extends JavaPlugin {
|
|||||||
public static WorldBlacklist getWorldBlacklist() {
|
public static WorldBlacklist getWorldBlacklist() {
|
||||||
return worldBlacklist;
|
return worldBlacklist;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static PlatformManager getPlatformManager() {
|
||||||
|
return platformManager;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -68,7 +68,7 @@ public class AxesManager extends SkillManager {
|
|||||||
* Handle the effects of the Axe Mastery ability
|
* Handle the effects of the Axe Mastery ability
|
||||||
*/
|
*/
|
||||||
public double axeMastery() {
|
public double axeMastery() {
|
||||||
if (!RandomChanceUtil.isActivationSuccessful(SkillActivationType.ALWAYS_FIRES, SubSkillType.AXES_AXE_MASTERY, getPlayer())) {
|
if (!RandomChanceUtil.isActivationSuccessful(SkillActivationType.ALWAYS_FIRES, SubSkillType.AXES_AXE_MASTERY, getPlayer(), mcMMOPlayer.getAttackStrength())) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -82,7 +82,7 @@ public class AxesManager extends SkillManager {
|
|||||||
* @param damage The amount of damage initially dealt by the event
|
* @param damage The amount of damage initially dealt by the event
|
||||||
*/
|
*/
|
||||||
public double criticalHit(LivingEntity target, double damage) {
|
public double criticalHit(LivingEntity target, double damage) {
|
||||||
if (!RandomChanceUtil.isActivationSuccessful(SkillActivationType.RANDOM_LINEAR_100_SCALE_WITH_CAP, SubSkillType.AXES_CRITICAL_STRIKES, getPlayer())) {
|
if (!RandomChanceUtil.isActivationSuccessful(SkillActivationType.RANDOM_LINEAR_100_SCALE_WITH_CAP, SubSkillType.AXES_CRITICAL_STRIKES, getPlayer(), mcMMOPlayer.getAttackStrength())) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -118,7 +118,7 @@ public class AxesManager extends SkillManager {
|
|||||||
|
|
||||||
for (ItemStack armor : target.getEquipment().getArmorContents()) {
|
for (ItemStack armor : target.getEquipment().getArmorContents()) {
|
||||||
if (armor != null && ItemUtils.isArmor(armor)) {
|
if (armor != null && ItemUtils.isArmor(armor)) {
|
||||||
if (RandomChanceUtil.isActivationSuccessful(SkillActivationType.RANDOM_STATIC_CHANCE, SubSkillType.AXES_ARMOR_IMPACT, getPlayer())) {
|
if (RandomChanceUtil.isActivationSuccessful(SkillActivationType.RANDOM_STATIC_CHANCE, SubSkillType.AXES_ARMOR_IMPACT, getPlayer(), mcMMOPlayer.getAttackStrength())) {
|
||||||
SkillUtils.handleDurabilityChange(armor, durabilityDamage, 1);
|
SkillUtils.handleDurabilityChange(armor, durabilityDamage, 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -136,7 +136,7 @@ public class AxesManager extends SkillManager {
|
|||||||
*/
|
*/
|
||||||
public double greaterImpact(LivingEntity target) {
|
public double greaterImpact(LivingEntity target) {
|
||||||
//static chance (3rd param)
|
//static chance (3rd param)
|
||||||
if (!RandomChanceUtil.isActivationSuccessful(SkillActivationType.RANDOM_STATIC_CHANCE, SubSkillType.AXES_GREATER_IMPACT, getPlayer())) {
|
if (!RandomChanceUtil.isActivationSuccessful(SkillActivationType.RANDOM_STATIC_CHANCE, SubSkillType.AXES_GREATER_IMPACT, getPlayer(), mcMMOPlayer.getAttackStrength())) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -60,7 +60,7 @@ public class SwordsManager extends SkillManager {
|
|||||||
* @param target The defending entity
|
* @param target The defending entity
|
||||||
*/
|
*/
|
||||||
public void ruptureCheck(LivingEntity target) {
|
public void ruptureCheck(LivingEntity target) {
|
||||||
if (RandomChanceUtil.isActivationSuccessful(SkillActivationType.RANDOM_LINEAR_100_SCALE_WITH_CAP, SubSkillType.SWORDS_RUPTURE, getPlayer())) {
|
if (RandomChanceUtil.isActivationSuccessful(SkillActivationType.RANDOM_LINEAR_100_SCALE_WITH_CAP, SubSkillType.SWORDS_RUPTURE, getPlayer(), this.mcMMOPlayer.getAttackStrength())) {
|
||||||
|
|
||||||
if (target instanceof Player) {
|
if (target instanceof Player) {
|
||||||
Player defender = (Player) target;
|
Player defender = (Player) target;
|
||||||
@ -89,8 +89,7 @@ public class SwordsManager extends SkillManager {
|
|||||||
|
|
||||||
if(rank > 0)
|
if(rank > 0)
|
||||||
{
|
{
|
||||||
double stabDamage = 1.0D + (rank * 1.5);
|
return (1.0D + (rank * 1.5));
|
||||||
return stabDamage;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -26,23 +26,11 @@ import org.bukkit.entity.Player;
|
|||||||
import org.bukkit.inventory.ItemStack;
|
import org.bukkit.inventory.ItemStack;
|
||||||
|
|
||||||
public class UnarmedManager extends SkillManager {
|
public class UnarmedManager extends SkillManager {
|
||||||
private long lastAttacked;
|
|
||||||
private long attackInterval;
|
|
||||||
|
|
||||||
public UnarmedManager(McMMOPlayer mcMMOPlayer) {
|
public UnarmedManager(McMMOPlayer mcMMOPlayer) {
|
||||||
super(mcMMOPlayer, PrimarySkillType.UNARMED);
|
super(mcMMOPlayer, PrimarySkillType.UNARMED);
|
||||||
initUnarmedPerPlayerVars();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Inits variables used for each player for unarmed
|
|
||||||
*/
|
|
||||||
private void initUnarmedPerPlayerVars() {
|
|
||||||
lastAttacked = 0;
|
|
||||||
attackInterval = 750;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public boolean canActivateAbility() {
|
public boolean canActivateAbility() {
|
||||||
return mcMMOPlayer.getToolPreparationMode(ToolType.FISTS) && Permissions.berserk(getPlayer());
|
return mcMMOPlayer.getToolPreparationMode(ToolType.FISTS) && Permissions.berserk(getPlayer());
|
||||||
}
|
}
|
||||||
@ -113,7 +101,7 @@ public class UnarmedManager extends SkillManager {
|
|||||||
* @param defender The defending player
|
* @param defender The defending player
|
||||||
*/
|
*/
|
||||||
public void disarmCheck(Player defender) {
|
public void disarmCheck(Player defender) {
|
||||||
if (RandomChanceUtil.isActivationSuccessful(SkillActivationType.RANDOM_LINEAR_100_SCALE_WITH_CAP, SubSkillType.UNARMED_DISARM, getPlayer()) && !hasIronGrip(defender)) {
|
if (RandomChanceUtil.isActivationSuccessful(SkillActivationType.RANDOM_LINEAR_100_SCALE_WITH_CAP, SubSkillType.UNARMED_DISARM, getPlayer(), mcMMOPlayer.getAttackStrength()) && !hasIronGrip(defender)) {
|
||||||
if (EventUtils.callDisarmEvent(defender).isCancelled()) {
|
if (EventUtils.callDisarmEvent(defender).isCancelled()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -150,7 +138,7 @@ public class UnarmedManager extends SkillManager {
|
|||||||
* @param damage The amount of damage initially dealt by the event
|
* @param damage The amount of damage initially dealt by the event
|
||||||
*/
|
*/
|
||||||
public double berserkDamage(double damage) {
|
public double berserkDamage(double damage) {
|
||||||
damage = (damage * Unarmed.berserkDamageModifier) - damage;
|
damage = ((damage * Unarmed.berserkDamageModifier) * mcMMOPlayer.getAttackStrength()) - damage;
|
||||||
|
|
||||||
return damage;
|
return damage;
|
||||||
}
|
}
|
||||||
@ -158,7 +146,7 @@ public class UnarmedManager extends SkillManager {
|
|||||||
/**
|
/**
|
||||||
* Handle the effects of the Iron Arm ability
|
* Handle the effects of the Iron Arm ability
|
||||||
*/
|
*/
|
||||||
public double ironArm() {
|
public double calculateIronArmDamage() {
|
||||||
if (!RandomChanceUtil.isActivationSuccessful(SkillActivationType.ALWAYS_FIRES, SubSkillType.UNARMED_IRON_ARM_STYLE, getPlayer())) {
|
if (!RandomChanceUtil.isActivationSuccessful(SkillActivationType.ALWAYS_FIRES, SubSkillType.UNARMED_IRON_ARM_STYLE, getPlayer())) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -166,10 +154,6 @@ public class UnarmedManager extends SkillManager {
|
|||||||
return getIronArmDamage();
|
return getIronArmDamage();
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isPunchingCooldownOver() {
|
|
||||||
return (lastAttacked + attackInterval) <= System.currentTimeMillis();
|
|
||||||
}
|
|
||||||
|
|
||||||
public double getIronArmDamage() {
|
public double getIronArmDamage() {
|
||||||
int rank = RankUtils.getRank(getPlayer(), SubSkillType.UNARMED_IRON_ARM_STYLE);
|
int rank = RankUtils.getRank(getPlayer(), SubSkillType.UNARMED_IRON_ARM_STYLE);
|
||||||
|
|
||||||
@ -199,20 +183,4 @@ public class UnarmedManager extends SkillManager {
|
|||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
public long getLastAttacked() {
|
|
||||||
return lastAttacked;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setLastAttacked(long lastAttacked) {
|
|
||||||
this.lastAttacked = lastAttacked;
|
|
||||||
}
|
|
||||||
|
|
||||||
public long getAttackInterval() {
|
|
||||||
return attackInterval;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setAttackInterval(long attackInterval) {
|
|
||||||
this.attackInterval = attackInterval;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
package com.gmail.nossr50.util.commands;
|
package com.gmail.nossr50.util.commands;
|
||||||
|
|
||||||
import com.gmail.nossr50.commands.*;
|
import com.gmail.nossr50.commands.*;
|
||||||
|
import com.gmail.nossr50.commands.admin.CompatibilityCommand;
|
||||||
import com.gmail.nossr50.commands.admin.McmmoReloadLocaleCommand;
|
import com.gmail.nossr50.commands.admin.McmmoReloadLocaleCommand;
|
||||||
import com.gmail.nossr50.commands.admin.PlayerDebugCommand;
|
import com.gmail.nossr50.commands.admin.PlayerDebugCommand;
|
||||||
import com.gmail.nossr50.commands.chat.AdminChatCommand;
|
import com.gmail.nossr50.commands.chat.AdminChatCommand;
|
||||||
@ -421,6 +422,13 @@ public final class CommandRegistrationManager {
|
|||||||
command.setExecutor(new McmmoReloadLocaleCommand());
|
command.setExecutor(new McmmoReloadLocaleCommand());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static void registerCompatibilityCommand() {
|
||||||
|
PluginCommand command = mcMMO.p.getCommand("mmocompat"); //TODO: Localize
|
||||||
|
command.setDescription("Information about mcMMO and whether or not its in compatibility mode or fully functional.");
|
||||||
|
command.setUsage(LocaleLoader.formatString("Commands.Usage.0", "mmocompat"));
|
||||||
|
command.setExecutor(new CompatibilityCommand());
|
||||||
|
}
|
||||||
|
|
||||||
public static void registerCommands() {
|
public static void registerCommands() {
|
||||||
// Generic Commands
|
// Generic Commands
|
||||||
registerMmoInfoCommand();
|
registerMmoInfoCommand();
|
||||||
@ -472,5 +480,8 @@ public final class CommandRegistrationManager {
|
|||||||
|
|
||||||
// Admin commands
|
// Admin commands
|
||||||
registerReloadLocaleCommand();
|
registerReloadLocaleCommand();
|
||||||
|
|
||||||
|
// Misc
|
||||||
|
registerCompatibilityCommand();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,12 @@
|
|||||||
|
package com.gmail.nossr50.util.compat;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Compatibility Layers should be named after the functionality they serve
|
||||||
|
*/
|
||||||
|
public interface CompatibilityLayer {
|
||||||
|
/**
|
||||||
|
* Whether or not this CompatibilityLayer successfully initialized and in theory should be functional
|
||||||
|
* @return true if this CompatibilityLayer is functional
|
||||||
|
*/
|
||||||
|
boolean noErrorsOnInitialize();
|
||||||
|
}
|
@ -0,0 +1,125 @@
|
|||||||
|
package com.gmail.nossr50.util.compat;
|
||||||
|
|
||||||
|
import com.gmail.nossr50.locale.LocaleLoader;
|
||||||
|
import com.gmail.nossr50.mcMMO;
|
||||||
|
import com.gmail.nossr50.util.StringUtils;
|
||||||
|
import com.gmail.nossr50.util.compat.layers.PlayerAttackCooldownExploitPreventionLayer;
|
||||||
|
import com.gmail.nossr50.util.nms.NMSVersion;
|
||||||
|
import com.gmail.nossr50.util.platform.MinecraftGameVersion;
|
||||||
|
import org.bukkit.command.CommandSender;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* These classes are a band-aid solution for adding NMS support into 2.1.XXX
|
||||||
|
* In 2.2 we are switching to modules and that will clean things up significantly
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public class CompatibilityManager {
|
||||||
|
private HashMap<CompatibilityType, Boolean> supportedLayers;
|
||||||
|
private boolean isFullyCompatibleServerSoftware = true; //true if all compatibility layers load successfully
|
||||||
|
private final MinecraftGameVersion minecraftGameVersion;
|
||||||
|
private final NMSVersion nmsVersion;
|
||||||
|
|
||||||
|
/* Compatibility Layers */
|
||||||
|
private PlayerAttackCooldownExploitPreventionLayer playerAttackCooldownExploitPreventionLayer;
|
||||||
|
|
||||||
|
public CompatibilityManager(MinecraftGameVersion minecraftGameVersion) {
|
||||||
|
mcMMO.p.getLogger().info("Loading compatibility layers...");
|
||||||
|
this.minecraftGameVersion = minecraftGameVersion;
|
||||||
|
this.nmsVersion = determineNMSVersion();
|
||||||
|
init();
|
||||||
|
mcMMO.p.getLogger().info("Finished loading compatibility layers.");
|
||||||
|
}
|
||||||
|
|
||||||
|
private void init() {
|
||||||
|
initSupportedLayersMap();
|
||||||
|
initCompatibilityLayers();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void initSupportedLayersMap() {
|
||||||
|
supportedLayers = new HashMap<>(); //Init map
|
||||||
|
|
||||||
|
for(CompatibilityType compatibilityType : CompatibilityType.values()) {
|
||||||
|
supportedLayers.put(compatibilityType, false); //All layers are set to false when initialized
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initialize all necessary compatibility layers
|
||||||
|
* For any unsupported layers, load a dummy layer
|
||||||
|
*/
|
||||||
|
private void initCompatibilityLayers() {
|
||||||
|
if(nmsVersion == NMSVersion.UNSUPPORTED) {
|
||||||
|
mcMMO.p.getLogger().info("NMS not supported for this version of Minecraft, possible solutions include updating mcMMO or updating your server software. NMS Support is not available on every version of Minecraft.");
|
||||||
|
mcMMO.p.getLogger().info("Certain features of mcMMO that require NMS will be disabled, you can check what is disabled by running the /mmocompat command!");
|
||||||
|
//Load dummy compatibility layers
|
||||||
|
isFullyCompatibleServerSoftware = false;
|
||||||
|
loadDummyCompatibilityLayers();
|
||||||
|
} else {
|
||||||
|
playerAttackCooldownExploitPreventionLayer = new PlayerAttackCooldownExploitPreventionLayer(nmsVersion);
|
||||||
|
|
||||||
|
//Mark as operational
|
||||||
|
if(playerAttackCooldownExploitPreventionLayer.noErrorsOnInitialize()) {
|
||||||
|
supportedLayers.put(CompatibilityType.PLAYER_ATTACK_COOLDOWN_EXPLOIT_PREVENTION, true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void loadDummyCompatibilityLayers() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public void reportCompatibilityStatus(CommandSender commandSender) {
|
||||||
|
if(isFullyCompatibleServerSoftware) {
|
||||||
|
commandSender.sendMessage(LocaleLoader.getString("mcMMO.Template.Prefix",
|
||||||
|
"mcMMO is fully compatible with the currently running server software."));
|
||||||
|
} else {
|
||||||
|
//TODO: Better messages for each incompatible layer
|
||||||
|
for(CompatibilityType compatibilityType : CompatibilityType.values()) {
|
||||||
|
if(!supportedLayers.get(compatibilityType)) {
|
||||||
|
commandSender.sendMessage(LocaleLoader.getString("mcMMO.Template.Prefix",
|
||||||
|
"Support layer for " + StringUtils.getCapitalized(compatibilityType.toString()) + "is not supported on this version of Minecraft."));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
commandSender.sendMessage(LocaleLoader.getString("mcMMO.Template.Prefix", "NMS Status - " + nmsVersion.toString()));
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isCompatibilityLayerOperational(CompatibilityType compatibilityType) {
|
||||||
|
return supportedLayers.get(compatibilityType);
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isFullyCompatibleServerSoftware() {
|
||||||
|
return isFullyCompatibleServerSoftware;
|
||||||
|
}
|
||||||
|
|
||||||
|
public NMSVersion getNmsVersion() {
|
||||||
|
return nmsVersion;
|
||||||
|
}
|
||||||
|
|
||||||
|
private NMSVersion determineNMSVersion() {
|
||||||
|
switch(minecraftGameVersion.getMajorVersion().asInt()) {
|
||||||
|
case 1:
|
||||||
|
switch(minecraftGameVersion.getMinorVersion().asInt()) {
|
||||||
|
case 12:
|
||||||
|
return NMSVersion.NMS_1_12_2;
|
||||||
|
case 13:
|
||||||
|
return NMSVersion.NMS_1_13_2;
|
||||||
|
case 14:
|
||||||
|
return NMSVersion.NMS_1_14_4;
|
||||||
|
case 15:
|
||||||
|
return NMSVersion.NMS_1_15_2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return NMSVersion.UNSUPPORTED;
|
||||||
|
}
|
||||||
|
|
||||||
|
public PlayerAttackCooldownExploitPreventionLayer getPlayerAttackCooldownExploitPreventionLayer() {
|
||||||
|
return playerAttackCooldownExploitPreventionLayer;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,5 @@
|
|||||||
|
package com.gmail.nossr50.util.compat;
|
||||||
|
|
||||||
|
public enum CompatibilityType {
|
||||||
|
PLAYER_ATTACK_COOLDOWN_EXPLOIT_PREVENTION
|
||||||
|
}
|
@ -0,0 +1,32 @@
|
|||||||
|
package com.gmail.nossr50.util.compat.layers;
|
||||||
|
|
||||||
|
import com.gmail.nossr50.util.compat.CompatibilityLayer;
|
||||||
|
import com.gmail.nossr50.util.nms.NMSVersion;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* These classes are a band-aid solution for adding NMS support into 2.1.XXX
|
||||||
|
* In 2.2 we are switching to modules and that will clean things up significantly
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public abstract class AbstractCompatibilityLayer implements CompatibilityLayer {
|
||||||
|
|
||||||
|
protected boolean noErrorsOnInitialize = true;
|
||||||
|
protected final @NotNull NMSVersion nmsVersion;
|
||||||
|
|
||||||
|
public AbstractCompatibilityLayer(@NotNull NMSVersion nmsVersion) {
|
||||||
|
this.nmsVersion = nmsVersion;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initialize the CompatibilityLayer
|
||||||
|
* @return true if the CompatibilityLayer initialized and should be functional
|
||||||
|
*/
|
||||||
|
public abstract boolean initializeLayer();
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean noErrorsOnInitialize() {
|
||||||
|
return noErrorsOnInitialize;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,33 @@
|
|||||||
|
package com.gmail.nossr50.util.compat.layers;
|
||||||
|
|
||||||
|
import com.gmail.nossr50.util.nms.NMSVersion;
|
||||||
|
import org.bukkit.entity.Player;
|
||||||
|
|
||||||
|
import java.lang.reflect.InvocationTargetException;
|
||||||
|
|
||||||
|
public class DummyPlayerAttackCooldownExploitPreventionLayer extends PlayerAttackCooldownExploitPreventionLayer {
|
||||||
|
public DummyPlayerAttackCooldownExploitPreventionLayer() {
|
||||||
|
super(NMSVersion.UNSUPPORTED);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean initializeLayer() {
|
||||||
|
return noErrorsOnInitialize;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public float getAttackStrength(Player player) throws InvocationTargetException, IllegalAccessException {
|
||||||
|
return 1.0F; //Always full strength
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public float getCooldownValue(Player player) throws InvocationTargetException, IllegalAccessException {
|
||||||
|
return 0F;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void resetAttackStrength(Player player) throws InvocationTargetException, IllegalAccessException {
|
||||||
|
//Do nothing
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,198 @@
|
|||||||
|
package com.gmail.nossr50.util.compat.layers;
|
||||||
|
|
||||||
|
import com.gmail.nossr50.mcMMO;
|
||||||
|
import com.gmail.nossr50.util.nms.NMSConstants;
|
||||||
|
import com.gmail.nossr50.util.nms.NMSVersion;
|
||||||
|
import org.bukkit.entity.Player;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
|
import java.lang.reflect.InvocationTargetException;
|
||||||
|
import java.lang.reflect.Method;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* These classes are a band-aid solution for adding NMS support into 2.1.XXX
|
||||||
|
* In 2.2 we are switching to modules and that will clean things up significantly
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public class PlayerAttackCooldownExploitPreventionLayer extends AbstractCompatibilityLayer implements PlayerAttackCooldownMethods{
|
||||||
|
|
||||||
|
private final String cbNMSVersionPath;
|
||||||
|
|
||||||
|
protected Class<?> craftPlayerClass;
|
||||||
|
protected Class<?> entityHumanClass;
|
||||||
|
|
||||||
|
protected Method playerAttackCooldownMethod;
|
||||||
|
protected Method playerAttackStrengthMethod;
|
||||||
|
protected Method resetPlayerAttackCooldownMethod;
|
||||||
|
protected Method getHandleMethod;
|
||||||
|
|
||||||
|
public PlayerAttackCooldownExploitPreventionLayer(@NotNull NMSVersion nmsVersion) {
|
||||||
|
super(nmsVersion);
|
||||||
|
mcMMO.p.getLogger().info("Loading Compatibility Layer... (Player Attack Cooldown Exploit Prevention)");
|
||||||
|
if(!isCompatibleWithMinecraftVersion()) {
|
||||||
|
mcMMO.p.getLogger().severe("this version of mcMMO does not support NMS for this version of Minecraft, try updating mcMMO or updating Minecraft. Not all versions of Minecraft will have NMS support built into mcMMO.");
|
||||||
|
cbNMSVersionPath = "";
|
||||||
|
} else {
|
||||||
|
if(NMSConstants.getCraftBukkitVersionPath(nmsVersion) != null) {
|
||||||
|
cbNMSVersionPath = NMSConstants.getCraftBukkitVersionPath(nmsVersion);
|
||||||
|
noErrorsOnInitialize = initializeLayer();
|
||||||
|
|
||||||
|
if(noErrorsOnInitialize) {
|
||||||
|
mcMMO.p.getLogger().info("Successfully Loaded Compatibility Layer! (Player Attack Cooldown Exploit Prevention)");
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
mcMMO.p.getLogger().info("Failed to load - CL (Player Attack Cooldown Exploit Prevention) Could not find CB NMS path for CL");
|
||||||
|
flagErrorsDuringStartup();
|
||||||
|
mcMMO.p.getLogger().warning("Could not wire NMS package path for CraftBukkit!");
|
||||||
|
cbNMSVersionPath = "";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean isCompatibleWithMinecraftVersion() {
|
||||||
|
switch(nmsVersion) {
|
||||||
|
case NMS_1_13_2:
|
||||||
|
case NMS_1_14_4:
|
||||||
|
case NMS_1_15_2:
|
||||||
|
return true;
|
||||||
|
default:
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Cache all reflection methods/types/classes needed for the NMS of this CompatibilityLayer
|
||||||
|
* @param cooldownMethodName the cooldown method name
|
||||||
|
* @param attackStrengthMethodName the attack strength method name
|
||||||
|
* @param resetAttackCooldownMethodName the reset attack cooldown method name
|
||||||
|
* @param getHandleMethodName the get handle method name
|
||||||
|
* @return true if NMS was successfully wired
|
||||||
|
*/
|
||||||
|
public boolean wireNMS(@NotNull String cooldownMethodName, @NotNull String attackStrengthMethodName, @NotNull String resetAttackCooldownMethodName, @NotNull String getHandleMethodName) {
|
||||||
|
entityHumanClass = initEntityHumanClass();
|
||||||
|
craftPlayerClass = initCraftPlayerClass();
|
||||||
|
|
||||||
|
try {
|
||||||
|
this.playerAttackCooldownMethod = entityHumanClass.getMethod(cooldownMethodName);
|
||||||
|
this.playerAttackStrengthMethod = entityHumanClass.getMethod(attackStrengthMethodName, float.class);
|
||||||
|
this.resetPlayerAttackCooldownMethod = entityHumanClass.getMethod(resetAttackCooldownMethodName);
|
||||||
|
if (craftPlayerClass != null) {
|
||||||
|
this.getHandleMethod = craftPlayerClass.getMethod(getHandleMethodName);
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
} catch (NoSuchMethodException e) {
|
||||||
|
flagErrorsDuringStartup();
|
||||||
|
e.printStackTrace();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the cached player attack cooldown method
|
||||||
|
* @return the cached player attack cooldown method
|
||||||
|
*/
|
||||||
|
private @Nullable Method getPlayerAttackCooldownMethod() {
|
||||||
|
return playerAttackCooldownMethod;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the cached player attack strength method
|
||||||
|
* @return the cached player attack strength method
|
||||||
|
*/
|
||||||
|
private @Nullable Method getPlayerAttackStrengthMethod() {
|
||||||
|
return playerAttackStrengthMethod;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the cached player attack cooldown reset method
|
||||||
|
* @return the cached player attack cooldown reset method
|
||||||
|
*/
|
||||||
|
private @Nullable Method getResetPlayerAttackCooldownMethod() {
|
||||||
|
return resetPlayerAttackCooldownMethod;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Grab the CraftPlayer class type from NMS
|
||||||
|
* @return the CraftPlayer class type from NMS
|
||||||
|
*/
|
||||||
|
private @Nullable Class<?> initCraftPlayerClass() {
|
||||||
|
try {
|
||||||
|
return Class.forName(NMSConstants.getCraftPlayerClassPath(cbNMSVersionPath));
|
||||||
|
} catch (ClassNotFoundException e) {
|
||||||
|
flagErrorsDuringStartup();
|
||||||
|
e.printStackTrace();
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Grab the EntityHuman class type from NMS
|
||||||
|
* @return the EntityHuman class type from NMS
|
||||||
|
*/
|
||||||
|
private @Nullable Class<?> initEntityHumanClass() {
|
||||||
|
try {
|
||||||
|
return Class.forName(NMSConstants.getEntityHumanClassPath(cbNMSVersionPath));
|
||||||
|
} catch (ClassNotFoundException e) {
|
||||||
|
flagErrorsDuringStartup();
|
||||||
|
e.printStackTrace();
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void flagErrorsDuringStartup() {
|
||||||
|
noErrorsOnInitialize = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Grabs the attack strength for a player
|
||||||
|
* Should be noted that as of today there is no way to capture a players current attack strength in spigot when they attack an entity outside of network packet listening
|
||||||
|
* @param player target player
|
||||||
|
* @return the float value of the player's attack strength
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public float getAttackStrength(Player player) throws InvocationTargetException, IllegalAccessException {
|
||||||
|
Object craftPlayer = craftPlayerClass.cast(player);
|
||||||
|
Object entityHuman = entityHumanClass.cast(getHandleMethod.invoke(craftPlayer));
|
||||||
|
|
||||||
|
return (float) playerAttackStrengthMethod.invoke(entityHuman, 0F); //Add no adjustment ticks
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public float getCooldownValue(Player player) throws InvocationTargetException, IllegalAccessException {
|
||||||
|
Object craftPlayer = craftPlayerClass.cast(player);
|
||||||
|
Object entityHuman = entityHumanClass.cast(getHandleMethod.invoke(craftPlayer));
|
||||||
|
|
||||||
|
return (float) playerAttackCooldownMethod.invoke(entityHuman); //Add no adjustment ticks
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void resetAttackStrength(Player player) throws InvocationTargetException, IllegalAccessException {
|
||||||
|
Object craftPlayer = craftPlayerClass.cast(player);
|
||||||
|
Object entityHuman = entityHumanClass.cast(getHandleMethod.invoke(craftPlayer));
|
||||||
|
|
||||||
|
resetPlayerAttackCooldownMethod.invoke(entityHuman);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean initializeLayer() {
|
||||||
|
switch(nmsVersion) {
|
||||||
|
case NMS_1_12_2:
|
||||||
|
return wireNMS("dr", "n", "ds", "getHandle");
|
||||||
|
case NMS_1_13_2:
|
||||||
|
return wireNMS("dG", "r", "dH", "getHandle");
|
||||||
|
case NMS_1_14_4:
|
||||||
|
return wireNMS("dY", "s", "dZ", "getHandle");
|
||||||
|
case NMS_1_15_2:
|
||||||
|
return wireNMS("ex", "s", "ey", "getHandle");
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,19 @@
|
|||||||
|
package com.gmail.nossr50.util.compat.layers;
|
||||||
|
|
||||||
|
import org.bukkit.entity.Player;
|
||||||
|
|
||||||
|
import java.lang.reflect.InvocationTargetException;
|
||||||
|
|
||||||
|
public interface PlayerAttackCooldownMethods {
|
||||||
|
/**
|
||||||
|
* Grabs the attack strength for a player
|
||||||
|
* Should be noted that as of today there is no way to capture a players current attack strength in spigot when they attack an entity outside of network packet listening
|
||||||
|
* @param player target player
|
||||||
|
* @return the float value of the player's attack strength
|
||||||
|
*/
|
||||||
|
float getAttackStrength(Player player) throws InvocationTargetException, IllegalAccessException;
|
||||||
|
|
||||||
|
float getCooldownValue(Player player) throws InvocationTargetException, IllegalAccessException;
|
||||||
|
|
||||||
|
void resetAttackStrength(Player player) throws InvocationTargetException, IllegalAccessException;
|
||||||
|
}
|
59
src/main/java/com/gmail/nossr50/util/nms/NMSConstants.java
Normal file
59
src/main/java/com/gmail/nossr50/util/nms/NMSConstants.java
Normal file
@ -0,0 +1,59 @@
|
|||||||
|
package com.gmail.nossr50.util.nms;
|
||||||
|
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
|
public class NMSConstants {
|
||||||
|
public final static String BUKKIT_PACKAGE_PATH = "org.bukkit";
|
||||||
|
public final static String CRAFT_BUKKIT_PACKAGE_PATH = "org.bukkit.craftbukkit";
|
||||||
|
public final static String NET_MINECRAFT_SERVER = "net.minecraft.server";
|
||||||
|
|
||||||
|
private final static String CRAFT_PLAYER_CLASS_PATH = "entity.CraftPlayer";
|
||||||
|
private final static String ENTITY_HUMAN_CLASS_PATH = "EntityHuman";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Grabs the fully qualified path of a class from CB
|
||||||
|
* @param targetClass source root path
|
||||||
|
* @return the fully qualified path of a CB class
|
||||||
|
*/
|
||||||
|
protected static String getFullyQualifiedCraftBukkitPath(String cbVersionPackage, String targetClass) {
|
||||||
|
return CRAFT_BUKKIT_PACKAGE_PATH + "." + cbVersionPackage + "." + targetClass;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected static String getFullQualifiedBukkitPath(String fromSourceRoot) {
|
||||||
|
return BUKKIT_PACKAGE_PATH + "." + fromSourceRoot;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected static String getFullyQualifiedNMSPath(String cbVersionPackage, String fromSourceRoot) {
|
||||||
|
return NET_MINECRAFT_SERVER + "." +cbVersionPackage + "." + fromSourceRoot;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String getCraftPlayerClassPath(String cbVersionPackage) {
|
||||||
|
return getFullyQualifiedCraftBukkitPath(cbVersionPackage, CRAFT_PLAYER_CLASS_PATH);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String getEntityHumanClassPath(String cbVersionPackage) {
|
||||||
|
return getFullyQualifiedNMSPath(cbVersionPackage, ENTITY_HUMAN_CLASS_PATH);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static @Nullable String getCraftBukkitVersionPath(NMSVersion nmsVersion) {
|
||||||
|
switch (nmsVersion) {
|
||||||
|
|
||||||
|
case NMS_1_8_8:
|
||||||
|
break;
|
||||||
|
case NMS_1_12_2:
|
||||||
|
return "v1_12_R1";
|
||||||
|
case NMS_1_13_2:
|
||||||
|
return "v1_13_R2";
|
||||||
|
case NMS_1_14_4:
|
||||||
|
return "v1_14_R1";
|
||||||
|
case NMS_1_15_2:
|
||||||
|
return "v1_15_R1";
|
||||||
|
case NMS_1_16:
|
||||||
|
break;
|
||||||
|
case UNSUPPORTED:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
39
src/main/java/com/gmail/nossr50/util/nms/NMSVersion.java
Normal file
39
src/main/java/com/gmail/nossr50/util/nms/NMSVersion.java
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
package com.gmail.nossr50.util.nms;
|
||||||
|
|
||||||
|
public enum NMSVersion {
|
||||||
|
//1.8
|
||||||
|
NMS_1_8_8("1.8.8"),
|
||||||
|
|
||||||
|
//1.12
|
||||||
|
NMS_1_12_2("1.12.2"),
|
||||||
|
|
||||||
|
//1.13
|
||||||
|
NMS_1_13_2("1.13.2"),
|
||||||
|
|
||||||
|
//1.14
|
||||||
|
NMS_1_14_4("1.14.4"),
|
||||||
|
|
||||||
|
//1.15
|
||||||
|
NMS_1_15_2("1.15.2"),
|
||||||
|
|
||||||
|
//1.16
|
||||||
|
NMS_1_16("1.16"),
|
||||||
|
|
||||||
|
//Version not known to this build of mcMMO
|
||||||
|
UNSUPPORTED("unsupported");
|
||||||
|
|
||||||
|
private final String sanitizedVersionNumber;
|
||||||
|
|
||||||
|
NMSVersion(String sanitizedVersionNumber) {
|
||||||
|
this.sanitizedVersionNumber = sanitizedVersionNumber;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The standardized major.minor.patch {@link String} for the current NMS mappings
|
||||||
|
*
|
||||||
|
* @return the standardized major.minor.patch version string, patch is omitted if it is not a patch version
|
||||||
|
*/
|
||||||
|
public String getSanitizedVersionNumber() {
|
||||||
|
return sanitizedVersionNumber;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,23 @@
|
|||||||
|
package com.gmail.nossr50.util.platform;
|
||||||
|
|
||||||
|
import com.gmail.nossr50.util.compat.CompatibilityManager;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* These classes are a band-aid solution for adding NMS support into 2.1.XXX
|
||||||
|
* In 2.2 we are switching to modules and that will clean things up significantly
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public abstract class AbstractPlatform implements Platform{
|
||||||
|
|
||||||
|
protected final CompatibilityManager compatibilityManager;
|
||||||
|
protected final MinecraftGameVersion minecraftGameVersion;
|
||||||
|
protected final ServerSoftwareType serverSoftwareType;
|
||||||
|
|
||||||
|
public AbstractPlatform(MinecraftGameVersion minecraftGameVersion, ServerSoftwareType serverSoftwareType, CompatibilityManager compatibilityManager) {
|
||||||
|
this.minecraftGameVersion = minecraftGameVersion;
|
||||||
|
this.serverSoftwareType = serverSoftwareType;
|
||||||
|
this.compatibilityManager = compatibilityManager;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,32 @@
|
|||||||
|
package com.gmail.nossr50.util.platform;
|
||||||
|
|
||||||
|
import com.gmail.nossr50.util.compat.CompatibilityManager;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* These classes are a band-aid solution for adding NMS support into 2.1.XXX
|
||||||
|
* In 2.2 we are switching to modules and that will clean things up significantly
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public class BukkitPlatform extends AbstractPlatform {
|
||||||
|
public BukkitPlatform(MinecraftGameVersion minecraftGameVersion) {
|
||||||
|
super(minecraftGameVersion, ServerSoftwareType.CRAFT_BUKKIT, new CompatibilityManager(minecraftGameVersion));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public @NotNull ServerSoftwareType getServerSoftwareType() {
|
||||||
|
return super.serverSoftwareType;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public @NotNull CompatibilityManager getCompatibilityManager() {
|
||||||
|
return compatibilityManager;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public @NotNull MinecraftGameVersion getGameVersion() {
|
||||||
|
return super.minecraftGameVersion;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,113 @@
|
|||||||
|
package com.gmail.nossr50.util.platform;
|
||||||
|
|
||||||
|
import com.gmail.nossr50.util.platform.version.SimpleNumericVersion;
|
||||||
|
import com.gmail.nossr50.util.platform.version.Versioned;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
|
import java.util.Objects;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* These classes are a band-aid solution for adding NMS support into 2.1.XXX
|
||||||
|
* In 2.2 we are switching to modules and that will clean things up significantly
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public abstract class MajorMinorPatchVersion implements Versioned {
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
private final SimpleNumericVersion majorVersion;
|
||||||
|
@NotNull
|
||||||
|
private final SimpleNumericVersion minorVersion;
|
||||||
|
@NotNull
|
||||||
|
private final SimpleNumericVersion patchVersion;
|
||||||
|
|
||||||
|
public MajorMinorPatchVersion(@NotNull SimpleNumericVersion majorVersion, @NotNull SimpleNumericVersion minorVersion) {
|
||||||
|
this.majorVersion = majorVersion;
|
||||||
|
this.minorVersion = minorVersion;
|
||||||
|
this.patchVersion = new SimpleNumericVersion(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
public MajorMinorPatchVersion(@NotNull SimpleNumericVersion majorVersion, @NotNull SimpleNumericVersion minorVersion, @Nullable SimpleNumericVersion patchVersion) {
|
||||||
|
this.majorVersion = majorVersion;
|
||||||
|
this.minorVersion = minorVersion;
|
||||||
|
|
||||||
|
if(patchVersion == null) {
|
||||||
|
this.patchVersion = new SimpleNumericVersion(0);
|
||||||
|
} else {
|
||||||
|
this.patchVersion = patchVersion;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public MajorMinorPatchVersion(int majorVerNumber, int minorVerNumber, int patchVerNumber) {
|
||||||
|
this.majorVersion = new SimpleNumericVersion(majorVerNumber);
|
||||||
|
this.minorVersion = new SimpleNumericVersion(minorVerNumber);
|
||||||
|
this.patchVersion = new SimpleNumericVersion(patchVerNumber);
|
||||||
|
}
|
||||||
|
|
||||||
|
public MajorMinorPatchVersion(int majorVerNumber, int minorVerNumber) {
|
||||||
|
this.majorVersion = new SimpleNumericVersion(majorVerNumber);
|
||||||
|
this.minorVersion = new SimpleNumericVersion(minorVerNumber);
|
||||||
|
this.patchVersion = new SimpleNumericVersion(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the major version string
|
||||||
|
* @return the major version string
|
||||||
|
*/
|
||||||
|
public @NotNull SimpleNumericVersion getMajorVersion() {
|
||||||
|
return majorVersion;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the minor version string
|
||||||
|
* @return the minor version string
|
||||||
|
*/
|
||||||
|
public @NotNull SimpleNumericVersion getMinorVersion() {
|
||||||
|
return minorVersion;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the patch version string
|
||||||
|
* @return patch version string or null if patch numeric value is less than or equal to 0
|
||||||
|
*/
|
||||||
|
public @NotNull SimpleNumericVersion getPatchVersion() {
|
||||||
|
return patchVersion;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getVersionStr() {
|
||||||
|
if(isPatch()) {
|
||||||
|
return majorVersion.getVersionString() + "."
|
||||||
|
+ minorVersion + "."
|
||||||
|
+ patchVersion;
|
||||||
|
} else {
|
||||||
|
return majorVersion.getVersionString() + "."
|
||||||
|
+ minorVersion.getVersionString();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Whether or not this version of Minecraft is a patch
|
||||||
|
* a patch version value above 0 will indicate that this is a patch
|
||||||
|
* @return true if this version is a patch
|
||||||
|
*/
|
||||||
|
public boolean isPatch() {
|
||||||
|
return patchVersion.asInt() > 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object o) {
|
||||||
|
if (this == o) return true;
|
||||||
|
if (o == null || getClass() != o.getClass()) return false;
|
||||||
|
MajorMinorPatchVersion that = (MajorMinorPatchVersion) o;
|
||||||
|
return majorVersion.equals(that.majorVersion) &&
|
||||||
|
minorVersion.equals(that.minorVersion) &&
|
||||||
|
patchVersion.equals(that.patchVersion);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
return Objects.hash(majorVersion, minorVersion, patchVersion);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,30 @@
|
|||||||
|
package com.gmail.nossr50.util.platform;
|
||||||
|
|
||||||
|
import com.gmail.nossr50.util.platform.version.SimpleNumericVersion;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* These classes are a band-aid solution for adding NMS support into 2.1.XXX
|
||||||
|
* In 2.2 we are switching to modules and that will clean things up significantly
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public class MinecraftGameVersion extends MajorMinorPatchVersion {
|
||||||
|
public MinecraftGameVersion(@NotNull SimpleNumericVersion majorVersion, @NotNull SimpleNumericVersion minorVersion) {
|
||||||
|
super(majorVersion, minorVersion);
|
||||||
|
}
|
||||||
|
|
||||||
|
public MinecraftGameVersion(@NotNull SimpleNumericVersion majorVersion, @NotNull SimpleNumericVersion minorVersion, @Nullable SimpleNumericVersion patchVersion) {
|
||||||
|
super(majorVersion, minorVersion, patchVersion);
|
||||||
|
}
|
||||||
|
|
||||||
|
public MinecraftGameVersion(int majorVerNumber, int minorVerNumber, int patchVerNumber) {
|
||||||
|
super(majorVerNumber, minorVerNumber, patchVerNumber);
|
||||||
|
}
|
||||||
|
|
||||||
|
public MinecraftGameVersion(int majorVerNumber, int minorVerNumber) {
|
||||||
|
super(majorVerNumber, minorVerNumber);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
32
src/main/java/com/gmail/nossr50/util/platform/Platform.java
Normal file
32
src/main/java/com/gmail/nossr50/util/platform/Platform.java
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
package com.gmail.nossr50.util.platform;
|
||||||
|
|
||||||
|
import com.gmail.nossr50.util.compat.CompatibilityManager;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* These classes are a band-aid solution for adding NMS support into 2.1.XXX
|
||||||
|
* In 2.2 we are switching to modules and that will clean things up significantly
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public interface Platform {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Target {@link ServerSoftwareType} for this {@link Platform}
|
||||||
|
* @return the {@link ServerSoftwareType} for this {@link Platform}
|
||||||
|
*/
|
||||||
|
@NotNull ServerSoftwareType getServerSoftwareType();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the {@link CompatibilityManager} for this {@link Platform}
|
||||||
|
* @return the {@link CompatibilityManager} for this platform
|
||||||
|
*/
|
||||||
|
@NotNull CompatibilityManager getCompatibilityManager();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The target game version of this {@link Platform}
|
||||||
|
* @return the target {@link MinecraftGameVersion} of this {@link Platform}
|
||||||
|
*/
|
||||||
|
@NotNull MinecraftGameVersion getGameVersion();
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,45 @@
|
|||||||
|
package com.gmail.nossr50.util.platform;
|
||||||
|
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* These classes are a band-aid solution for adding NMS support into 2.1.XXX
|
||||||
|
* In 2.2 we are switching to modules and that will clean things up significantly
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public class PlatformBuilder {
|
||||||
|
private MinecraftGameVersion minecraftGameVersion;
|
||||||
|
private ServerSoftwareType serverSoftwareType;
|
||||||
|
|
||||||
|
public PlatformBuilder() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public PlatformBuilder setMinecraftGameVersion(@NotNull MinecraftGameVersion minecraftGameVersion) {
|
||||||
|
this.minecraftGameVersion = minecraftGameVersion;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public PlatformBuilder setSoftwareType(@NotNull ServerSoftwareType softwareType) {
|
||||||
|
this.serverSoftwareType = softwareType;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public @Nullable Platform build() {
|
||||||
|
switch(serverSoftwareType) {
|
||||||
|
|
||||||
|
case PAPER:
|
||||||
|
case SPIGOT:
|
||||||
|
case CRAFT_BUKKIT:
|
||||||
|
return createBukkitPlatform();
|
||||||
|
default:
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private BukkitPlatform createBukkitPlatform() {
|
||||||
|
return new BukkitPlatform(minecraftGameVersion);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,130 @@
|
|||||||
|
package com.gmail.nossr50.util.platform;
|
||||||
|
|
||||||
|
import com.gmail.nossr50.mcMMO;
|
||||||
|
import com.gmail.nossr50.util.compat.CompatibilityManager;
|
||||||
|
import org.bukkit.Bukkit;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Locale;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* These classes are a band-aid solution for adding NMS support into 2.1.XXX
|
||||||
|
* In 2.2 we are switching to modules and that will clean things up significantly
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public class PlatformManager {
|
||||||
|
protected Platform platform; //current platform
|
||||||
|
|
||||||
|
public PlatformManager() {
|
||||||
|
init();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void init() {
|
||||||
|
platform = loadPlatform();
|
||||||
|
}
|
||||||
|
|
||||||
|
public Platform getPlatform() {
|
||||||
|
return platform;
|
||||||
|
}
|
||||||
|
|
||||||
|
private @Nullable Platform loadPlatform() {
|
||||||
|
ServerSoftwareType serverSoftwareType = determinePlatformType();
|
||||||
|
PlatformBuilder platformBuilder = new PlatformBuilder();
|
||||||
|
MinecraftGameVersion gameVersion = determineGameVersion(Bukkit.getBukkitVersion());
|
||||||
|
|
||||||
|
return platformBuilder
|
||||||
|
.setMinecraftGameVersion(gameVersion)
|
||||||
|
.setSoftwareType(serverSoftwareType)
|
||||||
|
.build();
|
||||||
|
}
|
||||||
|
|
||||||
|
//TODO: make this work on things other than bukkit
|
||||||
|
@Deprecated //Only good for determining bukkit game versions
|
||||||
|
private @NotNull MinecraftGameVersion determineGameVersion(String platformVersionString) {
|
||||||
|
int major = 0, minor = 0, patch = 0;
|
||||||
|
|
||||||
|
String[] splitVersion = platformVersionString.split("\\.", 3);
|
||||||
|
|
||||||
|
mcMMO.p.getLogger().info("Platform String: " + platformVersionString);
|
||||||
|
|
||||||
|
//TODO: this is very hacky and probably isn't reliable
|
||||||
|
//Grab all consecutive digits
|
||||||
|
major = getSubsequentDigits(splitVersion[0].toCharArray(), 0);
|
||||||
|
minor = getSubsequentDigits(splitVersion[1].toCharArray(), 0);
|
||||||
|
//Not all versions of Minecraft have a patch digit
|
||||||
|
//If the first character isn't a digit it's not a patch number and its some crap we don't care about
|
||||||
|
if(splitVersion.length > 2 && Character.isDigit(splitVersion[2].toCharArray()[0]))
|
||||||
|
patch = getSubsequentDigits(splitVersion[2].toCharArray(), 0);
|
||||||
|
|
||||||
|
mcMMO.p.getLogger().info("Minecraft version determined to be - "
|
||||||
|
+ major + "."
|
||||||
|
+ minor + "."
|
||||||
|
+ patch);
|
||||||
|
|
||||||
|
return new MinecraftGameVersion(major, minor, patch);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get all consecutive digits in a char array from position
|
||||||
|
* @param charArray target char array
|
||||||
|
* @param position starting position
|
||||||
|
* @return all consecutive digits from position
|
||||||
|
*/
|
||||||
|
private int getSubsequentDigits(char[] charArray, int position) {
|
||||||
|
ArrayList<Character> digitArrayList = new ArrayList<>();
|
||||||
|
|
||||||
|
do {
|
||||||
|
if(Character.isDigit(charArray[position])) {
|
||||||
|
digitArrayList.add(charArray[position]);
|
||||||
|
position++;
|
||||||
|
} else {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} while (position < charArray.length);
|
||||||
|
|
||||||
|
//Convert List<Character> -> String
|
||||||
|
String digits = digitArrayList
|
||||||
|
.stream()
|
||||||
|
.map(String::valueOf)
|
||||||
|
.collect(Collectors.joining());
|
||||||
|
|
||||||
|
//Copy value
|
||||||
|
return Integer.parseInt(digits);
|
||||||
|
}
|
||||||
|
|
||||||
|
//TODO: Rewrite this properly once we actually support a not-bukkit platform
|
||||||
|
private @NotNull ServerSoftwareType determinePlatformType() {
|
||||||
|
if(Bukkit.getVersion().toLowerCase(Locale.ENGLISH).contains("paper"))
|
||||||
|
return ServerSoftwareType.PAPER;
|
||||||
|
else if(Bukkit.getVersion().toLowerCase(Locale.ENGLISH).contains("spigot"))
|
||||||
|
return ServerSoftwareType.SPIGOT;
|
||||||
|
else
|
||||||
|
return ServerSoftwareType.CRAFT_BUKKIT;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ServerSoftwareType getServerSoftware()
|
||||||
|
{
|
||||||
|
return platform.getServerSoftwareType();
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getServerSoftwareStr()
|
||||||
|
{
|
||||||
|
switch(getServerSoftware())
|
||||||
|
{
|
||||||
|
case PAPER:
|
||||||
|
return "Paper";
|
||||||
|
case SPIGOT:
|
||||||
|
return "Spigot";
|
||||||
|
default:
|
||||||
|
return "CraftBukkit";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public @Nullable CompatibilityManager getCompatibilityManager() {
|
||||||
|
return platform.getCompatibilityManager();
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,9 @@
|
|||||||
|
package com.gmail.nossr50.util.platform;
|
||||||
|
|
||||||
|
public enum ServerSoftwareType {
|
||||||
|
PAPER,
|
||||||
|
SPIGOT,
|
||||||
|
CRAFT_BUKKIT,
|
||||||
|
SPONGE,
|
||||||
|
OTHER
|
||||||
|
}
|
@ -0,0 +1,5 @@
|
|||||||
|
package com.gmail.nossr50.util.platform.version;
|
||||||
|
|
||||||
|
public interface NumericVersioned extends Versioned {
|
||||||
|
int asInt();
|
||||||
|
}
|
@ -0,0 +1,22 @@
|
|||||||
|
package com.gmail.nossr50.util.platform.version;
|
||||||
|
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
|
public class SimpleNumericVersion extends SimpleVersion implements NumericVersioned {
|
||||||
|
private int versionNumber;
|
||||||
|
|
||||||
|
public SimpleNumericVersion(int versionNumber) {
|
||||||
|
super(String.valueOf(versionNumber));
|
||||||
|
this.versionNumber = versionNumber;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int asInt() {
|
||||||
|
return versionNumber;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public @NotNull String getVersionStr() {
|
||||||
|
return super.getVersionString();
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,17 @@
|
|||||||
|
package com.gmail.nossr50.util.platform.version;
|
||||||
|
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
|
public class SimpleVersion {
|
||||||
|
@NotNull
|
||||||
|
private final String versionString;
|
||||||
|
|
||||||
|
public SimpleVersion(@NotNull String versionString) {
|
||||||
|
this.versionString = versionString;
|
||||||
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
public String getVersionString() {
|
||||||
|
return versionString;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,5 @@
|
|||||||
|
package com.gmail.nossr50.util.platform.version;
|
||||||
|
|
||||||
|
public interface Versioned {
|
||||||
|
String getVersionStr();
|
||||||
|
}
|
@ -14,7 +14,29 @@ public class RandomChanceSkill implements RandomChanceExecution {
|
|||||||
protected final SubSkillType subSkillType;
|
protected final SubSkillType subSkillType;
|
||||||
protected final double probabilityCap;
|
protected final double probabilityCap;
|
||||||
protected final boolean isLucky;
|
protected final boolean isLucky;
|
||||||
private int skillLevel;
|
protected int skillLevel;
|
||||||
|
protected double resultModifier;
|
||||||
|
|
||||||
|
public RandomChanceSkill(Player player, SubSkillType subSkillType, double resultModifier)
|
||||||
|
{
|
||||||
|
this.primarySkillType = subSkillType.getParentSkill();
|
||||||
|
this.subSkillType = subSkillType;
|
||||||
|
this.probabilityCap = RandomChanceUtil.LINEAR_CURVE_VAR;
|
||||||
|
|
||||||
|
final McMMOPlayer mcMMOPlayer = UserManager.getPlayer(player);
|
||||||
|
if (player != null && mcMMOPlayer != null) {
|
||||||
|
this.skillLevel = mcMMOPlayer.getSkillLevel(primarySkillType);
|
||||||
|
} else {
|
||||||
|
this.skillLevel = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(player != null)
|
||||||
|
isLucky = Permissions.lucky(player, primarySkillType);
|
||||||
|
else
|
||||||
|
isLucky = false;
|
||||||
|
|
||||||
|
this.resultModifier = resultModifier;
|
||||||
|
}
|
||||||
|
|
||||||
public RandomChanceSkill(Player player, SubSkillType subSkillType)
|
public RandomChanceSkill(Player player, SubSkillType subSkillType)
|
||||||
{
|
{
|
||||||
@ -33,6 +55,8 @@ public class RandomChanceSkill implements RandomChanceExecution {
|
|||||||
isLucky = Permissions.lucky(player, primarySkillType);
|
isLucky = Permissions.lucky(player, primarySkillType);
|
||||||
else
|
else
|
||||||
isLucky = false;
|
isLucky = false;
|
||||||
|
|
||||||
|
this.resultModifier = 1.0D;
|
||||||
}
|
}
|
||||||
|
|
||||||
public RandomChanceSkill(Player player, SubSkillType subSkillType, boolean hasCap)
|
public RandomChanceSkill(Player player, SubSkillType subSkillType, boolean hasCap)
|
||||||
@ -56,6 +80,33 @@ public class RandomChanceSkill implements RandomChanceExecution {
|
|||||||
isLucky = Permissions.lucky(player, primarySkillType);
|
isLucky = Permissions.lucky(player, primarySkillType);
|
||||||
else
|
else
|
||||||
isLucky = false;
|
isLucky = false;
|
||||||
|
|
||||||
|
this.resultModifier = 1.0D;
|
||||||
|
}
|
||||||
|
|
||||||
|
public RandomChanceSkill(Player player, SubSkillType subSkillType, boolean hasCap, double resultModifier)
|
||||||
|
{
|
||||||
|
if(hasCap)
|
||||||
|
this.probabilityCap = AdvancedConfig.getInstance().getMaximumProbability(subSkillType);
|
||||||
|
else
|
||||||
|
this.probabilityCap = RandomChanceUtil.LINEAR_CURVE_VAR;
|
||||||
|
|
||||||
|
this.primarySkillType = subSkillType.getParentSkill();
|
||||||
|
this.subSkillType = subSkillType;
|
||||||
|
|
||||||
|
final McMMOPlayer mcMMOPlayer = UserManager.getPlayer(player);
|
||||||
|
if (player != null && mcMMOPlayer != null) {
|
||||||
|
this.skillLevel = mcMMOPlayer.getSkillLevel(primarySkillType);
|
||||||
|
} else {
|
||||||
|
this.skillLevel = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(player != null)
|
||||||
|
isLucky = Permissions.lucky(player, primarySkillType);
|
||||||
|
else
|
||||||
|
isLucky = false;
|
||||||
|
|
||||||
|
this.resultModifier = resultModifier;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -118,4 +169,12 @@ public class RandomChanceSkill implements RandomChanceExecution {
|
|||||||
public boolean isLucky() {
|
public boolean isLucky() {
|
||||||
return isLucky;
|
return isLucky;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public double getResultModifier() {
|
||||||
|
return resultModifier;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setResultModifier(double resultModifier) {
|
||||||
|
this.resultModifier = resultModifier;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -13,6 +13,13 @@ public class RandomChanceSkillStatic extends RandomChanceSkill {
|
|||||||
this.xPos = xPos;
|
this.xPos = xPos;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public RandomChanceSkillStatic(double xPos, Player player, SubSkillType subSkillType, double resultModifier)
|
||||||
|
{
|
||||||
|
super(player, subSkillType, resultModifier);
|
||||||
|
|
||||||
|
this.xPos = xPos;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the XPos used in the formula for success
|
* Gets the XPos used in the formula for success
|
||||||
*
|
*
|
||||||
|
@ -46,6 +46,32 @@ public class RandomChanceUtil
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method is the final step in determining if a Sub-Skill / Secondary Skill in mcMMO successfully activates either from chance or otherwise
|
||||||
|
* Random skills check for success based on numbers and then fire a cancellable event, if that event is not cancelled they succeed
|
||||||
|
* non-RNG skills just fire the cancellable event and succeed if they go uncancelled
|
||||||
|
*
|
||||||
|
* @param skillActivationType this value represents what kind of activation procedures this sub-skill uses
|
||||||
|
* @param subSkillType The identifier for this specific sub-skill
|
||||||
|
* @param player The owner of this sub-skill
|
||||||
|
* @return returns true if all conditions are met and the event is not cancelled
|
||||||
|
*/
|
||||||
|
public static boolean isActivationSuccessful(SkillActivationType skillActivationType, SubSkillType subSkillType, Player player, double resultModifier)
|
||||||
|
{
|
||||||
|
switch(skillActivationType)
|
||||||
|
{
|
||||||
|
case RANDOM_LINEAR_100_SCALE_WITH_CAP:
|
||||||
|
return checkRandomChanceExecutionSuccess(player, subSkillType, true);
|
||||||
|
case RANDOM_STATIC_CHANCE:
|
||||||
|
return checkRandomStaticChanceExecutionSuccess(player, subSkillType, resultModifier);
|
||||||
|
case ALWAYS_FIRES:
|
||||||
|
SubSkillEvent event = EventUtils.callSubSkillEvent(player, subSkillType);
|
||||||
|
return !event.isCancelled();
|
||||||
|
default:
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public static double getActivationChance(SkillActivationType skillActivationType, SubSkillType subSkillType, Player player)
|
public static double getActivationChance(SkillActivationType skillActivationType, SubSkillType subSkillType, Player player)
|
||||||
{
|
{
|
||||||
switch(skillActivationType)
|
switch(skillActivationType)
|
||||||
@ -78,7 +104,24 @@ public class RandomChanceUtil
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static boolean rollDice(double chanceOfSuccess, int bound) {
|
public static boolean rollDice(double chanceOfSuccess, int bound) {
|
||||||
return chanceOfSuccess > ThreadLocalRandom.current().nextInt(bound);
|
return rollDice(chanceOfSuccess, bound, 1.0F);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean rollDice(double chanceOfSuccess, int bound, double resultModifier) {
|
||||||
|
return chanceOfSuccess > (ThreadLocalRandom.current().nextInt(bound) * resultModifier);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Used for stuff like Excavation, Fishing, etc...
|
||||||
|
* @param randomChance
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public static boolean checkRandomChanceExecutionSuccess(RandomChanceSkillStatic randomChance, double resultModifier)
|
||||||
|
{
|
||||||
|
double chanceOfSuccess = calculateChanceOfSuccess(randomChance);
|
||||||
|
|
||||||
|
//Check the odds
|
||||||
|
return rollDice(chanceOfSuccess, 100, resultModifier);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -88,10 +131,7 @@ public class RandomChanceUtil
|
|||||||
*/
|
*/
|
||||||
public static boolean checkRandomChanceExecutionSuccess(RandomChanceSkillStatic randomChance)
|
public static boolean checkRandomChanceExecutionSuccess(RandomChanceSkillStatic randomChance)
|
||||||
{
|
{
|
||||||
double chanceOfSuccess = calculateChanceOfSuccess(randomChance);
|
return checkRandomChanceExecutionSuccess(randomChance, 1.0F);
|
||||||
|
|
||||||
//Check the odds
|
|
||||||
return rollDice(chanceOfSuccess, 100);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static boolean checkRandomChanceExecutionSuccess(RandomChanceSkill randomChance)
|
public static boolean checkRandomChanceExecutionSuccess(RandomChanceSkill randomChance)
|
||||||
@ -115,9 +155,7 @@ public class RandomChanceUtil
|
|||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
public static double getRandomChanceExecutionChance(RandomChanceExecution randomChance) {
|
public static double getRandomChanceExecutionChance(RandomChanceExecution randomChance) {
|
||||||
double chanceOfSuccess = getChanceOfSuccess(randomChance.getXPos(), randomChance.getProbabilityCap(), LINEAR_CURVE_VAR);
|
return getChanceOfSuccess(randomChance.getXPos(), randomChance.getProbabilityCap(), LINEAR_CURVE_VAR);
|
||||||
|
|
||||||
return chanceOfSuccess;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static double getRandomChanceExecutionChance(RandomChanceStatic randomChance) {
|
public static double getRandomChanceExecutionChance(RandomChanceStatic randomChance) {
|
||||||
@ -210,7 +248,18 @@ public class RandomChanceUtil
|
|||||||
return checkRandomChanceExecutionSuccess(new RandomChanceSkill(player, subSkillType));
|
return checkRandomChanceExecutionSuccess(new RandomChanceSkill(player, subSkillType));
|
||||||
}
|
}
|
||||||
|
|
||||||
public static boolean checkRandomStaticChanceExecutionSuccess(Player player, SubSkillType subSkillType)
|
public static boolean checkRandomChanceExecutionSuccess(Player player, SubSkillType subSkillType, boolean hasCap, double resultModifier)
|
||||||
|
{
|
||||||
|
return checkRandomChanceExecutionSuccess(new RandomChanceSkill(player, subSkillType, hasCap, resultModifier));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean checkRandomChanceExecutionSuccess(Player player, SubSkillType subSkillType, double resultModifier)
|
||||||
|
{
|
||||||
|
return checkRandomChanceExecutionSuccess(new RandomChanceSkill(player, subSkillType, resultModifier));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public static boolean checkRandomStaticChanceExecutionSuccess(Player player, SubSkillType subSkillType, double resultModifier)
|
||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
return checkRandomChanceExecutionSuccess(new RandomChanceSkillStatic(getStaticRandomChance(subSkillType), player, subSkillType));
|
return checkRandomChanceExecutionSuccess(new RandomChanceSkillStatic(getStaticRandomChance(subSkillType), player, subSkillType));
|
||||||
@ -222,6 +271,11 @@ public class RandomChanceUtil
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static boolean checkRandomStaticChanceExecutionSuccess(Player player, SubSkillType subSkillType)
|
||||||
|
{
|
||||||
|
return checkRandomStaticChanceExecutionSuccess(player, subSkillType, 1.0F);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Grabs static activation rolls for Secondary Abilities
|
* Grabs static activation rolls for Secondary Abilities
|
||||||
* @param subSkillType The secondary ability to grab properties of
|
* @param subSkillType The secondary ability to grab properties of
|
||||||
|
@ -74,7 +74,7 @@ public final class CombatUtils {
|
|||||||
//Add Stab Damage
|
//Add Stab Damage
|
||||||
if(swordsManager.canUseStab())
|
if(swordsManager.canUseStab())
|
||||||
{
|
{
|
||||||
finalDamage+=swordsManager.getStabDamage();
|
finalDamage+=(swordsManager.getStabDamage() * mcMMOPlayer.getAttackStrength());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (swordsManager.canUseSerratedStrike()) {
|
if (swordsManager.canUseSerratedStrike()) {
|
||||||
@ -83,13 +83,38 @@ public final class CombatUtils {
|
|||||||
|
|
||||||
if(canUseLimitBreak(player, target, SubSkillType.SWORDS_SWORDS_LIMIT_BREAK))
|
if(canUseLimitBreak(player, target, SubSkillType.SWORDS_SWORDS_LIMIT_BREAK))
|
||||||
{
|
{
|
||||||
finalDamage+=getLimitBreakDamage(player, target, SubSkillType.SWORDS_SWORDS_LIMIT_BREAK);
|
finalDamage+=(getLimitBreakDamage(player, target, SubSkillType.SWORDS_SWORDS_LIMIT_BREAK) * mcMMOPlayer.getAttackStrength());
|
||||||
}
|
}
|
||||||
|
|
||||||
applyScaledModifiers(initialDamage, finalDamage, event);
|
applyScaledModifiers(initialDamage, finalDamage, event);
|
||||||
startGainXp(mcMMOPlayer, target, PrimarySkillType.SWORDS);
|
startGainXp(mcMMOPlayer, target, PrimarySkillType.SWORDS);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// public static void strengthDebug(Player player) {
|
||||||
|
// BukkitPlatform bukkitPlatform = (BukkitPlatform) mcMMO.getPlatformManager().getPlatform();
|
||||||
|
// Bukkit.broadcastMessage("Strength: "+bukkitPlatform.getPlayerAttackStrength(player));
|
||||||
|
//
|
||||||
|
// Bukkit.getScheduler().scheduleSyncDelayedTask(mcMMO.p, () -> {
|
||||||
|
// Bukkit.broadcastMessage("1 Tick Delay: " + bukkitPlatform.getPlayerAttackStrength(player));
|
||||||
|
// }, 1);
|
||||||
|
//
|
||||||
|
// Bukkit.getScheduler().scheduleSyncDelayedTask(mcMMO.p, () -> {
|
||||||
|
// Bukkit.broadcastMessage("5 Tick Delay: " + bukkitPlatform.getPlayerAttackStrength(player));
|
||||||
|
// }, 5);
|
||||||
|
//
|
||||||
|
// Bukkit.getScheduler().scheduleSyncDelayedTask(mcMMO.p, () -> {
|
||||||
|
// Bukkit.broadcastMessage("80 Tick Delay: " + bukkitPlatform.getPlayerAttackStrength(player));
|
||||||
|
// }, 20 * 4);
|
||||||
|
//
|
||||||
|
// Bukkit.broadcastMessage("");
|
||||||
|
//
|
||||||
|
//// if(isPlayerFullStrength(player)) {
|
||||||
|
//// Bukkit.broadcastMessage("Full Strength!");
|
||||||
|
//// } else {
|
||||||
|
//// Bukkit.broadcastMessage("Not full strength!");
|
||||||
|
//// }
|
||||||
|
// }
|
||||||
|
|
||||||
private static void processAxeCombat(LivingEntity target, Player player, EntityDamageByEntityEvent event) {
|
private static void processAxeCombat(LivingEntity target, Player player, EntityDamageByEntityEvent event) {
|
||||||
if (event.getCause() == DamageCause.THORNS) {
|
if (event.getCause() == DamageCause.THORNS) {
|
||||||
return;
|
return;
|
||||||
@ -128,12 +153,12 @@ public final class CombatUtils {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (axesManager.canCriticalHit(target)) {
|
if (axesManager.canCriticalHit(target)) {
|
||||||
finalDamage+=axesManager.criticalHit(target, finalDamage);
|
finalDamage+=(axesManager.criticalHit(target, finalDamage) * mcMMOPlayer.getAttackStrength());
|
||||||
}
|
}
|
||||||
|
|
||||||
if(canUseLimitBreak(player, target, SubSkillType.AXES_AXES_LIMIT_BREAK))
|
if(canUseLimitBreak(player, target, SubSkillType.AXES_AXES_LIMIT_BREAK))
|
||||||
{
|
{
|
||||||
finalDamage+=getLimitBreakDamage(player, target, SubSkillType.AXES_AXES_LIMIT_BREAK);
|
finalDamage+=(getLimitBreakDamage(player, target, SubSkillType.AXES_AXES_LIMIT_BREAK) * mcMMOPlayer.getAttackStrength());
|
||||||
}
|
}
|
||||||
|
|
||||||
applyScaledModifiers(initialDamage, finalDamage, event);
|
applyScaledModifiers(initialDamage, finalDamage, event);
|
||||||
@ -161,15 +186,13 @@ public final class CombatUtils {
|
|||||||
mcMMOPlayer.checkAbilityActivation(PrimarySkillType.UNARMED);
|
mcMMOPlayer.checkAbilityActivation(PrimarySkillType.UNARMED);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(unarmedManager.isPunchingCooldownOver())
|
|
||||||
{
|
|
||||||
//Only execute bonuses if the player is not spamming
|
//Only execute bonuses if the player is not spamming
|
||||||
if (unarmedManager.canUseIronArm()) {
|
if (unarmedManager.canUseIronArm()) {
|
||||||
finalDamage+=unarmedManager.ironArm();
|
finalDamage+=(unarmedManager.calculateIronArmDamage() * mcMMOPlayer.getAttackStrength());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (unarmedManager.canUseBerserk()) {
|
if (unarmedManager.canUseBerserk()) {
|
||||||
finalDamage+=unarmedManager.berserkDamage(finalDamage);
|
finalDamage+=(unarmedManager.berserkDamage(finalDamage) * mcMMOPlayer.getAttackStrength());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (unarmedManager.canDisarm(target)) {
|
if (unarmedManager.canDisarm(target)) {
|
||||||
@ -178,13 +201,11 @@ public final class CombatUtils {
|
|||||||
|
|
||||||
if(canUseLimitBreak(player, target, SubSkillType.UNARMED_UNARMED_LIMIT_BREAK))
|
if(canUseLimitBreak(player, target, SubSkillType.UNARMED_UNARMED_LIMIT_BREAK))
|
||||||
{
|
{
|
||||||
finalDamage+=getLimitBreakDamage(player, target, SubSkillType.UNARMED_UNARMED_LIMIT_BREAK);
|
finalDamage+=(getLimitBreakDamage(player, target, SubSkillType.UNARMED_UNARMED_LIMIT_BREAK) * mcMMOPlayer.getAttackStrength());
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
applyScaledModifiers(initialDamage, finalDamage, event);
|
applyScaledModifiers(initialDamage, finalDamage, event);
|
||||||
startGainXp(mcMMOPlayer, target, PrimarySkillType.UNARMED);
|
startGainXp(mcMMOPlayer, target, PrimarySkillType.UNARMED);
|
||||||
unarmedManager.setLastAttacked(System.currentTimeMillis()); //Track how often the player is punching
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void processTamingCombat(LivingEntity target, Player master, Wolf wolf, EntityDamageByEntityEvent event) {
|
private static void processTamingCombat(LivingEntity target, Player master, Wolf wolf, EntityDamageByEntityEvent event) {
|
||||||
@ -280,9 +301,8 @@ public final class CombatUtils {
|
|||||||
*
|
*
|
||||||
* @param event The event to run the combat checks on.
|
* @param event The event to run the combat checks on.
|
||||||
*/
|
*/
|
||||||
public static void processCombatAttack(EntityDamageByEntityEvent event, Entity attacker, LivingEntity target) {
|
public static void processCombatAttack(EntityDamageByEntityEvent event, Entity damageSourceEntity, LivingEntity target) {
|
||||||
Entity damager = event.getDamager();
|
EntityType entityType = damageSourceEntity.getType();
|
||||||
EntityType entityType = damager.getType();
|
|
||||||
|
|
||||||
if (target instanceof Player) {
|
if (target instanceof Player) {
|
||||||
if (Misc.isNPCEntityExcludingVillagers(target)) {
|
if (Misc.isNPCEntityExcludingVillagers(target)) {
|
||||||
@ -298,7 +318,7 @@ public final class CombatUtils {
|
|||||||
AcrobaticsManager acrobaticsManager = mcMMOPlayer.getAcrobaticsManager();
|
AcrobaticsManager acrobaticsManager = mcMMOPlayer.getAcrobaticsManager();
|
||||||
|
|
||||||
if (acrobaticsManager.canDodge(target)) {
|
if (acrobaticsManager.canDodge(target)) {
|
||||||
event.setDamage(acrobaticsManager.dodgeCheck(attacker, event.getDamage()));
|
event.setDamage(acrobaticsManager.dodgeCheck(damageSourceEntity, event.getDamage()));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ItemUtils.isSword(player.getInventory().getItemInMainHand())) {
|
if (ItemUtils.isSword(player.getInventory().getItemInMainHand())) {
|
||||||
@ -308,24 +328,25 @@ public final class CombatUtils {
|
|||||||
|
|
||||||
SwordsManager swordsManager = mcMMOPlayer.getSwordsManager();
|
SwordsManager swordsManager = mcMMOPlayer.getSwordsManager();
|
||||||
|
|
||||||
if (swordsManager.canUseCounterAttack(damager)) {
|
if (swordsManager.canUseCounterAttack(damageSourceEntity)) {
|
||||||
swordsManager.counterAttackChecks((LivingEntity) damager, event.getDamage());
|
swordsManager.counterAttackChecks((LivingEntity) damageSourceEntity, event.getDamage());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (attacker instanceof Player && entityType == EntityType.PLAYER) {
|
if (damageSourceEntity instanceof Player && entityType == EntityType.PLAYER) {
|
||||||
Player player = (Player) attacker;
|
Player player = (Player) damageSourceEntity;
|
||||||
|
|
||||||
if (!UserManager.hasPlayerDataKey(player)) {
|
if (UserManager.getPlayer(player) == null) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
McMMOPlayer attackingPlayer = UserManager.getPlayer(player);
|
||||||
ItemStack heldItem = player.getInventory().getItemInMainHand();
|
ItemStack heldItem = player.getInventory().getItemInMainHand();
|
||||||
|
|
||||||
if (target instanceof Tameable) {
|
if (target instanceof Tameable) {
|
||||||
if (heldItem.getType() == Material.BONE) {
|
if (heldItem.getType() == Material.BONE) {
|
||||||
TamingManager tamingManager = UserManager.getPlayer(player).getTamingManager();
|
TamingManager tamingManager = attackingPlayer.getTamingManager();
|
||||||
|
|
||||||
if (tamingManager.canUseBeastLore()) {
|
if (tamingManager.canUseBeastLore()) {
|
||||||
tamingManager.beastLore(target);
|
tamingManager.beastLore(target);
|
||||||
@ -369,7 +390,7 @@ public final class CombatUtils {
|
|||||||
}
|
}
|
||||||
|
|
||||||
else if (entityType == EntityType.WOLF) {
|
else if (entityType == EntityType.WOLF) {
|
||||||
Wolf wolf = (Wolf) damager;
|
Wolf wolf = (Wolf) damageSourceEntity;
|
||||||
AnimalTamer tamer = wolf.getOwner();
|
AnimalTamer tamer = wolf.getOwner();
|
||||||
|
|
||||||
if (tamer != null && tamer instanceof Player && PrimarySkillType.TAMING.shouldProcess(target)) {
|
if (tamer != null && tamer instanceof Player && PrimarySkillType.TAMING.shouldProcess(target)) {
|
||||||
@ -381,7 +402,7 @@ public final class CombatUtils {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (entityType == EntityType.ARROW || entityType == EntityType.SPECTRAL_ARROW) {
|
else if (entityType == EntityType.ARROW || entityType == EntityType.SPECTRAL_ARROW) {
|
||||||
Projectile arrow = (Projectile) damager;
|
Projectile arrow = (Projectile) damageSourceEntity;
|
||||||
ProjectileSource projectileSource = arrow.getShooter();
|
ProjectileSource projectileSource = arrow.getShooter();
|
||||||
|
|
||||||
if (projectileSource != null && projectileSource instanceof Player && PrimarySkillType.ARCHERY.shouldProcess(target)) {
|
if (projectileSource != null && projectileSource instanceof Player && PrimarySkillType.ARCHERY.shouldProcess(target)) {
|
||||||
|
@ -19,6 +19,8 @@ load: POSTWORLD
|
|||||||
api-version: 1.13
|
api-version: 1.13
|
||||||
|
|
||||||
commands:
|
commands:
|
||||||
|
mmocompat:
|
||||||
|
description: Information about the server and whether or not its considered fully compatible or running in compatibility mode
|
||||||
mmodebug:
|
mmodebug:
|
||||||
aliases: [mcmmodebugmode]
|
aliases: [mcmmodebugmode]
|
||||||
description: Toggles a debug mode which will print useful information to chat
|
description: Toggles a debug mode which will print useful information to chat
|
||||||
|
Loading…
Reference in New Issue
Block a user