update for 1.21.3 compatibility

This commit is contained in:
nossr50 2024-10-31 20:37:54 -07:00
parent 8087d5f647
commit 99bb5857f8
11 changed files with 289 additions and 109 deletions

View File

@ -1,9 +1,11 @@
Version 2.2.023
Compatibility with Minecraft 1.21.3
Version 2.2.022 Version 2.2.022
Fixed a bug where Roll was always reducing damage (thanks Ineusia) Fixed a bug where Roll was always reducing damage (thanks Ineusia)
Fix COTW errors on older versions (thanks Warriorrrr) Fix COTW errors on older versions (thanks Warriorrrr)
Fixed slimes spawning from slime division not inheriting tags. (thanks Ineusia) Fixed slimes spawning from slime division not inheriting tags. (thanks Ineusia)
Version 2.2.021 Version 2.2.021
Fixed issue where Roll wasn't reducing as much damage as it should have been (thanks Ineusia) Fixed issue where Roll wasn't reducing as much damage as it should have been (thanks Ineusia)
Updated locale_es (thanks Devilcasters) Updated locale_es (thanks Devilcasters)

64
pom.xml
View File

@ -13,6 +13,8 @@
</scm> </scm>
<properties> <properties>
<spigot.version>1.21.3-R0.1-SNAPSHOT</spigot.version>
<adventure.version>4.3.5-SNAPSHOT</adventure.version>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>17</maven.compiler.source> <maven.compiler.source>17</maven.compiler.source>
<maven.compiler.target>17</maven.compiler.target> <maven.compiler.target>17</maven.compiler.target>
@ -300,7 +302,7 @@
<dependency> <dependency>
<groupId>net.kyori</groupId> <groupId>net.kyori</groupId>
<artifactId>adventure-text-serializer-bungeecord</artifactId> <artifactId>adventure-text-serializer-bungeecord</artifactId>
<version>4.3.2</version> <version>${adventure.version}</version>
</dependency> </dependency>
<dependency> <dependency>
<groupId>net.kyori</groupId> <groupId>net.kyori</groupId>
@ -340,22 +342,22 @@
<dependency> <dependency>
<groupId>net.kyori</groupId> <groupId>net.kyori</groupId>
<artifactId>adventure-platform-api</artifactId> <artifactId>adventure-platform-api</artifactId>
<version>4.3.3</version> <version>${adventure.version}</version>
</dependency> </dependency>
<dependency> <dependency>
<groupId>net.kyori</groupId> <groupId>net.kyori</groupId>
<artifactId>adventure-platform-bukkit</artifactId> <artifactId>adventure-platform-bukkit</artifactId>
<version>LATEST</version> <version>${adventure.version}</version>
</dependency> </dependency>
<dependency> <dependency>
<groupId>net.kyori</groupId> <groupId>net.kyori</groupId>
<artifactId>adventure-platform-facet</artifactId> <artifactId>adventure-platform-facet</artifactId>
<version>4.3.3</version> <version>${adventure.version}</version>
</dependency> </dependency>
<dependency> <dependency>
<groupId>net.kyori</groupId> <groupId>net.kyori</groupId>
<artifactId>adventure-platform-viaversion</artifactId> <artifactId>adventure-platform-viaversion</artifactId>
<version>4.3.3</version> <version>${adventure.version}</version>
</dependency> </dependency>
<dependency> <dependency>
<groupId>net.kyori</groupId> <groupId>net.kyori</groupId>
@ -376,7 +378,7 @@
<dependency> <dependency>
<groupId>org.spigotmc</groupId> <groupId>org.spigotmc</groupId>
<artifactId>spigot-api</artifactId> <artifactId>spigot-api</artifactId>
<version>1.21-R0.1-SNAPSHOT</version> <version>${spigot.version}</version>
<scope>provided</scope> <scope>provided</scope>
</dependency> </dependency>
<dependency> <dependency>
@ -427,6 +429,12 @@
<version>5.2.0</version> <version>5.2.0</version>
<scope>test</scope> <scope>test</scope>
</dependency> </dependency>
<!-- <dependency>-->
<!-- <groupId>com.github.seeseemelk</groupId>-->
<!-- <artifactId>MockBukkit-v1.21</artifactId>-->
<!-- <version>[version]</version>-->
<!-- <scope>test</scope>-->
<!-- </dependency>-->
<dependency> <dependency>
<groupId>org.apache.tomcat</groupId> <groupId>org.apache.tomcat</groupId>
<artifactId>tomcat-jdbc</artifactId> <artifactId>tomcat-jdbc</artifactId>
@ -450,29 +458,25 @@
<version>0.3.1</version> <version>0.3.1</version>
<scope>compile</scope> <scope>compile</scope>
</dependency> </dependency>
<!-- <dependency>-->
<!-- <groupId>org.apache.logging.log4j</groupId>-->
<!-- <artifactId>log4j-core</artifactId>-->
<!-- <version>2.22.1</version> &lt;!&ndash; Make sure this version matches the other log4j dependencies &ndash;&gt;-->
<!-- <scope>test</scope>-->
<!-- </dependency>-->
<!-- <dependency>-->
<!-- <groupId>org.apache.logging.log4j</groupId>-->
<!-- <artifactId>log4j-api</artifactId>-->
<!-- <version>2.22.1</version>-->
<!-- <scope>test</scope>-->
<!-- </dependency>-->
<!-- <dependency>-->
<!-- <groupId>org.apache.logging.log4j</groupId>-->
<!-- <artifactId>log4j-slf4j-impl</artifactId>-->
<!-- <version>2.22.1</version>-->
<!-- <scope>test</scope>-->
<!-- </dependency>-->
<!-- <dependency>-->
<!-- <groupId>com.github.seeseemelk</groupId>-->
<!-- <artifactId>MockBukkit-v1.19</artifactId>-->
<!-- <version>LATEST</version>-->
<!-- <scope>test</scope>-->
<!-- </dependency>-->
</dependencies> </dependencies>
<!-- <profiles>-->
<!-- <profile>-->
<!-- <id>spigot-1.18.2</id>-->
<!-- <properties>-->
<!-- <spigot.version>1.18.2-R0.1-SNAPSHOT</spigot.version>-->
<!-- </properties>-->
<!-- </profile>-->
<!-- <profile>-->
<!-- <id>spigot-1.21.1</id>-->
<!-- <properties>-->
<!-- <spigot.version>1.21.1-R0.1-SNAPSHOT</spigot.version>-->
<!-- </properties>-->
<!-- </profile>-->
<!-- <profile>-->
<!-- <id>spigot-1.21.3</id>-->
<!-- <properties>-->
<!-- <spigot.version>1.21.3-R0.1-SNAPSHOT</spigot.version>-->
<!-- </properties>-->
<!-- </profile>-->
<!-- </profiles>-->
</project> </project>

View File

@ -14,6 +14,7 @@ import com.gmail.nossr50.util.Misc;
import com.gmail.nossr50.util.Permissions; import com.gmail.nossr50.util.Permissions;
import com.gmail.nossr50.util.text.StringUtils; import com.gmail.nossr50.util.text.StringUtils;
import net.kyori.adventure.audience.Audience; import net.kyori.adventure.audience.Audience;
import net.kyori.adventure.chat.SignedMessage;
import net.kyori.adventure.text.TextComponent; import net.kyori.adventure.text.TextComponent;
import org.bukkit.command.ConsoleCommandSender; import org.bukkit.command.ConsoleCommandSender;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;

View File

@ -49,6 +49,7 @@ import java.util.Arrays;
import java.util.List; import java.util.List;
import java.util.Set; import java.util.Set;
import static com.gmail.nossr50.util.AttributeMapper.MAPPED_MAX_HEALTH;
import static com.gmail.nossr50.util.MobMetadataUtils.*; import static com.gmail.nossr50.util.MobMetadataUtils.*;
public class EntityListener implements Listener { public class EntityListener implements Listener {
@ -411,7 +412,7 @@ public class EntityListener implements Listener {
player.sendMessage(ChatColor.GOLD + "(mmodebug start of combat report) EntityDamageByEntityEvent DEBUG Info:"); player.sendMessage(ChatColor.GOLD + "(mmodebug start of combat report) EntityDamageByEntityEvent DEBUG Info:");
player.sendMessage("You are being damaged by another player in this event"); player.sendMessage("You are being damaged by another player in this event");
player.sendMessage("Raw Damage: " + entityDamageEvent.getDamage()); player.sendMessage("Raw Damage: " + entityDamageEvent.getDamage());
player.sendMessage("Your max health: "+player.getAttribute(Attribute.GENERIC_MAX_HEALTH).getValue()); player.sendMessage("Your max health: "+player.getAttribute(MAPPED_MAX_HEALTH).getValue());
player.sendMessage("Your current health: "+player.getHealth()); player.sendMessage("Your current health: "+player.getHealth());
player.sendMessage(ChatColor.GREEN + "Damage Modifiers (final damage)"); player.sendMessage(ChatColor.GREEN + "Damage Modifiers (final damage)");
@ -444,7 +445,7 @@ public class EntityListener implements Listener {
} }
player.sendMessage("Final damage: " + entityDamageEvent.getFinalDamage()); player.sendMessage("Final damage: " + entityDamageEvent.getFinalDamage());
player.sendMessage("Target players max health: "+otherPlayer.getAttribute(Attribute.GENERIC_MAX_HEALTH).getValue()); player.sendMessage("Target players max health: "+otherPlayer.getAttribute(MAPPED_MAX_HEALTH).getValue());
player.sendMessage("Target players current health: "+otherPlayer.getHealth()); player.sendMessage("Target players current health: "+otherPlayer.getHealth());
if (entityDamageEvent.isCancelled()) { if (entityDamageEvent.isCancelled()) {

View File

@ -138,7 +138,6 @@ public class mcMMO extends JavaPlugin {
private PotionConfig potionConfig; private PotionConfig potionConfig;
private CustomItemSupportConfig customItemSupportConfig; private CustomItemSupportConfig customItemSupportConfig;
private EnchantmentMapper enchantmentMapper; private EnchantmentMapper enchantmentMapper;
private AttributeMapper attributeMapper;
private FoliaLib foliaLib; private FoliaLib foliaLib;
private PartyManager partyManager; private PartyManager partyManager;
@ -195,8 +194,6 @@ public class mcMMO extends JavaPlugin {
materialMapStore = new MaterialMapStore(); materialMapStore = new MaterialMapStore();
// Init compatibility mappers // Init compatibility mappers
enchantmentMapper = new EnchantmentMapper(this); enchantmentMapper = new EnchantmentMapper(this);
attributeMapper = new AttributeMapper(this);
loadConfigFiles(); loadConfigFiles();
if (!noErrorsInConfigFiles) { if (!noErrorsInConfigFiles) {
@ -818,10 +815,6 @@ public class mcMMO extends JavaPlugin {
return enchantmentMapper; return enchantmentMapper;
} }
public AttributeMapper getAttributeMapper() {
return attributeMapper;
}
public @NotNull FoliaLib getFoliaLib() { public @NotNull FoliaLib getFoliaLib() {
return foliaLib; return foliaLib;
} }

View File

@ -13,7 +13,7 @@ import org.bukkit.entity.LivingEntity;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import static org.bukkit.attribute.Attribute.GENERIC_MAX_HEALTH; import static com.gmail.nossr50.util.AttributeMapper.MAPPED_MAX_HEALTH;
public class RuptureTask extends CancellableRunnable { public class RuptureTask extends CancellableRunnable {
@ -28,9 +28,16 @@ public class RuptureTask extends CancellableRunnable {
private int damageTickTracker; private int damageTickTracker;
private int animationTick; private int animationTick;
private final double pureTickDamage; private final double pureTickDamage;
private final double explosionDamage;
public RuptureTask(@NotNull McMMOPlayer ruptureSource, @NotNull LivingEntity targetEntity, double pureTickDamage, double explosionDamage) { /**
* Constructor for the RuptureTask class.
*
* @param ruptureSource The McMMOPlayer who is the source of the rupture.
* @param targetEntity The LivingEntity that is the target of the rupture.
* @param pureTickDamage The amount of damage to be applied per tick.
*/
public RuptureTask(@NotNull McMMOPlayer ruptureSource, @NotNull LivingEntity targetEntity,
double pureTickDamage) {
this.ruptureSource = ruptureSource; this.ruptureSource = ruptureSource;
this.targetEntity = targetEntity; this.targetEntity = targetEntity;
this.expireTick = mcMMO.p.getAdvancedConfig().getRuptureDurationSeconds(targetEntity instanceof Player) * 20; this.expireTick = mcMMO.p.getAdvancedConfig().getRuptureDurationSeconds(targetEntity instanceof Player) * 20;
@ -39,7 +46,24 @@ public class RuptureTask extends CancellableRunnable {
this.damageTickTracker = 0; this.damageTickTracker = 0;
this.animationTick = ANIMATION_TICK_INTERVAL; //Play an animation right away this.animationTick = ANIMATION_TICK_INTERVAL; //Play an animation right away
this.pureTickDamage = pureTickDamage; this.pureTickDamage = pureTickDamage;
this.explosionDamage = explosionDamage; }
/**
* Deprecated constructor for the RuptureTask class.
*
* @deprecated This constructor is deprecated and will be removed in future versions.
* Use {@link #RuptureTask(McMMOPlayer, LivingEntity, double)} instead.
*
* @param ruptureSource The McMMOPlayer who is the source of the rupture.
* @param targetEntity The LivingEntity that is the target of the rupture.
* @param pureTickDamage The amount of damage to be applied per tick.
* @param ignored This parameter is ignored and should not be used.
* @since 2.2.023
*/
@Deprecated(forRemoval = true, since = "2.2.023")
public RuptureTask(@NotNull McMMOPlayer ruptureSource, @NotNull LivingEntity targetEntity,
double pureTickDamage, double ignored) {
this(ruptureSource, targetEntity, pureTickDamage);
} }
@Override @Override
@ -100,11 +124,11 @@ public class RuptureTask extends CancellableRunnable {
final double damagedHealth = healthBeforeRuptureIsApplied - damage; final double damagedHealth = healthBeforeRuptureIsApplied - damage;
final AttributeInstance maxHealthAttribute = targetEntity.getAttribute(GENERIC_MAX_HEALTH); final AttributeInstance maxHealthAttribute = targetEntity.getAttribute(MAPPED_MAX_HEALTH);
if (maxHealthAttribute == null) { if (maxHealthAttribute == null) {
// Can't remove health if max health is null // Can't remove health if max health is null
mcMMO.p.getLogger().info("RuptureTask: Target entity has an illegal state for its health." + mcMMO.p.getLogger().info("RuptureTask: Target entity has an illegal state for its health." +
" Cancelling Rupture. Target has null " + GENERIC_MAX_HEALTH + " attribute."); " Cancelling Rupture. Target has null " + MAPPED_MAX_HEALTH + " attribute.");
return true; return true;
} }
@ -129,18 +153,6 @@ public class RuptureTask extends CancellableRunnable {
} }
public void endRupture() { public void endRupture() {
// targetEntity.setMetadata(mcMMO.EXPLOSION_FROM_RUPTURE, new FixedMetadataValue(mcMMO.p, "null"));
//
// ParticleEffectUtils.playGreaterImpactEffect(targetEntity); //Animate
//
// if (ruptureSource.getPlayer() != null && ruptureSource.getPlayer().isValid()) {
// targetEntity.damage(getExplosionDamage(), ruptureSource.getPlayer());
// } else {
// targetEntity.damage(getExplosionDamage(), null);
// }
//
// targetEntity.removeMetadata(mcMMO.RUPTURE_META_KEY, mcMMO.p);
targetEntity.removeMetadata(MetadataConstants.METADATA_KEY_RUPTURE, mcMMO.p); targetEntity.removeMetadata(MetadataConstants.METADATA_KEY_RUPTURE, mcMMO.p);
this.cancel(); //Task no longer needed this.cancel(); //Task no longer needed
} }
@ -159,10 +171,6 @@ public class RuptureTask extends CancellableRunnable {
return tickDamage; return tickDamage;
} }
private double getExplosionDamage() {
return explosionDamage;
}
@Override @Override
public String toString() { public String toString() {
return "RuptureTask{" + return "RuptureTask{" +
@ -172,7 +180,6 @@ public class RuptureTask extends CancellableRunnable {
", ruptureTick=" + ruptureTick + ", ruptureTick=" + ruptureTick +
", damageTickTracker=" + damageTickTracker + ", damageTickTracker=" + damageTickTracker +
", pureTickDamage=" + pureTickDamage + ", pureTickDamage=" + pureTickDamage +
", explosionDamage=" + explosionDamage +
'}'; '}';
} }
@ -181,11 +188,16 @@ public class RuptureTask extends CancellableRunnable {
if (this == o) return true; if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false; if (o == null || getClass() != o.getClass()) return false;
RuptureTask that = (RuptureTask) o; RuptureTask that = (RuptureTask) o;
return expireTick == that.expireTick && ruptureTick == that.ruptureTick && damageTickTracker == that.damageTickTracker && Double.compare(that.pureTickDamage, pureTickDamage) == 0 && Double.compare(that.explosionDamage, explosionDamage) == 0 && Objects.equal(ruptureSource, that.ruptureSource) && Objects.equal(targetEntity, that.targetEntity); return expireTick == that.expireTick
&& ruptureTick == that.ruptureTick
&& damageTickTracker == that.damageTickTracker
&& Double.compare(that.pureTickDamage, pureTickDamage) == 0
&& Objects.equal(ruptureSource, that.ruptureSource) && Objects.equal(targetEntity, that.targetEntity);
} }
@Override @Override
public int hashCode() { public int hashCode() {
return Objects.hashCode(ruptureSource, targetEntity, expireTick, ruptureTick, damageTickTracker, pureTickDamage, explosionDamage); return Objects.hashCode(ruptureSource, targetEntity, expireTick,
ruptureTick, damageTickTracker, pureTickDamage);
} }
} }

View File

@ -91,8 +91,7 @@ public class SwordsManager extends SkillManager {
} }
RuptureTask ruptureTask = new RuptureTask(mmoPlayer, target, RuptureTask ruptureTask = new RuptureTask(mmoPlayer, target,
mcMMO.p.getAdvancedConfig().getRuptureTickDamage(target instanceof Player, getRuptureRank()), mcMMO.p.getAdvancedConfig().getRuptureTickDamage(target instanceof Player, getRuptureRank()));
mcMMO.p.getAdvancedConfig().getRuptureExplosionDamage(target instanceof Player, getRuptureRank()));
RuptureTaskMeta ruptureTaskMeta = new RuptureTaskMeta(mcMMO.p, ruptureTask); RuptureTaskMeta ruptureTaskMeta = new RuptureTaskMeta(mcMMO.p, ruptureTask);

View File

@ -31,6 +31,8 @@ import org.jetbrains.annotations.NotNull;
import java.util.HashMap; import java.util.HashMap;
import static com.gmail.nossr50.util.AttributeMapper.MAPPED_JUMP_STRENGTH;
import static com.gmail.nossr50.util.AttributeMapper.MAPPED_MOVEMENT_SPEED;
import static com.gmail.nossr50.util.MobMetadataUtils.flagMetadata; import static com.gmail.nossr50.util.MobMetadataUtils.flagMetadata;
public class TamingManager extends SkillManager { public class TamingManager extends SkillManager {
@ -235,13 +237,13 @@ public class TamingManager extends SkillManager {
// Bred mules & donkeys can actually have horse-like stats, but llamas cannot. // Bred mules & donkeys can actually have horse-like stats, but llamas cannot.
if (beast instanceof AbstractHorse horseLikeCreature && !(beast instanceof Llama)) { if (beast instanceof AbstractHorse horseLikeCreature && !(beast instanceof Llama)) {
AttributeInstance jumpAttribute = horseLikeCreature.getAttribute(mcMMO.p.getAttributeMapper().getHorseJumpStrength()); AttributeInstance jumpAttribute = horseLikeCreature.getAttribute(MAPPED_JUMP_STRENGTH);
if (jumpAttribute != null) { if (jumpAttribute != null) {
double jumpStrength = jumpAttribute.getValue(); double jumpStrength = jumpAttribute.getValue();
// Taken from https://minecraft.wiki/w/Horse#Jump_strength // Taken from https://minecraft.wiki/w/Horse#Jump_strength
jumpStrength = -0.1817584952 * Math.pow(jumpStrength, 3) + 3.689713992 * Math.pow(jumpStrength, 2) + 2.128599134 * jumpStrength - 0.343930367; jumpStrength = -0.1817584952 * Math.pow(jumpStrength, 3) + 3.689713992 * Math.pow(jumpStrength, 2) + 2.128599134 * jumpStrength - 0.343930367;
message = message.concat("\n" + LocaleLoader.getString("Combat.BeastLoreHorseSpeed", horseLikeCreature.getAttribute(Attribute.GENERIC_MOVEMENT_SPEED).getValue() * 43)) message = message.concat("\n" + LocaleLoader.getString("Combat.BeastLoreHorseSpeed", horseLikeCreature.getAttribute(MAPPED_MOVEMENT_SPEED).getValue() * 43))
.concat("\n" + LocaleLoader.getString("Combat.BeastLoreHorseJumpStrength", jumpStrength)); .concat("\n" + LocaleLoader.getString("Combat.BeastLoreHorseJumpStrength", jumpStrength));
} }
} }

View File

@ -4,42 +4,194 @@ import com.gmail.nossr50.mcMMO;
import org.bukkit.Registry; import org.bukkit.Registry;
import org.bukkit.attribute.Attribute; import org.bukkit.attribute.Attribute;
public class AttributeMapper { import java.lang.reflect.Field;
private final mcMMO pluginRef; import java.lang.reflect.InvocationTargetException;
private static final String GENERIC_JUMP_STRENGTH = "generic.jump_strength"; import java.lang.reflect.Method;
private static final String HORSE_JUMP_STRENGTH = "horse.jump_strength"; import java.util.Arrays;
private final Attribute horseJumpStrength; import java.util.Optional;
import java.util.stream.Stream;
public AttributeMapper(mcMMO pluginRef) { public class AttributeMapper {
this.pluginRef = pluginRef;
this.horseJumpStrength = initHorseJumpStrength(); public static final String ATTRIBUTE = "ATTRIBUTE";
public static final String ORG_BUKKIT_REGISTRY = "org.bukkit.Registry";
// Prevent instantiation
private AttributeMapper() {
} }
private Attribute initHorseJumpStrength() { // Define constants for attribute keys and their legacy counterparts
// TODO: Use modern matching? private static final String MAX_HEALTH_1_21_3_STR = "max_health";
// if (Registry.ATTRIBUTE.match(GENERIC_JUMP_STRENGTH) != null) { private static final String MAX_HEALTH_1_18_2_STR = "generic.max_health";
// return Registry.ATTRIBUTE.match(GENERIC_JUMP_STRENGTH); public static final Attribute MAPPED_MAX_HEALTH;
// }
//
// if (Registry.ATTRIBUTE.match(HORSE_JUMP_STRENGTH) != null) {
// return Registry.ATTRIBUTE.match(HORSE_JUMP_STRENGTH);
// }
for (Attribute attr : Registry.ATTRIBUTE) { private static final String JUMP_STRENGTH_1_23_1 = "jump_strength";
if (attr.getKey().getKey().equalsIgnoreCase(HORSE_JUMP_STRENGTH) private static final String JUMP_STRENGTH_1_21_1 = "generic.jump_strength";
|| attr.getKey().getKey().equalsIgnoreCase(GENERIC_JUMP_STRENGTH) private static final String JUMP_STR_1_18_2 = "horse.jump_strength";
|| attr.name().equalsIgnoreCase(HORSE_JUMP_STRENGTH) public static final Attribute MAPPED_JUMP_STRENGTH;
|| attr.name().equalsIgnoreCase(GENERIC_JUMP_STRENGTH)) {
return attr; public static final Attribute MAPPED_MOVEMENT_SPEED;
} private static final String MOVEMENT_SPEED_1_18_2 = "generic.movement_speed";
private static final String MOVEMENT_SPEED_1_21_1 = "generic.movement_speed";
private static final String MOVEMENT_SPEED_1_21_3 = "movement_speed";
// Add other attributes similarly...
// For brevity, only key attributes are shown
static {
MAPPED_MAX_HEALTH = findAttribute(MAX_HEALTH_1_21_3_STR, MAX_HEALTH_1_18_2_STR);
MAPPED_JUMP_STRENGTH = findAttribute(JUMP_STRENGTH_1_23_1, JUMP_STRENGTH_1_21_1, JUMP_STR_1_18_2);
MAPPED_MOVEMENT_SPEED = findAttribute(MOVEMENT_SPEED_1_18_2, MOVEMENT_SPEED_1_21_1, MOVEMENT_SPEED_1_21_3);
}
private static Attribute findAttribute(String... keys) {
Stream<?> attributeStream;
try {
// Try to get Registry.ATTRIBUTE using reflection
Class<?> registryClass = Class.forName(ORG_BUKKIT_REGISTRY);
Field attributeField = registryClass.getField(ATTRIBUTE);
Object attributeRegistry = attributeField.get(null);
// Get the stream() method of the attribute registry
Method streamMethod = attributeRegistry.getClass().getMethod("stream");
attributeStream = (Stream<?>) streamMethod.invoke(attributeRegistry);
} catch (ClassNotFoundException | NoSuchFieldException | IllegalAccessException | NoSuchMethodException |
InvocationTargetException e) {
// Fallback to older versions where Attribute is an enum
Object[] enumConstants = Attribute.class.getEnumConstants();
attributeStream = Arrays.stream(enumConstants);
} }
pluginRef.getLogger().severe("Unable to find the Generic Jump Strength or Horse Jump Strength attribute, " + Optional<?> optionalAttribute = attributeStream
"mcMMO will not function properly."); .filter(attr -> {
throw new IllegalStateException("Unable to find the Generic Jump Strength or Horse Jump Strength attribute"); try {
String attrKey = null;
String attrName = null;
// Try to get attr.getKey().getKey()
Method getKeyMethod = attr.getClass().getMethod("getKey");
Object namespacedKey = getKeyMethod.invoke(attr);
if (namespacedKey != null) {
Method getKeyStringMethod = namespacedKey.getClass().getMethod("getKey");
attrKey = (String) getKeyStringMethod.invoke(namespacedKey);
}
// Try to get attr.name()
Method nameMethod;
try {
nameMethod = attr.getClass().getMethod("name");
attrName = (String) nameMethod.invoke(attr);
} catch (NoSuchMethodException e) {
// name() method doesn't exist in newer versions
attrName = null;
}
// Compare with provided keys
for (String key : keys) {
if ((attrKey != null && attrKey.equalsIgnoreCase(key)) ||
(attrName != null && attrName.equalsIgnoreCase(key))) {
return true;
}
}
} catch (Exception e) {
mcMMO.p.getLogger().severe("Unable to find the attribute with possible keys: "
+ Arrays.toString(keys) + ", mcMMO will not function properly.");
throw new RuntimeException(e);
}
return false;
})
.findFirst();
if (optionalAttribute.isPresent()) {
return (Attribute) optionalAttribute.get();
} else {
mcMMO.p.getLogger().severe("Unable to find the attribute with possible keys: "
+ Arrays.toString(keys) + ", mcMMO will not function properly.");
throw new IllegalStateException("Unable to find the attribute with possible keys: "
+ Arrays.toString(keys));
}
} }
public Attribute getHorseJumpStrength() { /*
return horseJumpStrength; For easy reference...
} List of 1.18 Attributes by name...
GENERIC_MAX_HEALTH("generic.max_health"),
GENERIC_FOLLOW_RANGE("generic.follow_range"),
GENERIC_KNOCKBACK_RESISTANCE("generic.knockback_resistance"),
GENERIC_MOVEMENT_SPEED("generic.movement_speed"),
GENERIC_FLYING_SPEED("generic.flying_speed"),
GENERIC_ATTACK_DAMAGE("generic.attack_damage"),
GENERIC_ATTACK_KNOCKBACK("generic.attack_knockback"),
GENERIC_ATTACK_SPEED("generic.attack_speed"),
GENERIC_ARMOR("generic.armor"),
GENERIC_ARMOR_TOUGHNESS("generic.armor_toughness"),
GENERIC_LUCK("generic.luck"),
HORSE_JUMP_STRENGTH("horse.jump_strength"),
ZOMBIE_SPAWN_REINFORCEMENTS("zombie.spawn_reinforcements");
List of 1.21.1 Attributes by name...
GENERIC_MAX_HEALTH("generic.max_health"),
GENERIC_FOLLOW_RANGE("generic.follow_range"),
GENERIC_KNOCKBACK_RESISTANCE("generic.knockback_resistance"),
GENERIC_MOVEMENT_SPEED("generic.movement_speed"),
GENERIC_FLYING_SPEED("generic.flying_speed"),
GENERIC_ATTACK_DAMAGE("generic.attack_damage"),
GENERIC_ATTACK_KNOCKBACK("generic.attack_knockback"),
GENERIC_ATTACK_SPEED("generic.attack_speed"),
GENERIC_ARMOR("generic.armor"),
GENERIC_ARMOR_TOUGHNESS("generic.armor_toughness"),
GENERIC_FALL_DAMAGE_MULTIPLIER("generic.fall_damage_multiplier"),
GENERIC_LUCK("generic.luck"),
GENERIC_MAX_ABSORPTION("generic.max_absorption"),
GENERIC_SAFE_FALL_DISTANCE("generic.safe_fall_distance"),
GENERIC_SCALE("generic.scale"),
GENERIC_STEP_HEIGHT("generic.step_height"),
GENERIC_GRAVITY("generic.gravity"),
GENERIC_JUMP_STRENGTH("generic.jump_strength"),
GENERIC_EXPLOSION_KNOCKBACK_RESISTANCE("generic.explosion_knockback_resistance"),
GENERIC_MOVEMENT_EFFICIENCY("generic.movement_efficiency"),
GENERIC_OXYGEN_BONUS("generic.oxygen_bonus"),
GENERIC_WATER_MOVEMENT_EFFICIENCY("generic.water_movement_efficiency"),
PLAYER_BLOCK_INTERACTION_RANGE("player.block_interaction_range"),
PLAYER_ENTITY_INTERACTION_RANGE("player.entity_interaction_range"),
PLAYER_BLOCK_BREAK_SPEED("player.block_break_speed"),
PLAYER_MINING_EFFICIENCY("player.mining_efficiency"),
PLAYER_SNEAKING_SPEED("player.sneaking_speed"),
PLAYER_SUBMERGED_MINING_SPEED("player.submerged_mining_speed"),
PLAYER_SWEEPING_DAMAGE_RATIO("player.sweeping_damage_ratio"),
ZOMBIE_SPAWN_REINFORCEMENTS("zombie.spawn_reinforcements");
List of 1.21.3 Attributes...
Attribute MAX_HEALTH = getAttribute("max_health");
Attribute FOLLOW_RANGE = getAttribute("follow_range");
Attribute KNOCKBACK_RESISTANCE = getAttribute("knockback_resistance");
Attribute MOVEMENT_SPEED = getAttribute("movement_speed");
Attribute FLYING_SPEED = getAttribute("flying_speed");
Attribute ATTACK_DAMAGE = getAttribute("attack_damage");
Attribute ATTACK_KNOCKBACK = getAttribute("attack_knockback");
Attribute ATTACK_SPEED = getAttribute("attack_speed");
Attribute ARMOR = getAttribute("armor");
Attribute ARMOR_TOUGHNESS = getAttribute("armor_toughness");
Attribute FALL_DAMAGE_MULTIPLIER = getAttribute("fall_damage_multiplier");
Attribute LUCK = getAttribute("luck");
Attribute MAX_ABSORPTION = getAttribute("max_absorption");
Attribute SAFE_FALL_DISTANCE = getAttribute("safe_fall_distance");
Attribute SCALE = getAttribute("scale");
Attribute STEP_HEIGHT = getAttribute("step_height");
Attribute GRAVITY = getAttribute("gravity");
Attribute JUMP_STRENGTH = getAttribute("jump_strength");
Attribute BURNING_TIME = getAttribute("burning_time");
Attribute EXPLOSION_KNOCKBACK_RESISTANCE = getAttribute("explosion_knockback_resistance");
Attribute MOVEMENT_EFFICIENCY = getAttribute("movement_efficiency");
Attribute OXYGEN_BONUS = getAttribute("oxygen_bonus");
Attribute WATER_MOVEMENT_EFFICIENCY = getAttribute("water_movement_efficiency");
Attribute TEMPT_RANGE = getAttribute("tempt_range");
Attribute BLOCK_INTERACTION_RANGE = getAttribute("block_interaction_range");
Attribute ENTITY_INTERACTION_RANGE = getAttribute("entity_interaction_range");
Attribute BLOCK_BREAK_SPEED = getAttribute("block_break_speed");
Attribute MINING_EFFICIENCY = getAttribute("mining_efficiency");
Attribute SNEAKING_SPEED = getAttribute("sneaking_speed");
Attribute SUBMERGED_MINING_SPEED = getAttribute("submerged_mining_speed");
Attribute SWEEPING_DAMAGE_RATIO = getAttribute("sweeping_damage_ratio");
Attribute SPAWN_REINFORCEMENTS = getAttribute("spawn_reinforcements");
*/
} }

View File

@ -9,24 +9,37 @@ public class BiomeAdapter {
public static final Set<Biome> ICE_BIOMES; public static final Set<Biome> ICE_BIOMES;
static { static {
List<Biome> allBiomes = Arrays.asList(Biome.values()); final List<Biome> allBiomes = getAllBiomes();
List<Biome> waterBiomes = new ArrayList<>(); final Set<Biome> waterBiomes = new HashSet<>();
List<Biome> iceBiomes = new ArrayList<>(); final Set<Biome> iceBiomes = new HashSet<>();
for (Biome biome : allBiomes) { for (Biome biome : allBiomes) {
if (isWater(biome.name()) && !isCold(biome.name())) { String biomeName = getBiomeName(biome);
if (isWater(biomeName) && !isCold(biomeName)) {
waterBiomes.add(biome); waterBiomes.add(biome);
} else if (isCold(biome.name())) { } else if (isCold(biomeName)) {
iceBiomes.add(biome); iceBiomes.add(biome);
} }
} }
WATER_BIOMES = EnumSet.copyOf(waterBiomes); WATER_BIOMES = Collections.unmodifiableSet(waterBiomes);
ICE_BIOMES = EnumSet.copyOf(iceBiomes); ICE_BIOMES = Collections.unmodifiableSet(iceBiomes);
}
@SuppressWarnings("deprecation")
private static List<Biome> getAllBiomes() {
return Arrays.asList(Biome.values());
}
@SuppressWarnings("deprecation")
private static String getBiomeName(Biome biome) {
return biome.name();
} }
private static boolean isWater(String name) { private static boolean isWater(String name) {
return name.contains("RIVER") || name.contains("OCEAN"); return name.contains("RIVER") || name.contains("OCEAN");
} }
private static boolean isCold(String name) { private static boolean isCold(String name) {
return (name.contains("COLD") || name.contains("ICE") || name.contains("FROZEN") || name.contains("TAIGA")) && !(name.contains("WARM")); return (name.contains("COLD") || name.contains("ICE")
|| name.contains("FROZEN") || name.contains("TAIGA")) && !name.contains("WARM");
} }
} }

View File

@ -39,6 +39,7 @@ import org.jetbrains.annotations.Nullable;
import java.util.List; import java.util.List;
import static com.gmail.nossr50.datatypes.experience.XPGainReason.PVP; import static com.gmail.nossr50.datatypes.experience.XPGainReason.PVP;
import static com.gmail.nossr50.util.AttributeMapper.MAPPED_MOVEMENT_SPEED;
import static com.gmail.nossr50.util.MobMetadataUtils.hasMobFlag; import static com.gmail.nossr50.util.MobMetadataUtils.hasMobFlag;
public final class CombatUtils { public final class CombatUtils {
@ -1071,7 +1072,7 @@ public final class CombatUtils {
} }
public static void modifyMoveSpeed(@NotNull LivingEntity livingEntity, double multiplier) { public static void modifyMoveSpeed(@NotNull LivingEntity livingEntity, double multiplier) {
AttributeInstance attributeInstance = livingEntity.getAttribute(Attribute.GENERIC_MOVEMENT_SPEED); AttributeInstance attributeInstance = livingEntity.getAttribute(MAPPED_MOVEMENT_SPEED);
if (attributeInstance != null) { if (attributeInstance != null) {
double normalSpeed = attributeInstance.getBaseValue(); double normalSpeed = attributeInstance.getBaseValue();