diff --git a/src/main/java/com/gmail/nossr50/datatypes/skills/SubSkillType.java b/src/main/java/com/gmail/nossr50/datatypes/skills/SubSkillType.java index 767745a16..289e6f8a1 100644 --- a/src/main/java/com/gmail/nossr50/datatypes/skills/SubSkillType.java +++ b/src/main/java/com/gmail/nossr50/datatypes/skills/SubSkillType.java @@ -113,7 +113,7 @@ public enum SubSkillType { /* CROSSBOWS */ - CROSSBOWS_CONE_OF_DEATH(8), + CROSSBOWS_CONE_OF_DEATH(3), CROSSBOWS_CROSSBOWS_LIMIT_BREAK(10); diff --git a/src/main/java/com/gmail/nossr50/listeners/EntityListener.java b/src/main/java/com/gmail/nossr50/listeners/EntityListener.java index 242e29948..68b9cadca 100644 --- a/src/main/java/com/gmail/nossr50/listeners/EntityListener.java +++ b/src/main/java/com/gmail/nossr50/listeners/EntityListener.java @@ -125,12 +125,18 @@ public class EntityListener implements Listener { projectile.setMetadata(mcMMO.arrowDistanceKey, new FixedMetadataValue(plugin, projectile.getLocation())); } - @EventHandler(ignoreCancelled = true, priority = EventPriority.MONITOR) + @EventHandler(ignoreCancelled = true, priority = EventPriority.LOWEST) public void onProjectileLaunch(ProjectileLaunchEvent event) { /* WORLD BLACKLIST CHECK */ if(WorldBlacklist.isWorldBlacklisted(event.getEntity().getWorld())) return; + if(mcMMO.getSpawnedProjectileTracker().isSpawnedProjectile(event.getEntity())) { + mcMMO.getSpawnedProjectileTracker().untrackProjectile(event.getEntity()); + return; + } + + if(event.getEntity().getShooter() instanceof Player) { Player player = (Player) event.getEntity().getShooter(); diff --git a/src/main/java/com/gmail/nossr50/mcMMO.java b/src/main/java/com/gmail/nossr50/mcMMO.java index 4741b8651..2ac7bf8cf 100644 --- a/src/main/java/com/gmail/nossr50/mcMMO.java +++ b/src/main/java/com/gmail/nossr50/mcMMO.java @@ -80,6 +80,7 @@ public class mcMMO extends JavaPlugin { private static MaterialMapStore materialMapStore; private static PlayerLevelUtils playerLevelUtils; private static SmeltingTracker smeltingTracker; + private static SpawnedProjectileTracker spawnedProjectileTracker; /* Blacklist */ private static WorldBlacklist worldBlacklist; @@ -271,6 +272,9 @@ public class mcMMO extends JavaPlugin { //Init smelting tracker smeltingTracker = new SmeltingTracker(); + + //Init spawned projectile tracker + spawnedProjectileTracker = new SpawnedProjectileTracker(); } public static PlayerLevelUtils getPlayerLevelUtils() { @@ -679,4 +683,8 @@ public class mcMMO extends JavaPlugin { public static SmeltingTracker getSmeltingTracker() { return smeltingTracker; } + + public static SpawnedProjectileTracker getSpawnedProjectileTracker() { + return spawnedProjectileTracker; + } } diff --git a/src/main/java/com/gmail/nossr50/skills/crossbows/CrossbowManager.java b/src/main/java/com/gmail/nossr50/skills/crossbows/CrossbowManager.java index 7600ee3a5..114515831 100644 --- a/src/main/java/com/gmail/nossr50/skills/crossbows/CrossbowManager.java +++ b/src/main/java/com/gmail/nossr50/skills/crossbows/CrossbowManager.java @@ -7,6 +7,8 @@ import com.gmail.nossr50.mcMMO; import com.gmail.nossr50.skills.SkillManager; import com.gmail.nossr50.skills.archery.Archery; import com.gmail.nossr50.util.Permissions; +import com.gmail.nossr50.util.skills.RankUtils; +import org.apache.commons.lang.math.RandomUtils; import org.bukkit.Bukkit; import org.bukkit.Location; import org.bukkit.World; @@ -14,11 +16,17 @@ import org.bukkit.entity.Entity; import org.bukkit.entity.LivingEntity; import org.bukkit.entity.Projectile; import org.bukkit.event.entity.ProjectileLaunchEvent; +import org.bukkit.util.Vector; +import org.jetbrains.annotations.NotNull; + +import java.util.ArrayList; +import java.util.Random; public class CrossbowManager extends SkillManager { public CrossbowManager(McMMOPlayer mcMMOPlayer) { super(mcMMOPlayer, PrimarySkillType.CROSSBOWS); } + private static final int SPREAD_VALUE = 12; /** * Calculate bonus XP awarded for Archery when hitting a far-away target. @@ -57,10 +65,47 @@ public class CrossbowManager extends SkillManager { private void coneOfDeathProcessing(ProjectileLaunchEvent projectileLaunchEvent) { - Projectile mainProjectile = projectileLaunchEvent.getEntity(); - World world = mainProjectile.getWorld(); + spawnConeArrows(projectileLaunchEvent.getEntity()); + } + private void spawnConeArrows(@NotNull Projectile originProjectile) { + World world = originProjectile.getWorld(); + Vector originVector = originProjectile.getVelocity().clone(); + float originProjectileMagnitude = (float) originVector.length(); + + Vector originUnitVector = originVector.clone().normalize(); + + for(int i = 0; i < getConeOfDeathProjectileCount(); i++) { + Vector newProjectileVector = byRotateVector(originUnitVector, 0); + spawnTrackedProjectile(originProjectile, world, originProjectileMagnitude, newProjectileVector, getRandomizedSpreadValue()); + } + } + + private int getConeOfDeathProjectileCount() { + switch(RankUtils.getRank(mcMMOPlayer.getPlayer(), SubSkillType.CROSSBOWS_CONE_OF_DEATH)) { + case 1: + return 9; + case 2: + return 18; + default: + return 27; + } + } + + private int getRandomizedSpreadValue() { + return SPREAD_VALUE + 12 + RandomUtils.nextInt(24); + } + + private void spawnTrackedProjectile(@NotNull Projectile originProjectile, World world, float originProjectileMagnitude, Vector additionalProjectileVectorA, int spreadValue) { + Projectile spawnedProjectile = world.spawnArrow(originProjectile.getLocation(), additionalProjectileVectorA, originProjectileMagnitude, spreadValue); + spawnedProjectile.setShooter(mcMMOPlayer.getPlayer()); + mcMMO.getSpawnedProjectileTracker().trackProjectile(spawnedProjectile); + } + + @NotNull + private Vector byRotateVector(Vector originUnitVector, double angle) { + return originUnitVector.clone().rotateAroundAxis(originUnitVector, angle); } diff --git a/src/main/java/com/gmail/nossr50/util/ItemUtils.java b/src/main/java/com/gmail/nossr50/util/ItemUtils.java index 733986548..9a476462c 100644 --- a/src/main/java/com/gmail/nossr50/util/ItemUtils.java +++ b/src/main/java/com/gmail/nossr50/util/ItemUtils.java @@ -62,22 +62,22 @@ public final class ItemUtils { return mcMMO.getMaterialMapStore().isTrident(itemStack.getType().getKey().getKey()); } - public static void registerTridentRecipes() { - Material tridentMaterial = Material.getMaterial("trident"); - if(tridentMaterial != null) { - ItemStack weakTridentIS = new ItemStack(tridentMaterial); - NamespacedKey weakTridentNamespacedKey = new NamespacedKey(mcMMO.p, "mcmmo:weak_trident"); - - ShapedRecipe weakTridentRecipe = new ShapedRecipe(weakTridentNamespacedKey, weakTridentIS); - - weakTridentRecipe. - Bukkit.addRecipe(weakTridentRecipe); - } - if(Material.getMaterial("trident") == null) { - return; - } - - } +// public static void registerTridentRecipes() { +//// Material tridentMaterial = Material.getMaterial("trident"); +//// if(tridentMaterial != null) { +//// ItemStack weakTridentIS = new ItemStack(tridentMaterial); +//// NamespacedKey weakTridentNamespacedKey = new NamespacedKey(mcMMO.p, "mcmmo:weak_trident"); +//// +//// ShapedRecipe weakTridentRecipe = new ShapedRecipe(weakTridentNamespacedKey, weakTridentIS); +//// +//// weakTridentRecipe. +//// Bukkit.addRecipe(weakTridentRecipe); +//// } +//// if(Material.getMaterial("trident") == null) { +//// return; +//// } +// +// } diff --git a/src/main/java/com/gmail/nossr50/util/SpawnedProjectileTracker.java b/src/main/java/com/gmail/nossr50/util/SpawnedProjectileTracker.java new file mode 100644 index 000000000..0bad0d410 --- /dev/null +++ b/src/main/java/com/gmail/nossr50/util/SpawnedProjectileTracker.java @@ -0,0 +1,26 @@ +package com.gmail.nossr50.util; + +import org.bukkit.entity.Projectile; + +import java.util.HashSet; +import java.util.Set; + +public class SpawnedProjectileTracker { + private final Set trackedProjectiles; + + public SpawnedProjectileTracker() { + trackedProjectiles = new HashSet<>(); + } + + public void trackProjectile(Projectile projectile) { + trackedProjectiles.add(projectile); + } + + public void untrackProjectile(Projectile projectile) { + trackedProjectiles.remove(projectile); + } + + public boolean isSpawnedProjectile(Projectile projectile) { + return trackedProjectiles.contains(projectile); + } +} diff --git a/src/main/resources/skillranks.yml b/src/main/resources/skillranks.yml index 0a01728cb..6837c5720 100644 --- a/src/main/resources/skillranks.yml +++ b/src/main/resources/skillranks.yml @@ -732,20 +732,10 @@ Crossbows: Rank_10: 1000 ConeOfDeath: Standard: - Rank_1: 10 - Rank_2: 25 - Rank_3: 35 - Rank_4: 50 - Rank_5: 65 - Rank_6: 75 - Rank_7: 85 - Rank_8: 100 + Rank_1: 1 + Rank_2: 50 + Rank_3: 100 RetroMode: - Rank_1: 100 - Rank_2: 250 - Rank_3: 350 - Rank_4: 500 - Rank_5: 650 - Rank_6: 750 - Rank_7: 850 - Rank_8: 1000 \ No newline at end of file + Rank_1: 10 + Rank_2: 500 + Rank_3: 1000 \ No newline at end of file