diff --git a/Changelog.txt b/Changelog.txt index 8e809c0de..9f79298c1 100644 --- a/Changelog.txt +++ b/Changelog.txt @@ -1,4 +1,7 @@ Version 2.2.000 + TODO: Add unit test to determine crossbow or bow skill + TODO: Add unit test for trident xp processing + TODO: Add missing entries to changelog (API) Many skills with RNG elements now send out a SubSkillEvent (which can be used to modify probability or cancel the results), some skills without RNG still send out this event when activated, this event is cancellable so it can be used to make a skill fail Treasure drop rate from Shake, Fishing, Hylian, and Excavation now benefit from the Luck perk Added 'Send_To_Console' settings to chat.yml to toggle sending party or admin chat messages to console diff --git a/src/main/java/com/gmail/nossr50/datatypes/player/McMMOPlayer.java b/src/main/java/com/gmail/nossr50/datatypes/player/McMMOPlayer.java index bba7cea29..a0c957892 100644 --- a/src/main/java/com/gmail/nossr50/datatypes/player/McMMOPlayer.java +++ b/src/main/java/com/gmail/nossr50/datatypes/player/McMMOPlayer.java @@ -233,15 +233,6 @@ public class McMMOPlayer implements Identified { return attackStrength; } -// public void setAttackStrength(double attackStrength) { -// this.attackStrength = attackStrength; -// } - - /*public void hideXpBar(PrimarySkillType primarySkillType) - { - experienceBarManager.hideExperienceBar(primarySkillType); - }*/ - public @NotNull PrimarySkillType getLastSkillShownScoreboard() { return lastSkillShownScoreboard; } @@ -314,6 +305,13 @@ public class McMMOPlayer implements Identified { public AxesManager getAxesManager() { return (AxesManager) skillManagers.get(PrimarySkillType.AXES); } + public CrossbowsManager getCrossbowsManager() { + return (CrossbowsManager) skillManagers.get(PrimarySkillType.CROSSBOWS); + } + + public TridentsManager getTridentsManager() { + return (TridentsManager) skillManagers.get(PrimarySkillType.TRIDENTS); + } public ExcavationManager getExcavationManager() { return (ExcavationManager) skillManagers.get(PrimarySkillType.EXCAVATION); 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 ead0326ca..433d9f2b9 100644 --- a/src/main/java/com/gmail/nossr50/datatypes/skills/SubSkillType.java +++ b/src/main/java/com/gmail/nossr50/datatypes/skills/SubSkillType.java @@ -33,6 +33,7 @@ public enum SubSkillType { /* CROSSBOWS */ CROSSBOWS_SUPER_SHOTGUN(1), + CROSSBOWS_CROSSBOWS_LIMIT_BREAK(10), /* Excavation */ EXCAVATION_ARCHAEOLOGY(8), @@ -98,6 +99,7 @@ public enum SubSkillType { /* Tridents */ TRIDENTS_TRIDENTS_SUPER_ABILITY(1), + TRIDENTS_TRIDENTS_LIMIT_BREAK(10), /* Unarmed */ UNARMED_ARROW_DEFLECT(1), diff --git a/src/main/java/com/gmail/nossr50/listeners/EntityListener.java b/src/main/java/com/gmail/nossr50/listeners/EntityListener.java index fc9f686be..2bcfc65a1 100644 --- a/src/main/java/com/gmail/nossr50/listeners/EntityListener.java +++ b/src/main/java/com/gmail/nossr50/listeners/EntityListener.java @@ -65,30 +65,6 @@ public class EntityListener implements Listener { mobMetadataService = mcMMO.getMetadataService().getMobMetadataService(); } -// @EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true) -// public void onBlockDropItemEvent(EntityDropItemEvent event) { -// if(event.getEntity() instanceof Block) { -// Block itemDispensingBlock = (Block) event.getEntity(); -// -// //Is it a berry bush? -// if(itemDispensingBlock.getType().toString().equalsIgnoreCase("sweet_berry_bush")) { -// //Berry Bush Time! -// if (event.getEntity().getMetadata(mcMMO.BONUS_DROPS_METAKEY).size() > 0) { -// Bukkit.broadcastMessage("Pop pop!"); -// BonusDropMeta bonusDropMeta = (BonusDropMeta) event.getEntity().getMetadata(mcMMO.BONUS_DROPS_METAKEY).get(0); -// int bonusCount = bonusDropMeta.asInt(); -// -// for (int i = 0; i < bonusCount; i++) { -// Misc.spawnItemNaturally(event.getEntity().getLocation(), event.getItemDrop().getItemStack(), ItemSpawnReason.BONUS_DROPS); -// } -// } -// } -// -// if(event.getEntity().hasMetadata(mcMMO.BONUS_DROPS_METAKEY)) -// event.getEntity().removeMetadata(mcMMO.BONUS_DROPS_METAKEY, pluginRef); -// } -// } - @EventHandler(priority = EventPriority.MONITOR) public void onEntityTransform(EntityTransformEvent event) { if(event.getEntity() instanceof LivingEntity livingEntity) { diff --git a/src/main/java/com/gmail/nossr50/skills/archery/ArcheryManager.java b/src/main/java/com/gmail/nossr50/skills/archery/ArcheryManager.java index fc8a8be28..b46317067 100644 --- a/src/main/java/com/gmail/nossr50/skills/archery/ArcheryManager.java +++ b/src/main/java/com/gmail/nossr50/skills/archery/ArcheryManager.java @@ -52,7 +52,7 @@ public class ArcheryManager extends SkillManager { * @param target The {@link LivingEntity} damaged by the arrow * @param arrow The {@link Entity} who shot the arrow */ - public double distanceXpBonusMultiplier(LivingEntity target, Entity arrow) { + public static double distanceXpBonusMultiplier(LivingEntity target, Entity arrow) { //Hacky Fix - some plugins spawn arrows and assign them to players after the ProjectileLaunchEvent fires if(!arrow.hasMetadata(MetadataConstants.METADATA_KEY_ARROW_DISTANCE)) return 1; diff --git a/src/main/java/com/gmail/nossr50/skills/tridents/TridentsManager.java b/src/main/java/com/gmail/nossr50/skills/tridents/TridentsManager.java index 5b52d9463..22ae802cb 100644 --- a/src/main/java/com/gmail/nossr50/skills/tridents/TridentsManager.java +++ b/src/main/java/com/gmail/nossr50/skills/tridents/TridentsManager.java @@ -2,10 +2,20 @@ package com.gmail.nossr50.skills.tridents; import com.gmail.nossr50.datatypes.player.McMMOPlayer; import com.gmail.nossr50.datatypes.skills.PrimarySkillType; +import com.gmail.nossr50.datatypes.skills.ToolType; import com.gmail.nossr50.skills.SkillManager; +import com.gmail.nossr50.util.Permissions; public class TridentsManager extends SkillManager { public TridentsManager(McMMOPlayer mmoPlayer) { super(mmoPlayer, PrimarySkillType.TRIDENTS); } + + /** + * Checks if the player can activate the Super Ability for Tridents + * @return true if the player can activate the Super Ability, false otherwise + */ + public boolean canActivateAbility() { + return mmoPlayer.getToolPreparationMode(ToolType.TRIDENTS) && Permissions.tridentsSuper(getPlayer()); + } } diff --git a/src/main/java/com/gmail/nossr50/util/skills/CombatUtils.java b/src/main/java/com/gmail/nossr50/util/skills/CombatUtils.java index ac9cc6388..1427be479 100644 --- a/src/main/java/com/gmail/nossr50/util/skills/CombatUtils.java +++ b/src/main/java/com/gmail/nossr50/util/skills/CombatUtils.java @@ -17,8 +17,10 @@ import com.gmail.nossr50.runnables.skills.AwardCombatXpTask; import com.gmail.nossr50.skills.acrobatics.AcrobaticsManager; import com.gmail.nossr50.skills.archery.ArcheryManager; import com.gmail.nossr50.skills.axes.AxesManager; +import com.gmail.nossr50.skills.crossbows.CrossbowsManager; import com.gmail.nossr50.skills.swords.SwordsManager; import com.gmail.nossr50.skills.taming.TamingManager; +import com.gmail.nossr50.skills.tridents.TridentsManager; import com.gmail.nossr50.skills.unarmed.UnarmedManager; import com.gmail.nossr50.util.*; import com.gmail.nossr50.util.player.NotificationManager; @@ -116,6 +118,75 @@ public final class CombatUtils { } } } + private static void processTridentCombat(@NotNull LivingEntity target, @NotNull Player player, @NotNull EntityDamageByEntityEvent event) { + if (event.getCause() == DamageCause.THORNS) { + return; + } + + double boostedDamage = event.getDamage(); + + McMMOPlayer mcMMOPlayer = UserManager.getPlayer(player); + + //Make sure the profiles been loaded + if(mcMMOPlayer == null) { + return; + } + + TridentsManager tridentsManager = mcMMOPlayer.getTridentsManager(); + + if (tridentsManager.canActivateAbility()) { + mcMMOPlayer.checkAbilityActivation(PrimarySkillType.TRIDENTS); + } + + if(canUseLimitBreak(player, target, SubSkillType.TRIDENTS_TRIDENTS_LIMIT_BREAK)) + { + boostedDamage+=(getLimitBreakDamage(player, target, SubSkillType.TRIDENTS_TRIDENTS_LIMIT_BREAK) * mcMMOPlayer.getAttackStrength()); + } + + event.setDamage(boostedDamage); + processCombatXP(mcMMOPlayer, target, PrimarySkillType.TRIDENTS); + + printFinalDamageDebug(player, event, mcMMOPlayer); + } + + private static void processCrossbowsCombat(@NotNull LivingEntity target, @NotNull Player player, @NotNull EntityDamageByEntityEvent event, @NotNull Projectile arrow) { + double initialDamage = event.getDamage(); + + McMMOPlayer mcMMOPlayer = UserManager.getPlayer(player); + + //Make sure the profiles been loaded + if(mcMMOPlayer == null) { + cleanupArrowMetadata(arrow); + return; + } + + // CrossbowsManager crossbowsManager = mcMMOPlayer.getCrossbowsManager(); + +// if (crossbowsManager.canActivateAbility()) { +// mcMMOPlayer.checkAbilityActivation(PrimarySkillType.CROSSBOWS); +// } + + double boostedDamage = event.getDamage(); + + if(canUseLimitBreak(player, target, SubSkillType.CROSSBOWS_CROSSBOWS_LIMIT_BREAK)) { + boostedDamage+=getLimitBreakDamage(player, target, SubSkillType.CROSSBOWS_CROSSBOWS_LIMIT_BREAK); + } + + double distanceMultiplier = ArcheryManager.distanceXpBonusMultiplier(target, arrow); + double forceMultiplier = 1.0; + + event.setDamage(boostedDamage); + processCombatXP(mcMMOPlayer, target, PrimarySkillType.CROSSBOWS, forceMultiplier * distanceMultiplier); + + printFinalDamageDebug(player, event, mcMMOPlayer, + "Distance Multiplier: "+distanceMultiplier, + "Force Multiplier: "+forceMultiplier, + "Initial Damage: "+initialDamage, + "Final Damage: "+boostedDamage); + + //Clean data + cleanupArrowMetadata(arrow); + } private static void processAxeCombat(@NotNull LivingEntity target, @NotNull Player player, @NotNull EntityDamageByEntityEvent event) { if (event.getCause() == DamageCause.THORNS) { @@ -277,7 +348,7 @@ public final class CombatUtils { boostedDamage+=getLimitBreakDamage(player, target, SubSkillType.ARCHERY_ARCHERY_LIMIT_BREAK); } - double distanceMultiplier = archeryManager.distanceXpBonusMultiplier(target, arrow); + double distanceMultiplier = ArcheryManager.distanceXpBonusMultiplier(target, arrow); double forceMultiplier = 1.0; //Hacky Fix - some plugins spawn arrows and assign them to players after the ProjectileLaunchEvent fires if(arrow.hasMetadata(MetadataConstants.METADATA_KEY_BOW_FORCE)) @@ -387,6 +458,15 @@ public final class CombatUtils { processUnarmedCombat(target, player, event); } } + else if (ItemUtils.isTrident(heldItem)) { + if (!mcMMO.p.getSkillTools().canCombatSkillsTrigger(PrimarySkillType.TRIDENTS, target)) { + return; + } + + if (mcMMO.p.getSkillTools().doesPlayerHaveSkillPermission(player, PrimarySkillType.TRIDENTS)) { + processTridentCombat(target, player, event); + } + } } else if (entityType == EntityType.WOLF) { @@ -405,6 +485,7 @@ public final class CombatUtils { ProjectileSource projectileSource = arrow.getShooter(); if (projectileSource instanceof Player player && mcMMO.p.getSkillTools().canCombatSkillsTrigger(PrimarySkillType.ARCHERY, target)) { + // TODO: Add metadata to projectiles to determine source weapon to process combat skills if (!Misc.isNPCEntityExcludingVillagers(player) && mcMMO.p.getSkillTools().doesPlayerHaveSkillPermission(player, PrimarySkillType.ARCHERY)) { processArcheryCombat(target, player, event, arrow); diff --git a/src/main/resources/locale/locale_en_US.properties b/src/main/resources/locale/locale_en_US.properties index d00b2cbdc..ac1f969c7 100644 --- a/src/main/resources/locale/locale_en_US.properties +++ b/src/main/resources/locale/locale_en_US.properties @@ -407,7 +407,7 @@ Salvage.Skills.Adept.Level=You must be level &e{0}&c to salvage &e{1} Salvage.Skills.TooDamaged=&4This item is too damaged to be salvaged. Salvage.Skills.ArcaneFailed=&cYou were unable to extract the knowledge contained within this item. Salvage.Skills.ArcanePartial=&cYou were only able to extract some of the knowledge contained within this item. -Salvage.Skills.ArcaneSuccess=&aYou able to extract all of the knowledge contained within this item! +Salvage.Skills.ArcaneSuccess=&aYou were able to extract all the knowledge contained within this item! Salvage.Listener.Anvil=&4You have placed a Salvage anvil, use this to Salvage tools and armor. Salvage.Listener=Salvage: Salvage.SkillName=SALVAGE @@ -423,7 +423,13 @@ Crossbows.Ability.Ready=&3You &6ready&3 your Crossbow. Crossbows.Skills.SSG.Refresh=&aYour &eSuper Shotgun &aability is refreshed! Crossbows.Skills.SSG.Other.On=&a{0}&2 used &Super Shotgun! Crossbows.SubSkill.SuperShotgun.Name=Super Shotgun +Crossbows.SubSkill.SuperShotgun.Description=Shoot dozens of arrows at once +Crossbows.SubSkill.SuperShotgun.Stat=Per Projectile damage {0} +Crossbows.SubSkill.CrossbowsLimitBreak.Name=Crossbows Limit Break +Crossbows.SubSkill.CrossbowsLimitBreak.Description=Breaking your limits. Increased damage against tough opponents. Intended for PVP, up to server settings for whether it will boost damage in PVE. +Crossbows.SubSkill.CrossbowsLimitBreak.Stat=Limit Break Max DMG Crossbows.Listener=Crossbows: + #TRIDENTS Tridents.SkillName=TRIDENTS Tridents.Ability.Lower=&7You lower your trident. @@ -431,6 +437,11 @@ Tridents.Ability.Ready=&3You &6ready&3 your Trident. Tridents.Skills.TA.Refresh=&aYour &eSuper &aability is refreshed! Tridents.Skills.TA.Other.On=&a{0}&2 used Trident &Super! Tridents.SubSkill.SuperAbility.Name=Tridents Super Ability +Tridents.SubSkill.SuperAbility.Description=N/A +Tridents.SubSkill.SuperAbility.Stat=N/A +Tridents.SubSkill.TridentsLimitBreak.Name=Tridents Limit Break +Tridents.SubSkill.TridentsLimitBreak.Description=Breaking your limits. Increased damage against tough opponents. Intended for PVP, up to server settings for whether it will boost damage in PVE. +Tridents.SubSkill.TridentsLimitBreak.Stat=Limit Break Max DMG Tridents.Listener=Tridents: #SWORDS diff --git a/src/main/resources/plugin.yml b/src/main/resources/plugin.yml index eccc5a451..62ec6c032 100644 --- a/src/main/resources/plugin.yml +++ b/src/main/resources/plugin.yml @@ -335,8 +335,11 @@ permissions: description: Allows access to all Crossbows abilities children: mcmmo.ability.crossbows.supershotgun: true + mcmmo.ability.crossbows.crossbowslimitbreak: true mcmmo.ability.crossbows.supershotgun: description: Allows access to the Super Shotgun ability + mcmmo.ability.crossbows.crossbowslimitbreak: + description: Adds damage to crossbows mcmmo.ability.excavation.*: default: false description: Allows access to all Excavation abilities @@ -710,8 +713,11 @@ permissions: description: Allows access to all Trident abilities children: mcmmo.ability.tridents.superability: true + mcmmo.ability.tridents.tridentslimitbreak: true mcmmo.ability.tridents.superability: description: Allows access to tridents super ability + mcmmo.ability.tridents.tridentslimitbreak: + description: Adds damage to tridents mcmmo.ability.unarmed.*: default: false description: Allows access to all Unarmed abilities diff --git a/src/main/resources/skillranks.yml b/src/main/resources/skillranks.yml index 455403a12..ae71e5074 100644 --- a/src/main/resources/skillranks.yml +++ b/src/main/resources/skillranks.yml @@ -202,12 +202,58 @@ Axes: Rank_3: 150 Rank_4: 200 Crossbows: + CrossbowsLimitBreak: + Standard: + Rank_1: 10 + Rank_2: 20 + Rank_3: 30 + Rank_4: 40 + Rank_5: 50 + Rank_6: 60 + Rank_7: 70 + Rank_8: 80 + Rank_9: 90 + Rank_10: 100 + RetroMode: + Rank_1: 100 + Rank_2: 200 + Rank_3: 300 + Rank_4: 400 + Rank_5: 500 + Rank_6: 600 + Rank_7: 700 + Rank_8: 800 + Rank_9: 900 + Rank_10: 1000 SuperShotgun: Standard: Rank_1: 5 RetroMode: Rank_1: 50 Tridents: + TridentsLimitBreak: + Standard: + Rank_1: 10 + Rank_2: 20 + Rank_3: 30 + Rank_4: 40 + Rank_5: 50 + Rank_6: 60 + Rank_7: 70 + Rank_8: 80 + Rank_9: 90 + Rank_10: 100 + RetroMode: + Rank_1: 100 + Rank_2: 200 + Rank_3: 300 + Rank_4: 400 + Rank_5: 500 + Rank_6: 600 + Rank_7: 700 + Rank_8: 800 + Rank_9: 900 + Rank_10: 1000 TridentsSuperAbility: Standard: Rank_1: 5