mirror of
https://github.com/mcMMO-Dev/mcMMO.git
synced 2026-08-18 03:05:10 +00:00
refactor: replace Rupture's Bukkit metadata with an owned registry (#5332)
This commit is contained in:
@ -2,7 +2,7 @@ package com.gmail.nossr50.api;
|
|||||||
|
|
||||||
import com.gmail.nossr50.datatypes.player.McMMOPlayer;
|
import com.gmail.nossr50.datatypes.player.McMMOPlayer;
|
||||||
import com.gmail.nossr50.datatypes.skills.SuperAbilityType;
|
import com.gmail.nossr50.datatypes.skills.SuperAbilityType;
|
||||||
import com.gmail.nossr50.util.MetadataConstants;
|
import com.gmail.nossr50.runnables.skills.RuptureTask;
|
||||||
import com.gmail.nossr50.util.player.UserManager;
|
import com.gmail.nossr50.util.player.UserManager;
|
||||||
import org.bukkit.entity.LivingEntity;
|
import org.bukkit.entity.LivingEntity;
|
||||||
import org.bukkit.entity.Player;
|
import org.bukkit.entity.Player;
|
||||||
@ -110,10 +110,6 @@ public final class AbilityAPI {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static boolean isBleeding(LivingEntity entity) {
|
public static boolean isBleeding(LivingEntity entity) {
|
||||||
if (entity.isValid()) {
|
return entity.isValid() && RuptureTask.getActive(entity) != null;
|
||||||
return entity.hasMetadata(MetadataConstants.METADATA_KEY_RUPTURE);
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,10 +1,22 @@
|
|||||||
package com.gmail.nossr50.datatypes.meta;
|
package com.gmail.nossr50.datatypes.meta;
|
||||||
|
|
||||||
|
import com.gmail.nossr50.api.AbilityAPI;
|
||||||
import com.gmail.nossr50.runnables.skills.RuptureTask;
|
import com.gmail.nossr50.runnables.skills.RuptureTask;
|
||||||
|
import org.bukkit.entity.Entity;
|
||||||
|
import org.bukkit.entity.LivingEntity;
|
||||||
import org.bukkit.metadata.FixedMetadataValue;
|
import org.bukkit.metadata.FixedMetadataValue;
|
||||||
import org.bukkit.plugin.Plugin;
|
import org.bukkit.plugin.Plugin;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* No longer used. mcMMO stopped attaching rupture state to entities as Bukkit metadata
|
||||||
|
* in 2.3.001; active ruptures are tracked internally instead. Use
|
||||||
|
* {@link AbilityAPI#isBleeding(LivingEntity)} to check for an active bleed, or
|
||||||
|
* {@link RuptureTask#getActive(Entity)} to retrieve the task.
|
||||||
|
*
|
||||||
|
* @deprecated mcMMO no longer creates or reads this metadata.
|
||||||
|
*/
|
||||||
|
@Deprecated(forRemoval = true, since = "2.3.001")
|
||||||
public class RuptureTaskMeta extends FixedMetadataValue {
|
public class RuptureTaskMeta extends FixedMetadataValue {
|
||||||
|
|
||||||
private final @NotNull RuptureTask ruptureTask;
|
private final @NotNull RuptureTask ruptureTask;
|
||||||
|
|||||||
@ -12,7 +12,6 @@ import com.gmail.nossr50.datatypes.chat.ChatChannel;
|
|||||||
import com.gmail.nossr50.datatypes.experience.XPGainReason;
|
import com.gmail.nossr50.datatypes.experience.XPGainReason;
|
||||||
import com.gmail.nossr50.datatypes.experience.XPGainSource;
|
import com.gmail.nossr50.datatypes.experience.XPGainSource;
|
||||||
import com.gmail.nossr50.datatypes.interactions.NotificationType;
|
import com.gmail.nossr50.datatypes.interactions.NotificationType;
|
||||||
import com.gmail.nossr50.datatypes.meta.RuptureTaskMeta;
|
|
||||||
import com.gmail.nossr50.datatypes.party.Party;
|
import com.gmail.nossr50.datatypes.party.Party;
|
||||||
import com.gmail.nossr50.datatypes.party.PartyTeleportRecord;
|
import com.gmail.nossr50.datatypes.party.PartyTeleportRecord;
|
||||||
import com.gmail.nossr50.datatypes.skills.PrimarySkillType;
|
import com.gmail.nossr50.datatypes.skills.PrimarySkillType;
|
||||||
@ -48,7 +47,6 @@ import com.gmail.nossr50.skills.unarmed.UnarmedManager;
|
|||||||
import com.gmail.nossr50.skills.woodcutting.WoodcuttingManager;
|
import com.gmail.nossr50.skills.woodcutting.WoodcuttingManager;
|
||||||
import com.gmail.nossr50.util.BlockUtils;
|
import com.gmail.nossr50.util.BlockUtils;
|
||||||
import com.gmail.nossr50.util.EventUtils;
|
import com.gmail.nossr50.util.EventUtils;
|
||||||
import com.gmail.nossr50.util.MetadataConstants;
|
|
||||||
import com.gmail.nossr50.util.Misc;
|
import com.gmail.nossr50.util.Misc;
|
||||||
import com.gmail.nossr50.util.Permissions;
|
import com.gmail.nossr50.util.Permissions;
|
||||||
import com.gmail.nossr50.util.experience.ExperienceBarManager;
|
import com.gmail.nossr50.util.experience.ExperienceBarManager;
|
||||||
@ -1296,17 +1294,9 @@ public class McMMOPlayer implements Identified {
|
|||||||
*/
|
*/
|
||||||
public void logout(boolean syncSave) {
|
public void logout(boolean syncSave) {
|
||||||
final Player thisPlayer = getPlayer();
|
final Player thisPlayer = getPlayer();
|
||||||
if (thisPlayer.hasMetadata(MetadataConstants.METADATA_KEY_RUPTURE)) {
|
final RuptureTask ruptureTask = RuptureTask.getActive(thisPlayer);
|
||||||
final RuptureTaskMeta ruptureTaskMeta
|
if (ruptureTask != null) {
|
||||||
= (RuptureTaskMeta) thisPlayer.getMetadata(
|
ruptureTask.cancel();
|
||||||
MetadataConstants.METADATA_KEY_RUPTURE).get(0);
|
|
||||||
if (ruptureTaskMeta != null) {
|
|
||||||
final RuptureTask ruptureTimerTask = ruptureTaskMeta.getRuptureTimerTask();
|
|
||||||
if (ruptureTimerTask != null) {
|
|
||||||
ruptureTimerTask.cancel();
|
|
||||||
}
|
|
||||||
thisPlayer.removeMetadata(MetadataConstants.METADATA_KEY_RUPTURE, mcMMO.p);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
cleanup();
|
cleanup();
|
||||||
|
|||||||
@ -6,21 +6,29 @@ import com.gmail.nossr50.datatypes.player.McMMOPlayer;
|
|||||||
import com.gmail.nossr50.events.skills.rupture.McMMOEntityDamageByRuptureEvent;
|
import com.gmail.nossr50.events.skills.rupture.McMMOEntityDamageByRuptureEvent;
|
||||||
import com.gmail.nossr50.mcMMO;
|
import com.gmail.nossr50.mcMMO;
|
||||||
import com.gmail.nossr50.util.CancellableRunnable;
|
import com.gmail.nossr50.util.CancellableRunnable;
|
||||||
import com.gmail.nossr50.util.MetadataConstants;
|
|
||||||
import com.gmail.nossr50.util.MobHealthbarUtils;
|
import com.gmail.nossr50.util.MobHealthbarUtils;
|
||||||
import com.gmail.nossr50.util.skills.ParticleEffectUtils;
|
import com.gmail.nossr50.util.skills.ParticleEffectUtils;
|
||||||
import com.gmail.nossr50.util.sounds.SoundManager;
|
import com.gmail.nossr50.util.sounds.SoundManager;
|
||||||
import com.gmail.nossr50.util.sounds.SoundType;
|
import com.gmail.nossr50.util.sounds.SoundType;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.UUID;
|
||||||
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
import org.bukkit.attribute.AttributeInstance;
|
import org.bukkit.attribute.AttributeInstance;
|
||||||
|
import org.bukkit.entity.Entity;
|
||||||
import org.bukkit.entity.LivingEntity;
|
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 org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
public class RuptureTask extends CancellableRunnable {
|
public class RuptureTask extends CancellableRunnable {
|
||||||
|
|
||||||
public static final int DAMAGE_TICK_INTERVAL = 10;
|
public static final int DAMAGE_TICK_INTERVAL = 10;
|
||||||
public static final int ANIMATION_TICK_INTERVAL = 1;
|
public static final int ANIMATION_TICK_INTERVAL = 1;
|
||||||
|
|
||||||
|
// Active rupture per target entity.
|
||||||
|
private static final @NotNull Map<UUID, RuptureTask> ACTIVE_RUPTURES =
|
||||||
|
new ConcurrentHashMap<>();
|
||||||
|
|
||||||
private final @NotNull McMMOPlayer ruptureSource;
|
private final @NotNull McMMOPlayer ruptureSource;
|
||||||
private final @NotNull LivingEntity targetEntity;
|
private final @NotNull LivingEntity targetEntity;
|
||||||
private final int expireTick;
|
private final int expireTick;
|
||||||
@ -53,6 +61,20 @@ public class RuptureTask extends CancellableRunnable {
|
|||||||
this.pureTickDamage = pureTickDamage;
|
this.pureTickDamage = pureTickDamage;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static @Nullable RuptureTask getActive(@NotNull Entity target) {
|
||||||
|
return ACTIVE_RUPTURES.get(target.getUniqueId());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Registers this rupture as the target's active bleed and starts it ticking.
|
||||||
|
* The task removes itself from the registry when it is cancelled; on Folia the
|
||||||
|
* retired callback covers entities that are removed before the next tick.
|
||||||
|
*/
|
||||||
|
public void schedule() {
|
||||||
|
ACTIVE_RUPTURES.put(targetEntity.getUniqueId(), this);
|
||||||
|
mcMMO.p.getFoliaLib().getScheduler().runAtEntityTimer(targetEntity, this, this::cancel, 1, 1);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Deprecated constructor for the RuptureTask class.
|
* Deprecated constructor for the RuptureTask class.
|
||||||
*
|
*
|
||||||
@ -106,10 +128,15 @@ public class RuptureTask extends CancellableRunnable {
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
this.cancel(); //Task no longer needed
|
this.cancel(); //Task no longer needed
|
||||||
targetEntity.removeMetadata(MetadataConstants.METADATA_KEY_RUPTURE, mcMMO.p);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void cancel() {
|
||||||
|
ACTIVE_RUPTURES.remove(targetEntity.getUniqueId(), this);
|
||||||
|
super.cancel();
|
||||||
|
}
|
||||||
|
|
||||||
private void playAnimation() {
|
private void playAnimation() {
|
||||||
if (animationTick >= ANIMATION_TICK_INTERVAL) {
|
if (animationTick >= ANIMATION_TICK_INTERVAL) {
|
||||||
ParticleEffectUtils.playBleedEffect(targetEntity); //Animate
|
ParticleEffectUtils.playBleedEffect(targetEntity); //Animate
|
||||||
@ -176,7 +203,6 @@ public class RuptureTask extends CancellableRunnable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void endRupture() {
|
private void endRupture() {
|
||||||
targetEntity.removeMetadata(MetadataConstants.METADATA_KEY_RUPTURE, mcMMO.p);
|
|
||||||
this.cancel(); //Task no longer needed
|
this.cancel(); //Task no longer needed
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -1,7 +1,6 @@
|
|||||||
package com.gmail.nossr50.skills.swords;
|
package com.gmail.nossr50.skills.swords;
|
||||||
|
|
||||||
import com.gmail.nossr50.datatypes.interactions.NotificationType;
|
import com.gmail.nossr50.datatypes.interactions.NotificationType;
|
||||||
import com.gmail.nossr50.datatypes.meta.RuptureTaskMeta;
|
|
||||||
import com.gmail.nossr50.datatypes.player.McMMOPlayer;
|
import com.gmail.nossr50.datatypes.player.McMMOPlayer;
|
||||||
import com.gmail.nossr50.datatypes.skills.PrimarySkillType;
|
import com.gmail.nossr50.datatypes.skills.PrimarySkillType;
|
||||||
import com.gmail.nossr50.datatypes.skills.SubSkillType;
|
import com.gmail.nossr50.datatypes.skills.SubSkillType;
|
||||||
@ -10,7 +9,6 @@ import com.gmail.nossr50.datatypes.skills.ToolType;
|
|||||||
import com.gmail.nossr50.mcMMO;
|
import com.gmail.nossr50.mcMMO;
|
||||||
import com.gmail.nossr50.runnables.skills.RuptureTask;
|
import com.gmail.nossr50.runnables.skills.RuptureTask;
|
||||||
import com.gmail.nossr50.skills.SkillManager;
|
import com.gmail.nossr50.skills.SkillManager;
|
||||||
import com.gmail.nossr50.util.MetadataConstants;
|
|
||||||
import com.gmail.nossr50.util.Permissions;
|
import com.gmail.nossr50.util.Permissions;
|
||||||
import com.gmail.nossr50.util.player.NotificationManager;
|
import com.gmail.nossr50.util.player.NotificationManager;
|
||||||
import com.gmail.nossr50.util.random.ProbabilityUtil;
|
import com.gmail.nossr50.util.random.ProbabilityUtil;
|
||||||
@ -81,17 +79,15 @@ public class SwordsManager extends SkillManager {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (target.hasMetadata(MetadataConstants.METADATA_KEY_RUPTURE)) {
|
final RuptureTask ongoingRupture = RuptureTask.getActive(target);
|
||||||
RuptureTaskMeta ruptureTaskMeta = (RuptureTaskMeta) target.getMetadata(
|
if (ongoingRupture != null) {
|
||||||
MetadataConstants.METADATA_KEY_RUPTURE).get(0);
|
|
||||||
|
|
||||||
if (mmoPlayer.isDebugMode()) {
|
if (mmoPlayer.isDebugMode()) {
|
||||||
mmoPlayer.getPlayer()
|
mmoPlayer.getPlayer()
|
||||||
.sendMessage("Rupture task ongoing for target " + target);
|
.sendMessage("Rupture task ongoing for target " + target);
|
||||||
mmoPlayer.getPlayer().sendMessage(ruptureTaskMeta.getRuptureTimerTask().toString());
|
mmoPlayer.getPlayer().sendMessage(ongoingRupture.toString());
|
||||||
}
|
}
|
||||||
|
|
||||||
ruptureTaskMeta.getRuptureTimerTask().refreshRupture();
|
ongoingRupture.refreshRupture();
|
||||||
return; //Don't apply bleed
|
return; //Don't apply bleed
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -118,10 +114,7 @@ public class SwordsManager extends SkillManager {
|
|||||||
mcMMO.p.getAdvancedConfig()
|
mcMMO.p.getAdvancedConfig()
|
||||||
.getRuptureTickDamage(target instanceof Player, getRuptureRank()));
|
.getRuptureTickDamage(target instanceof Player, getRuptureRank()));
|
||||||
|
|
||||||
final RuptureTaskMeta ruptureTaskMeta = new RuptureTaskMeta(mcMMO.p, ruptureTask);
|
ruptureTask.schedule();
|
||||||
|
|
||||||
mcMMO.p.getFoliaLib().getScheduler().runAtEntityTimer(target, ruptureTask, 1, 1);
|
|
||||||
target.setMetadata(MetadataConstants.METADATA_KEY_RUPTURE, ruptureTaskMeta);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -17,7 +17,6 @@ public class MetadataConstants {
|
|||||||
* removed by {@link MobHealthbarUtils#restoreNameFromSnapshot}.
|
* removed by {@link MobHealthbarUtils#restoreNameFromSnapshot}.
|
||||||
*/
|
*/
|
||||||
public static final @NotNull Set<String> MOB_METADATA_KEYS = Set.of(
|
public static final @NotNull Set<String> MOB_METADATA_KEYS = Set.of(
|
||||||
MetadataConstants.METADATA_KEY_RUPTURE,
|
|
||||||
MetadataConstants.METADATA_KEY_EXPLOSION_FROM_RUPTURE
|
MetadataConstants.METADATA_KEY_EXPLOSION_FROM_RUPTURE
|
||||||
);
|
);
|
||||||
|
|
||||||
@ -66,7 +65,17 @@ public class MetadataConstants {
|
|||||||
public static final @NotNull String METADATA_KEY_VILLAGER_TRADE_ORIGIN_ITEM = "mcmmo_villager_trade_origin_item";
|
public static final @NotNull String METADATA_KEY_VILLAGER_TRADE_ORIGIN_ITEM = "mcmmo_villager_trade_origin_item";
|
||||||
public static final @NotNull String METADATA_KEY_EXPLOITED_ENDERMEN = "mcmmo_exploited_endermen";
|
public static final @NotNull String METADATA_KEY_EXPLOITED_ENDERMEN = "mcmmo_exploited_endermen";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* No longer used. mcMMO stopped applying this metadata to bleeding entities in 2.3.001,
|
||||||
|
* so {@code hasMetadata} checks against this key always return false. Use
|
||||||
|
* {@link com.gmail.nossr50.api.AbilityAPI#isBleeding(org.bukkit.entity.LivingEntity)} instead.
|
||||||
|
*
|
||||||
|
* @deprecated mcMMO no longer applies this metadata; see
|
||||||
|
* {@link com.gmail.nossr50.api.AbilityAPI#isBleeding}.
|
||||||
|
*/
|
||||||
|
@Deprecated(forRemoval = true, since = "2.3.001")
|
||||||
public static final @NotNull String METADATA_KEY_RUPTURE = "mcmmo_rupture";
|
public static final @NotNull String METADATA_KEY_RUPTURE = "mcmmo_rupture";
|
||||||
|
|
||||||
public static final byte SIMPLE_FLAG_VALUE = (byte) 0x1;
|
public static final byte SIMPLE_FLAG_VALUE = (byte) 0x1;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@ -14,14 +14,12 @@ import static org.mockito.Mockito.when;
|
|||||||
import com.gmail.nossr50.MMOTestEnvironment;
|
import com.gmail.nossr50.MMOTestEnvironment;
|
||||||
import com.gmail.nossr50.api.exceptions.InvalidSkillException;
|
import com.gmail.nossr50.api.exceptions.InvalidSkillException;
|
||||||
import com.gmail.nossr50.datatypes.interactions.NotificationType;
|
import com.gmail.nossr50.datatypes.interactions.NotificationType;
|
||||||
import com.gmail.nossr50.datatypes.meta.RuptureTaskMeta;
|
|
||||||
import com.gmail.nossr50.datatypes.skills.PrimarySkillType;
|
import com.gmail.nossr50.datatypes.skills.PrimarySkillType;
|
||||||
import com.gmail.nossr50.datatypes.skills.SubSkillType;
|
import com.gmail.nossr50.datatypes.skills.SubSkillType;
|
||||||
import com.gmail.nossr50.datatypes.skills.SuperAbilityType;
|
import com.gmail.nossr50.datatypes.skills.SuperAbilityType;
|
||||||
import com.gmail.nossr50.datatypes.skills.ToolType;
|
import com.gmail.nossr50.datatypes.skills.ToolType;
|
||||||
import com.gmail.nossr50.mcMMO;
|
import com.gmail.nossr50.mcMMO;
|
||||||
import com.gmail.nossr50.runnables.skills.RuptureTask;
|
import com.gmail.nossr50.runnables.skills.RuptureTask;
|
||||||
import com.gmail.nossr50.util.MetadataConstants;
|
|
||||||
import com.gmail.nossr50.util.Permissions;
|
import com.gmail.nossr50.util.Permissions;
|
||||||
import com.gmail.nossr50.util.player.NotificationManager;
|
import com.gmail.nossr50.util.player.NotificationManager;
|
||||||
import com.gmail.nossr50.util.random.ProbabilityUtil;
|
import com.gmail.nossr50.util.random.ProbabilityUtil;
|
||||||
@ -29,7 +27,9 @@ import com.gmail.nossr50.util.skills.CombatUtils;
|
|||||||
import com.gmail.nossr50.util.skills.RankUtils;
|
import com.gmail.nossr50.util.skills.RankUtils;
|
||||||
import com.tcoded.folialib.FoliaLib;
|
import com.tcoded.folialib.FoliaLib;
|
||||||
import com.tcoded.folialib.impl.PlatformScheduler;
|
import com.tcoded.folialib.impl.PlatformScheduler;
|
||||||
import java.util.List;
|
import java.lang.reflect.Field;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.UUID;
|
||||||
import org.bukkit.entity.Entity;
|
import org.bukkit.entity.Entity;
|
||||||
import org.bukkit.entity.LivingEntity;
|
import org.bukkit.entity.LivingEntity;
|
||||||
import org.bukkit.entity.Player;
|
import org.bukkit.entity.Player;
|
||||||
@ -67,6 +67,7 @@ class SwordsManagerTest extends MMOTestEnvironment {
|
|||||||
|
|
||||||
swordsManager = new SwordsManager(mmoPlayer);
|
swordsManager = new SwordsManager(mmoPlayer);
|
||||||
target = Mockito.mock(LivingEntity.class);
|
target = Mockito.mock(LivingEntity.class);
|
||||||
|
when(target.getUniqueId()).thenReturn(UUID.randomUUID());
|
||||||
|
|
||||||
// Simulate Paper 26.1.2+ during a damage event: the ticker was already reset, so the
|
// Simulate Paper 26.1.2+ during a damage event: the ticker was already reset, so the
|
||||||
// live cooldown misreports the charge of the committed hit.
|
// live cooldown misreports the charge of the committed hit.
|
||||||
@ -86,7 +87,6 @@ class SwordsManagerTest extends MMOTestEnvironment {
|
|||||||
.thenReturn(true);
|
.thenReturn(true);
|
||||||
Mockito.when(RankUtils.getRank(player, SubSkillType.SWORDS_RUPTURE)).thenReturn(3);
|
Mockito.when(RankUtils.getRank(player, SubSkillType.SWORDS_RUPTURE)).thenReturn(3);
|
||||||
when(advancedConfig.getRuptureChanceToApplyOnHit(3)).thenReturn(33.0);
|
when(advancedConfig.getRuptureChanceToApplyOnHit(3)).thenReturn(33.0);
|
||||||
when(target.hasMetadata(MetadataConstants.METADATA_KEY_RUPTURE)).thenReturn(false);
|
|
||||||
|
|
||||||
try (MockedStatic<ProbabilityUtil> probabilityUtil = mockStatic(ProbabilityUtil.class)) {
|
try (MockedStatic<ProbabilityUtil> probabilityUtil = mockStatic(ProbabilityUtil.class)) {
|
||||||
// When - a hit committed at half attack strength lands and the roll fails
|
// When - a hit committed at half attack strength lands and the roll fails
|
||||||
@ -171,18 +171,21 @@ class SwordsManagerTest extends MMOTestEnvironment {
|
|||||||
when(advancedConfig.getRuptureChanceToApplyOnHit(3)).thenReturn(100.0);
|
when(advancedConfig.getRuptureChanceToApplyOnHit(3)).thenReturn(100.0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Seeds RuptureTask's active-rupture registry for the test.
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
private void trackRupture(Entity target, RuptureTask task) throws Exception {
|
||||||
|
Field field = RuptureTask.class.getDeclaredField("ACTIVE_RUPTURES");
|
||||||
|
field.setAccessible(true);
|
||||||
|
((Map<UUID, RuptureTask>) field.get(null)).put(target.getUniqueId(), task);
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void existingRuptureShouldBeRefreshedInsteadOfReRolled() {
|
void existingRuptureShouldBeRefreshedInsteadOfReRolled() throws Exception {
|
||||||
try (MockedStatic<ProbabilityUtil> probabilityUtil =
|
try (MockedStatic<ProbabilityUtil> probabilityUtil =
|
||||||
mockStatic(ProbabilityUtil.class)) {
|
mockStatic(ProbabilityUtil.class)) {
|
||||||
// Given - the target is already bleeding from a rupture
|
// Given - the target is already bleeding from a rupture
|
||||||
final RuptureTask ongoingRupture = Mockito.mock(RuptureTask.class);
|
final RuptureTask ongoingRupture = Mockito.mock(RuptureTask.class);
|
||||||
final RuptureTaskMeta ruptureMeta = Mockito.mock(RuptureTaskMeta.class);
|
trackRupture(target, ongoingRupture);
|
||||||
when(ruptureMeta.getRuptureTimerTask()).thenReturn(ongoingRupture);
|
|
||||||
when(target.hasMetadata(MetadataConstants.METADATA_KEY_RUPTURE))
|
|
||||||
.thenReturn(true);
|
|
||||||
when(target.getMetadata(MetadataConstants.METADATA_KEY_RUPTURE))
|
|
||||||
.thenReturn(List.of(ruptureMeta));
|
|
||||||
|
|
||||||
// When - another rupture-capable hit lands
|
// When - another rupture-capable hit lands
|
||||||
swordsManager.processRupture(target, 1.0);
|
swordsManager.processRupture(target, 1.0);
|
||||||
@ -207,10 +210,9 @@ class SwordsManagerTest extends MMOTestEnvironment {
|
|||||||
swordsManager.processRupture(target, 1.0);
|
swordsManager.processRupture(target, 1.0);
|
||||||
|
|
||||||
// Then - a bleed task starts ticking on the target and is remembered on it
|
// Then - a bleed task starts ticking on the target and is remembered on it
|
||||||
verify(scheduler).runAtEntityTimer(eq(target), any(RuptureTask.class), eq(1L),
|
verify(scheduler).runAtEntityTimer(eq(target), any(RuptureTask.class),
|
||||||
eq(1L));
|
any(Runnable.class), eq(1L), eq(1L));
|
||||||
verify(target).setMetadata(eq(MetadataConstants.METADATA_KEY_RUPTURE),
|
assertThat(RuptureTask.getActive(target)).isNotNull();
|
||||||
any(RuptureTaskMeta.class));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -220,6 +222,7 @@ class SwordsManagerTest extends MMOTestEnvironment {
|
|||||||
mockStatic(ProbabilityUtil.class)) {
|
mockStatic(ProbabilityUtil.class)) {
|
||||||
// Given - a defending player who is blocking with a shield
|
// Given - a defending player who is blocking with a shield
|
||||||
final Player defender = Mockito.mock(Player.class);
|
final Player defender = Mockito.mock(Player.class);
|
||||||
|
when(defender.getUniqueId()).thenReturn(UUID.randomUUID());
|
||||||
when(defender.isBlocking()).thenReturn(true);
|
when(defender.isBlocking()).thenReturn(true);
|
||||||
probabilityUtil.when(() -> ProbabilityUtil.isStaticSkillRNGSuccessful(
|
probabilityUtil.when(() -> ProbabilityUtil.isStaticSkillRNGSuccessful(
|
||||||
eq(PrimarySkillType.SWORDS), eq(mmoPlayer), eq(100.0)))
|
eq(PrimarySkillType.SWORDS), eq(mmoPlayer), eq(100.0)))
|
||||||
@ -229,8 +232,7 @@ class SwordsManagerTest extends MMOTestEnvironment {
|
|||||||
swordsManager.processRupture(defender, 1.0);
|
swordsManager.processRupture(defender, 1.0);
|
||||||
|
|
||||||
// Then - no bleed starts
|
// Then - no bleed starts
|
||||||
verify(defender, never()).setMetadata(eq(MetadataConstants.METADATA_KEY_RUPTURE),
|
assertThat(RuptureTask.getActive(defender)).isNull();
|
||||||
any());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -240,6 +242,7 @@ class SwordsManagerTest extends MMOTestEnvironment {
|
|||||||
mockStatic(ProbabilityUtil.class)) {
|
mockStatic(ProbabilityUtil.class)) {
|
||||||
// Given - a non-blocking defending player who uses notifications
|
// Given - a non-blocking defending player who uses notifications
|
||||||
final Player defender = Mockito.mock(Player.class);
|
final Player defender = Mockito.mock(Player.class);
|
||||||
|
when(defender.getUniqueId()).thenReturn(UUID.randomUUID());
|
||||||
when(NotificationManager.doesPlayerUseNotifications(defender)).thenReturn(true);
|
when(NotificationManager.doesPlayerUseNotifications(defender)).thenReturn(true);
|
||||||
probabilityUtil.when(() -> ProbabilityUtil.isStaticSkillRNGSuccessful(
|
probabilityUtil.when(() -> ProbabilityUtil.isStaticSkillRNGSuccessful(
|
||||||
eq(PrimarySkillType.SWORDS), eq(mmoPlayer), eq(100.0)))
|
eq(PrimarySkillType.SWORDS), eq(mmoPlayer), eq(100.0)))
|
||||||
|
|||||||
Reference in New Issue
Block a user