Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions Changelog.txt
Original file line number Diff line number Diff line change
@@ -1,3 +1,13 @@
Version 2.2.049
Combat abilities work with spear in off-hand again (see notes)
Sweet berry bushes now work with Herbalism (thanks dnocturne)
(Codebase) Fixed unit tests for Java 25 (thanks Warriorrrr)
Fixed copper items not giving XP for Repair (thanks Remski01)
Fixed edge case where mcMMO could drop items with stack size set outside normal bounds

NOTES:
As a semi-permanent work around, mcMMO keeps track of when players swing their weapon, if they have swung it recently enough combat skills will work even if you have a spear in your off-hand.
Prior to this patch, mcMMO disabled combat abilities when spear was in off-hand to prevent the off-hand spear charge from applying combat abilities from other skills, as mcMMO was unable to determine which item (mainhand vs offhand) caused the damage from the event information alone.
Version 2.2.048
Fixed error when loading Spears skill manager on older Minecraft versions
Fixed error when using /spears command on an older Minecraft version
Expand Down
35 changes: 28 additions & 7 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,17 @@
<propertiesEncoding>UTF-8</propertiesEncoding>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<executions>
<execution>
<goals>
<goal>properties</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<artifactId>maven-surefire-plugin</artifactId>
<version>3.2.5</version>
Expand All @@ -97,6 +108,8 @@
<junitArtifactName>org.junit.jupiter:junit-jupiter</junitArtifactName>
<trimStackTrace>false</trimStackTrace>
<excludedGroups>skip</excludedGroups>
<!-- https://javadoc.io/doc/org.mockito/mockito-core/latest/org.mockito/org/mockito/Mockito.html#0.3 -->
<argLine>-javaagent:${org.mockito:mockito-core:jar}</argLine>
</configuration>
</plugin>
<plugin>
Expand Down Expand Up @@ -290,12 +303,26 @@
<artifactId>assertj-core</artifactId>
<version>3.25.3</version>
<scope>test</scope>
<exclusions>
<!-- Exclude bytebuddy, messes with tests on java 25+ -->
<exclusion>
<groupId>net.bytebuddy</groupId>
<artifactId>byte-buddy</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>net.dmulloy2</groupId>
<artifactId>ProtocolLib</artifactId>
<version>5.3.0</version>
<scope>compile</scope>
<exclusions>
<!-- Exclude bytebuddy, messes with tests on java 25+ -->
<exclusion>
<groupId>net.bytebuddy</groupId>
<artifactId>byte-buddy</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>com.h2database</groupId>
Expand Down Expand Up @@ -506,13 +533,7 @@
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-core</artifactId>
<version>5.12.0</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-inline</artifactId>
<version>5.2.0</version>
<version>5.21.0</version>
<scope>test</scope>
</dependency>
<dependency>
Expand Down
10 changes: 10 additions & 0 deletions src/main/java/com/gmail/nossr50/datatypes/player/McMMOPlayer.java
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,7 @@
import org.jetbrains.annotations.VisibleForTesting;

public class McMMOPlayer implements Identified {
private static final long NO_SWING = 0L;
private final @NotNull Identity identity;

//Hacky fix for now, redesign later
Expand All @@ -97,6 +98,7 @@ public class McMMOPlayer implements Identified {
private Party invite;
private Party allianceInvite;
private int itemShareModifier;
private long lastSwingTimestamp = NO_SWING;

private PartyTeleportRecord ptpRecord;

Expand Down Expand Up @@ -1278,4 +1280,12 @@ public void cleanup() {
public void setChatMode(@NotNull ChatChannel chatChannel) {
this.chatChannel = chatChannel;
}

public long getLastSwingTimestamp() {
return lastSwingTimestamp;
}

public void setLastSwingTimestamp(long lastSwingTimestamp) {
this.lastSwingTimestamp = lastSwingTimestamp;
}
}
12 changes: 7 additions & 5 deletions src/main/java/com/gmail/nossr50/listeners/BlockListener.java
Original file line number Diff line number Diff line change
Expand Up @@ -147,12 +147,14 @@ public void onBlockDropItemEvent(BlockDropItemEvent event) {
}

int amountToAddFromBonus = bonusDropMeta.asInt();
final McMMOModifyBlockDropItemEvent modifyBlockDropItemEvent
final McMMOModifyBlockDropItemEvent modifyDropEvent
= new McMMOModifyBlockDropItemEvent(event, item, amountToAddFromBonus);
plugin.getServer().getPluginManager().callEvent(modifyBlockDropItemEvent);
if (!modifyBlockDropItemEvent.isCancelled()
&& modifyBlockDropItemEvent.getModifiedItemStackQuantity() > originalAmount) {
eventItemStack.setAmount(modifyBlockDropItemEvent.getModifiedItemStackQuantity());
plugin.getServer().getPluginManager().callEvent(modifyDropEvent);
if (!modifyDropEvent.isCancelled()
&& modifyDropEvent.getModifiedItemStackQuantity() > originalAmount) {
eventItemStack.setAmount(
Math.min(modifyDropEvent.getModifiedItemStackQuantity(),
item.getItemStack().getMaxStackSize()));
}
}
}
Expand Down
22 changes: 21 additions & 1 deletion src/main/java/com/gmail/nossr50/listeners/PlayerListener.java
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,8 @@
import org.bukkit.event.entity.EntityPickupItemEvent;
import org.bukkit.event.entity.PlayerDeathEvent;
import org.bukkit.event.player.AsyncPlayerChatEvent;
import org.bukkit.event.player.PlayerAnimationEvent;
import org.bukkit.event.player.PlayerAnimationType;
import org.bukkit.event.player.PlayerChangedWorldEvent;
import org.bukkit.event.player.PlayerCommandPreprocessEvent;
import org.bukkit.event.player.PlayerDropItemEvent;
Expand Down Expand Up @@ -909,7 +911,6 @@ public void onPlayerInteractMonitor(PlayerInteractEvent event) {

HerbalismManager herbalismManager = mmoPlayer.getHerbalismManager();

// FakePlayerAnimationEvent fakeSwing = new FakePlayerAnimationEvent(event.getPlayer(), PlayerAnimationType.ARM_SWING); //PlayerAnimationEvent compat
if (!event.isCancelled() || event.useInteractedBlock() != Event.Result.DENY) {
//TODO: Is this code to set false from bone meal even needed? I'll have to double check later.
if (heldItem.getType() == Material.BONE_MEAL) {
Expand Down Expand Up @@ -1122,4 +1123,23 @@ public void onPlayerSwapHandItems(PlayerSwapHandItemsEvent event) {
SkillUtils.removeAbilityBuff(event.getMainHandItem());
SkillUtils.removeAbilityBuff(event.getOffHandItem());
}

@EventHandler(ignoreCancelled = false, priority = EventPriority.MONITOR)
public void onPlayerAnimation(PlayerAnimationEvent event) {
if (event.getAnimationType() != PlayerAnimationType.ARM_SWING) {
return;
}

final Player player = event.getPlayer();

if (!UserManager.hasPlayerDataKey(player)) {
return;
}

final McMMOPlayer mmoPlayer = UserManager.getPlayer(player);

if (mmoPlayer != null) {
mmoPlayer.setLastSwingTimestamp(System.currentTimeMillis());
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -535,6 +535,10 @@ public void awardXPForPlantBlocks(HashSet<Block> brokenPlants) {
}

public boolean isAgeableMature(Ageable ageable) {
// Sweet berry bush is harvestable at age 2 and 3 (max is 3)
if (ageable.getMaterial() == Material.SWEET_BERRY_BUSH) {
return ageable.getAge() >= 2;
}
return ageable.getAge() == ageable.getMaximumAge()
&& ageable.getAge() != 0;
}
Expand Down Expand Up @@ -868,6 +872,7 @@ private boolean processGreenThumbPlants(@NotNull BlockState blockState,
case "beetroots" -> replantMaterial = Material.matchMaterial("BEETROOT_SEEDS");
case "cocoa" -> replantMaterial = Material.matchMaterial("COCOA_BEANS");
case "torchflower" -> replantMaterial = Material.matchMaterial("TORCHFLOWER_SEEDS");
case "sweet_berry_bush" -> replantMaterial = Material.matchMaterial("SWEET_BERRIES");
default -> {
return false;
}
Expand Down Expand Up @@ -956,6 +961,17 @@ private boolean processGrowingPlants(BlockState blockState, Ageable ageable,
}
break;

case "sweet_berry_bush":

// Sweet berry bush has ages 0-3, where 2+ has berries
// Cap at age 1 to prevent instant re-harvest exploit with enough herbalism levels
if (greenTerra || greenThumbStage >= 2) {
finalAge = 1;
} else {
finalAge = 0;
}
break;

default:
return false;
}
Expand Down
58 changes: 31 additions & 27 deletions src/main/java/com/gmail/nossr50/util/skills/CombatUtils.java
Original file line number Diff line number Diff line change
Expand Up @@ -125,18 +125,18 @@ private static void processSwordCombat(@NotNull LivingEntity target, @NotNull Pl
return;
}

// TODO: Temporary hack to avoid unintended spear interactions
if (isSpear(player.getInventory().getItemInOffHand())) {
return;
}

final McMMOPlayer mmoPlayer = UserManager.getPlayer(player);

//Make sure the profiles been loaded
if (mmoPlayer == null) {
return;
}

// Hack to avoid other combat abilities applying to off-hand spear attacks
if (isSpear(player.getInventory().getItemInOffHand()) && isNotSwinging(mmoPlayer)) {
return;
}

SwordsManager swordsManager = mmoPlayer.getSwordsManager();
double boostedDamage = event.getDamage();

Expand Down Expand Up @@ -194,11 +194,6 @@ private static void processTridentCombatMelee(@NotNull LivingEntity target,
return;
}

// TODO: Temporary hack to avoid unintended spear interactions
if (isSpear(player.getInventory().getItemInOffHand())) {
return;
}

double boostedDamage = event.getDamage();

final McMMOPlayer mmoPlayer = UserManager.getPlayer(player);
Expand All @@ -208,6 +203,11 @@ private static void processTridentCombatMelee(@NotNull LivingEntity target,
return;
}

// Hack to avoid other combat abilities applying to off-hand spear attacks
if (isSpear(player.getInventory().getItemInOffHand()) && isNotSwinging(mmoPlayer)) {
return;
}

final TridentsManager tridentsManager = mmoPlayer.getTridentsManager();

// if (tridentsManager.canActivateAbility()) {
Expand Down Expand Up @@ -312,11 +312,6 @@ private static void processMacesCombat(@NotNull LivingEntity target,
return;
}

// TODO: Temporary hack to avoid unintended spear interactions
if (isSpear(player.getInventory().getItemInOffHand())) {
return;
}

double boostedDamage = event.getDamage();

final McMMOPlayer mmoPlayer = UserManager.getPlayer(player);
Expand All @@ -326,6 +321,11 @@ private static void processMacesCombat(@NotNull LivingEntity target,
return;
}

// Hack to avoid other combat abilities applying to off-hand spear attacks
if (isSpear(player.getInventory().getItemInOffHand()) && isNotSwinging(mmoPlayer)) {
return;
}

final MacesManager macesManager = mmoPlayer.getMacesManager();

// Apply Limit Break DMG
Expand Down Expand Up @@ -395,11 +395,6 @@ private static void processAxeCombat(@NotNull LivingEntity target, @NotNull Play
return;
}

// TODO: Temporary hack to avoid unintended spear interactions
if (isSpear(player.getInventory().getItemInOffHand())) {
return;
}

double boostedDamage = event.getDamage();

final McMMOPlayer mmoPlayer = UserManager.getPlayer(player);
Expand All @@ -409,6 +404,11 @@ private static void processAxeCombat(@NotNull LivingEntity target, @NotNull Play
return;
}

// Hack to avoid other combat abilities applying to off-hand spear attacks
if (isSpear(player.getInventory().getItemInOffHand()) && isNotSwinging(mmoPlayer)) {
return;
}

final AxesManager axesManager = mmoPlayer.getAxesManager();

if (axesManager.canActivateAbility()) {
Expand Down Expand Up @@ -454,18 +454,18 @@ private static void processUnarmedCombat(@NotNull LivingEntity target, @NotNull

double boostedDamage = event.getDamage();

// TODO: Temporary hack to avoid unintended spear interactions
if (isSpear(player.getInventory().getItemInOffHand())) {
return;
}

final McMMOPlayer mmoPlayer = UserManager.getPlayer(player);

//Make sure the profiles been loaded
if (mmoPlayer == null) {
return;
}

// Hack to avoid other combat abilities applying to off-hand spear attacks
if (isSpear(player.getInventory().getItemInOffHand()) && isNotSwinging(mmoPlayer)) {
return;
}

final UnarmedManager unarmedManager = mmoPlayer.getUnarmedManager();

if (unarmedManager.canActivateAbility()) {
Expand Down Expand Up @@ -949,8 +949,6 @@ public static void applyAbilityAoE(@NotNull Player attacker, @NotNull LivingEnti
continue;
}

//EventUtils.callFakeArmSwingEvent(attacker);

switch (type) {
case SWORDS:
if (entity instanceof Player) {
Expand Down Expand Up @@ -1227,4 +1225,10 @@ public static void delayArrowMetaCleanup(@NotNull AbstractArrow arrow) {
mcMMO.p.getFoliaLib().getScheduler()
.runLater(() -> ProjectileUtils.cleanupProjectileMetadata(arrow), 20 * 120);
}

public static boolean isNotSwinging(McMMOPlayer mmoPlayer) {
// If player has swung in the last second, it's extremely unlikely the damage originates
// from an off-hand spear charge attack
return mmoPlayer.getLastSwingTimestamp() + 500L < System.currentTimeMillis();
}
}
1 change: 1 addition & 0 deletions src/main/resources/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -484,6 +484,7 @@ Green_Thumb_Replanting_Crops:
Potatoes: true
Beetroots: true
Cocoa: true
Sweet_Berry_Bush: true
#
# Settings for Double Drops
###
Expand Down