mirror of
https://github.com/mcMMO-Dev/mcMMO.git
synced 2024-11-24 14:16:45 +01:00
Crossbow Fixes
This commit is contained in:
parent
f051edd03d
commit
b3b8a12b6d
2
pom.xml
2
pom.xml
@ -2,7 +2,7 @@
|
|||||||
<modelVersion>4.0.0</modelVersion>
|
<modelVersion>4.0.0</modelVersion>
|
||||||
<groupId>com.gmail.nossr50.mcMMO</groupId>
|
<groupId>com.gmail.nossr50.mcMMO</groupId>
|
||||||
<artifactId>mcMMO</artifactId>
|
<artifactId>mcMMO</artifactId>
|
||||||
<version>2.2.000-BETA-04-SNAPSHOT</version>
|
<version>2.2.000-BETA-07-SNAPSHOT</version>
|
||||||
<name>mcMMO</name>
|
<name>mcMMO</name>
|
||||||
<url>https://github.com/mcMMO-Dev/mcMMO</url>
|
<url>https://github.com/mcMMO-Dev/mcMMO</url>
|
||||||
<scm>
|
<scm>
|
||||||
|
@ -2,20 +2,19 @@ package com.gmail.nossr50.commands.skills;
|
|||||||
|
|
||||||
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.util.player.UserManager;
|
import com.gmail.nossr50.util.player.UserManager;
|
||||||
import com.gmail.nossr50.util.skills.CombatUtils;
|
import com.gmail.nossr50.util.skills.CombatUtils;
|
||||||
import com.gmail.nossr50.util.skills.SkillUtils;
|
import com.gmail.nossr50.util.skills.SkillUtils;
|
||||||
import com.gmail.nossr50.util.text.TextComponentFactory;
|
import com.gmail.nossr50.util.text.TextComponentFactory;
|
||||||
import net.kyori.adventure.text.Component;
|
import net.kyori.adventure.text.Component;
|
||||||
import org.bukkit.ChatColor;
|
import org.bukkit.ChatColor;
|
||||||
import org.bukkit.entity.Cat;
|
|
||||||
import org.bukkit.entity.Player;
|
import org.bukkit.entity.Player;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import static com.gmail.nossr50.datatypes.skills.SubSkillType.*;
|
import static com.gmail.nossr50.datatypes.skills.SubSkillType.TRIDENTS_IMPALE;
|
||||||
|
import static com.gmail.nossr50.datatypes.skills.SubSkillType.TRIDENTS_TRIDENTS_LIMIT_BREAK;
|
||||||
|
|
||||||
public class TridentsCommand extends SkillCommand {
|
public class TridentsCommand extends SkillCommand {
|
||||||
|
|
||||||
|
@ -963,14 +963,14 @@ public class McMMOPlayer implements Identified {
|
|||||||
/**
|
/**
|
||||||
* Check to see if an ability can be activated.
|
* Check to see if an ability can be activated.
|
||||||
*
|
*
|
||||||
* @param bowType The type of bow (crossbow, bow)
|
* @param isCrossbow true for crossbow, false for bow
|
||||||
*/
|
*/
|
||||||
public void checkAbilityActivationProjectiles(BowType bowType) {
|
public void checkAbilityActivationProjectiles(boolean isCrossbow) {
|
||||||
PrimarySkillType primarySkillType = bowType == BowType.CROSSBOW ? PrimarySkillType.CROSSBOWS : PrimarySkillType.ARCHERY;
|
PrimarySkillType primarySkillType = isCrossbow ? PrimarySkillType.CROSSBOWS : PrimarySkillType.ARCHERY;
|
||||||
|
|
||||||
// TODO: Refactor this crappy logic
|
// TODO: Refactor this crappy logic
|
||||||
ToolType tool = bowType == BowType.CROSSBOW ? ToolType.CROSSBOW : ToolType.BOW;
|
ToolType tool = isCrossbow ? ToolType.CROSSBOW : ToolType.BOW;
|
||||||
SuperAbilityType superAbilityType = bowType == BowType.CROSSBOW ? SuperAbilityType.SUPER_SHOTGUN : SuperAbilityType.EXPLOSIVE_SHOT;
|
SuperAbilityType superAbilityType = isCrossbow ? SuperAbilityType.SUPER_SHOTGUN : SuperAbilityType.EXPLOSIVE_SHOT;
|
||||||
SubSkillType subSkillType = superAbilityType.getSubSkillTypeDefinition();
|
SubSkillType subSkillType = superAbilityType.getSubSkillTypeDefinition();
|
||||||
|
|
||||||
if (getAbilityMode(superAbilityType) || !superAbilityType.getPermissions(player)) {
|
if (getAbilityMode(superAbilityType) || !superAbilityType.getPermissions(player)) {
|
||||||
|
@ -26,7 +26,6 @@ import com.gmail.nossr50.util.player.NotificationManager;
|
|||||||
import com.gmail.nossr50.util.player.UserManager;
|
import com.gmail.nossr50.util.player.UserManager;
|
||||||
import com.gmail.nossr50.util.random.ProbabilityUtil;
|
import com.gmail.nossr50.util.random.ProbabilityUtil;
|
||||||
import com.gmail.nossr50.util.skills.CombatUtils;
|
import com.gmail.nossr50.util.skills.CombatUtils;
|
||||||
import com.gmail.nossr50.util.skills.ProjectileUtils;
|
|
||||||
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.ChatColor;
|
import org.bukkit.ChatColor;
|
||||||
@ -105,7 +104,7 @@ public class EntityListener implements Listener {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
|
@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = false)
|
||||||
public void onEntityShootBow(EntityShootBowEvent event) {
|
public void onEntityShootBow(EntityShootBowEvent event) {
|
||||||
/* WORLD BLACKLIST CHECK */
|
/* WORLD BLACKLIST CHECK */
|
||||||
if(WorldBlacklist.isWorldBlacklisted(event.getEntity().getWorld()))
|
if(WorldBlacklist.isWorldBlacklisted(event.getEntity().getWorld()))
|
||||||
@ -113,18 +112,10 @@ public class EntityListener implements Listener {
|
|||||||
|
|
||||||
if(event.getEntity() instanceof Player player)
|
if(event.getEntity() instanceof Player player)
|
||||||
{
|
{
|
||||||
|
|
||||||
/* WORLD GUARD MAIN FLAG CHECK */
|
|
||||||
if(WorldGuardUtils.isWorldGuardLoaded())
|
|
||||||
{
|
|
||||||
if(!WorldGuardManager.getInstance().hasMainFlag(player))
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
Entity projectile = event.getProjectile();
|
Entity projectile = event.getProjectile();
|
||||||
|
|
||||||
//Should be noted that there are API changes regarding Arrow from 1.13.2 to current versions of the game
|
//Should be noted that there are API changes regarding Arrow from 1.13.2 to current versions of the game
|
||||||
if (!(projectile instanceof Arrow)) {
|
if (!(projectile instanceof Arrow arrow)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -133,20 +124,16 @@ public class EntityListener implements Listener {
|
|||||||
if (bow == null)
|
if (bow == null)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// determine if bow or crossbow
|
|
||||||
BowType bowType = ItemUtils.isCrossbow(bow) ? BowType.CROSSBOW : BowType.BOW;
|
|
||||||
|
|
||||||
if (bow.containsEnchantment(Enchantment.ARROW_INFINITE)) {
|
if (bow.containsEnchantment(Enchantment.ARROW_INFINITE)) {
|
||||||
projectile.setMetadata(MetadataConstants.METADATA_KEY_INF_ARROW, MetadataConstants.MCMMO_METADATA_VALUE);
|
projectile.setMetadata(MetadataConstants.METADATA_KEY_INF_ARROW, MetadataConstants.MCMMO_METADATA_VALUE);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set BowType, Force, and Distance metadata
|
// Set BowType, Force, and Distance metadata
|
||||||
projectile.setMetadata(MetadataConstants.METADATA_KEY_BOW_TYPE, new FixedMetadataValue(pluginRef, bowType));
|
|
||||||
projectile.setMetadata(MetadataConstants.METADATA_KEY_BOW_FORCE, new FixedMetadataValue(pluginRef, Math.min(event.getForce() * mcMMO.p.getAdvancedConfig().getForceMultiplier(), 1.0)));
|
projectile.setMetadata(MetadataConstants.METADATA_KEY_BOW_FORCE, new FixedMetadataValue(pluginRef, Math.min(event.getForce() * mcMMO.p.getAdvancedConfig().getForceMultiplier(), 1.0)));
|
||||||
projectile.setMetadata(MetadataConstants.METADATA_KEY_ARROW_DISTANCE, new FixedMetadataValue(pluginRef, projectile.getLocation()));
|
projectile.setMetadata(MetadataConstants.METADATA_KEY_ARROW_DISTANCE, new FixedMetadataValue(pluginRef, arrow.getLocation()));
|
||||||
|
|
||||||
//Cleanup metadata in 1 minute in case normal collection falls through
|
//Cleanup metadata in 1 minute in case normal collection falls through
|
||||||
CombatUtils.delayArrowMetaCleanup((Projectile) projectile);
|
CombatUtils.delayArrowMetaCleanup(arrow);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -168,14 +155,14 @@ public class EntityListener implements Listener {
|
|||||||
Projectile projectile = event.getEntity();
|
Projectile projectile = event.getEntity();
|
||||||
EntityType entityType = projectile.getType();
|
EntityType entityType = projectile.getType();
|
||||||
|
|
||||||
if(entityType == EntityType.ARROW || entityType == EntityType.SPECTRAL_ARROW) {
|
if(projectile instanceof Arrow arrow) {
|
||||||
CombatUtils.delayArrowMetaCleanup(projectile); //Cleans up metadata 1 minute from now in case other collection methods fall through
|
CombatUtils.delayArrowMetaCleanup(arrow); //Cleans up metadata 1 minute from now in case other collection methods fall through
|
||||||
|
|
||||||
if(!projectile.hasMetadata(MetadataConstants.METADATA_KEY_BOW_FORCE))
|
if(!projectile.hasMetadata(MetadataConstants.METADATA_KEY_BOW_FORCE))
|
||||||
projectile.setMetadata(MetadataConstants.METADATA_KEY_BOW_FORCE, new FixedMetadataValue(pluginRef, 1.0));
|
projectile.setMetadata(MetadataConstants.METADATA_KEY_BOW_FORCE, new FixedMetadataValue(pluginRef, 1.0));
|
||||||
|
|
||||||
if(!projectile.hasMetadata(MetadataConstants.METADATA_KEY_ARROW_DISTANCE))
|
if(!projectile.hasMetadata(MetadataConstants.METADATA_KEY_ARROW_DISTANCE))
|
||||||
projectile.setMetadata(MetadataConstants.METADATA_KEY_ARROW_DISTANCE, new FixedMetadataValue(pluginRef, projectile.getLocation()));
|
projectile.setMetadata(MetadataConstants.METADATA_KEY_ARROW_DISTANCE, new FixedMetadataValue(pluginRef, arrow.getLocation()));
|
||||||
|
|
||||||
//Check both hands
|
//Check both hands
|
||||||
if(ItemUtils.doesPlayerHaveEnchantmentInHands(player, "piercing")) {
|
if(ItemUtils.doesPlayerHaveEnchantmentInHands(player, "piercing")) {
|
||||||
@ -411,8 +398,8 @@ public class EntityListener implements Listener {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(entityDamageEvent.getDamager() instanceof Projectile) {
|
if(entityDamageEvent.getDamager() instanceof Arrow arrow) {
|
||||||
ProjectileUtils.cleanupProjectileMetadata((Projectile) entityDamageEvent.getDamager());
|
CombatUtils.delayArrowMetaCleanup(arrow);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(entityDamageEvent.getEntity() instanceof Player player && entityDamageEvent.getDamager() instanceof Player) {
|
if(entityDamageEvent.getEntity() instanceof Player player && entityDamageEvent.getDamager() instanceof Player) {
|
||||||
@ -1119,6 +1106,10 @@ public class EntityListener implements Listener {
|
|||||||
if (WorldBlacklist.isWorldBlacklisted(event.getEntity().getWorld()))
|
if (WorldBlacklist.isWorldBlacklisted(event.getEntity().getWorld()))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
Crossbows.processCrossbows(event, pluginRef);
|
if(event.getEntity() instanceof Arrow arrow) {
|
||||||
|
if(arrow.isShotFromCrossbow()) {
|
||||||
|
Crossbows.processCrossbows(event, pluginRef, arrow);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -13,14 +13,14 @@ import static com.gmail.nossr50.util.skills.ProjectileUtils.getNormal;
|
|||||||
* Util class for crossbows.
|
* Util class for crossbows.
|
||||||
*/
|
*/
|
||||||
public class Crossbows {
|
public class Crossbows {
|
||||||
public static void processCrossbows(ProjectileHitEvent event, Plugin pluginRef) {
|
public static void processCrossbows(ProjectileHitEvent event, Plugin pluginRef, Arrow arrow) {
|
||||||
if(event.getEntity() instanceof Arrow originalArrow && event.getHitBlock() != null && event.getHitBlockFace() != null) {
|
if(event.getHitBlock() != null && event.getHitBlockFace() != null) {
|
||||||
if (originalArrow.getShooter() instanceof Player) {
|
if (arrow.getShooter() instanceof Player) {
|
||||||
McMMOPlayer mmoPlayer = UserManager.getPlayer((Player) originalArrow.getShooter());
|
McMMOPlayer mmoPlayer = UserManager.getPlayer((Player) arrow.getShooter());
|
||||||
if (mmoPlayer != null) {
|
if (mmoPlayer != null) {
|
||||||
mmoPlayer.getCrossbowsManager().handleRicochet(
|
mmoPlayer.getCrossbowsManager().handleRicochet(
|
||||||
pluginRef,
|
pluginRef,
|
||||||
originalArrow,
|
arrow,
|
||||||
getNormal(event.getHitBlockFace()));
|
getNormal(event.getHitBlockFace()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -5,8 +5,6 @@ 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.mcMMO;
|
import com.gmail.nossr50.mcMMO;
|
||||||
import com.gmail.nossr50.skills.SkillManager;
|
import com.gmail.nossr50.skills.SkillManager;
|
||||||
import com.gmail.nossr50.skills.archery.Archery;
|
|
||||||
import com.gmail.nossr50.util.BowType;
|
|
||||||
import com.gmail.nossr50.util.MetadataConstants;
|
import com.gmail.nossr50.util.MetadataConstants;
|
||||||
import com.gmail.nossr50.util.Permissions;
|
import com.gmail.nossr50.util.Permissions;
|
||||||
import com.gmail.nossr50.util.random.ProbabilityUtil;
|
import com.gmail.nossr50.util.random.ProbabilityUtil;
|
||||||
@ -25,17 +23,20 @@ public class CrossbowsManager extends SkillManager {
|
|||||||
super(mmoPlayer, PrimarySkillType.CROSSBOWS);
|
super(mmoPlayer, PrimarySkillType.CROSSBOWS);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void handleRicochet(@NotNull Plugin pluginRef, @NotNull Arrow originalArrow, @NotNull Vector hitBlockNormal) {
|
public void handleRicochet(@NotNull Plugin pluginRef, @NotNull Arrow arrow, @NotNull Vector hitBlockNormal) {
|
||||||
|
if(!arrow.isShotFromCrossbow())
|
||||||
|
return;
|
||||||
|
|
||||||
// Check player permission
|
// Check player permission
|
||||||
if (!Permissions.trickShot(mmoPlayer.getPlayer())) {
|
if (!Permissions.trickShot(mmoPlayer.getPlayer())) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Add an event for this for plugins to hook into
|
// TODO: Add an event for this for plugins to hook into
|
||||||
spawnReflectedArrow(pluginRef, originalArrow, originalArrow.getLocation(), hitBlockNormal);
|
spawnReflectedArrow(pluginRef, arrow, arrow.getLocation(), hitBlockNormal);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void spawnReflectedArrow(@NotNull Plugin pluginRef, @NotNull Arrow originalArrow,
|
private void spawnReflectedArrow(@NotNull Plugin pluginRef, @NotNull Arrow originalArrow,
|
||||||
@NotNull Location origin, @NotNull Vector normal) {
|
@NotNull Location origin, @NotNull Vector normal) {
|
||||||
int bounceCount = 0;
|
int bounceCount = 0;
|
||||||
|
|
||||||
@ -66,8 +67,6 @@ public class CrossbowsManager extends SkillManager {
|
|||||||
new FixedMetadataValue(pluginRef, bounceCount + 1));
|
new FixedMetadataValue(pluginRef, bounceCount + 1));
|
||||||
arrow.setMetadata(MetadataConstants.METADATA_KEY_SPAWNED_ARROW,
|
arrow.setMetadata(MetadataConstants.METADATA_KEY_SPAWNED_ARROW,
|
||||||
new FixedMetadataValue(pluginRef, originalArrowShooter));
|
new FixedMetadataValue(pluginRef, originalArrowShooter));
|
||||||
arrow.setMetadata(MetadataConstants.METADATA_KEY_BOW_TYPE,
|
|
||||||
new FixedMetadataValue(pluginRef, BowType.CROSSBOW));
|
|
||||||
|
|
||||||
originalArrow.remove();
|
originalArrow.remove();
|
||||||
}
|
}
|
||||||
@ -89,7 +88,7 @@ public class CrossbowsManager extends SkillManager {
|
|||||||
|
|
||||||
public double poweredShot(double oldDamage) {
|
public double poweredShot(double oldDamage) {
|
||||||
if (ProbabilityUtil.isNonRNGSkillActivationSuccessful(SubSkillType.CROSSBOWS_POWERED_SHOT, getPlayer())) {
|
if (ProbabilityUtil.isNonRNGSkillActivationSuccessful(SubSkillType.CROSSBOWS_POWERED_SHOT, getPlayer())) {
|
||||||
return Archery.getSkillShotBonusDamage(getPlayer(), oldDamage);
|
return getPoweredShotBonusDamage(getPlayer(), oldDamage);
|
||||||
} else {
|
} else {
|
||||||
return oldDamage;
|
return oldDamage;
|
||||||
}
|
}
|
||||||
|
@ -35,6 +35,7 @@ public class ExcavationManager extends SkillManager {
|
|||||||
* @param blockState The {@link BlockState} to check ability activation for
|
* @param blockState The {@link BlockState} to check ability activation for
|
||||||
*/
|
*/
|
||||||
public void excavationBlockCheck(BlockState blockState) {
|
public void excavationBlockCheck(BlockState blockState) {
|
||||||
|
int xp = Excavation.getBlockXP(blockState);
|
||||||
requireNonNull(blockState, "excavationBlockCheck: blockState cannot be null");
|
requireNonNull(blockState, "excavationBlockCheck: blockState cannot be null");
|
||||||
if (Permissions.isSubSkillEnabled(getPlayer(), SubSkillType.EXCAVATION_ARCHAEOLOGY)) {
|
if (Permissions.isSubSkillEnabled(getPlayer(), SubSkillType.EXCAVATION_ARCHAEOLOGY)) {
|
||||||
List<ExcavationTreasure> treasures = getTreasures(blockState);
|
List<ExcavationTreasure> treasures = getTreasures(blockState);
|
||||||
@ -51,6 +52,8 @@ public class ExcavationManager extends SkillManager {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
applyXpGain(xp, XPGainReason.PVE, XPGainSource.SELF);
|
||||||
}
|
}
|
||||||
|
|
||||||
@VisibleForTesting
|
@VisibleForTesting
|
||||||
@ -61,17 +64,18 @@ public class ExcavationManager extends SkillManager {
|
|||||||
|
|
||||||
@VisibleForTesting
|
@VisibleForTesting
|
||||||
public void processExcavationBonusesOnBlock(BlockState blockState, ExcavationTreasure treasure, Location location) {
|
public void processExcavationBonusesOnBlock(BlockState blockState, ExcavationTreasure treasure, Location location) {
|
||||||
int xp = Excavation.getBlockXP(blockState);
|
|
||||||
|
|
||||||
//Spawn Vanilla XP orbs if a dice roll succeeds
|
//Spawn Vanilla XP orbs if a dice roll succeeds
|
||||||
if(ProbabilityUtil.isStaticSkillRNGSuccessful(PrimarySkillType.EXCAVATION, getPlayer(), getArchaelogyExperienceOrbChance())) {
|
if(ProbabilityUtil.isStaticSkillRNGSuccessful(PrimarySkillType.EXCAVATION, getPlayer(), getArchaelogyExperienceOrbChance())) {
|
||||||
Misc.spawnExperienceOrb(location, getExperienceOrbsReward());
|
Misc.spawnExperienceOrb(location, getExperienceOrbsReward());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int xp = 0;
|
||||||
xp += treasure.getXp();
|
xp += treasure.getXp();
|
||||||
Misc.spawnItem(getPlayer(), location, treasure.getDrop(), ItemSpawnReason.EXCAVATION_TREASURE);
|
Misc.spawnItem(getPlayer(), location, treasure.getDrop(), ItemSpawnReason.EXCAVATION_TREASURE);
|
||||||
|
if (xp > 0) {
|
||||||
applyXpGain(xp, XPGainReason.PVE, XPGainSource.SELF);
|
applyXpGain(xp, XPGainReason.PVE, XPGainSource.SELF);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public int getExperienceOrbsReward() {
|
public int getExperienceOrbsReward() {
|
||||||
return getArchaeologyRank();
|
return getArchaeologyRank();
|
||||||
|
@ -1,6 +0,0 @@
|
|||||||
package com.gmail.nossr50.util;
|
|
||||||
|
|
||||||
public enum BowType {
|
|
||||||
BOW,
|
|
||||||
CROSSBOW
|
|
||||||
}
|
|
@ -51,17 +51,6 @@ public final class ItemUtils {
|
|||||||
return isBow(item) || isCrossbow(item);
|
return isBow(item) || isCrossbow(item);
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Unit tests
|
|
||||||
public static BowType getBowType(@NotNull ItemStack item) {
|
|
||||||
if (isBow(item)) {
|
|
||||||
return BowType.BOW;
|
|
||||||
} else if (isCrossbow(item)) {
|
|
||||||
return BowType.CROSSBOW;
|
|
||||||
}
|
|
||||||
|
|
||||||
throw new IllegalArgumentException(item + " is not a bow or crossbow");
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO: Unit tests
|
// TODO: Unit tests
|
||||||
public static boolean isTrident(@NotNull ItemStack item) {
|
public static boolean isTrident(@NotNull ItemStack item) {
|
||||||
return mcMMO.getMaterialMapStore().isTrident(item.getType().getKey().getKey());
|
return mcMMO.getMaterialMapStore().isTrident(item.getType().getKey().getKey());
|
||||||
|
@ -16,7 +16,6 @@ public class MetadataConstants {
|
|||||||
public static final @NotNull String METADATA_KEY_REPLANT = "mcMMO: Recently Replanted";
|
public static final @NotNull String METADATA_KEY_REPLANT = "mcMMO: Recently Replanted";
|
||||||
public static final @NotNull String METADATA_KEY_SPAWNED_ARROW = "mcMMO: Spawned Arrow";
|
public static final @NotNull String METADATA_KEY_SPAWNED_ARROW = "mcMMO: Spawned Arrow";
|
||||||
public static final @NotNull String METADATA_KEY_BOUNCE_COUNT = "mcMMO: Arrow Bounce Count";
|
public static final @NotNull String METADATA_KEY_BOUNCE_COUNT = "mcMMO: Arrow Bounce Count";
|
||||||
public static final @NotNull String METADATA_KEY_BOW_TYPE = "mcMMO: Bow Type";
|
|
||||||
public static final @NotNull String METADATA_KEY_EXPLOSION_FROM_RUPTURE = "mcMMO: Rupture Explosion";
|
public static final @NotNull String METADATA_KEY_EXPLOSION_FROM_RUPTURE = "mcMMO: Rupture Explosion";
|
||||||
public static final @NotNull String METADATA_KEY_FISH_HOOK_REF = "mcMMO: Fish Hook Tracker";
|
public static final @NotNull String METADATA_KEY_FISH_HOOK_REF = "mcMMO: Fish Hook Tracker";
|
||||||
public static final @NotNull String METADATA_KEY_DODGE_TRACKER = "mcMMO: Dodge Tracker";
|
public static final @NotNull String METADATA_KEY_DODGE_TRACKER = "mcMMO: Dodge Tracker";
|
||||||
|
@ -52,8 +52,10 @@ public final class CombatUtils {
|
|||||||
// TODO: Unit tests
|
// TODO: Unit tests
|
||||||
public static void processProjectileSkillSuperAbilityActivation(McMMOPlayer mmoPlayer, ItemStack heldItem) {
|
public static void processProjectileSkillSuperAbilityActivation(McMMOPlayer mmoPlayer, ItemStack heldItem) {
|
||||||
if (heldItem != null && mmoPlayer != null) {
|
if (heldItem != null && mmoPlayer != null) {
|
||||||
if (ItemUtils.isBowOrCrossbow(heldItem))
|
if (ItemUtils.isBowOrCrossbow(heldItem)) {
|
||||||
mmoPlayer.checkAbilityActivationProjectiles(ItemUtils.getBowType(heldItem));
|
boolean isCrossbow = ItemUtils.isCrossbow(heldItem);
|
||||||
|
mmoPlayer.checkAbilityActivationProjectiles(isCrossbow);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -159,14 +161,14 @@ public final class CombatUtils {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private static void processCrossbowsCombat(@NotNull LivingEntity target, @NotNull Player player,
|
private static void processCrossbowsCombat(@NotNull LivingEntity target, @NotNull Player player,
|
||||||
@NotNull EntityDamageByEntityEvent event, @NotNull Projectile arrow) {
|
@NotNull EntityDamageByEntityEvent event, @NotNull Arrow arrow) {
|
||||||
double initialDamage = event.getDamage();
|
double initialDamage = event.getDamage();
|
||||||
|
|
||||||
McMMOPlayer mcMMOPlayer = UserManager.getPlayer(player);
|
McMMOPlayer mcMMOPlayer = UserManager.getPlayer(player);
|
||||||
|
|
||||||
//Make sure the profiles been loaded
|
//Make sure the profiles been loaded
|
||||||
if(mcMMOPlayer == null) {
|
if(mcMMOPlayer == null) {
|
||||||
ProjectileUtils.cleanupProjectileMetadata(arrow);
|
delayArrowMetaCleanup(arrow);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -194,7 +196,7 @@ public final class CombatUtils {
|
|||||||
"Final Damage: "+boostedDamage);
|
"Final Damage: "+boostedDamage);
|
||||||
|
|
||||||
//Clean data
|
//Clean data
|
||||||
ProjectileUtils.cleanupProjectileMetadata(arrow);
|
delayArrowMetaCleanup(arrow);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void processAxeCombat(@NotNull LivingEntity target, @NotNull Player player, @NotNull EntityDamageByEntityEvent event) {
|
private static void processAxeCombat(@NotNull LivingEntity target, @NotNull Player player, @NotNull EntityDamageByEntityEvent event) {
|
||||||
@ -324,14 +326,15 @@ public final class CombatUtils {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void processArcheryCombat(@NotNull LivingEntity target, @NotNull Player player, @NotNull EntityDamageByEntityEvent event, @NotNull Projectile arrow) {
|
private static void processArcheryCombat(@NotNull LivingEntity target, @NotNull Player player,
|
||||||
|
@NotNull EntityDamageByEntityEvent event, @NotNull Arrow arrow) {
|
||||||
double initialDamage = event.getDamage();
|
double initialDamage = event.getDamage();
|
||||||
|
|
||||||
McMMOPlayer mcMMOPlayer = UserManager.getPlayer(player);
|
McMMOPlayer mcMMOPlayer = UserManager.getPlayer(player);
|
||||||
|
|
||||||
//Make sure the profiles been loaded
|
//Make sure the profiles been loaded
|
||||||
if(mcMMOPlayer == null) {
|
if(mcMMOPlayer == null) {
|
||||||
ProjectileUtils.cleanupProjectileMetadata(arrow);
|
delayArrowMetaCleanup(arrow);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -372,7 +375,7 @@ public final class CombatUtils {
|
|||||||
"Initial Damage: "+initialDamage,
|
"Initial Damage: "+initialDamage,
|
||||||
"Final Damage: "+boostedDamage);
|
"Final Damage: "+boostedDamage);
|
||||||
//Clean data
|
//Clean data
|
||||||
ProjectileUtils.cleanupProjectileMetadata(arrow);
|
delayArrowMetaCleanup(arrow);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -489,22 +492,20 @@ public final class CombatUtils {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (entityType == EntityType.ARROW || entityType == EntityType.SPECTRAL_ARROW) {
|
else if (painSource instanceof Arrow arrow) {
|
||||||
Projectile arrow = (Projectile) painSource;
|
|
||||||
ProjectileSource projectileSource = arrow.getShooter();
|
ProjectileSource projectileSource = arrow.getShooter();
|
||||||
|
boolean isCrossbow = arrow.isShotFromCrossbow();
|
||||||
if (projectileSource instanceof Player player) {
|
if (projectileSource instanceof Player player) {
|
||||||
BowType bowType = getBowTypeFromMetadata(arrow);
|
|
||||||
|
|
||||||
if (!Misc.isNPCEntityExcludingVillagers(player)) {
|
if (!Misc.isNPCEntityExcludingVillagers(player)) {
|
||||||
if(bowType == BowType.BOW && mcMMO.p.getSkillTools().canCombatSkillsTrigger(PrimarySkillType.ARCHERY, target)) {
|
if(!isCrossbow && mcMMO.p.getSkillTools().canCombatSkillsTrigger(PrimarySkillType.ARCHERY, target)) {
|
||||||
processArcheryCombat(target, player, event, arrow);
|
processArcheryCombat(target, player, event, arrow);
|
||||||
} else if(bowType == BowType.CROSSBOW && mcMMO.p.getSkillTools().canCombatSkillsTrigger(PrimarySkillType.CROSSBOWS, target)) {
|
} else if(isCrossbow && mcMMO.p.getSkillTools().canCombatSkillsTrigger(PrimarySkillType.CROSSBOWS, target)) {
|
||||||
processCrossbowsCombat(target, player, event, arrow);
|
processCrossbowsCombat(target, player, event, arrow);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
//Cleanup Arrow
|
//Cleanup Arrow
|
||||||
ProjectileUtils.cleanupProjectileMetadata(arrow);
|
delayArrowMetaCleanup(arrow);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (target.getType() != EntityType.CREEPER
|
if (target.getType() != EntityType.CREEPER
|
||||||
@ -522,18 +523,6 @@ public final class CombatUtils {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static BowType getBowTypeFromMetadata(Projectile projectile) {
|
|
||||||
// Return the BowType from the metadata, or default to BOW
|
|
||||||
if (projectile.hasMetadata(MetadataConstants.METADATA_KEY_BOW_TYPE)) {
|
|
||||||
List<MetadataValue> metadataValue = projectile.getMetadata(MetadataConstants.METADATA_KEY_BOW_TYPE);
|
|
||||||
|
|
||||||
if (!metadataValue.isEmpty()) {
|
|
||||||
return (BowType) metadataValue.get(0).value();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
throw new IllegalStateException("BowType metadata is empty");
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This cleans up names from displaying in chat as hearts
|
* This cleans up names from displaying in chat as hearts
|
||||||
* @param entity target entity
|
* @param entity target entity
|
||||||
@ -728,7 +717,7 @@ public final class CombatUtils {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static boolean hasIgnoreDamageMetadata(@NotNull LivingEntity target) {
|
public static boolean hasIgnoreDamageMetadata(@NotNull LivingEntity target) {
|
||||||
return target.getMetadata(MetadataConstants.METADATA_KEY_CUSTOM_DAMAGE).size() != 0;
|
return target.hasMetadata(MetadataConstants.METADATA_KEY_CUSTOM_DAMAGE);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void dealNoInvulnerabilityTickDamageRupture(@NotNull LivingEntity target, double damage, Entity attacker, int toolTier) {
|
public static void dealNoInvulnerabilityTickDamageRupture(@NotNull LivingEntity target, double damage, Entity attacker, int toolTier) {
|
||||||
@ -1040,9 +1029,9 @@ public final class CombatUtils {
|
|||||||
/**
|
/**
|
||||||
* Clean up metadata from a projectile after a minute has passed
|
* Clean up metadata from a projectile after a minute has passed
|
||||||
*
|
*
|
||||||
* @param entity the projectile
|
* @param arrow the projectile
|
||||||
*/
|
*/
|
||||||
public static void delayArrowMetaCleanup(@NotNull Projectile entity) {
|
public static void delayArrowMetaCleanup(@NotNull Arrow arrow) {
|
||||||
mcMMO.p.getFoliaLib().getImpl().runLater(() -> ProjectileUtils.cleanupProjectileMetadata(entity), 20*60);
|
mcMMO.p.getFoliaLib().getImpl().runLater(() -> ProjectileUtils.cleanupProjectileMetadata(arrow), 20*120);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3,7 +3,7 @@ package com.gmail.nossr50.util.skills;
|
|||||||
import com.gmail.nossr50.mcMMO;
|
import com.gmail.nossr50.mcMMO;
|
||||||
import com.gmail.nossr50.util.MetadataConstants;
|
import com.gmail.nossr50.util.MetadataConstants;
|
||||||
import org.bukkit.block.BlockFace;
|
import org.bukkit.block.BlockFace;
|
||||||
import org.bukkit.entity.Projectile;
|
import org.bukkit.entity.Arrow;
|
||||||
import org.bukkit.util.Vector;
|
import org.bukkit.util.Vector;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
@ -23,28 +23,24 @@ public class ProjectileUtils {
|
|||||||
/**
|
/**
|
||||||
* Clean up all possible mcMMO related metadata for a projectile
|
* Clean up all possible mcMMO related metadata for a projectile
|
||||||
*
|
*
|
||||||
* @param entity projectile
|
* @param arrow projectile
|
||||||
*/
|
*/
|
||||||
// TODO: Add test
|
// TODO: Add test
|
||||||
public static void cleanupProjectileMetadata(@NotNull Projectile entity) {
|
public static void cleanupProjectileMetadata(@NotNull Arrow arrow) {
|
||||||
if(entity.hasMetadata(MetadataConstants.METADATA_KEY_INF_ARROW)) {
|
if(arrow.hasMetadata(MetadataConstants.METADATA_KEY_INF_ARROW)) {
|
||||||
entity.removeMetadata(MetadataConstants.METADATA_KEY_INF_ARROW, mcMMO.p);
|
arrow.removeMetadata(MetadataConstants.METADATA_KEY_INF_ARROW, mcMMO.p);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(entity.hasMetadata(MetadataConstants.METADATA_KEY_BOW_FORCE)) {
|
if(arrow.hasMetadata(MetadataConstants.METADATA_KEY_BOW_FORCE)) {
|
||||||
entity.removeMetadata(MetadataConstants.METADATA_KEY_BOW_FORCE, mcMMO.p);
|
arrow.removeMetadata(MetadataConstants.METADATA_KEY_BOW_FORCE, mcMMO.p);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(entity.hasMetadata(MetadataConstants.METADATA_KEY_ARROW_DISTANCE)) {
|
if(arrow.hasMetadata(MetadataConstants.METADATA_KEY_ARROW_DISTANCE)) {
|
||||||
entity.removeMetadata(MetadataConstants.METADATA_KEY_ARROW_DISTANCE, mcMMO.p);
|
arrow.removeMetadata(MetadataConstants.METADATA_KEY_ARROW_DISTANCE, mcMMO.p);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(entity.hasMetadata(MetadataConstants.METADATA_KEY_BOW_TYPE)) {
|
if(arrow.hasMetadata(MetadataConstants.METADATA_KEY_SPAWNED_ARROW)) {
|
||||||
entity.removeMetadata(MetadataConstants.METADATA_KEY_BOW_TYPE, mcMMO.p);
|
arrow.removeMetadata(MetadataConstants.METADATA_KEY_SPAWNED_ARROW, mcMMO.p);
|
||||||
}
|
|
||||||
|
|
||||||
if(entity.hasMetadata(MetadataConstants.METADATA_KEY_SPAWNED_ARROW)) {
|
|
||||||
entity.removeMetadata(MetadataConstants.METADATA_KEY_SPAWNED_ARROW, mcMMO.p);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -859,6 +859,8 @@ permissions:
|
|||||||
mcmmo.commands.alchemy: true
|
mcmmo.commands.alchemy: true
|
||||||
mcmmo.commands.archery: true
|
mcmmo.commands.archery: true
|
||||||
mcmmo.commands.axes: true
|
mcmmo.commands.axes: true
|
||||||
|
mcmmo.commands.crossbows: true
|
||||||
|
mcmmo.commands.tridents: true
|
||||||
mcmmo.commands.excavation: true
|
mcmmo.commands.excavation: true
|
||||||
mcmmo.commands.fishing: true
|
mcmmo.commands.fishing: true
|
||||||
mcmmo.commands.herbalism: true
|
mcmmo.commands.herbalism: true
|
||||||
@ -2212,6 +2214,8 @@ permissions:
|
|||||||
mcmmo.skills.taming: true
|
mcmmo.skills.taming: true
|
||||||
mcmmo.skills.unarmed: true
|
mcmmo.skills.unarmed: true
|
||||||
mcmmo.skills.woodcutting: true
|
mcmmo.skills.woodcutting: true
|
||||||
|
mcmmo.skills.crossbows: true
|
||||||
|
mcmmo.skills.tridents: true
|
||||||
mcmmo.skills.acrobatics:
|
mcmmo.skills.acrobatics:
|
||||||
description: Allows access to the Acrobatics skill
|
description: Allows access to the Acrobatics skill
|
||||||
children:
|
children:
|
||||||
|
Loading…
Reference in New Issue
Block a user