From d63122734eeedd1b0b79d8d52c53a08f0819fc4b Mon Sep 17 00:00:00 2001 From: Charles445 Date: Sat, 27 Nov 2021 13:53:04 -0600 Subject: [PATCH] Pet Fixes, Offhand Fix, Detonation, Mod Compat, Swiper Nerf, Additional Protection Toggle Transformer introduced (unfortunately) to fix a lot of issues Compatibility for fishing mods in Advnced Lure and Advanced Luck of the Sea Compatibility for looting in mods Fix for offhand enchantments causing bugs Option to prevent pets from using weapon enchantments Fix for Adept adding experience to drops that normally give none Swiper swipe no longer bypasses armor Swiper swipe reduced range Option to turn off extra protection effects Bump gradle, transformer gradle --- build.gradle | 10 +- .../EnchantmentAdvancedBaneOfArthropods.java | 2 +- .../EnchantmentAdvancedEfficiency.java | 3 +- .../Ench0_1_0/EnchantmentAdvancedSmite.java | 2 +- .../Rin/Ench0_1_0/EnchantmentBlessedEdge.java | 3 + .../Rin/Ench0_1_0/EnchantmentButchering.java | 3 + .../Rin/Ench0_1_0/EnchantmentCursedEdge.java | 3 + .../Rin/Ench0_1_0/EnchantmentDefusion.java | 3 + .../Rin/Ench0_1_0/EnchantmentFieryEdge.java | 2 +- .../Ench0_1_0/EnchantmentPurification.java | 5 +- .../Ench0_1_0/EnchantmentReviledBlade.java | 3 + .../EnchantmentRune_PiercingCapabilities.java | 3 + .../Rin/Ench0_1_0/EnchantmentRusted.java | 4 +- .../Ench0_1_0/EnchantmentSpellBreaker.java | 3 + .../Ench0_1_0/EnchantmentSwifterSlashes.java | 3 + .../Rin/Ench0_1_0/EnchantmentWaterAspect.java | 2 + .../EnchantmentAdvancedKnockback.java | 3 +- .../Rin/Ench0_2_0/EnchantmentCulling.java | 3 + .../Rin/Ench0_2_0/EnchantmentLifesteal.java | 5 +- .../Rin/Ench0_2_0/EnchantmentMortalitas.java | 3 + .../Ench0_2_0/EnchantmentPenetratingEdge.java | 3 + .../EnchantmentRune_MagicalBlessing.java | 3 + .../Ench0_2_0/EnchantmentUnpredictable.java | 3 + .../EnchantmentAdvancedBlastProtection.java | 375 ++++---- .../Ench0_3_0/EnchantmentAdvancedLooting.java | 26 +- .../EnchantmentAdvancedLuckOfTheSea.java | 25 +- .../Ench0_3_0/EnchantmentAdvancedLure.java | 20 +- .../Ench0_3_0/EnchantmentAshDestroyer.java | 3 + .../Rin/Ench0_3_0/EnchantmentClearsky.java | 2 + .../Rin/Ench0_3_0/EnchantmentDesolator.java | 3 + .../Ench0_3_0/EnchantmentDisorientation.java | 3 +- .../Rin/Ench0_3_0/EnchantmentEnvenomed.java | 2 +- .../Rin/Ench0_3_0/EnchantmentLevitator.java | 2 +- .../Rin/Ench0_3_0/EnchantmentMoonlight.java | 7 +- .../Ench0_3_0/EnchantmentPurgingBlade.java | 3 + .../Rin/Ench0_3_0/EnchantmentRaining.java | 3 + .../Rin/Ench0_3_0/EnchantmentSunshine.java | 9 +- .../Ench0_3_0/EnchantmentThunderstorm.java | 2 + .../Rin/Ench0_3_0/EnchantmentViper.java | 3 + .../Rin/Ench0_4_0/EnchantmentAdept.java | 3 + .../EnchantmentAncient_CurseInflicter.java | 2 +- .../Rin/Ench0_4_0/EnchantmentBrutality.java | 2 +- .../EnchantmentCurseofVulnerability.java | 4 +- .../Rin/Ench0_4_0/EnchantmentDarkShadows.java | 5 +- .../EnchantmentDifficultyScaled.java | 3 + .../Rin/Ench0_4_0/EnchantmentDisarmament.java | 4 + .../Rin/Ench0_4_0/EnchantmentFAtier.java | 2 +- .../Rin/Ench0_4_0/EnchantmentFlinging.java | 3 +- .../Rin/Ench0_4_0/EnchantmentFreezing.java | 3 + .../Ench0_4_0/EnchantmentHors_de_combat.java | 2 +- .../Rin/Ench0_4_0/EnchantmentInhumanity.java | 2 +- .../Ench0_4_0/EnchantmentInnerBerserk.java | 3 + .../EnchantmentReinforcedSharpness.java | 3 +- .../EnchantmentSubjectEnchantments.java | 2 +- .../Rin/Ench0_4_0/EnchantmentSwiper.java | 10 +- .../Rin/Ench0_4_0/EnchantmentTierDamage.java | 2 +- .../Rin/Ench0_4_5/EnchantmentInstability.java | 3 + .../Rin/Ench0_4_5/EnchantmentMastery.java | 6 + .../EnchantmentBase.java | 40 + .../com/Shultrea/Rin/Hook/HookArthropod.java | 99 +++ .../com/Shultrea/Rin/Hook/HookHelper.java | 38 + .../Shultrea/Rin/Main_Sector/ModConfig.java | 8 + .../Rin/Main_Sector/somanyenchantments.java | 2 +- .../Shultrea/Rin/Transformer/CoreLoader.java | 50 ++ .../com/Shultrea/Rin/Transformer/SMEASM.java | 278 ++++++ .../Rin/Transformer/helper/ASMHelper.java | 834 ++++++++++++++++++ .../Transformer/helper/InsnComparator.java | 117 +++ .../Rin/Transformer/helper/ObfHelper.java | 163 ++++ .../helper/ObfRemappingClassWriter.java | 57 ++ .../Rin/Transformer/util/TransformUtil.java | 243 +++++ ...ditionalProtectionEnchantmentsEffects.java | 15 +- .../Rin/Utility_Sector/ExtraEvent.java | 4 + .../Rin/Utility_Sector/OtherHandler.java | 4 +- 73 files changed, 2351 insertions(+), 230 deletions(-) create mode 100644 src/main/java/com/Shultrea/Rin/Hook/HookArthropod.java create mode 100644 src/main/java/com/Shultrea/Rin/Hook/HookHelper.java create mode 100644 src/main/java/com/Shultrea/Rin/Transformer/CoreLoader.java create mode 100644 src/main/java/com/Shultrea/Rin/Transformer/SMEASM.java create mode 100644 src/main/java/com/Shultrea/Rin/Transformer/helper/ASMHelper.java create mode 100644 src/main/java/com/Shultrea/Rin/Transformer/helper/InsnComparator.java create mode 100644 src/main/java/com/Shultrea/Rin/Transformer/helper/ObfHelper.java create mode 100644 src/main/java/com/Shultrea/Rin/Transformer/helper/ObfRemappingClassWriter.java create mode 100644 src/main/java/com/Shultrea/Rin/Transformer/util/TransformUtil.java diff --git a/build.gradle b/build.gradle index 832f771..7790d95 100644 --- a/build.gradle +++ b/build.gradle @@ -11,7 +11,7 @@ apply plugin: 'net.minecraftforge.gradle.forge' //Only edit below this line, the above code adds and enables the necessary things for Forge to be setup. -version = "0.5.2" +version = "0.5.3" group = "com.Shultrea.Rin" // http://maven.apache.org/guides/mini/guide-naming-conventions.html archivesBaseName = "SoManyEnchantments" @@ -75,3 +75,11 @@ processResources { exclude 'mcmod.info' } } + +jar { + manifest + { + attributes "FMLCorePlugin": "com.Shultrea.Rin.Transformer.CoreLoader" + attributes "FMLCorePluginContainsFMLMod": "com.Shultrea.Rin.Main_Sector.somanyenchantments" + } +} diff --git a/src/main/java/com/Shultrea/Rin/Ench0_1_0/EnchantmentAdvancedBaneOfArthropods.java b/src/main/java/com/Shultrea/Rin/Ench0_1_0/EnchantmentAdvancedBaneOfArthropods.java index 93128ed..a787d67 100644 --- a/src/main/java/com/Shultrea/Rin/Ench0_1_0/EnchantmentAdvancedBaneOfArthropods.java +++ b/src/main/java/com/Shultrea/Rin/Ench0_1_0/EnchantmentAdvancedBaneOfArthropods.java @@ -76,7 +76,7 @@ public float calcDamageByCreature(int level, EnumCreatureAttribute creatureType) } @Override - public void onEntityDamaged(EntityLivingBase user, Entity entiti, int level) + public void onEntityDamagedAlt(EntityLivingBase user, Entity entiti, ItemStack stack, int level) { if(entiti instanceof EntityLivingBase){ EntityLivingBase entity = (EntityLivingBase) entiti; diff --git a/src/main/java/com/Shultrea/Rin/Ench0_1_0/EnchantmentAdvancedEfficiency.java b/src/main/java/com/Shultrea/Rin/Ench0_1_0/EnchantmentAdvancedEfficiency.java index 0b65e10..afac485 100644 --- a/src/main/java/com/Shultrea/Rin/Ench0_1_0/EnchantmentAdvancedEfficiency.java +++ b/src/main/java/com/Shultrea/Rin/Ench0_1_0/EnchantmentAdvancedEfficiency.java @@ -124,7 +124,8 @@ public void onAxeAttackEfficiency(LivingHurtEvent fEvent) if(EnchantmentHelper.getEnchantmentLevel(Smc_010.ExtremeEfficency, dmgSource) <= 0) return; - + if(this.isOffensivePetDisallowed(fEvent.getSource().getImmediateSource(), fEvent.getSource().getTrueSource())) + return; int levelEE = EnchantmentHelper.getEnchantmentLevel(Smc_010.ExtremeEfficency, dmgSource); diff --git a/src/main/java/com/Shultrea/Rin/Ench0_1_0/EnchantmentAdvancedSmite.java b/src/main/java/com/Shultrea/Rin/Ench0_1_0/EnchantmentAdvancedSmite.java index 25c7ba3..7e82618 100644 --- a/src/main/java/com/Shultrea/Rin/Ench0_1_0/EnchantmentAdvancedSmite.java +++ b/src/main/java/com/Shultrea/Rin/Ench0_1_0/EnchantmentAdvancedSmite.java @@ -64,7 +64,7 @@ public boolean canApply(ItemStack fTest) return fTest.getItem() instanceof ItemAxe ? true : super.canApply(fTest); } @Override - public void onEntityDamaged(EntityLivingBase user, Entity entiti, int level) + public void onEntityDamagedAlt(EntityLivingBase user, Entity entiti, ItemStack stack, int level) { if(!(entiti instanceof EntityLivingBase)) return; diff --git a/src/main/java/com/Shultrea/Rin/Ench0_1_0/EnchantmentBlessedEdge.java b/src/main/java/com/Shultrea/Rin/Ench0_1_0/EnchantmentBlessedEdge.java index 1b90f77..a943157 100644 --- a/src/main/java/com/Shultrea/Rin/Ench0_1_0/EnchantmentBlessedEdge.java +++ b/src/main/java/com/Shultrea/Rin/Ench0_1_0/EnchantmentBlessedEdge.java @@ -77,6 +77,9 @@ public void HandleEnchant(LivingHurtEvent fEvent) if(EnchantmentHelper.getEnchantmentLevel(Smc_010.BlessedEdge, dmgSource) <= 0) return; + if(this.isOffensivePetDisallowed(fEvent.getSource().getImmediateSource(), fEvent.getSource().getTrueSource())) + return; + int levelBless = EnchantmentHelper.getEnchantmentLevel(Smc_010.BlessedEdge, dmgSource); attacker.heal( fEvent.getAmount() * (levelBless * 0.03f)); diff --git a/src/main/java/com/Shultrea/Rin/Ench0_1_0/EnchantmentButchering.java b/src/main/java/com/Shultrea/Rin/Ench0_1_0/EnchantmentButchering.java index f80085f..cadeb3b 100644 --- a/src/main/java/com/Shultrea/Rin/Ench0_1_0/EnchantmentButchering.java +++ b/src/main/java/com/Shultrea/Rin/Ench0_1_0/EnchantmentButchering.java @@ -90,6 +90,9 @@ public void HandleEnchant(LivingHurtEvent fEvent) if(EnchantmentHelper.getEnchantmentLevel(Smc_010.Butchering, dmgSource) <= 0) return; + if(this.isOffensivePetDisallowed(fEvent.getSource().getImmediateSource(), fEvent.getSource().getTrueSource())) + return; + int levelButchering = EnchantmentHelper.getEnchantmentLevel(Smc_010.Butchering, dmgSource); if(fEvent.getEntity() instanceof EntityAnimal) { diff --git a/src/main/java/com/Shultrea/Rin/Ench0_1_0/EnchantmentCursedEdge.java b/src/main/java/com/Shultrea/Rin/Ench0_1_0/EnchantmentCursedEdge.java index 2e463e5..272180b 100644 --- a/src/main/java/com/Shultrea/Rin/Ench0_1_0/EnchantmentCursedEdge.java +++ b/src/main/java/com/Shultrea/Rin/Ench0_1_0/EnchantmentCursedEdge.java @@ -87,6 +87,9 @@ public void HandleEnchant(LivingDamageEvent fEvent) if(EnchantmentHelper.getEnchantmentLevel(Smc_010.CursedEdge, dmgSource) <= 0) return; + if(this.isOffensivePetDisallowed(fEvent.getSource().getImmediateSource(), fEvent.getSource().getTrueSource())) + return; + int levelCurse = EnchantmentHelper.getEnchantmentLevel(Smc_010.CursedEdge, dmgSource); float Damage = fEvent.getAmount() * ((levelCurse * 0.20f) + 1.00f); diff --git a/src/main/java/com/Shultrea/Rin/Ench0_1_0/EnchantmentDefusion.java b/src/main/java/com/Shultrea/Rin/Ench0_1_0/EnchantmentDefusion.java index 01ebe85..22b95ee 100644 --- a/src/main/java/com/Shultrea/Rin/Ench0_1_0/EnchantmentDefusion.java +++ b/src/main/java/com/Shultrea/Rin/Ench0_1_0/EnchantmentDefusion.java @@ -87,6 +87,9 @@ public void HandleEnchant(LivingHurtEvent fEvent) if(EnchantmentHelper.getEnchantmentLevel(Smc_010.Defusion, dmgSource) <= 0) return; + if(this.isOffensivePetDisallowed(fEvent.getSource().getImmediateSource(), fEvent.getSource().getTrueSource())) + return; + int levelDefusing = EnchantmentHelper.getEnchantmentLevel(Smc_010.Defusion, dmgSource); if(fEvent.getEntity() instanceof EntityCreeper) { diff --git a/src/main/java/com/Shultrea/Rin/Ench0_1_0/EnchantmentFieryEdge.java b/src/main/java/com/Shultrea/Rin/Ench0_1_0/EnchantmentFieryEdge.java index 861e364..011ee01 100644 --- a/src/main/java/com/Shultrea/Rin/Ench0_1_0/EnchantmentFieryEdge.java +++ b/src/main/java/com/Shultrea/Rin/Ench0_1_0/EnchantmentFieryEdge.java @@ -53,7 +53,7 @@ public boolean canApplyTogether(Enchantment fTest) } @Override - public void onEntityDamaged(EntityLivingBase user, Entity target, int level) + public void onEntityDamagedAlt(EntityLivingBase user, Entity target, ItemStack stack, int level) { if(!(target instanceof EntityLivingBase)) return; diff --git a/src/main/java/com/Shultrea/Rin/Ench0_1_0/EnchantmentPurification.java b/src/main/java/com/Shultrea/Rin/Ench0_1_0/EnchantmentPurification.java index 9c17108..93a58cd 100644 --- a/src/main/java/com/Shultrea/Rin/Ench0_1_0/EnchantmentPurification.java +++ b/src/main/java/com/Shultrea/Rin/Ench0_1_0/EnchantmentPurification.java @@ -61,7 +61,7 @@ public int getMaxEnchantability(int par1) } @Override - public void onEntityDamaged (EntityLivingBase user, Entity target, int level) { + public void onEntityDamagedAlt(EntityLivingBase user, Entity target, ItemStack stack, int level) { if(!(target instanceof EntityLivingBase)) return; @@ -70,8 +70,7 @@ public void onEntityDamaged (EntityLivingBase user, Entity target, int level) { return; EntityLivingBase victim = (EntityLivingBase) target; - ItemStack item = user.getHeldItemMainhand(); - int lvl = EnchantmentHelper.getEnchantmentLevel(Smc_010.Purification, item); + int lvl = EnchantmentHelper.getEnchantmentLevel(Smc_010.Purification, stack); if(lvl <= 0) return; diff --git a/src/main/java/com/Shultrea/Rin/Ench0_1_0/EnchantmentReviledBlade.java b/src/main/java/com/Shultrea/Rin/Ench0_1_0/EnchantmentReviledBlade.java index 9e5a932..45cabc3 100644 --- a/src/main/java/com/Shultrea/Rin/Ench0_1_0/EnchantmentReviledBlade.java +++ b/src/main/java/com/Shultrea/Rin/Ench0_1_0/EnchantmentReviledBlade.java @@ -65,6 +65,9 @@ public void HandleEnchant(LivingDamageEvent fEvent) if(EnchantmentHelper.getEnchantmentLevel(Smc_010.ReviledBlade, weapon) > 0) { + if(this.isOffensivePetDisallowed(fEvent.getSource().getImmediateSource(), fEvent.getSource().getTrueSource())) + return; + float defenderHealthPercent = fEvent.getEntityLiving().getHealth() / fEvent.getEntityLiving().getMaxHealth(); int levelfinish = EnchantmentHelper.getEnchantmentLevel(Smc_010.ReviledBlade, weapon); float dmgMod = (1.0f - defenderHealthPercent) * ((levelfinish * 0.1f) + 0.9f); diff --git a/src/main/java/com/Shultrea/Rin/Ench0_1_0/EnchantmentRune_PiercingCapabilities.java b/src/main/java/com/Shultrea/Rin/Ench0_1_0/EnchantmentRune_PiercingCapabilities.java index e78e0f7..0b0f156 100644 --- a/src/main/java/com/Shultrea/Rin/Ench0_1_0/EnchantmentRune_PiercingCapabilities.java +++ b/src/main/java/com/Shultrea/Rin/Ench0_1_0/EnchantmentRune_PiercingCapabilities.java @@ -82,6 +82,9 @@ public void HandleEnchant(LivingHurtEvent fEvent) if(pierceLevel <= 0) return; + if(this.isOffensivePetDisallowed(fEvent.getSource().getImmediateSource(), fEvent.getSource().getTrueSource())) + return; + float damage = fEvent.getAmount() * 0.25f * pierceLevel; fEvent.setAmount(fEvent.getAmount() - (fEvent.getAmount() * pierceLevel * 0.25f)); diff --git a/src/main/java/com/Shultrea/Rin/Ench0_1_0/EnchantmentRusted.java b/src/main/java/com/Shultrea/Rin/Ench0_1_0/EnchantmentRusted.java index d3ccf31..1ddfd84 100644 --- a/src/main/java/com/Shultrea/Rin/Ench0_1_0/EnchantmentRusted.java +++ b/src/main/java/com/Shultrea/Rin/Ench0_1_0/EnchantmentRusted.java @@ -171,10 +171,10 @@ private int getLevel(ItemStack is, Enchantment enchantment) { @Override - public void onEntityDamaged(EntityLivingBase user, Entity entiti, int level) + public void onEntityDamagedAlt(EntityLivingBase user, Entity entiti, ItemStack stack, int level) { if(level > 0) - user.getHeldItemMainhand().damageItem(1 + user.getRNG().nextInt(level * 2), user); + stack.damageItem(1 + user.getRNG().nextInt(level * 2), user); } } diff --git a/src/main/java/com/Shultrea/Rin/Ench0_1_0/EnchantmentSpellBreaker.java b/src/main/java/com/Shultrea/Rin/Ench0_1_0/EnchantmentSpellBreaker.java index 64d16d3..15435e2 100644 --- a/src/main/java/com/Shultrea/Rin/Ench0_1_0/EnchantmentSpellBreaker.java +++ b/src/main/java/com/Shultrea/Rin/Ench0_1_0/EnchantmentSpellBreaker.java @@ -111,6 +111,9 @@ public void onHurt(LivingHurtEvent e) { if(level <= 0) return; + if(this.isOffensivePetDisallowed(e.getSource().getImmediateSource(), e.getSource().getTrueSource())) + return; + if(e.getEntityLiving().getActivePotionEffects().size() > 0) e.setAmount(e.getAmount() + (0.625f * level) * e.getEntityLiving().getActivePotionEffects().size()); diff --git a/src/main/java/com/Shultrea/Rin/Ench0_1_0/EnchantmentSwifterSlashes.java b/src/main/java/com/Shultrea/Rin/Ench0_1_0/EnchantmentSwifterSlashes.java index 09d1322..9cba30f 100644 --- a/src/main/java/com/Shultrea/Rin/Ench0_1_0/EnchantmentSwifterSlashes.java +++ b/src/main/java/com/Shultrea/Rin/Ench0_1_0/EnchantmentSwifterSlashes.java @@ -158,6 +158,9 @@ public void HandleEnchant(LivingHurtEvent fEvent) int level = EnchantmentHelper.getEnchantmentLevel(Smc_010.SwifterSlashes, weapon); if(EnchantmentHelper.getEnchantmentLevel(Smc_010.SwifterSlashes, weapon) <= 0) return; + + if(this.isOffensivePetDisallowed(fEvent.getSource().getImmediateSource(), fEvent.getSource().getTrueSource())) + return; if(fEvent.getEntityLiving().world.rand.nextInt(100) < 25 + (level * 4)) { diff --git a/src/main/java/com/Shultrea/Rin/Ench0_1_0/EnchantmentWaterAspect.java b/src/main/java/com/Shultrea/Rin/Ench0_1_0/EnchantmentWaterAspect.java index 2878ca5..fc82555 100644 --- a/src/main/java/com/Shultrea/Rin/Ench0_1_0/EnchantmentWaterAspect.java +++ b/src/main/java/com/Shultrea/Rin/Ench0_1_0/EnchantmentWaterAspect.java @@ -81,6 +81,8 @@ public void HandleEnchant(LivingHurtEvent fEvent) if(EnchantmentHelper.getEnchantmentLevel(Smc_010.WaterAspect, dmgSource) <= 0) return; + if(this.isOffensivePetDisallowed(fEvent.getSource().getImmediateSource(), fEvent.getSource().getTrueSource())) + return; int levelWaterAspect = EnchantmentHelper.getEnchantmentLevel(Smc_010.WaterAspect, dmgSource); diff --git a/src/main/java/com/Shultrea/Rin/Ench0_2_0/EnchantmentAdvancedKnockback.java b/src/main/java/com/Shultrea/Rin/Ench0_2_0/EnchantmentAdvancedKnockback.java index f54dab4..15af23f 100644 --- a/src/main/java/com/Shultrea/Rin/Ench0_2_0/EnchantmentAdvancedKnockback.java +++ b/src/main/java/com/Shultrea/Rin/Ench0_2_0/EnchantmentAdvancedKnockback.java @@ -115,11 +115,10 @@ public int level(ItemStack stack) { @Override - public void onEntityDamaged (EntityLivingBase user, Entity target, int level) + public void onEntityDamagedAlt(EntityLivingBase user, Entity target, ItemStack stack, int level) { if(target instanceof EntityLivingBase) { - ItemStack stack = user.getHeldItemMainhand(); int levelknockBack = EnchantmentHelper.getEnchantmentLevel(Smc_020.AdvancedKnockback, stack); int modKnockback = 1; double Y = levelknockBack * 0.075D; diff --git a/src/main/java/com/Shultrea/Rin/Ench0_2_0/EnchantmentCulling.java b/src/main/java/com/Shultrea/Rin/Ench0_2_0/EnchantmentCulling.java index 29539c2..8f239c4 100644 --- a/src/main/java/com/Shultrea/Rin/Ench0_2_0/EnchantmentCulling.java +++ b/src/main/java/com/Shultrea/Rin/Ench0_2_0/EnchantmentCulling.java @@ -100,6 +100,9 @@ public void HandleEnchant(LivingHurtEvent fEvent) if(EnchantmentHelper.getEnchantmentLevel(Smc_020.Culling, dmgSource) <= 0) return; + if(this.isOffensivePetDisallowed(fEvent.getSource().getImmediateSource(), fEvent.getSource().getTrueSource())) + return; + int level = EnchantmentHelper.getEnchantmentLevel(Smc_020.Culling, dmgSource); float half = level; diff --git a/src/main/java/com/Shultrea/Rin/Ench0_2_0/EnchantmentLifesteal.java b/src/main/java/com/Shultrea/Rin/Ench0_2_0/EnchantmentLifesteal.java index 460a6d3..6d296dd 100644 --- a/src/main/java/com/Shultrea/Rin/Ench0_2_0/EnchantmentLifesteal.java +++ b/src/main/java/com/Shultrea/Rin/Ench0_2_0/EnchantmentLifesteal.java @@ -78,7 +78,10 @@ public void HandlingFirst(LivingHurtEvent fEvent) if(EnchantmentHelper.getEnchantmentLevel(Smc_020.Lifesteal, weapon) <= 0) return; - + + if(this.isOffensivePetDisallowed(fEvent.getSource().getImmediateSource(), fEvent.getSource().getTrueSource())) + return; + attacker.heal(fEvent.getAmount() * (levellifesteal * 0.025f + 0.025f)); UtilityAccessor.damageTarget(fEvent.getEntityLiving(), somanyenchantments.PhysicalDamage, fEvent.getAmount() * (0.05F + ((levellifesteal * 0.05F)))); diff --git a/src/main/java/com/Shultrea/Rin/Ench0_2_0/EnchantmentMortalitas.java b/src/main/java/com/Shultrea/Rin/Ench0_2_0/EnchantmentMortalitas.java index 56a8603..478306c 100644 --- a/src/main/java/com/Shultrea/Rin/Ench0_2_0/EnchantmentMortalitas.java +++ b/src/main/java/com/Shultrea/Rin/Ench0_2_0/EnchantmentMortalitas.java @@ -74,6 +74,9 @@ public void onDamage(LivingHurtEvent e){ if(level <= 0) return; + if(this.isOffensivePetDisallowed(e.getSource().getImmediateSource(), e.getSource().getTrueSource())) + return; + if(!stack.hasTagCompound()) stack.setTagCompound(new NBTTagCompound()); diff --git a/src/main/java/com/Shultrea/Rin/Ench0_2_0/EnchantmentPenetratingEdge.java b/src/main/java/com/Shultrea/Rin/Ench0_2_0/EnchantmentPenetratingEdge.java index d7b527f..0f3e039 100644 --- a/src/main/java/com/Shultrea/Rin/Ench0_2_0/EnchantmentPenetratingEdge.java +++ b/src/main/java/com/Shultrea/Rin/Ench0_2_0/EnchantmentPenetratingEdge.java @@ -92,6 +92,9 @@ public void HandleEnchant(LivingHurtEvent fEvent) if(!(fEvent.getEntity() instanceof EntityLivingBase)) return; + if(this.isOffensivePetDisallowed(fEvent.getSource().getImmediateSource(), fEvent.getSource().getTrueSource())) + return; + float ArmorDetector; EntityLivingBase entity = (EntityLivingBase)fEvent.getEntity(); diff --git a/src/main/java/com/Shultrea/Rin/Ench0_2_0/EnchantmentRune_MagicalBlessing.java b/src/main/java/com/Shultrea/Rin/Ench0_2_0/EnchantmentRune_MagicalBlessing.java index 413b401..86c8ed9 100644 --- a/src/main/java/com/Shultrea/Rin/Ench0_2_0/EnchantmentRune_MagicalBlessing.java +++ b/src/main/java/com/Shultrea/Rin/Ench0_2_0/EnchantmentRune_MagicalBlessing.java @@ -93,6 +93,9 @@ public void HandleEnchant(LivingHurtEvent fEvent) if(EnchantmentHelper.getEnchantmentLevel(this, stack) <= 0) return; + if(this.isOffensivePetDisallowed(fEvent.getSource().getImmediateSource(), fEvent.getSource().getTrueSource())) + return; + if(EnchantmentHelper.getEnchantmentLevel(Smc_010.Rune_PiercingCapabilities, stack) != 0) return; diff --git a/src/main/java/com/Shultrea/Rin/Ench0_2_0/EnchantmentUnpredictable.java b/src/main/java/com/Shultrea/Rin/Ench0_2_0/EnchantmentUnpredictable.java index dc80ff5..91833dd 100644 --- a/src/main/java/com/Shultrea/Rin/Ench0_2_0/EnchantmentUnpredictable.java +++ b/src/main/java/com/Shultrea/Rin/Ench0_2_0/EnchantmentUnpredictable.java @@ -73,6 +73,9 @@ public void HandleEnchant(LivingHurtEvent fEvent) if(EnchantmentHelper.getEnchantmentLevel(Smc_020.Unpredictable, dmgSource) <= 0) return; + if(this.isOffensivePetDisallowed(fEvent.getSource().getImmediateSource(), fEvent.getSource().getTrueSource())) + return; + int levelDamageRandomizer = EnchantmentHelper.getEnchantmentLevel(Smc_020.Unpredictable, dmgSource); { float random = (float) Math.random() * (fEvent.getAmount() * (levelDamageRandomizer * 1.25f)); diff --git a/src/main/java/com/Shultrea/Rin/Ench0_3_0/EnchantmentAdvancedBlastProtection.java b/src/main/java/com/Shultrea/Rin/Ench0_3_0/EnchantmentAdvancedBlastProtection.java index c16d6d2..de130fc 100644 --- a/src/main/java/com/Shultrea/Rin/Ench0_3_0/EnchantmentAdvancedBlastProtection.java +++ b/src/main/java/com/Shultrea/Rin/Ench0_3_0/EnchantmentAdvancedBlastProtection.java @@ -6,6 +6,7 @@ import java.util.List; import com.Shultrea.Rin.Enchantment_Base_Sector.EnchantmentBase; +import com.Shultrea.Rin.Enchantments_Sector.Smc_030; import com.Shultrea.Rin.Interfaces.IEnchantmentProtection; import com.Shultrea.Rin.Interfaces.IEnhancedEnchantment; import com.Shultrea.Rin.Main_Sector.ModConfig; @@ -16,9 +17,11 @@ import net.minecraft.enchantment.EnchantmentProtection; import net.minecraft.enchantment.EnumEnchantmentType; import net.minecraft.entity.EntityLivingBase; +import net.minecraft.init.Enchantments; import net.minecraft.inventory.EntityEquipmentSlot; import net.minecraft.item.ItemStack; import net.minecraft.util.DamageSource; +import net.minecraft.util.math.MathHelper; import net.minecraft.world.Explosion; import net.minecraftforge.event.world.ExplosionEvent; import net.minecraftforge.fml.common.ObfuscationReflectionHelper; @@ -32,7 +35,7 @@ public class EnchantmentAdvancedBlastProtection extends EnchantmentBase implemen public EnchantmentAdvancedBlastProtection() { - super(Rarity.RARE, EnumEnchantmentType.ARMOR, new EntityEquipmentSlot[]{EntityEquipmentSlot.HEAD, EntityEquipmentSlot.CHEST, EntityEquipmentSlot.LEGS, EntityEquipmentSlot.FEET}); + super(Rarity.RARE, EnumEnchantmentType.ARMOR, new EntityEquipmentSlot[]{EntityEquipmentSlot.HEAD, EntityEquipmentSlot.CHEST, EntityEquipmentSlot.LEGS, EntityEquipmentSlot.FEET}); this.setName("AdvancedBlastProtection"); this.setRegistryName("AdvancedBlastProtection"); } @@ -45,129 +48,149 @@ public boolean isConfigEnabled() @Override public int getMaxLevel() - { - return ModConfig.level.AdvancedBlastProtection; - } + { + return ModConfig.level.AdvancedBlastProtection; + } @Override - public int getMinEnchantability(int par1) - { + public int getMinEnchantability(int par1) + { return 24 + (par1 - 1) * 14; - } + } - @Override - public int getMaxEnchantability(int par1) - { - return this.getMinEnchantability(par1) + 50; - } - - @Override - public boolean canApplyTogether(Enchantment fTest) - { - if(fTest instanceof EnchantmentProtection){ - EnchantmentProtection p = (EnchantmentProtection) fTest; - if(p.protectionType != EnchantmentProtection.Type.FALL) - return false; - - else return true; - } - - if(fTest instanceof EnchantmentAdvancedFeatherFalling) - return true; - - return super.canApplyTogether(fTest) && !(fTest instanceof IEnchantmentProtection); - } - - @Override - public int calcModifierDamage(int level, DamageSource source) - { - return source.canHarmInCreative() ? 0 : source.isExplosion() ? level * 3 : 0; - } + @Override + public int getMaxEnchantability(int par1) + { + return this.getMinEnchantability(par1) + 50; + } + + @Override + public boolean canApplyTogether(Enchantment fTest) + { + if(fTest instanceof EnchantmentProtection){ + EnchantmentProtection p = (EnchantmentProtection) fTest; + if(p.protectionType != EnchantmentProtection.Type.FALL) + return false; + + else return true; + } + + if(fTest instanceof EnchantmentAdvancedFeatherFalling) + return true; + + return super.canApplyTogether(fTest) && !(fTest instanceof IEnchantmentProtection); + } + + @Override + public int calcModifierDamage(int level, DamageSource source) + { + return source.canHarmInCreative() ? 0 : source.isExplosion() ? level * 3 : 0; + } + + public static double getKnockbackValue(double damage, EntityLivingBase entity) + { + //Return damage if nothing is applied here + + if(!Smc_030.AdvancedBlastProtection.isEnabled()) + return damage; + + int i = EnchantmentHelper.getMaxEnchantmentLevel(Smc_030.AdvancedBlastProtection, entity); + + if (i > 0) + { + //Normal blast protection is a modifier of 0.15f + //This is inaccurate to the original SME, but it's hard to figure out what SME does + damage -= (double)MathHelper.floor(damage * (double)((float)i * 0.3F)); + } + + return damage; + } - @SubscribeEvent(priority=EventPriority.LOWEST) - public void DetonateKnockBackReduction(ExplosionEvent.Detonate e) - { - - List victims = e.getAffectedEntities(); - int size = victims.size(); - for(int j = 0; j < size; ++j){ - if(victims.isEmpty()) - return; - - if(!(victims.get(j) instanceof EntityLivingBase)) - continue; - - EntityLivingBase individual = (EntityLivingBase) victims.get(j); - - int enchLevel = EnchantmentHelper.getMaxEnchantmentLevel(this, individual); - if(enchLevel <= 0) - continue; + /* This handler was bugged and was causing damage whenever a detonation happened even if the detonation did not do damage, so this system has been overhauled instead + * Handling is now done in SMEASM and HookHelper + @SubscribeEvent(priority=EventPriority.LOWEST) + public void DetonateKnockBackReduction(ExplosionEvent.Detonate e) + { + + List victims = e.getAffectedEntities(); + int size = victims.size(); + for(int j = 0; j < size; ++j){ + if(victims.isEmpty()) + return; + + if(!(victims.get(j) instanceof EntityLivingBase)) + continue; + + EntityLivingBase individual = (EntityLivingBase) victims.get(j); + + int enchLevel = EnchantmentHelper.getMaxEnchantmentLevel(this, individual); + if(enchLevel <= 0) + continue; - e.getAffectedEntities().remove(j); - size = size - 1; - - float explosionSize = 0; - - Explosion explosion = e.getExplosion(); - - if(explosion == null) - return; - - try - { - //Create and cache power - if(power==null) - { - power = ObfuscationReflectionHelper.findField(Explosion.class, "field_77280_f"); - power.setAccessible(true); - } - - explosionSize = power.getFloat(explosion); - } - catch(Exception ex) - { - ex.printStackTrace(); - } - - EnchantmentsUtility.damageExplosion(individual, explosion, explosionSize, individual.world, this); - - //System.out.println(explosionSize); - - - // motionX *= EnchantmentsUtility.getAdvancedKnockBackReduction(individual); - // motionY *= EnchantmentsUtility.getAdvancedKnockBackReduction(individual); - // motionZ *= EnchantmentsUtility.getAdvancedKnockBackReduction(individual); - - - - } - } - - /* - @SubscribeEvent(priority=EventPriority.HIGH) - public void DetonateKnockBackReduce(LivingUpdateEvent fEvent) { - if(!(fEvent.getEntity() instanceof EntityLivingBase)) - return; - - EntityLivingBase wearer = fEvent.getEntityLiving(); - - int enchLevel = EnchantmentHelper.getMaxEnchantmentLevel(Smc_030.AdvancedBlastProtection, wearer); + e.getAffectedEntities().remove(j); + size = size - 1; + + float explosionSize = 0; + + Explosion explosion = e.getExplosion(); + + if(explosion == null) + return; + + try + { + //Create and cache power + if(power==null) + { + power = ObfuscationReflectionHelper.findField(Explosion.class, "field_77280_f"); + power.setAccessible(true); + } + + explosionSize = power.getFloat(explosion); + } + catch(Exception ex) + { + ex.printStackTrace(); + } + + EnchantmentsUtility.damageExplosion(individual, explosion, explosionSize, individual.world, this); + + //System.out.println(explosionSize); + + + // motionX *= EnchantmentsUtility.getAdvancedKnockBackReduction(individual); + // motionY *= EnchantmentsUtility.getAdvancedKnockBackReduction(individual); + // motionZ *= EnchantmentsUtility.getAdvancedKnockBackReduction(individual); + + } + } + */ + + /* + @SubscribeEvent(priority=EventPriority.HIGH) + public void DetonateKnockBackReduce(LivingUpdateEvent fEvent) { + if(!(fEvent.getEntity() instanceof EntityLivingBase)) + return; + + EntityLivingBase wearer = fEvent.getEntityLiving(); + + int enchLevel = EnchantmentHelper.getMaxEnchantmentLevel(Smc_030.AdvancedBlastProtection, wearer); if(enchLevel <= 0){ RemoveKnockBack(wearer); return; } - level = enchLevel - 1; - + level = enchLevel - 1; + AddKnockBack(wearer); - } - private void AddKnockBack(EntityLivingBase fEntity) + } + private void AddKnockBack(EntityLivingBase fEntity) { - ItemStack weapon = fEntity.getHeldItemMainhand(); - //int level = potyon.getAmplifier() + 1; + ItemStack weapon = fEntity.getHeldItemMainhand(); + //int level = potyon.getAmplifier() + 1; IAttributeInstance attackAttr = fEntity.getAttributeMap().getAttributeInstance(SharedMonsterAttributes.KNOCKBACK_RESISTANCE); AttributeModifier attackDamage = new AttributeModifier(UUID.fromString("e23481-134f-4c54-a535-29c3a241c7a21"),"blastProtectKnockBack", 0.1f + (level * 0.30f), 0); @@ -175,7 +198,7 @@ private void AddKnockBack(EntityLivingBase fEntity) if(attackAttr.getModifier(UUID.fromString("e23481-134f-4c54-a535-29c3a241c7a21")) != null) - return; + return; attackAttr.applyModifier(attackDamage); } @@ -191,82 +214,82 @@ private void RemoveKnockBack(EntityLivingBase fEntity) - AttributeModifier attackDamage = new AttributeModifier(UUID.fromString("e23481-134f-4c54-a535-29c3a241c7a21"),"blastProtectKnockBack", 0.1f + (level * 0.30f), 0); - attackAttr.removeModifier(attackDamage); + AttributeModifier attackDamage = new AttributeModifier(UUID.fromString("e23481-134f-4c54-a535-29c3a241c7a21"),"blastProtectKnockBack", 0.1f + (level * 0.30f), 0); + attackAttr.removeModifier(attackDamage); } */ - /** - @Override - public void onEntityDamaged(EntityLivingBase user, Entity target, int level){ + /** + @Override + public void onEntityDamaged(EntityLivingBase user, Entity target, int level){ - user.motionX = user.motionX - (user.motionX * level * 0.15f + 0.4f); - user.motionY = user.motionY - (user.motionY * level * 0.15f + 0.4f); - user.motionZ = user.motionZ - (user.motionZ * level * 0.15f + 0.4f); + user.motionX = user.motionX - (user.motionX * level * 0.15f + 0.4f); + user.motionY = user.motionY - (user.motionY * level * 0.15f + 0.4f); + user.motionZ = user.motionZ - (user.motionZ * level * 0.15f + 0.4f); - - } - */ - - /* - @SubscribeEvent(priority = EventPriority.LOWEST) - public void onAttack(LivingAttackEvent e) { - - if(!e.getSource().isExplosion()) + + } + */ + + /* + @SubscribeEvent(priority = EventPriority.LOWEST) + public void onAttack(LivingAttackEvent e) { + + if(!e.getSource().isExplosion()) + return; + + if(e.getSource().canHarmInCreative()) return; - - if(e.getSource().canHarmInCreative()) - return; - if(!(e.getEntityLiving() instanceof EntityPlayer)) - return; - - EntityPlayer user = (EntityPlayer) e.getEntityLiving(); - - if(user == null) - return; + if(!(e.getEntityLiving() instanceof EntityPlayer)) + return; + + EntityPlayer user = (EntityPlayer) e.getEntityLiving(); + + if(user == null) + return; - int level = EnchantmentHelper.getMaxEnchantmentLevel(this, user); - - if(level <= 0) - return; - - System.out.println(e.getAmount()); - - } - /* - e.setCanceled(true); - - if(e.getSource().getTrueSource() != null && e.getSource().getTrueSource() instanceof EntityLivingBase && !user.isCreative()) - user.attackEntityFrom(DamageSource.causeExplosionDamage((EntityLivingBase) e.getSource().getTrueSource()).setDamageAllowedInCreativeMode(), e.getAmount()); - - else user.attackEntityFrom(new DamageSource("explosion").setExplosion().setDifficultyScaled(), e.getAmount()); - //user.velocityChanged = true; - - double x = user.motionX - (user.motionX * (level * 0.15f + 0.4f)); - double y = user.motionY - (user.motionY * (level * 0.15f + 0.4f)); - double z = user.motionZ - (user.motionZ * (level * 0.15f + 0.4f)); - - if(!user.world.isRemote) { - //System.out.println(user.motionX + " - X BEFORE"); - //System.out.println(user.motionY + " - Y BEFORE"); - //System.out.println(user.motionZ + " - Z BEFORE"); - - user.motionX = x; - user.motionY = y; - user.motionZ = z; - - //System.out.println(user.vel + " - X AFTER"); - //System.out.println(user.motionY + " - Y AFTER"); - //System.out.println(user.motionZ + " - Z AFTER"); - user.velocityChanged = true; - } - if(user.world.isRemote) user.setVelocity(x, y, z); - } - - - } + int level = EnchantmentHelper.getMaxEnchantmentLevel(this, user); + + if(level <= 0) + return; + + System.out.println(e.getAmount()); + + } + /* + e.setCanceled(true); + + if(e.getSource().getTrueSource() != null && e.getSource().getTrueSource() instanceof EntityLivingBase && !user.isCreative()) + user.attackEntityFrom(DamageSource.causeExplosionDamage((EntityLivingBase) e.getSource().getTrueSource()).setDamageAllowedInCreativeMode(), e.getAmount()); + + else user.attackEntityFrom(new DamageSource("explosion").setExplosion().setDifficultyScaled(), e.getAmount()); + //user.velocityChanged = true; + + double x = user.motionX - (user.motionX * (level * 0.15f + 0.4f)); + double y = user.motionY - (user.motionY * (level * 0.15f + 0.4f)); + double z = user.motionZ - (user.motionZ * (level * 0.15f + 0.4f)); + + if(!user.world.isRemote) { + //System.out.println(user.motionX + " - X BEFORE"); + //System.out.println(user.motionY + " - Y BEFORE"); + //System.out.println(user.motionZ + " - Z BEFORE"); + + user.motionX = x; + user.motionY = y; + user.motionZ = z; + + //System.out.println(user.vel + " - X AFTER"); + //System.out.println(user.motionY + " - Y AFTER"); + //System.out.println(user.motionZ + " - Z AFTER"); + user.velocityChanged = true; + } + if(user.world.isRemote) user.setVelocity(x, y, z); + } + + + } */ /* @SubscribeEvent diff --git a/src/main/java/com/Shultrea/Rin/Ench0_3_0/EnchantmentAdvancedLooting.java b/src/main/java/com/Shultrea/Rin/Ench0_3_0/EnchantmentAdvancedLooting.java index ad18755..032f607 100644 --- a/src/main/java/com/Shultrea/Rin/Ench0_3_0/EnchantmentAdvancedLooting.java +++ b/src/main/java/com/Shultrea/Rin/Ench0_3_0/EnchantmentAdvancedLooting.java @@ -8,6 +8,7 @@ import net.minecraft.enchantment.Enchantment.Rarity; import net.minecraft.enchantment.EnchantmentHelper; import net.minecraft.enchantment.EnumEnchantmentType; +import net.minecraft.entity.EntityLivingBase; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.init.Enchantments; import net.minecraft.inventory.EntityEquipmentSlot; @@ -55,6 +56,24 @@ public boolean canApplyTogether(Enchantment fTest) return fTest == Enchantments.LOOTING ? false : super.canApplyTogether(fTest); } + public static int getValue(int original, EntityLivingBase entity) + { + if(!Smc_030.AdvancedLooting.isEnabled()) + return 0; + + int levelLooting = EnchantmentHelper.getMaxEnchantmentLevel(Smc_030.AdvancedLooting, entity); + + if(levelLooting <= 0) + return 0; + + int toReturn = original + 2 + ((levelLooting - 1) * 2); + if(Math.random() < 0.25f) + toReturn = toReturn + 2 + (levelLooting * 2); + + return toReturn; + } + + /* @SubscribeEvent(priority = EventPriority.LOWEST) public void HandleEnchant(LootingLevelEvent fEvent) { @@ -78,9 +97,6 @@ public void HandleEnchant(LootingLevelEvent fEvent) fEvent.setLootingLevel(fEvent.getLootingLevel() + 2 + (levelLooting * 2)); } - } - - - } - + */ +} diff --git a/src/main/java/com/Shultrea/Rin/Ench0_3_0/EnchantmentAdvancedLuckOfTheSea.java b/src/main/java/com/Shultrea/Rin/Ench0_3_0/EnchantmentAdvancedLuckOfTheSea.java index 662c1c1..a61e5e8 100644 --- a/src/main/java/com/Shultrea/Rin/Ench0_3_0/EnchantmentAdvancedLuckOfTheSea.java +++ b/src/main/java/com/Shultrea/Rin/Ench0_3_0/EnchantmentAdvancedLuckOfTheSea.java @@ -7,14 +7,9 @@ import net.minecraft.enchantment.Enchantment; import net.minecraft.enchantment.EnchantmentHelper; import net.minecraft.enchantment.EnumEnchantmentType; -import net.minecraft.entity.EntityLivingBase; -import net.minecraft.entity.projectile.EntityFishHook; import net.minecraft.init.Enchantments; import net.minecraft.inventory.EntityEquipmentSlot; import net.minecraft.item.ItemStack; -import net.minecraftforge.event.entity.EntityJoinWorldEvent; -import net.minecraftforge.fml.common.eventhandler.EventPriority; -import net.minecraftforge.fml.common.eventhandler.SubscribeEvent; public class EnchantmentAdvancedLuckOfTheSea extends EnchantmentBase { @@ -56,6 +51,23 @@ public boolean canApplyTogether(Enchantment fTest) return fTest == Enchantments.LUCK_OF_THE_SEA ? false : super.canApplyTogether(fTest); } + public static int getValue(ItemStack stack) + { + if(!Smc_030.AdvancedLuckOfTheSea.isEnabled()) + return 0; + + int level = EnchantmentHelper.getEnchantmentLevel(Smc_030.AdvancedLuckOfTheSea, stack); + if(level <= 0) + return 0; + + int toReturn = level * 2 + 2; + if(Math.random() < 0.15f) + toReturn = level * 3 + 3; + + return toReturn; + } + + /* @SubscribeEvent(priority=EventPriority.HIGHEST) public void onEvent(EntityJoinWorldEvent fEvent) { @@ -83,6 +95,7 @@ public void onEvent(EntityJoinWorldEvent fEvent) hook.setLuck(level * 3 + 3); } } -} } + */ +} \ No newline at end of file diff --git a/src/main/java/com/Shultrea/Rin/Ench0_3_0/EnchantmentAdvancedLure.java b/src/main/java/com/Shultrea/Rin/Ench0_3_0/EnchantmentAdvancedLure.java index 172b670..488d475 100644 --- a/src/main/java/com/Shultrea/Rin/Ench0_3_0/EnchantmentAdvancedLure.java +++ b/src/main/java/com/Shultrea/Rin/Ench0_3_0/EnchantmentAdvancedLure.java @@ -55,6 +55,23 @@ public boolean canApplyTogether(Enchantment fTest) return fTest == Enchantments.LURE ? false : super.canApplyTogether(fTest); } + public static int getValue(ItemStack stack) + { + if(!Smc_030.AdvancedLure.isEnabled()) + return 0; + + int level = EnchantmentHelper.getEnchantmentLevel(Smc_030.AdvancedLure, stack); + if(level <= 0) + return 0; + + int toReturn = level + 1; + if(Math.random() < 0.15f) + toReturn = level + 2; + + return toReturn; + } + + /* @SubscribeEvent(priority=EventPriority.HIGHEST) public void onEvent(EntityJoinWorldEvent fEvent) { @@ -86,6 +103,7 @@ public void onEvent(EntityJoinWorldEvent fEvent) hook.setLureSpeed(level + 2); } } -} } + */ +} \ No newline at end of file diff --git a/src/main/java/com/Shultrea/Rin/Ench0_3_0/EnchantmentAshDestroyer.java b/src/main/java/com/Shultrea/Rin/Ench0_3_0/EnchantmentAshDestroyer.java index 8a3996b..8cdf211 100644 --- a/src/main/java/com/Shultrea/Rin/Ench0_3_0/EnchantmentAshDestroyer.java +++ b/src/main/java/com/Shultrea/Rin/Ench0_3_0/EnchantmentAshDestroyer.java @@ -81,6 +81,9 @@ public void HandleEnchant(LivingDamageEvent fEvent) if(EnchantmentHelper.getEnchantmentLevel(Smc_030.AshDestroyer, dmgSource) <= 0) return; + if(this.isOffensivePetDisallowed(fEvent.getSource().getImmediateSource(), fEvent.getSource().getTrueSource())) + return; + int levelAshBringer = EnchantmentHelper.getEnchantmentLevel(Smc_030.AshDestroyer, dmgSource); { diff --git a/src/main/java/com/Shultrea/Rin/Ench0_3_0/EnchantmentClearsky.java b/src/main/java/com/Shultrea/Rin/Ench0_3_0/EnchantmentClearsky.java index c01cc3f..4cd547a 100644 --- a/src/main/java/com/Shultrea/Rin/Ench0_3_0/EnchantmentClearsky.java +++ b/src/main/java/com/Shultrea/Rin/Ench0_3_0/EnchantmentClearsky.java @@ -79,6 +79,8 @@ public void HandleEnchant(LivingHurtEvent fEvent){ if(EnchantmentHelper.getEnchantmentLevel(Smc_030.Clearsky, dmgSource) <= 0) return; + if(this.isOffensivePetDisallowed(fEvent.getSource().getImmediateSource(), fEvent.getSource().getTrueSource())) + return; int levelSunshine = EnchantmentHelper.getEnchantmentLevel(Smc_030.Clearsky, dmgSource); diff --git a/src/main/java/com/Shultrea/Rin/Ench0_3_0/EnchantmentDesolator.java b/src/main/java/com/Shultrea/Rin/Ench0_3_0/EnchantmentDesolator.java index 0883da2..234e4a7 100644 --- a/src/main/java/com/Shultrea/Rin/Ench0_3_0/EnchantmentDesolator.java +++ b/src/main/java/com/Shultrea/Rin/Ench0_3_0/EnchantmentDesolator.java @@ -77,6 +77,9 @@ public void HandleEnchant(LivingHurtEvent fEvent) if(EnchantmentHelper.getEnchantmentLevel(Smc_030.Desolator, weapon) <= 0) return; + if(this.isOffensivePetDisallowed(fEvent.getSource().getImmediateSource(), fEvent.getSource().getTrueSource())) + return; + if(fEvent.getEntity().world.rand.nextInt(100) < 8 * level) { if(level >= 3){ diff --git a/src/main/java/com/Shultrea/Rin/Ench0_3_0/EnchantmentDisorientation.java b/src/main/java/com/Shultrea/Rin/Ench0_3_0/EnchantmentDisorientation.java index 5354abd..0b74ee3 100644 --- a/src/main/java/com/Shultrea/Rin/Ench0_3_0/EnchantmentDisorientation.java +++ b/src/main/java/com/Shultrea/Rin/Ench0_3_0/EnchantmentDisorientation.java @@ -14,6 +14,7 @@ import net.minecraft.entity.EntityLivingBase; import net.minecraft.init.MobEffects; import net.minecraft.inventory.EntityEquipmentSlot; +import net.minecraft.item.ItemStack; import net.minecraft.potion.PotionEffect; import net.minecraftforge.event.entity.player.CriticalHitEvent; import net.minecraftforge.fml.common.eventhandler.SubscribeEvent; @@ -78,7 +79,7 @@ public void criticalWhenDisoriented(CriticalHitEvent e){ @Override - public void onEntityDamaged(EntityLivingBase user, Entity entiti, int level) + public void onEntityDamagedAlt(EntityLivingBase user, Entity entiti, ItemStack stack, int level) { if(!(entiti instanceof EntityLivingBase)) return; diff --git a/src/main/java/com/Shultrea/Rin/Ench0_3_0/EnchantmentEnvenomed.java b/src/main/java/com/Shultrea/Rin/Ench0_3_0/EnchantmentEnvenomed.java index 9311923..14c1910 100644 --- a/src/main/java/com/Shultrea/Rin/Ench0_3_0/EnchantmentEnvenomed.java +++ b/src/main/java/com/Shultrea/Rin/Ench0_3_0/EnchantmentEnvenomed.java @@ -52,7 +52,7 @@ public boolean canApplyTogether(Enchantment fTest) } @Override - public void onEntityDamaged(EntityLivingBase user, Entity entiti, int level) + public void onEntityDamagedAlt(EntityLivingBase user, Entity entiti, ItemStack stack, int level) { if(!(entiti instanceof EntityLivingBase)) return; diff --git a/src/main/java/com/Shultrea/Rin/Ench0_3_0/EnchantmentLevitator.java b/src/main/java/com/Shultrea/Rin/Ench0_3_0/EnchantmentLevitator.java index 9dc6f07..908a753 100644 --- a/src/main/java/com/Shultrea/Rin/Ench0_3_0/EnchantmentLevitator.java +++ b/src/main/java/com/Shultrea/Rin/Ench0_3_0/EnchantmentLevitator.java @@ -53,7 +53,7 @@ public boolean canApplyTogether(Enchantment fTest) } @Override - public void onEntityDamaged(EntityLivingBase user, Entity entiti, int level) + public void onEntityDamagedAlt(EntityLivingBase user, Entity entiti, ItemStack stack, int level) { if(!(entiti instanceof EntityLivingBase)) return; diff --git a/src/main/java/com/Shultrea/Rin/Ench0_3_0/EnchantmentMoonlight.java b/src/main/java/com/Shultrea/Rin/Ench0_3_0/EnchantmentMoonlight.java index 97e03e9..36bc76b 100644 --- a/src/main/java/com/Shultrea/Rin/Ench0_3_0/EnchantmentMoonlight.java +++ b/src/main/java/com/Shultrea/Rin/Ench0_3_0/EnchantmentMoonlight.java @@ -12,6 +12,7 @@ import net.minecraft.entity.EntityLivingBase; import net.minecraft.init.MobEffects; import net.minecraft.inventory.EntityEquipmentSlot; +import net.minecraft.item.ItemStack; import net.minecraft.potion.PotionEffect; import net.minecraftforge.event.entity.living.LivingHurtEvent; import net.minecraftforge.fml.common.eventhandler.EventPriority; @@ -58,7 +59,7 @@ public boolean canApplyTogether(Enchantment fTest) } @Override - public void onEntityDamaged(EntityLivingBase user, Entity entiti, int level) + public void onEntityDamagedAlt(EntityLivingBase user, Entity entiti, ItemStack stack, int level) { if(!(entiti instanceof EntityLivingBase)) return; @@ -79,6 +80,10 @@ public void onEntityDamaged(EntityLivingBase user, Entity entiti, int level) @SubscribeEvent(priority = EventPriority.HIGHEST) public void onHurtEvent(LivingHurtEvent e){ if(!(EnchantmentsUtility.checkEventCondition(e, this))) return; + + if(this.isOffensivePetDisallowed(e.getSource().getImmediateSource(), e.getSource().getTrueSource())) + return; + EntityLivingBase attacker = (EntityLivingBase) e.getSource().getTrueSource(); e.setAmount(EnchantmentsUtility.reduceDamage(attacker, false, attacker.getHeldItemMainhand(), this) + e.getAmount()); diff --git a/src/main/java/com/Shultrea/Rin/Ench0_3_0/EnchantmentPurgingBlade.java b/src/main/java/com/Shultrea/Rin/Ench0_3_0/EnchantmentPurgingBlade.java index 64405f3..7fa68e6 100644 --- a/src/main/java/com/Shultrea/Rin/Ench0_3_0/EnchantmentPurgingBlade.java +++ b/src/main/java/com/Shultrea/Rin/Ench0_3_0/EnchantmentPurgingBlade.java @@ -74,6 +74,9 @@ public void HandleEnchant(LivingHurtEvent fEvent) if(EnchantmentHelper.getEnchantmentLevel(Smc_030.PurgingBlade, dmgSource) <= 0) return; + if(this.isOffensivePetDisallowed(fEvent.getSource().getImmediateSource(), fEvent.getSource().getTrueSource())) + return; + int levelPurging = EnchantmentHelper.getEnchantmentLevel(Smc_030.PurgingBlade, dmgSource); if(Math.random() <= 0.1 + (0.06f * levelPurging)){ diff --git a/src/main/java/com/Shultrea/Rin/Ench0_3_0/EnchantmentRaining.java b/src/main/java/com/Shultrea/Rin/Ench0_3_0/EnchantmentRaining.java index 84859e4..bd365d6 100644 --- a/src/main/java/com/Shultrea/Rin/Ench0_3_0/EnchantmentRaining.java +++ b/src/main/java/com/Shultrea/Rin/Ench0_3_0/EnchantmentRaining.java @@ -76,6 +76,9 @@ public void HandleEnchant(LivingHurtEvent fEvent){ if(EnchantmentHelper.getEnchantmentLevel(Smc_030.Raining, dmgSource) <= 0) return; + if(this.isOffensivePetDisallowed(fEvent.getSource().getImmediateSource(), fEvent.getSource().getTrueSource())) + return; + int levelRain = EnchantmentHelper.getEnchantmentLevel(Smc_030.Raining, dmgSource); float Damage = fEvent.getAmount(); diff --git a/src/main/java/com/Shultrea/Rin/Ench0_3_0/EnchantmentSunshine.java b/src/main/java/com/Shultrea/Rin/Ench0_3_0/EnchantmentSunshine.java index a945f04..f5c5928 100644 --- a/src/main/java/com/Shultrea/Rin/Ench0_3_0/EnchantmentSunshine.java +++ b/src/main/java/com/Shultrea/Rin/Ench0_3_0/EnchantmentSunshine.java @@ -12,6 +12,7 @@ import net.minecraft.entity.EntityLivingBase; import net.minecraft.init.MobEffects; import net.minecraft.inventory.EntityEquipmentSlot; +import net.minecraft.item.ItemStack; import net.minecraft.potion.PotionEffect; import net.minecraftforge.event.entity.living.LivingHurtEvent; import net.minecraftforge.fml.common.eventhandler.EventPriority; @@ -58,14 +59,14 @@ public boolean canApplyTogether(Enchantment fTest) } @Override - public void onEntityDamaged(EntityLivingBase user, Entity entiti, int level) + public void onEntityDamagedAlt(EntityLivingBase user, Entity entiti, ItemStack stack, int level) { if(!(entiti instanceof EntityLivingBase)) return; EntityLivingBase entity = (EntityLivingBase) entiti; - float damage = EnchantmentsUtility.reduceDamage(user, true, user.getHeldItemMainhand(), this); + float damage = EnchantmentsUtility.reduceDamage(user, true, stack, this); if(user.world.isDaytime() && EnchantmentsUtility.noBlockLight(user)){ if(!entity.isPotionActive(MobEffects.GLOWING)) @@ -81,6 +82,10 @@ public void onEntityDamaged(EntityLivingBase user, Entity entiti, int level) @SubscribeEvent(priority = EventPriority.HIGHEST) public void onHurtEvent(LivingHurtEvent e){ if(!(EnchantmentsUtility.checkEventCondition(e, this))) return; + + if(this.isOffensivePetDisallowed(e.getSource().getImmediateSource(), e.getSource().getTrueSource())) + return; + EntityLivingBase attacker = (EntityLivingBase) e.getSource().getTrueSource(); float damage = EnchantmentsUtility.reduceDamage(attacker, true, attacker.getHeldItemMainhand(), this); e.setAmount(damage + e.getAmount()); diff --git a/src/main/java/com/Shultrea/Rin/Ench0_3_0/EnchantmentThunderstorm.java b/src/main/java/com/Shultrea/Rin/Ench0_3_0/EnchantmentThunderstorm.java index 755b27a..81f7b5c 100644 --- a/src/main/java/com/Shultrea/Rin/Ench0_3_0/EnchantmentThunderstorm.java +++ b/src/main/java/com/Shultrea/Rin/Ench0_3_0/EnchantmentThunderstorm.java @@ -170,6 +170,8 @@ public void HandleEnchant(LivingHurtEvent fEvent){ if(EnchantmentHelper.getEnchantmentLevel(Smc_030.Thunderstorm, dmgSource) <= 0) return; + if(this.isOffensivePetDisallowed(fEvent.getSource().getImmediateSource(), fEvent.getSource().getTrueSource())) + return; int levelWeather = EnchantmentHelper.getEnchantmentLevel(Smc_030.Thunderstorm, dmgSource); diff --git a/src/main/java/com/Shultrea/Rin/Ench0_3_0/EnchantmentViper.java b/src/main/java/com/Shultrea/Rin/Ench0_3_0/EnchantmentViper.java index 4d3f18d..faf44b1 100644 --- a/src/main/java/com/Shultrea/Rin/Ench0_3_0/EnchantmentViper.java +++ b/src/main/java/com/Shultrea/Rin/Ench0_3_0/EnchantmentViper.java @@ -79,6 +79,9 @@ public void HandleEnchant(LivingHurtEvent fEvent) if(EnchantmentHelper.getEnchantmentLevel(Smc_030.Viper, dmgSource) <= 0) return; + if(this.isOffensivePetDisallowed(fEvent.getSource().getImmediateSource(), fEvent.getSource().getTrueSource())) + return; + int levelViper = EnchantmentHelper.getEnchantmentLevel(Smc_030.Viper, dmgSource); float forgeDamage = fEvent.getAmount(); diff --git a/src/main/java/com/Shultrea/Rin/Ench0_4_0/EnchantmentAdept.java b/src/main/java/com/Shultrea/Rin/Ench0_4_0/EnchantmentAdept.java index da81938..d9175c4 100644 --- a/src/main/java/com/Shultrea/Rin/Ench0_4_0/EnchantmentAdept.java +++ b/src/main/java/com/Shultrea/Rin/Ench0_4_0/EnchantmentAdept.java @@ -87,6 +87,9 @@ public void onDeath(LivingExperienceDropEvent fEvent){ if(lvl <= 0) return; + //Don't add experience to drops that otherwise would have no experience + if(fEvent.getOriginalExperience() <= 0) + return; if(fEvent.getEntityLiving() != null && !fEvent.getEntityLiving().isNonBoss()) fEvent.setDroppedExperience(2 + lvl + (int)(fEvent.getOriginalExperience() * (0.75f + 0.5f * lvl))); diff --git a/src/main/java/com/Shultrea/Rin/Ench0_4_0/EnchantmentAncient_CurseInflicter.java b/src/main/java/com/Shultrea/Rin/Ench0_4_0/EnchantmentAncient_CurseInflicter.java index d250e6d..71b2b90 100644 --- a/src/main/java/com/Shultrea/Rin/Ench0_4_0/EnchantmentAncient_CurseInflicter.java +++ b/src/main/java/com/Shultrea/Rin/Ench0_4_0/EnchantmentAncient_CurseInflicter.java @@ -64,7 +64,7 @@ public boolean isTreasureEnchantment() { } @Override - public void onEntityDamaged(EntityLivingBase user, Entity target, int level){ + public void onEntityDamagedAlt(EntityLivingBase user, Entity target, ItemStack stackIn, int level){ if(target instanceof EntityLivingBase){ EntityLivingBase entity = (EntityLivingBase) target; diff --git a/src/main/java/com/Shultrea/Rin/Ench0_4_0/EnchantmentBrutality.java b/src/main/java/com/Shultrea/Rin/Ench0_4_0/EnchantmentBrutality.java index 4012336..f79ec86 100644 --- a/src/main/java/com/Shultrea/Rin/Ench0_4_0/EnchantmentBrutality.java +++ b/src/main/java/com/Shultrea/Rin/Ench0_4_0/EnchantmentBrutality.java @@ -44,7 +44,7 @@ public int getMaxEnchantability(int par1) } @Override - public void onEntityDamaged(EntityLivingBase user, Entity target, int level) + public void onEntityDamagedAlt(EntityLivingBase user, Entity target, ItemStack stack, int level) { if(!ModConfig.enabled.Brutality) return; diff --git a/src/main/java/com/Shultrea/Rin/Ench0_4_0/EnchantmentCurseofVulnerability.java b/src/main/java/com/Shultrea/Rin/Ench0_4_0/EnchantmentCurseofVulnerability.java index 4981217..625630a 100644 --- a/src/main/java/com/Shultrea/Rin/Ench0_4_0/EnchantmentCurseofVulnerability.java +++ b/src/main/java/com/Shultrea/Rin/Ench0_4_0/EnchantmentCurseofVulnerability.java @@ -75,7 +75,9 @@ public void onDamage(LivingDamageEvent e){ return; int level = EnchantmentHelper.getMaxEnchantmentLevel(this, e.getEntityLiving()); - if(level > 0) + if(level <= 0) + return; + e.setAmount(e.getAmount() * (1 + level * 0.40f)); } diff --git a/src/main/java/com/Shultrea/Rin/Ench0_4_0/EnchantmentDarkShadows.java b/src/main/java/com/Shultrea/Rin/Ench0_4_0/EnchantmentDarkShadows.java index c55afe8..8811920 100644 --- a/src/main/java/com/Shultrea/Rin/Ench0_4_0/EnchantmentDarkShadows.java +++ b/src/main/java/com/Shultrea/Rin/Ench0_4_0/EnchantmentDarkShadows.java @@ -60,7 +60,7 @@ public boolean canApplyTogether(Enchantment fTest) } @Override - public void onEntityDamaged(EntityLivingBase user, Entity entiti, int level) + public void onEntityDamagedAlt(EntityLivingBase user, Entity entiti, ItemStack stack, int level) { if(level >= 3 && entiti instanceof EntityLivingBase){ EntityLivingBase e = (EntityLivingBase) entiti; @@ -77,6 +77,9 @@ public void onEvent(LivingHurtEvent e){ EntityLivingBase attacker = (EntityLivingBase) e.getSource().getTrueSource(); int level = EnchantmentHelper.getEnchantmentLevel(this, attacker.getHeldItemMainhand()); if(level <= 0) return; + if(this.isOffensivePetDisallowed(e.getSource().getImmediateSource(), e.getSource().getTrueSource())) + return; + if(attacker.getBrightness() <= 0.1f && e.getEntityLiving().getBrightness() <= 0.1f) e.setAmount(e.getAmount() + level * 0.75f); diff --git a/src/main/java/com/Shultrea/Rin/Ench0_4_0/EnchantmentDifficultyScaled.java b/src/main/java/com/Shultrea/Rin/Ench0_4_0/EnchantmentDifficultyScaled.java index a01801c..c4e7903 100644 --- a/src/main/java/com/Shultrea/Rin/Ench0_4_0/EnchantmentDifficultyScaled.java +++ b/src/main/java/com/Shultrea/Rin/Ench0_4_0/EnchantmentDifficultyScaled.java @@ -96,6 +96,9 @@ public void HandleEnchant(LivingDamageEvent fEvent) if(EnchantmentHelper.getEnchantmentLevel(this, dmgSource) <= 0) return; + if(this.isOffensivePetDisallowed(fEvent.getSource().getImmediateSource(), fEvent.getSource().getTrueSource())) + return; + int level = EnchantmentHelper.getEnchantmentLevel(this, dmgSource); if(attacker.getEntityWorld().getDifficulty() == EnumDifficulty.HARD){ diff --git a/src/main/java/com/Shultrea/Rin/Ench0_4_0/EnchantmentDisarmament.java b/src/main/java/com/Shultrea/Rin/Ench0_4_0/EnchantmentDisarmament.java index 9cbf26b..70c4f97 100644 --- a/src/main/java/com/Shultrea/Rin/Ench0_4_0/EnchantmentDisarmament.java +++ b/src/main/java/com/Shultrea/Rin/Ench0_4_0/EnchantmentDisarmament.java @@ -67,6 +67,10 @@ public void HandleEnchant(LivingHurtEvent fEvent) if(EnchantmentHelper.getEnchantmentLevel(Smc_040.Disarmament, dmgSource) <= 0) return; + + if(this.isOffensivePetDisallowed(fEvent.getSource().getImmediateSource(), fEvent.getSource().getTrueSource())) + return; + int leveldisarm = EnchantmentHelper.getEnchantmentLevel(Smc_040.Disarmament, dmgSource); if(Math.random() * 100 < 25) diff --git a/src/main/java/com/Shultrea/Rin/Ench0_4_0/EnchantmentFAtier.java b/src/main/java/com/Shultrea/Rin/Ench0_4_0/EnchantmentFAtier.java index 5a5f1b6..7791487 100644 --- a/src/main/java/com/Shultrea/Rin/Ench0_4_0/EnchantmentFAtier.java +++ b/src/main/java/com/Shultrea/Rin/Ench0_4_0/EnchantmentFAtier.java @@ -109,7 +109,7 @@ public boolean isTreasureEnchantment() { * Called whenever a mob is damaged with an item that has this enchantment on it. */ @Override - public void onEntityDamaged(EntityLivingBase user, Entity target, int level) + public void onEntityDamagedAlt(EntityLivingBase user, Entity target, ItemStack stack, int level) { if(!isEnabled()) return; diff --git a/src/main/java/com/Shultrea/Rin/Ench0_4_0/EnchantmentFlinging.java b/src/main/java/com/Shultrea/Rin/Ench0_4_0/EnchantmentFlinging.java index ef73977..cf7a01b 100644 --- a/src/main/java/com/Shultrea/Rin/Ench0_4_0/EnchantmentFlinging.java +++ b/src/main/java/com/Shultrea/Rin/Ench0_4_0/EnchantmentFlinging.java @@ -59,9 +59,8 @@ public boolean canApplyTogether(Enchantment fTest) } @Override - public void onEntityDamaged (EntityLivingBase user, Entity target, int level) { + public void onEntityDamagedAlt(EntityLivingBase user, Entity target, ItemStack stack, int level) { - ItemStack stack = user.getHeldItemMainhand(); int levelknockBack = EnchantmentHelper.getEnchantmentLevel(Smc_040.flinging, stack); double Y = levelknockBack * 0.1875D + 0.075f; diff --git a/src/main/java/com/Shultrea/Rin/Ench0_4_0/EnchantmentFreezing.java b/src/main/java/com/Shultrea/Rin/Ench0_4_0/EnchantmentFreezing.java index adc8f9e..8f54d45 100644 --- a/src/main/java/com/Shultrea/Rin/Ench0_4_0/EnchantmentFreezing.java +++ b/src/main/java/com/Shultrea/Rin/Ench0_4_0/EnchantmentFreezing.java @@ -84,6 +84,9 @@ public void onEntityDamaged(LivingDamageEvent fEvent){ if(level <= 0) return; + if(this.isOffensivePetDisallowed(fEvent.getSource().getImmediateSource(), fEvent.getSource().getTrueSource())) + return; + EntityLivingBase victim = fEvent.getEntityLiving(); int ice = 0; diff --git a/src/main/java/com/Shultrea/Rin/Ench0_4_0/EnchantmentHors_de_combat.java b/src/main/java/com/Shultrea/Rin/Ench0_4_0/EnchantmentHors_de_combat.java index 5280d1a..742a6c8 100644 --- a/src/main/java/com/Shultrea/Rin/Ench0_4_0/EnchantmentHors_de_combat.java +++ b/src/main/java/com/Shultrea/Rin/Ench0_4_0/EnchantmentHors_de_combat.java @@ -55,7 +55,7 @@ public boolean canApplyTogether(Enchantment fTest) } @Override - public void onEntityDamaged(EntityLivingBase user, Entity victims, int level) + public void onEntityDamagedAlt(EntityLivingBase user, Entity victims, ItemStack stack, int level) { if(!isEnabled()) diff --git a/src/main/java/com/Shultrea/Rin/Ench0_4_0/EnchantmentInhumanity.java b/src/main/java/com/Shultrea/Rin/Ench0_4_0/EnchantmentInhumanity.java index 3045ad3..9ce1c7d 100644 --- a/src/main/java/com/Shultrea/Rin/Ench0_4_0/EnchantmentInhumanity.java +++ b/src/main/java/com/Shultrea/Rin/Ench0_4_0/EnchantmentInhumanity.java @@ -64,7 +64,7 @@ public boolean canApply(ItemStack fTest) } @Override - public void onEntityDamaged(EntityLivingBase user, Entity entiti, int level) + public void onEntityDamagedAlt(EntityLivingBase user, Entity entiti, ItemStack stack, int level) { if(!ModConfig.enabled.Inhumane) return; diff --git a/src/main/java/com/Shultrea/Rin/Ench0_4_0/EnchantmentInnerBerserk.java b/src/main/java/com/Shultrea/Rin/Ench0_4_0/EnchantmentInnerBerserk.java index 8c751ed..5b2c467 100644 --- a/src/main/java/com/Shultrea/Rin/Ench0_4_0/EnchantmentInnerBerserk.java +++ b/src/main/java/com/Shultrea/Rin/Ench0_4_0/EnchantmentInnerBerserk.java @@ -56,6 +56,9 @@ public void HandleEnchant(LivingDamageEvent fEvent) if(EnchantmentHelper.getMaxEnchantmentLevel(this, attacker) > 0) { + if(this.isOffensivePetDisallowed(fEvent.getSource().getImmediateSource(), fEvent.getSource().getTrueSource())) + return; + float defenderHealthPercent = attacker.getHealth() / attacker.getMaxHealth(); int levelfinish = EnchantmentHelper.getMaxEnchantmentLevel(this, attacker); float dmgMod = (1.0f - defenderHealthPercent) * ((levelfinish * 0.05f) + 1.1f); diff --git a/src/main/java/com/Shultrea/Rin/Ench0_4_0/EnchantmentReinforcedSharpness.java b/src/main/java/com/Shultrea/Rin/Ench0_4_0/EnchantmentReinforcedSharpness.java index 9f951b3..2b655f7 100644 --- a/src/main/java/com/Shultrea/Rin/Ench0_4_0/EnchantmentReinforcedSharpness.java +++ b/src/main/java/com/Shultrea/Rin/Ench0_4_0/EnchantmentReinforcedSharpness.java @@ -7,7 +7,6 @@ import com.Shultrea.Rin.Main_Sector.ModConfig; import net.minecraft.enchantment.Enchantment; -import net.minecraft.enchantment.Enchantment.Rarity; import net.minecraft.enchantment.EnchantmentDamage; import net.minecraft.entity.Entity; import net.minecraft.entity.EntityLivingBase; @@ -67,7 +66,7 @@ public float calcDamageByCreature(int level, EnumCreatureAttribute creatureType) } @Override - public void onEntityDamaged(EntityLivingBase user, Entity target, int level) + public void onEntityDamagedAlt(EntityLivingBase user, Entity target, ItemStack stack, int level) { if(ModConfig.enabled.SharperEdge && target instanceof EntityLivingBase && user instanceof EntityPlayer){ EntityLivingBase victim = (EntityLivingBase) target; diff --git a/src/main/java/com/Shultrea/Rin/Ench0_4_0/EnchantmentSubjectEnchantments.java b/src/main/java/com/Shultrea/Rin/Ench0_4_0/EnchantmentSubjectEnchantments.java index 28422c4..461ff29 100644 --- a/src/main/java/com/Shultrea/Rin/Ench0_4_0/EnchantmentSubjectEnchantments.java +++ b/src/main/java/com/Shultrea/Rin/Ench0_4_0/EnchantmentSubjectEnchantments.java @@ -151,7 +151,7 @@ public boolean canApply(ItemStack stack) } @Override - public void onEntityDamaged(EntityLivingBase user, Entity target, int level) + public void onEntityDamagedAlt(EntityLivingBase user, Entity target, ItemStack stack, int level) { if (target instanceof EntityLivingBase) { diff --git a/src/main/java/com/Shultrea/Rin/Ench0_4_0/EnchantmentSwiper.java b/src/main/java/com/Shultrea/Rin/Ench0_4_0/EnchantmentSwiper.java index ff039bb..defcad4 100644 --- a/src/main/java/com/Shultrea/Rin/Ench0_4_0/EnchantmentSwiper.java +++ b/src/main/java/com/Shultrea/Rin/Ench0_4_0/EnchantmentSwiper.java @@ -99,6 +99,9 @@ public void HandleEnchant(LivingDamageEvent fEvent) if(EnchantmentHelper.getEnchantmentLevel(Smc_040.Swiper, dmgSource) <= 0) return; + + if(this.isOffensivePetDisallowed(fEvent.getSource().getImmediateSource(), fEvent.getSource().getTrueSource())) + return; int levitationLevel = EnchantmentHelper.getEnchantmentLevel(Smc_030.Levitator, dmgSource); @@ -125,7 +128,8 @@ public void HandleEnchant(LivingDamageEvent fEvent) if(target == fEvent.getEntityLiving()) continue; - if(target.getDistance(attacker) > 4.00f + levelCleave * 0.25f) + //Old value was 4.00f + if(target.getDistance(attacker) > 3.00f + levelCleave * 0.25f) continue; Vec3d attackerCheck = EnchantmentsUtility.Cleave(target.posX-attacker.posX, target.posY-attacker.posY, target.posZ-attacker.posZ); @@ -136,14 +140,14 @@ public void HandleEnchant(LivingDamageEvent fEvent) // This is within our arc, let's deal our damage. DamageSource source = null; if(attacker instanceof EntityPlayer){ - source = new EntityDamageSource("playerCleave", attacker).setDamageBypassesArmor(); + source = new EntityDamageSource("playerCleave", attacker);//.setDamageBypassesArmor(); target.attackEntityFrom(source, splashDamage); target.setFire(lf); if(levitationLevel > 0) ((EntityLivingBase) target).addPotionEffect(new PotionEffect(MobEffects.LEVITATION, 30 + (levitationLevel * 12), 1 + levitationLevel)); } if(attacker instanceof EntityMob){ - source = new EntityDamageSource("mobCleave", attacker).setDamageBypassesArmor(); + source = new EntityDamageSource("mobCleave", attacker);//.setDamageBypassesArmor(); target.attackEntityFrom(source, splashDamage); target.setFire(lf); if(levitationLevel > 0) diff --git a/src/main/java/com/Shultrea/Rin/Ench0_4_0/EnchantmentTierDamage.java b/src/main/java/com/Shultrea/Rin/Ench0_4_0/EnchantmentTierDamage.java index 64606e9..96374b5 100644 --- a/src/main/java/com/Shultrea/Rin/Ench0_4_0/EnchantmentTierDamage.java +++ b/src/main/java/com/Shultrea/Rin/Ench0_4_0/EnchantmentTierDamage.java @@ -137,7 +137,7 @@ public boolean canApply(ItemStack stack) } @Override - public void onEntityDamaged(EntityLivingBase user, Entity target, int level) + public void onEntityDamagedAlt(EntityLivingBase user, Entity target, ItemStack stack, int level) { if (target instanceof EntityLivingBase) { diff --git a/src/main/java/com/Shultrea/Rin/Ench0_4_5/EnchantmentInstability.java b/src/main/java/com/Shultrea/Rin/Ench0_4_5/EnchantmentInstability.java index da279e4..e8ddd76 100644 --- a/src/main/java/com/Shultrea/Rin/Ench0_4_5/EnchantmentInstability.java +++ b/src/main/java/com/Shultrea/Rin/Ench0_4_5/EnchantmentInstability.java @@ -77,6 +77,9 @@ public void onAttack(LivingDamageEvent e) { if(level <= 0) return; + if(this.isOffensivePetDisallowed(e.getSource().getImmediateSource(), e.getSource().getTrueSource())) + return; + float percentage = ((float)stack.getItemDamage() / (float)stack.getMaxDamage()); //System.out.println(percentage + " percentage"); diff --git a/src/main/java/com/Shultrea/Rin/Ench0_4_5/EnchantmentMastery.java b/src/main/java/com/Shultrea/Rin/Ench0_4_5/EnchantmentMastery.java index bd60475..9338346 100644 --- a/src/main/java/com/Shultrea/Rin/Ench0_4_5/EnchantmentMastery.java +++ b/src/main/java/com/Shultrea/Rin/Ench0_4_5/EnchantmentMastery.java @@ -89,6 +89,12 @@ public void HandleEnchant(LivingHurtEvent e) if(EnchantmentHelper.getEnchantmentLevel(this, stack) <= 0) return; + if(this.isOffensivePetDisallowed(e.getSource().getImmediateSource(), e.getSource().getTrueSource())) + return; + + if(this.isOffensivePetDisallowed(e.getSource().getImmediateSource(), e.getSource().getTrueSource())) + return; + if(!stack.hasTagCompound()) stack.setTagCompound(new NBTTagCompound()); diff --git a/src/main/java/com/Shultrea/Rin/Enchantment_Base_Sector/EnchantmentBase.java b/src/main/java/com/Shultrea/Rin/Enchantment_Base_Sector/EnchantmentBase.java index 007817d..6802bbf 100644 --- a/src/main/java/com/Shultrea/Rin/Enchantment_Base_Sector/EnchantmentBase.java +++ b/src/main/java/com/Shultrea/Rin/Enchantment_Base_Sector/EnchantmentBase.java @@ -1,7 +1,12 @@ package com.Shultrea.Rin.Enchantment_Base_Sector; +import com.Shultrea.Rin.Main_Sector.ModConfig; + import net.minecraft.enchantment.Enchantment; import net.minecraft.enchantment.EnumEnchantmentType; +import net.minecraft.entity.Entity; +import net.minecraft.entity.EntityLivingBase; +import net.minecraft.entity.player.EntityPlayer; import net.minecraft.inventory.EntityEquipmentSlot; import net.minecraft.item.ItemStack; import net.minecraft.util.text.TextFormatting; @@ -146,4 +151,39 @@ public String getPrefix() { return ""; } + + public void onEntityDamagedAlt(EntityLivingBase user, Entity target, ItemStack weapon, int level) + { + + } + + /** Use onEntityDamagedAlt **/ + @Override + @Deprecated + public final void onEntityDamaged(EntityLivingBase user, Entity target, int level) + { + super.onEntityDamaged(user, target, level); + } + + /** Returns whether the combination of sources is disallowed for all enchantments **/ + public static boolean isOffensivePetDisallowed(Entity immediateSource, Entity trueSource) + { + if(immediateSource == null || trueSource == null) + return false; + + if(!ModConfig.miscellaneous.enablePetAttacks) + { + //Immediate is not true source + //Immediate is a living entity + //True source is a player + //Immediate is not a player + if(immediateSource != trueSource && immediateSource instanceof EntityLivingBase && trueSource instanceof EntityPlayer && !(immediateSource instanceof EntityPlayer)) + { + return true; + } + } + + //Passed all checks + return false; + } } diff --git a/src/main/java/com/Shultrea/Rin/Hook/HookArthropod.java b/src/main/java/com/Shultrea/Rin/Hook/HookArthropod.java new file mode 100644 index 0000000..aa76ca7 --- /dev/null +++ b/src/main/java/com/Shultrea/Rin/Hook/HookArthropod.java @@ -0,0 +1,99 @@ +package com.Shultrea.Rin.Hook; + +import javax.annotation.Nullable; + +import com.Shultrea.Rin.Enchantment_Base_Sector.EnchantmentBase; + +import net.minecraft.enchantment.Enchantment; +import net.minecraft.entity.Entity; +import net.minecraft.entity.EntityLivingBase; +import net.minecraft.item.ItemStack; +import net.minecraft.nbt.NBTTagList; + +public class HookArthropod +{ + //com/Shultrea/Rin/Hook/HookArthropod + //handleArthropod + //(Lnet/minecraft/entity/EntityLivingBase;Lnet/minecraft/entity/Entity;Z)V + public static void handleArthropod(EntityLivingBase user, Entity target, boolean offhand) + { + //System.out.println("handleArthropod: "+offhand); + + if (user != null) + { + ItemStack stack = offhand ? user.getHeldItemOffhand() : user.getHeldItemMainhand(); + if (!stack.isEmpty()) + { + NBTTagList nbttaglist = stack.getEnchantmentTagList(); + + for (int i = 0; i < nbttaglist.tagCount(); ++i) + { + int j = nbttaglist.getCompoundTagAt(i).getShort("id"); + int k = nbttaglist.getCompoundTagAt(i).getShort("lvl"); + + if (Enchantment.getEnchantmentByID(j) != null) + { + Enchantment ench = Enchantment.getEnchantmentByID(j); + if(ench instanceof EnchantmentBase) + { + EnchantmentBase enchant = (EnchantmentBase) ench; + if(enchant.isEnabled()) + enchant.onEntityDamagedAlt(user, target, stack, k); + } + } + } + } + } + } + + //com/Shultrea/Rin/Hook/HookArthropod + //hookArthropod + //(Lnet/minecraft/entity/EntityLivingBase;Lnet/minecraft/entity/Entity;)V + public static void hookArthropod(EntityLivingBase user, Entity target) + { + if (user != null) + { + boolean offhand = false; + + //FIXME check only if bettercombat is loaded + if(stackTraceHasClass("bettercombat.mod.network.PacketOffhandAttack$Handler")) + offhand = true; + + ItemStack stack = offhand ? user.getHeldItemOffhand() : user.getHeldItemMainhand(); + + if (!stack.isEmpty()) + { + NBTTagList nbttaglist = stack.getEnchantmentTagList(); + + for (int i = 0; i < nbttaglist.tagCount(); ++i) + { + int j = nbttaglist.getCompoundTagAt(i).getShort("id"); + int k = nbttaglist.getCompoundTagAt(i).getShort("lvl"); + + if (Enchantment.getEnchantmentByID(j) != null) + { + Enchantment ench = Enchantment.getEnchantmentByID(j); + if(ench instanceof EnchantmentBase) + { + EnchantmentBase enchant = (EnchantmentBase) ench; + if(enchant.isEnabled()) + enchant.onEntityDamagedAlt(user, target, stack, k); + } + } + } + } + } + } + + /** Check if the stack trace contains a class **/ + public static boolean stackTraceHasClass(String clazz) + { + for(StackTraceElement ste : Thread.currentThread().getStackTrace()) + { + if(ste.getClassName().equals(clazz)) + return true; + } + + return false; + } +} diff --git a/src/main/java/com/Shultrea/Rin/Hook/HookHelper.java b/src/main/java/com/Shultrea/Rin/Hook/HookHelper.java new file mode 100644 index 0000000..60d966b --- /dev/null +++ b/src/main/java/com/Shultrea/Rin/Hook/HookHelper.java @@ -0,0 +1,38 @@ +package com.Shultrea.Rin.Hook; + +import com.Shultrea.Rin.Ench0_3_0.EnchantmentAdvancedBlastProtection; +import com.Shultrea.Rin.Ench0_3_0.EnchantmentAdvancedLooting; +import com.Shultrea.Rin.Ench0_3_0.EnchantmentAdvancedLuckOfTheSea; +import com.Shultrea.Rin.Ench0_3_0.EnchantmentAdvancedLure; + +import net.minecraft.entity.EntityLivingBase; +import net.minecraft.item.ItemStack; + +public class HookHelper +{ + //Enchantment Helper hooks + + public static int modifyFishingLuckBonus(int original, ItemStack stack) + { + return Math.max(original, EnchantmentAdvancedLuckOfTheSea.getValue(stack)); + } + + public static int modifyFishingSpeedBonus(int original, ItemStack stack) + { + return Math.max(original, EnchantmentAdvancedLure.getValue(stack)); + } + + public static int modifyLootingModifier(int original, EntityLivingBase entity) + { + return Math.max(original, EnchantmentAdvancedLooting.getValue(original, entity)); + } + + + //EnchantmentProtection hooks + + //This is actually knockback, but whatever + public static double modifyBlastDamageReduction(double damage, EntityLivingBase entity) + { + return EnchantmentAdvancedBlastProtection.getKnockbackValue(damage, entity); + } +} diff --git a/src/main/java/com/Shultrea/Rin/Main_Sector/ModConfig.java b/src/main/java/com/Shultrea/Rin/Main_Sector/ModConfig.java index 56c1bc2..bf87557 100644 --- a/src/main/java/com/Shultrea/Rin/Main_Sector/ModConfig.java +++ b/src/main/java/com/Shultrea/Rin/Main_Sector/ModConfig.java @@ -67,6 +67,14 @@ public static class MiscellaneousConfig @Config.Name("Potion Blacklist as Whitelist") @Config.RequiresMcRestart public boolean potionBlacklistAsWhitelist = false; + + @Config.Comment("Whether enchantments should work with pet attacks") + @Config.Name("Enable Pet Attacks") + public boolean enablePetAttacks = false; + + @Config.Comment("Enables extra protection effects") + @Config.Name("Extra Protection Effects") + public boolean extraProtectionEffects = true; } @Mod.EventBusSubscriber(modid = somanyenchantments.MODID) diff --git a/src/main/java/com/Shultrea/Rin/Main_Sector/somanyenchantments.java b/src/main/java/com/Shultrea/Rin/Main_Sector/somanyenchantments.java index c881c02..c6fc469 100644 --- a/src/main/java/com/Shultrea/Rin/Main_Sector/somanyenchantments.java +++ b/src/main/java/com/Shultrea/Rin/Main_Sector/somanyenchantments.java @@ -39,7 +39,7 @@ public class somanyenchantments { // Mod Info public static final String MODID = "somanyenchantments"; public static final String NAME = "Rin's So Many Enchantments?"; - public static final String VERSION = "0.5.2"; + public static final String VERSION = "0.5.3"; // Mod Info End //Boolean diff --git a/src/main/java/com/Shultrea/Rin/Transformer/CoreLoader.java b/src/main/java/com/Shultrea/Rin/Transformer/CoreLoader.java new file mode 100644 index 0000000..8783574 --- /dev/null +++ b/src/main/java/com/Shultrea/Rin/Transformer/CoreLoader.java @@ -0,0 +1,50 @@ +package com.Shultrea.Rin.Transformer; + +import java.util.Map; + +import com.Shultrea.Rin.Transformer.helper.ObfHelper; + +import net.minecraftforge.fml.relauncher.IFMLLoadingPlugin; + +@IFMLLoadingPlugin.Name("SoManyEnchantments ASM") +@IFMLLoadingPlugin.SortingIndex(1002) +@IFMLLoadingPlugin.TransformerExclusions({ "com.Shultrea.Rin.Transformer", "com.Shultrea.Rin.Transformer." }) + +public class CoreLoader implements IFMLLoadingPlugin +{ + // + // IFMLLoadingPlugin + // + + @Override + public String[] getASMTransformerClass() + { + return new String[] { "com.Shultrea.Rin.Transformer.SMEASM" }; + } + + @Override + public void injectData(Map data) + { + ObfHelper.setObfuscated((Boolean) data.get("runtimeDeobfuscationEnabled")); + ObfHelper.setRunsAfterDeobfRemapper(true); + } + + @Override + public String getModContainerClass() + { + return null; + } + + @Override + public String getSetupClass() + { + return null; + } + + @Override + public String getAccessTransformerClass() + { + return null; + } +} + diff --git a/src/main/java/com/Shultrea/Rin/Transformer/SMEASM.java b/src/main/java/com/Shultrea/Rin/Transformer/SMEASM.java new file mode 100644 index 0000000..53418e2 --- /dev/null +++ b/src/main/java/com/Shultrea/Rin/Transformer/SMEASM.java @@ -0,0 +1,278 @@ +package com.Shultrea.Rin.Transformer; + +import javax.annotation.Nullable; + +import org.objectweb.asm.ClassWriter; +import org.objectweb.asm.Opcodes; +import org.objectweb.asm.tree.AbstractInsnNode; +import org.objectweb.asm.tree.ClassNode; +import org.objectweb.asm.tree.InsnList; +import org.objectweb.asm.tree.InsnNode; +import org.objectweb.asm.tree.MethodInsnNode; +import org.objectweb.asm.tree.MethodNode; +import org.objectweb.asm.tree.VarInsnNode; + +import com.Shultrea.Rin.Transformer.helper.ASMHelper; +import com.Shultrea.Rin.Transformer.util.TransformUtil; + +import net.minecraft.launchwrapper.IClassTransformer; + +public class SMEASM implements IClassTransformer +{ + + @Override + public byte[] transform(String name, String transformedName, byte[] basicClass) + { + /* + if(transformedName.equals("net.minecraft.entity.Entity")) + { + System.out.println("Patching Entity"); + return patchEntity(basicClass); + } + + if(transformedName.equals("net.minecraft.entity.player.EntityPlayer")) + { + System.out.println("Patching EntityPlayer"); + return patchPlayer(basicClass); + } + + if(transformedName.equals("bettercombat.mod.util.Helpers")) + { + System.out.println("Patching BetterCombat Helpers"); + return patchBetterCombat(basicClass); + } + */ + + if(transformedName.equals("net.minecraft.enchantment.EnchantmentHelper")) + { + System.out.println("Patching EnchantmentHelper"); + return patchEnchantmentHelper(basicClass); + } + + if(transformedName.equals("net.minecraft.enchantment.EnchantmentProtection")) + { + System.out.println("Patching EnchantmentProtection"); + return patchEnchantmentProtection(basicClass); + } + + return basicClass; + } + + private byte[] patchEnchantmentHelper(byte[] basicClass) + { + ClassNode clazzNode = ASMHelper.readClassFromBytes(basicClass); + + for(MethodNode m : clazzNode.methods) + { + if(m.name.equals("func_151385_b") || m.name.equals("applyArthropodEnchantments")) + { + hookArthropod(m); + } + else if(m.name.equals("func_191529_b") || m.name.equals("getFishingLuckBonus")) + { + hookAllIntegerReturn(m, "com/Shultrea/Rin/Hook/HookHelper", "modifyFishingLuckBonus", "(ILnet/minecraft/item/ItemStack;)I", aload(0)); + } + else if(m.name.equals("func_191528_c") || m.name.equals("getFishingSpeedBonus")) + { + hookAllIntegerReturn(m, "com/Shultrea/Rin/Hook/HookHelper", "modifyFishingSpeedBonus", "(ILnet/minecraft/item/ItemStack;)I", aload(0)); + } + else if(m.name.equals("func_185283_h") || m.name.equals("getLootingModifier")) + { + hookAllIntegerReturn(m, "com/Shultrea/Rin/Hook/HookHelper", "modifyLootingModifier", "(ILnet/minecraft/entity/EntityLivingBase;)I", aload(0)); + } + } + + return ASMHelper.writeClassToBytes(clazzNode, ClassWriter.COMPUTE_MAXS | ClassWriter.COMPUTE_FRAMES); + } + + private byte[] patchEnchantmentProtection(byte[] basicClass) + { + ClassNode clazzNode = ASMHelper.readClassFromBytes(basicClass); + + for(MethodNode m : clazzNode.methods) + { + //TODO fire duration, I guess + + if(m.name.equals("func_92092_a") || m.name.equals("getBlastDamageReduction")) + { + hookAllDoubleReturn(m, "com/Shultrea/Rin/Hook/HookHelper", "modifyBlastDamageReduction", "(DLnet/minecraft/entity/EntityLivingBase;)D", aload(0)); + } + } + + return ASMHelper.writeClassToBytes(clazzNode, ClassWriter.COMPUTE_MAXS | ClassWriter.COMPUTE_FRAMES); + } + + private void hookAllIntegerReturn(MethodNode m, String owner, String name, String desc, AbstractInsnNode... loads) + { + AbstractInsnNode anchor = m.instructions.getFirst(); + while(anchor.getNext() != null) + { + if(anchor.getOpcode() == Opcodes.IRETURN) + { + InsnList insert = new InsnList(); + for(AbstractInsnNode node : loads) + insert.add(node); + insert.add(new MethodInsnNode(Opcodes.INVOKESTATIC, owner, name, desc, false)); + m.instructions.insertBefore(anchor, insert); + + //(int on stack) + //IRETURN + + //--> + + //(int on stack) + //ALOAD 0 (ItemStack) + //HookHelper.modifyFishingLuckBonus(intonstack, stack) + //IRETURN + } + anchor = anchor.getNext(); + } + } + + private void hookAllDoubleReturn(MethodNode m, String owner, String name, String desc, AbstractInsnNode... loads) + { + AbstractInsnNode anchor = m.instructions.getFirst(); + while(anchor.getNext() != null) + { + if(anchor.getOpcode() == Opcodes.DRETURN) + { + InsnList insert = new InsnList(); + for(AbstractInsnNode node : loads) + insert.add(node); + insert.add(new MethodInsnNode(Opcodes.INVOKESTATIC, owner, name, desc, false)); + m.instructions.insertBefore(anchor, insert); + } + anchor = anchor.getNext(); + } + } + + private VarInsnNode aload(int loadvalue) + { + return new VarInsnNode(Opcodes.ALOAD, loadvalue); + } + + private void hookArthropod(MethodNode m) + { + InsnList insert = new InsnList(); + insert.add(new VarInsnNode(Opcodes.ALOAD, 0)); //entityLivingBaseIn + insert.add(new VarInsnNode(Opcodes.ALOAD, 1)); //entityIn + insert.add(new MethodInsnNode( + Opcodes.INVOKESTATIC, + "com/Shultrea/Rin/Hook/HookArthropod", + "hookArthropod", + "(Lnet/minecraft/entity/EntityLivingBase;Lnet/minecraft/entity/Entity;)V", + false + )); + TransformUtil.insertBeforeFirst(m, insert); + } + + private byte[] patchBetterCombat(byte[] basicClass) + { + ClassNode clazzNode = ASMHelper.readClassFromBytes(basicClass); + + for(MethodNode m : clazzNode.methods) + { + if(m.name.equals("attackTargetEntityItem")) + { + hookBetterCombatArthropod(m); + } + } + + return ASMHelper.writeClassToBytes(clazzNode, ClassWriter.COMPUTE_MAXS); + } + + private byte[] patchEntity(byte[] basicClass) + { + ClassNode clazzNode = ASMHelper.readClassFromBytes(basicClass); + + for(MethodNode m : clazzNode.methods) + { + if(m.name.equals("func_174815_a") || m.name.equals("applyEnchantments")) + { + hookEntityArthropod(m); + } + } + + return ASMHelper.writeClassToBytes(clazzNode, ClassWriter.COMPUTE_MAXS); + } + + private byte[] patchPlayer(byte[] basicClass) + { + ClassNode clazzNode = ASMHelper.readClassFromBytes(basicClass); + + for(MethodNode m : clazzNode.methods) + { + if(m.name.equals("func_71059_n") || m.name.equals("attackTargetEntityWithCurrentItem")) + { + hookPlayerArthropod(m); + } + } + + return ASMHelper.writeClassToBytes(clazzNode, ClassWriter.COMPUTE_MAXS); + } + + private void hookEntityArthropod(MethodNode m) + { + //Hook to be false only + + AbstractInsnNode anchor = getArthropodInvoke(m); + if(anchor == null) + return; + + InsnList insert = new InsnList(); + insert.add(new VarInsnNode(Opcodes.ALOAD, 1)); //entityLivingBaseIn + insert.add(new VarInsnNode(Opcodes.ALOAD, 2)); //entityIn + insert.add(new InsnNode(Opcodes.ICONST_0)); //false + insert.add(getNewArthropodHook()); + m.instructions.insert(anchor, insert); + } + + private void hookPlayerArthropod(MethodNode m) + { + //Hook to be false only + + AbstractInsnNode anchor = getArthropodInvoke(m); + if(anchor == null) + return; + + InsnList insert = new InsnList(); + insert.add(new VarInsnNode(Opcodes.ALOAD, 0)); //this + insert.add(new VarInsnNode(Opcodes.ALOAD, 1)); //targetEntity + insert.add(new InsnNode(Opcodes.ICONST_0)); //false + insert.add(getNewArthropodHook()); + m.instructions.insert(anchor, insert); + } + + private void hookBetterCombatArthropod(MethodNode m) + { + //Hook to be any + + AbstractInsnNode anchor = getArthropodInvoke(m); + if(anchor == null) + return; + + InsnList insert = new InsnList(); + insert.add(new VarInsnNode(Opcodes.ALOAD, 0)); //this + insert.add(new VarInsnNode(Opcodes.ALOAD, 1)); //targetEntity + insert.add(new VarInsnNode(Opcodes.ILOAD, 2)); //offhand + insert.add(getNewArthropodHook()); + m.instructions.insert(anchor, insert); + } + + @Nullable + private AbstractInsnNode getArthropodInvoke(MethodNode m) + { + return TransformUtil.findNextCallWithOpcodeAndName(m.instructions.getFirst(), Opcodes.INVOKESTATIC, "func_151385_b","applyArthropodEnchantments"); + } + + private AbstractInsnNode getNewArthropodHook() + { + return new MethodInsnNode( + Opcodes.INVOKESTATIC, + "com/Shultrea/Rin/Hook/HookArthropod", + "handleArthropod", + "(Lnet/minecraft/entity/EntityLivingBase;Lnet/minecraft/entity/Entity;Z)V", + false); + } + +} diff --git a/src/main/java/com/Shultrea/Rin/Transformer/helper/ASMHelper.java b/src/main/java/com/Shultrea/Rin/Transformer/helper/ASMHelper.java new file mode 100644 index 0000000..6aa7466 --- /dev/null +++ b/src/main/java/com/Shultrea/Rin/Transformer/helper/ASMHelper.java @@ -0,0 +1,834 @@ +package com.Shultrea.Rin.Transformer.helper; + +import java.io.File; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.PrintWriter; +import java.io.StringWriter; +import java.util.Collection; +import java.util.HashMap; +import java.util.Map; +import java.util.Set; + +import org.objectweb.asm.ClassReader; +import org.objectweb.asm.ClassWriter; +import org.objectweb.asm.MethodVisitor; +import org.objectweb.asm.Opcodes; +import org.objectweb.asm.commons.Remapper; +import org.objectweb.asm.commons.RemappingMethodAdapter; +import org.objectweb.asm.tree.AbstractInsnNode; +import org.objectweb.asm.tree.ClassNode; +import org.objectweb.asm.tree.InsnList; +import org.objectweb.asm.tree.JumpInsnNode; +import org.objectweb.asm.tree.LabelNode; +import org.objectweb.asm.tree.LocalVariableNode; +import org.objectweb.asm.tree.MethodNode; +import org.objectweb.asm.util.Printer; +import org.objectweb.asm.util.Textifier; +import org.objectweb.asm.util.TraceMethodVisitor; + +import com.google.common.collect.HashMultimap; +import com.google.common.collect.Multimap; +import com.google.common.collect.Sets; + +/** + * From the very helpful ASMHelper pack + * + * https://github.com/squeek502/ASMHelper + */ +public class ASMHelper +{ + public static InsnComparator insnComparator = new InsnComparator(); + private static final Multimap INTERFACE_LOOKUP_CACHE = HashMultimap.create(); + + /** + * Converts a class name to an internal class name. + * @return internal/class/name + */ + public static String toInternalClassName(String className) + { + return className.replace('.', '/'); + } + + /** + * @return true if the String is a valid descriptor; + */ + public static boolean isDescriptor(String descriptor) + { + return descriptor.length() == 1 || (descriptor.startsWith("L") && descriptor.endsWith(";")); + } + + /** + * Converts a class name to a descriptor. + * @return Linternal/class/name; + */ + public static String toDescriptor(String className) + { + return isDescriptor(className) ? className : "L" + toInternalClassName(className) + ";"; + } + + /** + * Turns the given return and parameter values into a method descriptor + * Converts the types into descriptors as needed + * @return (LparamType;)LreturnType; + */ + public static String toMethodDescriptor(String returnType, String... paramTypes) + { + StringBuilder paramDescriptors = new StringBuilder(); + for (String paramType : paramTypes) + paramDescriptors.append(toDescriptor(paramType)); + + return "(" + paramDescriptors.toString() + ")" + toDescriptor(returnType); + } + + /** + * Convert a byte array into a ClassNode. + */ + public static ClassNode readClassFromBytes(byte[] bytes) + { + return readClassFromBytes(bytes, 0); + } + + /** + * Overload of {@link #readClassFromBytes(byte[])} with a flags parameter. + */ + public static ClassNode readClassFromBytes(byte[] bytes, int flags) + { + ClassNode classNode = new ClassNode(); + ClassReader classReader = new ClassReader(bytes); + classReader.accept(classNode, flags); + return classNode; + } + + /** + * Convert a ClassNode into a byte array. + * Attempts to resolve issues with resolving super classes in an obfuscated environment. + * See {@link ObfRemappingClassWriter}. + */ + public static byte[] writeClassToBytes(ClassNode classNode) + { + return writeClassToBytes(classNode, ClassWriter.COMPUTE_MAXS); + } + + /** + * Overload of {@link #writeClassToBytes(ClassNode)} with a flags parameter. + */ + public static byte[] writeClassToBytes(ClassNode classNode, int flags) + { + if (ObfHelper.isObfuscated() && !ObfHelper.runsAfterDeobfRemapper()) + { + ClassWriter writer = new ObfRemappingClassWriter(flags); + classNode.accept(writer); + return writer.toByteArray(); + } + else + return writeClassToBytesNoDeobf(classNode, flags); + } + + /** + * Convert a ClassNode into a byte array. + * Will have issues with resolving super classes in an obfuscated environment. + */ + public static byte[] writeClassToBytesNoDeobf(ClassNode classNode) + { + return writeClassToBytesNoDeobf(classNode, ClassWriter.COMPUTE_MAXS); + } + + /** + * Overload of {@link #writeClassToBytesNoDeobf(ClassNode)} with a flags parameter. + */ + public static byte[] writeClassToBytesNoDeobf(ClassNode classNode, int flags) + { + ClassWriter writer = new ClassWriter(flags); + classNode.accept(writer); + return writer.toByteArray(); + } + + /** + * Uses writeClassToBytes to write a ClassNode into a File for decompilation and analysis. + */ + public static void writeClassToFile(ClassNode classNode, File file) throws IOException { + FileOutputStream fos = new FileOutputStream(file); + fos.write(writeClassToBytes(classNode)); + fos.close(); + } + + /** + * @return An InputStream instance for the specified class name loaded by the specified ClassLoader. + */ + public static InputStream getClassAsStreamFromClassLoader(String className, ClassLoader classLoader) + { + return classLoader.getResourceAsStream(className.replace('.', '/') + ".class"); + } + + /** + * @return A ClassReader instance for the specified class name. + */ + public static ClassReader getClassReaderForClassName(String className) throws IOException + { + return new ClassReader(getClassAsStreamFromClassLoader(className, ASMHelper.class.getClassLoader())); + } + + /** + * @return Whether or not the class read by the ClassReader has a valid super class. + */ + public static boolean classHasSuper(ClassReader classReader) + { + return classReader.getSuperName() != null && !classReader.getSuperName().equals("java/lang/Object"); + } + + private static Collection findAllInterfaces(ClassReader classReader) + { + // TODO: Find interfaces inside interfaces + Set interfaces = Sets.newHashSet(classReader.getInterfaces()); + + try + { + if (classHasSuper(classReader)) + { + String className2 = ObfHelper.getInternalClassName(classReader.getSuperName()); + if (INTERFACE_LOOKUP_CACHE.containsKey(className2)) + interfaces.addAll(INTERFACE_LOOKUP_CACHE.get(className2)); + else + interfaces.addAll(findAllInterfaces(getClassReaderForClassName(className2))); + } + } + catch (IOException e) + { + // This will trigger when the super class is abstract; just ignore the error + } + + INTERFACE_LOOKUP_CACHE.putAll(classReader.getClassName(), interfaces); + return interfaces; + } + + /** + * @return Whether or not the class read by the ClassReader implements the specified interface. + */ + public static boolean doesClassImplement(ClassReader classReader, String targetInterfaceInternalClassName) + { + if (!INTERFACE_LOOKUP_CACHE.containsKey(classReader.getClassName())) + findAllInterfaces(classReader); + + return INTERFACE_LOOKUP_CACHE.get(classReader.getClassName()).contains(targetInterfaceInternalClassName); + } + + /** + * @return Whether or not the class read by the ClassReader extends the specified class. + */ + public static boolean doesClassExtend(ClassReader classReader, String targetSuperInternalClassName) + { + if (!classHasSuper(classReader)) + return false; + + String immediateSuperName = ObfHelper.getInternalClassName(classReader.getSuperName()); + if (immediateSuperName.equals(targetSuperInternalClassName)) + return true; + + try + { + return doesClassExtend(getClassReaderForClassName(immediateSuperName), targetSuperInternalClassName); + } + catch (IOException e) + { + // This will trigger when the super class is abstract; just ignore the error + } + return false; + } + + /** + * @return Whether or not the instruction is a label or a line number. + */ + public static boolean isLabelOrLineNumber(AbstractInsnNode insn) + { + return insn.getType() == AbstractInsnNode.LABEL || insn.getType() == AbstractInsnNode.LINE; + } + + /** + * @return The first instruction for which {@link AbstractInsnNode#getType()} == {@code type} (could be {@code firstInsnToCheck}). + * If a matching instruction cannot be found, returns {@code null}. + */ + public static AbstractInsnNode getOrFindInstructionOfType(AbstractInsnNode firstInsnToCheck, int type) + { + return getOrFindInstructionOfType(firstInsnToCheck, type, false); + } + + /** + * @return The first instruction for which {@link AbstractInsnNode#getType()} == {@code type} (could be {@code firstInsnToCheck}). + * If {@code reverseDirection} is {@code true}, instructions will be traversed backwards (using getPrevious()). + * If a matching instruction cannot be found, returns {@code null}. + */ + public static AbstractInsnNode getOrFindInstructionOfType(AbstractInsnNode firstInsnToCheck, int type, boolean reverseDirection) + { + for (AbstractInsnNode instruction = firstInsnToCheck; instruction != null; instruction = reverseDirection ? instruction.getPrevious() : instruction.getNext()) + { + if (instruction.getType() == type) + return instruction; + } + return null; + } + + /** + * @return The first instruction for which {@link AbstractInsnNode#getOpcode()} == {@code opcode} (could be {@code firstInsnToCheck}). + * If a matching instruction cannot be found, returns {@code null} + */ + public static AbstractInsnNode getOrFindInstructionWithOpcode(AbstractInsnNode firstInsnToCheck, int opcode) + { + return getOrFindInstructionWithOpcode(firstInsnToCheck, opcode, false); + } + + /** + * @return The first instruction for which {@link AbstractInsnNode#getOpcode()} == {@code opcode} (could be {@code firstInsnToCheck}). + * If {@code reverseDirection} is {@code true}, instructions will be traversed backwards (using getPrevious()). + * If a matching instruction cannot be found, returns {@code null}. + */ + public static AbstractInsnNode getOrFindInstructionWithOpcode(AbstractInsnNode firstInsnToCheck, int opcode, boolean reverseDirection) + { + for (AbstractInsnNode instruction = firstInsnToCheck; instruction != null; instruction = reverseDirection ? instruction.getPrevious() : instruction.getNext()) + { + if (instruction.getOpcode() == opcode) + return instruction; + } + return null; + } + + /** + * @return The first instruction for which {@link #isLabelOrLineNumber} == {@code true} (could be {@code firstInsnToCheck}). + * If {@code reverseDirection} is {@code true}, instructions will be traversed backwards (using getPrevious()). + * If a matching instruction cannot be found, returns {@code null}. + */ + public static AbstractInsnNode getOrFindLabelOrLineNumber(AbstractInsnNode firstInsnToCheck) + { + return getOrFindInstruction(firstInsnToCheck, false); + } + + /** + * @return The first instruction for which {@link #isLabelOrLineNumber} == {@code true} (could be {@code firstInsnToCheck}). + * If a matching instruction cannot be found, returns {@code null}. + */ + public static AbstractInsnNode getOrFindLabelOrLineNumber(AbstractInsnNode firstInsnToCheck, boolean reverseDirection) + { + for (AbstractInsnNode instruction = firstInsnToCheck; instruction != null; instruction = reverseDirection ? instruction.getPrevious() : instruction.getNext()) + { + if (isLabelOrLineNumber(instruction)) + return instruction; + } + return null; + } + + /** + * @return The first instruction for which {@link #isLabelOrLineNumber} == {@code false} (could be {@code firstInsnToCheck}). + * If a matching instruction cannot be found, returns {@code null}. + */ + public static AbstractInsnNode getOrFindInstruction(AbstractInsnNode firstInsnToCheck) + { + return getOrFindInstruction(firstInsnToCheck, false); + } + + /** + * @return The first instruction for which {@link #isLabelOrLineNumber} == {@code false} (could be {@code firstInsnToCheck}). + * If {@code reverseDirection} is {@code true}, instructions will be traversed backwards (using getPrevious()). + * If a matching instruction cannot be found, returns {@code null}. + */ + public static AbstractInsnNode getOrFindInstruction(AbstractInsnNode firstInsnToCheck, boolean reverseDirection) + { + for (AbstractInsnNode instruction = firstInsnToCheck; instruction != null; instruction = reverseDirection ? instruction.getPrevious() : instruction.getNext()) + { + if (!isLabelOrLineNumber(instruction)) + return instruction; + } + return null; + } + + /** + * @return The first instruction of the {@code method} for which {@link #isLabelOrLineNumber} == {@code false}. + * If a matching instruction cannot be found, returns {@code null}. + */ + public static AbstractInsnNode findFirstInstruction(MethodNode method) + { + return getOrFindInstruction(method.instructions.getFirst()); + } + + /** + * @return The first instruction of the {@code method} for which {@link AbstractInsnNode#getOpcode()} == {@code opcode}. + * If a matching instruction cannot be found, returns {@code null}. + */ + public static AbstractInsnNode findFirstInstructionWithOpcode(MethodNode method, int opcode) + { + return getOrFindInstructionWithOpcode(method.instructions.getFirst(), opcode); + } + + /** + * @return The last instruction of the {@code method} for which {@link AbstractInsnNode#getOpcode()} == {@code opcode}. + * If a matching instruction cannot be found, returns {@code null}. + */ + public static AbstractInsnNode findLastInstructionWithOpcode(MethodNode method, int opcode) + { + return getOrFindInstructionWithOpcode(method.instructions.getLast(), opcode, true); + } + + /** + * @return The next instruction after {@code instruction} for which {@link #isLabelOrLineNumber} == {@code false} + * (excluding {@code instruction}). + * If a matching instruction cannot be found, returns {@code null}. + */ + public static AbstractInsnNode findNextInstruction(AbstractInsnNode instruction) + { + return getOrFindInstruction(instruction.getNext()); + } + + /** + * @return The next instruction after {@code instruction} for which {@link AbstractInsnNode#getOpcode()} == {@code opcode} + * (excluding {@code instruction}). + * If a matching instruction cannot be found, returns {@code null}. + */ + public static AbstractInsnNode findNextInstructionWithOpcode(AbstractInsnNode instruction, int opcode) + { + return getOrFindInstructionWithOpcode(instruction.getNext(), opcode); + } + + /** + * @return The next instruction after {@code instruction} for which {@link #isLabelOrLineNumber} == {@code true} + * (excluding {@code instruction}). + * If a matching instruction cannot be found, returns {@code null}. + */ + public static AbstractInsnNode findNextLabelOrLineNumber(AbstractInsnNode instruction) + { + return getOrFindLabelOrLineNumber(instruction.getNext()); + } + + /** + * @return The previous instruction before {@code instruction} for which {@link #isLabelOrLineNumber} == {@code false} + * (excluding {@code instruction}). + * If a matching instruction cannot be found, returns {@code null}. + */ + public static AbstractInsnNode findPreviousInstruction(AbstractInsnNode instruction) + { + return getOrFindInstruction(instruction.getPrevious(), true); + } + + /** + * @return The previous instruction before {@code instruction} for which {@link AbstractInsnNode#getOpcode()} == {@code opcode} + * (excluding {@code instruction}). + * If a matching instruction cannot be found, returns {@code null}. + */ + public static AbstractInsnNode findPreviousInstructionWithOpcode(AbstractInsnNode instruction, int opcode) + { + return getOrFindInstructionWithOpcode(instruction.getPrevious(), opcode, true); + } + + /** + * @return The previous instruction before {@code instruction} for which {@link #isLabelOrLineNumber} == {@code true} + * (excluding {@code instruction}). + * If a matching instruction cannot be found, returns {@code null}. + */ + public static AbstractInsnNode findPreviousLabelOrLineNumber(AbstractInsnNode instruction) + { + return getOrFindLabelOrLineNumber(instruction.getPrevious(), true); + } + + /** + * @return The method of the class that has both a matching {@code methodName} and {@code methodDesc}. + * If no matching method is found, returns {@code null}. + */ + public static MethodNode findMethodNodeOfClass(ClassNode classNode, String methodName, String methodDesc) + { + for (MethodNode method : classNode.methods) + { + if (method.name.equals(methodName) && (methodDesc == null || method.desc.equals(methodDesc))) + { + return method; + } + } + return null; + } + + /** + * @return The method of the class that has a matching {@code srgMethodName} or {@code mcpMethodName} and a matching {@code methodDesc}. + * If no matching method is found, returns {@code null}. + */ + public static MethodNode findMethodNodeOfClass(ClassNode classNode, String srgMethodName, String mcpMethodName, String methodDesc) + { + for (MethodNode method : classNode.methods) + { + if ((method.name.equals(srgMethodName) || method.name.equals(mcpMethodName)) && (methodDesc == null || method.desc.equals(methodDesc))) + { + return method; + } + } + return null; + } + + /** + * Adding instructions to abstract methods will cause a {@link java.lang.ClassFormatError} + * @return Whether or not the {@code MethodNode} is abstract + */ + public static boolean isMethodAbstract(MethodNode method) + { + return (method.access & Opcodes.ACC_ABSTRACT) != 0; + } + + /** + * Useful for defining the end label for ASM-inserted local variables. + * + * @return The last label of the method (usually after the RETURN instruction). + * If no matching {@link LabelNode} is found, returns {@code null}. + */ + public static LabelNode findEndLabel(MethodNode method) + { + for (AbstractInsnNode instruction = method.instructions.getLast(); instruction != null; instruction = instruction.getPrevious()) + { + if (instruction instanceof LabelNode) + return (LabelNode) instruction; + } + return null; + } + + /** + * Remove instructions from {@code insnList} starting with {@code startInclusive} + * up until reaching {@code endNotInclusive} ({@code endNotInclusive} will not be removed). + * + * @return The number of instructions removed + */ + public static int removeFromInsnListUntil(InsnList insnList, AbstractInsnNode startInclusive, AbstractInsnNode endNotInclusive) + { + AbstractInsnNode insnToRemove = startInclusive; + int numDeleted = 0; + while (insnToRemove != null && insnToRemove != endNotInclusive) + { + numDeleted++; + insnToRemove = insnToRemove.getNext(); + insnList.remove(insnToRemove.getPrevious()); + } + return numDeleted; + } + + /** + * Note: This is an alternative to {@link #removeFromInsnListUntil(InsnList, AbstractInsnNode, AbstractInsnNode) removeFromInsnListUntil} and will achieve a similar result.
+ *
+ * + * Skip instructions from {@code insnList} starting with {@code startInclusive} + * up until reaching {@code endNotInclusive} ({@code endNotInclusive} will not be skipped). + * + * This is achieved by inserting a GOTO instruction before {@code startInclusive} which is branched to a + * LabelNode that is inserted before {@code endNotInclusive}. + */ + public static void skipInstructions(InsnList insnList, AbstractInsnNode startInclusive, AbstractInsnNode endNotInclusive) + { + LabelNode skipLabel = new LabelNode(); + JumpInsnNode gotoInsn = new JumpInsnNode(Opcodes.GOTO, skipLabel); + insnList.insertBefore(startInclusive, gotoInsn); + insnList.insertBefore(endNotInclusive, skipLabel); + } + + /** + * Note: Does not move the instruction, but rather gets the instruction a certain + * distance away from {@code start}.
+ *
+ * + * Example: + *
+	 * {@code
+	 * // fifthInsn is pointing to the 5th instruction of insnList
+	 * AbstractInsnNode thirdInsn = ASMHelper.move(fifthInsn, -2);
+	 * AbstractInsnNode eightInsn = ASMHelper.move(fifthInsn, 3);
+	 * }
+	 * 
+ * + * @param start The instruction to move from + * @param distance The distance to move (can be positive or negative) + * @return The instruction {@code distance} away from the {@code start} instruction + */ + public static AbstractInsnNode move(final AbstractInsnNode start, int distance) + { + AbstractInsnNode movedTo = start; + for (int i = 0; i < Math.abs(distance) && movedTo != null; i++) + { + movedTo = distance > 0 ? movedTo.getNext() : movedTo.getPrevious(); + } + return movedTo; + } + + /** + * Convenience method for accessing {@link InsnComparator#areInsnsEqual} + */ + public static boolean instructionsMatch(AbstractInsnNode first, AbstractInsnNode second) + { + return insnComparator.areInsnsEqual(first, second); + } + + /** + * @return Whether or not the pattern in {@code checkFor} matches starting at {@code checkAgainst} + */ + public static boolean patternMatches(InsnList checkFor, AbstractInsnNode checkAgainst) + { + return checkForPatternAt(checkFor, checkAgainst).getFirst() != null; + } + + /** + * Checks whether or not the pattern in {@code checkFor} matches, starting at {@code checkAgainst}. + * + * @return All of the instructions that were matched by the {@code checkFor} pattern. + * If the pattern was not found, returns an empty {@link InsnList}.
+ *
+ * Note: If the pattern was matched, the size of the returned {@link InsnList} will be >= {@code checkFor}.size(). + */ + public static InsnList checkForPatternAt(InsnList checkFor, AbstractInsnNode checkAgainst) + { + InsnList foundInsnList = new InsnList(); + boolean firstNeedleFound = false; + for (AbstractInsnNode lookFor = checkFor.getFirst(); lookFor != null;) + { + if (checkAgainst == null) + return new InsnList(); + + if (isLabelOrLineNumber(lookFor)) + { + lookFor = lookFor.getNext(); + continue; + } + + if (isLabelOrLineNumber(checkAgainst)) + { + if (firstNeedleFound) + foundInsnList.add(checkAgainst); + checkAgainst = checkAgainst.getNext(); + continue; + } + + if (!instructionsMatch(lookFor, checkAgainst)) + return new InsnList(); + + foundInsnList.add(checkAgainst); + lookFor = lookFor.getNext(); + checkAgainst = checkAgainst.getNext(); + firstNeedleFound = true; + } + return foundInsnList; + } + + /** + * Searches for the pattern in {@code needle}, starting at {@code haystackStart}. + * + * @return All of the instructions that were matched by the pattern. + * If the pattern was not found, returns an empty {@link InsnList}.
+ *
+ * Note: If the pattern was matched, the size of the returned {@link InsnList} will be >= {@code checkFor}.size(). + */ + public static InsnList findAndGetFoundInsnList(AbstractInsnNode haystackStart, InsnList needle) + { + int needleStartOpcode = needle.getFirst().getOpcode(); + AbstractInsnNode checkAgainstStart = getOrFindInstructionWithOpcode(haystackStart, needleStartOpcode); + while (checkAgainstStart != null) + { + InsnList found = checkForPatternAt(needle, checkAgainstStart); + + if (found.getFirst() != null) + return found; + + checkAgainstStart = findNextInstructionWithOpcode(checkAgainstStart, needleStartOpcode); + } + return new InsnList(); + } + + /** + * Searches for the pattern in {@code needle} within {@code haystack}. + * + * @return The first instruction of the matched pattern. + * If the pattern was not found, returns an empty {@link InsnList}. + */ + public static AbstractInsnNode find(InsnList haystack, InsnList needle) + { + return find(haystack.getFirst(), needle); + } + + /** + * Searches for the pattern in {@code needle}, starting at {@code haystackStart}. + * + * @return The first instruction of the matched pattern. + * If the pattern was not found, returns {@code null}. + */ + public static AbstractInsnNode find(AbstractInsnNode haystackStart, InsnList needle) + { + if (needle.getFirst() == null) + return null; + + InsnList found = findAndGetFoundInsnList(haystackStart, needle); + return found.getFirst(); + } + + /** + * Searches for an instruction matching {@code needle} within {@code haystack}. + * + * @return The matching instruction. + * If a matching instruction was not found, returns {@code null}. + */ + public static AbstractInsnNode find(InsnList haystack, AbstractInsnNode needle) + { + return find(haystack.getFirst(), needle); + } + + /** + * Searches for an instruction matching {@code needle}, starting at {@code haystackStart}. + * + * @return The matching instruction. + * If a matching instruction was not found, returns {@code null}. + */ + public static AbstractInsnNode find(AbstractInsnNode haystackStart, AbstractInsnNode needle) + { + InsnList insnList = new InsnList(); + insnList.add(needle); + return find(haystackStart, insnList); + } + + /** + * Searches for the pattern in {@code needle} within {@code haystack} and replaces it with {@code replacement}. + * + * @return The instruction after the replacement. + * If the pattern was not found, returns {@code null}. + */ + public static AbstractInsnNode findAndReplace(InsnList haystack, InsnList needle, InsnList replacement) + { + return findAndReplace(haystack, needle, replacement, haystack.getFirst()); + } + + /** + * Searches for the pattern in {@code needle} within {@code haystack} (starting at {@code haystackStart}) + * and replaces it with {@code replacement}. + * + * @return The instruction after the replacement. + * If the pattern was not found, returns {@code null}. + */ + public static AbstractInsnNode findAndReplace(InsnList haystack, InsnList needle, InsnList replacement, AbstractInsnNode haystackStart) + { + InsnList found = findAndGetFoundInsnList(haystackStart, needle); + if (found.getFirst() != null) + { + haystack.insertBefore(found.getFirst(), replacement); + AbstractInsnNode afterNeedle = found.getLast().getNext(); + removeFromInsnListUntil(haystack, found.getFirst(), afterNeedle); + return afterNeedle; + } + return null; + } + + /** + * Searches for all instances of the pattern in {@code needle} within {@code haystack} + * and replaces them with {@code replacement}. + * + * @return The number of replacements made. + */ + public static int findAndReplaceAll(InsnList haystack, InsnList needle, InsnList replacement) + { + return findAndReplaceAll(haystack, needle, replacement, haystack.getFirst()); + } + + /** + * Searches for all instances of the pattern in {@code needle} within {@code haystack} + * (starting at {@code haystackStart}) and replaces them with {@code replacement}. + * + * @return The number of replacements made. + */ + public static int findAndReplaceAll(InsnList haystack, InsnList needle, InsnList replacement, AbstractInsnNode haystackStart) + { + int numReplaced = 0; + // insert/insertBefore clears the replacement list, so we need to use a copy each time + while ((haystackStart = findAndReplace(haystack, needle, cloneInsnList(replacement), haystackStart)) != null) + { + numReplaced++; + } + return numReplaced; + } + + /** + * Clones an instruction list, remapping labels in the process. + * + * @return The cloned {@code InsnList} + */ + public static InsnList cloneInsnList(InsnList source) + { + InsnList clone = new InsnList(); + + // used to map the old labels to their cloned counterpart + Map labelMap = new HashMap(); + + // build the label map + for (AbstractInsnNode instruction = source.getFirst(); instruction != null; instruction = instruction.getNext()) + { + if (instruction instanceof LabelNode) + { + labelMap.put(((LabelNode) instruction), new LabelNode()); + } + } + + for (AbstractInsnNode instruction = source.getFirst(); instruction != null; instruction = instruction.getNext()) + { + clone.add(instruction.clone(labelMap)); + } + + return clone; + } + + /** + * @return The local variable of the method that has both a matching {@code varName} and {@code varDesc}. + * If no matching local variable is found, returns {@code null}. + */ + public static LocalVariableNode findLocalVariableOfMethod(MethodNode method, String varName, String varDesc) + { + for (LocalVariableNode localVar : method.localVariables) + { + if (localVar.name.equals(varName) && localVar.desc.equals(varDesc)) + { + return localVar; + } + } + return null; + } + + /** + * Copy a method and rename it; everything else will be exactly the same + * @return The renamed method copy + */ + public static MethodNode copyAndRenameMethod(ClassNode classNode, MethodNode method, String newMethodName) + { + MethodVisitor methodCopyVisitor = classNode.visitMethod(method.access, newMethodName, method.desc, method.signature, method.exceptions.toArray(new String[method.exceptions.size()])); + method.accept(new RemappingMethodAdapter(method.access, method.desc, methodCopyVisitor, new Remapper(){})); + return methodCopyVisitor instanceof MethodNode ? (MethodNode) methodCopyVisitor : null; + } + + private static Printer printer = new Textifier(); + private static TraceMethodVisitor methodprinter = new TraceMethodVisitor(printer); + + /** + * @return {@code insnList} as a string.
+ *
+ * Example output:
+ *
+	 *    ALOAD 0
+	 *    GETFIELD net/minecraft/util/FoodStats.foodLevel : I
+	 *    ISTORE 3
+	 *    ALOAD 0
+	 * 
+ */ + public static String getInsnListAsString(InsnList insnList) + { + insnList.accept(methodprinter); + StringWriter sw = new StringWriter(); + printer.print(new PrintWriter(sw)); + printer.getText().clear(); + return sw.toString(); + } + + /** + * @return {@code method} as a string. + */ + public static String getMethodAsString(MethodNode method) + { + method.accept(methodprinter); + StringWriter sw = new StringWriter(); + printer.print(new PrintWriter(sw)); + printer.getText().clear(); + return sw.toString(); + } +} diff --git a/src/main/java/com/Shultrea/Rin/Transformer/helper/InsnComparator.java b/src/main/java/com/Shultrea/Rin/Transformer/helper/InsnComparator.java new file mode 100644 index 0000000..e72ba2e --- /dev/null +++ b/src/main/java/com/Shultrea/Rin/Transformer/helper/InsnComparator.java @@ -0,0 +1,117 @@ +package com.Shultrea.Rin.Transformer.helper; + +import java.io.Serializable; +import java.util.Comparator; + +import org.objectweb.asm.tree.AbstractInsnNode; +import org.objectweb.asm.tree.FieldInsnNode; +import org.objectweb.asm.tree.IincInsnNode; +import org.objectweb.asm.tree.IntInsnNode; +import org.objectweb.asm.tree.LdcInsnNode; +import org.objectweb.asm.tree.MethodInsnNode; +import org.objectweb.asm.tree.TypeInsnNode; +import org.objectweb.asm.tree.VarInsnNode; + +/** + * From the very helpful ASMHelper pack + * + * https://github.com/squeek502/ASMHelper + */ +public class InsnComparator implements Comparator, Serializable +{ + private static final long serialVersionUID = 408241651446425342L; + public static final int INT_WILDCARD = -1; + public static final String WILDCARD = "*"; + + @Override + public int compare(AbstractInsnNode a, AbstractInsnNode b) + { + return areInsnsEqual(a, b) ? 0 : 1; + } + + /** + * Respects {@link #INT_WILDCARD} and {@link #WILDCARD} instruction properties. + * Always returns true if {@code a} and {@code b} are label, line number, or frame instructions. + * + * @return Whether or not the given instructions are equivalent. + */ + public boolean areInsnsEqual(AbstractInsnNode a, AbstractInsnNode b) + { + if (a == b) + return true; + + if (a == null || b == null) + return false; + + if (a.equals(b)) + return true; + + if (a.getOpcode() != b.getOpcode()) + return false; + + switch (a.getType()) + { + case AbstractInsnNode.VAR_INSN: + return areVarInsnsEqual((VarInsnNode) a, (VarInsnNode) b); + case AbstractInsnNode.TYPE_INSN: + return areTypeInsnsEqual((TypeInsnNode) a, (TypeInsnNode) b); + case AbstractInsnNode.FIELD_INSN: + return areFieldInsnsEqual((FieldInsnNode) a, (FieldInsnNode) b); + case AbstractInsnNode.METHOD_INSN: + return areMethodInsnsEqual((MethodInsnNode) a, (MethodInsnNode) b); + case AbstractInsnNode.LDC_INSN: + return areLdcInsnsEqual((LdcInsnNode) a, (LdcInsnNode) b); + case AbstractInsnNode.IINC_INSN: + return areIincInsnsEqual((IincInsnNode) a, (IincInsnNode) b); + case AbstractInsnNode.INT_INSN: + return areIntInsnsEqual((IntInsnNode) a, (IntInsnNode) b); + default: + return true; + } + } + + private boolean areVarInsnsEqual(VarInsnNode a, VarInsnNode b) + { + return intValuesMatch(a.var, b.var); + } + + private boolean areTypeInsnsEqual(TypeInsnNode a, TypeInsnNode b) + { + return valuesMatch(a.desc, b.desc); + } + + private boolean areFieldInsnsEqual(FieldInsnNode a, FieldInsnNode b) + { + return valuesMatch(a.owner, b.owner) && valuesMatch(a.name, b.name) && valuesMatch(a.desc, b.desc); + } + + private boolean areMethodInsnsEqual(MethodInsnNode a, MethodInsnNode b) + { + return valuesMatch(a.owner, b.owner) && valuesMatch(a.name, b.name) && valuesMatch(a.desc, b.desc); + } + + private boolean areIntInsnsEqual(IntInsnNode a, IntInsnNode b) + { + return intValuesMatch(a.operand, b.operand); + } + + private boolean areIincInsnsEqual(IincInsnNode a, IincInsnNode b) + { + return intValuesMatch(a.var, b.var) && intValuesMatch(a.incr, b.incr); + } + + private boolean areLdcInsnsEqual(LdcInsnNode a, LdcInsnNode b) + { + return valuesMatch(a.cst, b.cst); + } + + private boolean intValuesMatch(int a, int b) + { + return a == b || a == INT_WILDCARD || b == INT_WILDCARD; + } + + private boolean valuesMatch(Object a, Object b) + { + return a.equals(b) || a.equals(WILDCARD) || b.equals(WILDCARD); + } +} diff --git a/src/main/java/com/Shultrea/Rin/Transformer/helper/ObfHelper.java b/src/main/java/com/Shultrea/Rin/Transformer/helper/ObfHelper.java new file mode 100644 index 0000000..8b4a977 --- /dev/null +++ b/src/main/java/com/Shultrea/Rin/Transformer/helper/ObfHelper.java @@ -0,0 +1,163 @@ +package com.Shultrea.Rin.Transformer.helper; + +import java.io.IOException; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import net.minecraft.launchwrapper.LaunchClassLoader; +import net.minecraftforge.fml.common.asm.transformers.deobf.FMLDeobfuscatingRemapper; + +/** + * From the very helpful ASMHelper pack + * + * https://github.com/squeek502/ASMHelper + */ +public class ObfHelper +{ + private static Boolean obfuscated = null; + private static Boolean runsAfterDeobfRemapper = null; + + /** + * Can be initialized by a core mod in {@link net.minecraftforge.fml.relauncher.IFMLLoadingPlugin#injectData} by + * using the value of "runtimeDeobfuscationEnabled" to + * avoid the class loader lookup in isObfuscated.
+ *
+ * Example: + *
+	 * public void injectData(Map data)
+	 * {
+	 *     ObfHelper.setObfuscated((Boolean) data.get("runtimeDeobfuscationEnabled"));
+	 * }
+	 * 
+ */ + public static void setObfuscated(boolean obfuscated) + { + ObfHelper.obfuscated = obfuscated; + } + + /** + * Should be initialized to true by a core mod that uses SortingIndex > 1000 + * (e.g. in {@link net.minecraftforge.fml.relauncher.IFMLLoadingPlugin#injectData}). + */ + public static void setRunsAfterDeobfRemapper(boolean runsAfterDeobfRemapper) + { + ObfHelper.runsAfterDeobfRemapper = runsAfterDeobfRemapper; + } + + /** + * @return Whether or not the current environment has been deobfuscated by FML + */ + public static boolean runsAfterDeobfRemapper() + { + if (runsAfterDeobfRemapper == null) + { + try + { + byte[] bytes = ((LaunchClassLoader) ObfHelper.class.getClassLoader()).getClassBytes("net.minecraft.world.World"); + ObfHelper.setRunsAfterDeobfRemapper(bytes != null); + } + catch (IOException e) + { + runsAfterDeobfRemapper = false; + } + } + return runsAfterDeobfRemapper; + } + + /** + * @return Whether or not the current environment contains obfuscated Minecraft code + */ + public static boolean isObfuscated() + { + if (obfuscated == null) + { + try + { + byte[] bytes = ((LaunchClassLoader) ObfHelper.class.getClassLoader()).getClassBytes("net.minecraft.world.World"); + ObfHelper.setObfuscated(bytes == null); + } + catch (IOException e) + { + obfuscated = true; + } + } + return obfuscated; + } + + /** + * Deobfuscates an obfuscated class name if {@link #isObfuscated()}. + */ + public static String toDeobfClassName(String obfClassName) + { + if (isObfuscated() && !runsAfterDeobfRemapper()) + return forceToDeobfClassName(obfClassName); + else + return obfClassName; + } + + /** + * Deobfuscates an obfuscated class name regardless of {@link #isObfuscated()}. + */ + public static String forceToDeobfClassName(String obfClassName) + { + return FMLDeobfuscatingRemapper.INSTANCE.map(obfClassName.replace('.', '/')).replace('/', '.'); + } + + /** + * Obfuscates a deobfuscated class name if {@link #isObfuscated()}. + */ + public static String toObfClassName(String deobfClassName) + { + if (isObfuscated() && !runsAfterDeobfRemapper()) + return forceToObfClassName(deobfClassName); + else + return deobfClassName; + } + + /** + * Obfuscates a deobfuscated class name regardless of {@link #isObfuscated()}. + */ + public static String forceToObfClassName(String deobfClassName) + { + return FMLDeobfuscatingRemapper.INSTANCE.unmap(deobfClassName.replace('.', '/')).replace('/', '.'); + } + + /** + * Converts a class name to an internal class name, obfuscating the class name if {@link #isObfuscated()}. + * @return internal/class/name + */ + public static String getInternalClassName(String className) + { + return toObfClassName(className).replace('.', '/'); + } + + /** + * Converts a class name to a descriptor, obfuscating the class name if {@link #isObfuscated()}. + * @return Linternal/class/name; + */ + public static String getDescriptor(String className) + { + return "L" + getInternalClassName(className) + ";"; + } + + /** + * Processes a descriptor, obfuscating class names if {@link #isObfuscated()}. + */ + public static String desc(String deobfDesc) + { + if (isObfuscated()) + { + // for each internal name, replace with the obfuscated version + Matcher classNameMatcher = Pattern.compile("L([^;]+);").matcher(deobfDesc); + StringBuffer obfDescBuffer = new StringBuffer(deobfDesc.length()); + while (classNameMatcher.find()) + { + classNameMatcher.appendReplacement(obfDescBuffer, getDescriptor(classNameMatcher.group(1).replace('/', '.'))); + } + classNameMatcher.appendTail(obfDescBuffer); + return obfDescBuffer.toString(); + } + else + return deobfDesc; + } +} diff --git a/src/main/java/com/Shultrea/Rin/Transformer/helper/ObfRemappingClassWriter.java b/src/main/java/com/Shultrea/Rin/Transformer/helper/ObfRemappingClassWriter.java new file mode 100644 index 0000000..255ec60 --- /dev/null +++ b/src/main/java/com/Shultrea/Rin/Transformer/helper/ObfRemappingClassWriter.java @@ -0,0 +1,57 @@ +package com.Shultrea.Rin.Transformer.helper; + +import org.objectweb.asm.ClassWriter; + +/** + * From the very helpful ASMHelper pack + * + * https://github.com/squeek502/ASMHelper + * + * + * {@link ClassWriter#getCommonSuperClass} needed to be overwritten + * in order to avoid ClassNotFoundExceptions in obfuscated environments. + */ +public class ObfRemappingClassWriter extends ClassWriter +{ + public ObfRemappingClassWriter(int flags) + { + super(flags); + } + + @Override + protected String getCommonSuperClass(final String type1, final String type2) + { + Class c, d; + ClassLoader classLoader = getClass().getClassLoader(); + try + { + c = Class.forName(ObfHelper.toDeobfClassName(type1.replace('/', '.')), false, classLoader); + d = Class.forName(ObfHelper.toDeobfClassName(type2.replace('/', '.')), false, classLoader); + } + catch (Exception e) + { + throw new RuntimeException(e); + } + if (c.isAssignableFrom(d)) + { + return type1; + } + if (d.isAssignableFrom(c)) + { + return type2; + } + if (c.isInterface() || d.isInterface()) + { + return "java/lang/Object"; + } + else + { + do + { + c = c.getSuperclass(); + } + while (!c.isAssignableFrom(d)); + return ObfHelper.toObfClassName(c.getName()).replace('.', '/'); + } + } +} diff --git a/src/main/java/com/Shultrea/Rin/Transformer/util/TransformUtil.java b/src/main/java/com/Shultrea/Rin/Transformer/util/TransformUtil.java new file mode 100644 index 0000000..2eb3b61 --- /dev/null +++ b/src/main/java/com/Shultrea/Rin/Transformer/util/TransformUtil.java @@ -0,0 +1,243 @@ +package com.Shultrea.Rin.Transformer.util; + +import javax.annotation.Nullable; + +import org.objectweb.asm.tree.AbstractInsnNode; +import org.objectweb.asm.tree.FieldInsnNode; +import org.objectweb.asm.tree.InsnList; +import org.objectweb.asm.tree.IntInsnNode; +import org.objectweb.asm.tree.LabelNode; +import org.objectweb.asm.tree.LocalVariableNode; +import org.objectweb.asm.tree.MethodInsnNode; +import org.objectweb.asm.tree.MethodNode; + +import com.Shultrea.Rin.Transformer.helper.ASMHelper; + +/** + * From RLTweaker + * + * https://github.com/Charles445/RLTweaker + */ +public class TransformUtil +{ + /** Search for a FieldInsnNode after the provided anchor. May specify multiple names for obfuscation purposes */ + @Nullable + public static FieldInsnNode findNextFieldWithOpcodeAndName(AbstractInsnNode anchor, int opcode, String... names) + { + AbstractInsnNode search = ASMHelper.findNextInstructionWithOpcode(anchor, opcode); + + while(search!=null) + { + if(search.getOpcode()==opcode) + { + for(String name : names) + { + if(name.equals(((FieldInsnNode)search).name)) + { + return (FieldInsnNode)search; + } + } + } + search = ASMHelper.findNextInstructionWithOpcode(search, opcode); + } + + return null; + } + + /** Search for a FieldInsnNode before the provided anchor. May specify multiple names for obfuscation purposes */ + @Nullable + public static FieldInsnNode findPreviousFieldWithOpcodeAndName(AbstractInsnNode anchor, int opcode, String... names) + { + AbstractInsnNode search = ASMHelper.findPreviousInstructionWithOpcode(anchor, opcode); + + while(search!=null) + { + if(search.getOpcode()==opcode) + { + for(String name : names) + { + if(name.equals(((FieldInsnNode)search).name)) + { + return (FieldInsnNode)search; + } + } + } + search = ASMHelper.findPreviousInstructionWithOpcode(search, opcode); + } + + return null; + } + + /** Search for an IntInsnNode after the provided anchor. */ + @Nullable + public static IntInsnNode findNextIntInsnNodeWithValue(AbstractInsnNode anchor, int value) + { + AbstractInsnNode search = ASMHelper.findNextInstruction(anchor); + + while(search!=null) + { + if(search.getType()==AbstractInsnNode.INT_INSN) + { + if(value==(((IntInsnNode)search).operand)) + { + return (IntInsnNode) search; + } + } + search = ASMHelper.findNextInstruction(search); + } + + return null; + } + + /** Search for an IntInsnNode before the provided anchor. */ + @Nullable + public static IntInsnNode findPreviousIntInsnNodeWithValue(AbstractInsnNode anchor, int value) + { + AbstractInsnNode search = ASMHelper.findPreviousInstruction(anchor); + + while(search!=null) + { + if(search.getType()==AbstractInsnNode.INT_INSN) + { + if(value==(((IntInsnNode)search).operand)) + { + return (IntInsnNode) search; + } + } + search = ASMHelper.findPreviousInstruction(search); + } + + return null; + } + + /** Search for a MethodInsnNode after the provided anchor. May specify multiple names for obfuscation purposes */ + @Nullable + public static MethodInsnNode findNextCallWithOpcodeAndName(AbstractInsnNode anchor, int opcode, String... names) + { + AbstractInsnNode search = ASMHelper.findNextInstructionWithOpcode(anchor, opcode); + + while(search!=null) + { + if(search.getOpcode()==opcode) + { + for(String name : names) + { + if(name.equals(((MethodInsnNode)search).name)) + { + return (MethodInsnNode)search; + } + } + } + search = ASMHelper.findNextInstructionWithOpcode(search, opcode); + } + + return null; + } + + /** Search for a MethodInsnNode before the provided anchor. May specify multiple names for obfuscation purposes */ + @Nullable + public static MethodInsnNode findPreviousCallWithOpcodeAndName(AbstractInsnNode anchor, int opcode, String... names) + { + AbstractInsnNode search = ASMHelper.findPreviousInstructionWithOpcode(anchor, opcode); + + while(search!=null) + { + if(search.getOpcode()==opcode) + { + for(String name : names) + { + if(name.equals(((MethodInsnNode)search).name)) + { + return (MethodInsnNode)search; + } + } + } + search = ASMHelper.findPreviousInstructionWithOpcode(search, opcode); + } + + return null; + } + + public static void insertBeforeFirst(MethodNode mNode, InsnList insnList) + { + mNode.instructions.insertBefore(ASMHelper.findFirstInstruction(mNode), insnList); + } + + /** Search for the LocalVariableNode with a matching desc*/ + @Nullable + public static LocalVariableNode findLocalVariableWithDesc(final MethodNode methodNode, final String desc) + { + int count = 0; + LocalVariableNode result = null; + + for(LocalVariableNode lvNode : methodNode.localVariables) + { + if(lvNode.desc.equals(desc)) + { + result = lvNode; + count++; + } + } + + return result; + } + + /** Search for the LocalVariableNode with a matching name*/ + @Nullable + public static LocalVariableNode findLocalVariableWithName(final MethodNode methodNode, final String name) + { + int count = 0; + LocalVariableNode result = null; + + for(LocalVariableNode lvNode : methodNode.localVariables) + { + if(lvNode.name.equals(name)) + { + result = lvNode; + count++; + } + } + + return result; + } + + @Nullable + /** REQUIRES MAXS : Creates, but does not add, a new local variable node */ + public static LocalVariableNode createNewLocalVariable(final MethodNode methodNode, String name, String desc) + { + int index=0; + for(LocalVariableNode lvn : methodNode.localVariables) + { + if(lvn.index >= index) + index = lvn.index + 1; + } + + AbstractInsnNode anchor = methodNode.instructions.getFirst(); + LabelNode l1 = null; + LabelNode l2 = null; + + //First and last labels of the method + while(anchor!=null) + { + if(anchor instanceof LabelNode) + { + if(l1==null) + { + l1 = (LabelNode)anchor; + } + + l2 = (LabelNode)anchor; + } + + anchor = anchor.getNext(); + } + + if(l1 == null | l2 == null) + { + //Failure, didn't manage the labels + return null; + } + + return new LocalVariableNode(name,desc,null,l1,l2,index); + } +} diff --git a/src/main/java/com/Shultrea/Rin/Utility_Sector/AdditionalProtectionEnchantmentsEffects.java b/src/main/java/com/Shultrea/Rin/Utility_Sector/AdditionalProtectionEnchantmentsEffects.java index b68a59c..4d64a0d 100644 --- a/src/main/java/com/Shultrea/Rin/Utility_Sector/AdditionalProtectionEnchantmentsEffects.java +++ b/src/main/java/com/Shultrea/Rin/Utility_Sector/AdditionalProtectionEnchantmentsEffects.java @@ -14,7 +14,8 @@ public class AdditionalProtectionEnchantmentsEffects { @SubscribeEvent(priority=EventPriority.LOW, receiveCanceled=true) public void protectionOnly(LivingHurtEvent fEvent){ - + if(!ModConfig.miscellaneous.extraProtectionEffects) + return; //System.out.println("EVENT EEEEEEEEEEEEEEE"); if(!(ModConfig.enabled.AdvancedProtection)) return; @@ -31,7 +32,8 @@ public void protectionOnly(LivingHurtEvent fEvent){ @SubscribeEvent(priority=EventPriority.LOW, receiveCanceled=true) public void projprotection(LivingHurtEvent fEvent){ - + if(!ModConfig.miscellaneous.extraProtectionEffects) + return; //System.out.println("EVENT EEEEEEEEEEEEEEE"); if(!(ModConfig.enabled.AdvancedProjectileProtection)) return; @@ -48,7 +50,8 @@ public void projprotection(LivingHurtEvent fEvent){ @SubscribeEvent(priority=EventPriority.LOW, receiveCanceled=true) public void fireprotection(LivingDamageEvent fEvent){ - + if(!ModConfig.miscellaneous.extraProtectionEffects) + return; //System.out.println("EVENT EEEEEEEEEEEEEEE"); if(!(ModConfig.enabled.AdvancedFireProtection)) return; @@ -65,7 +68,8 @@ public void fireprotection(LivingDamageEvent fEvent){ @SubscribeEvent(priority=EventPriority.LOW, receiveCanceled=true) public void blastprotection(LivingHurtEvent fEvent){ - + if(!ModConfig.miscellaneous.extraProtectionEffects) + return; //System.out.println("EVENT EEEEEEEEEEEEEEE"); if(!(ModConfig.enabled.AdvancedBlastProtection)) return; @@ -82,7 +86,8 @@ public void blastprotection(LivingHurtEvent fEvent){ @SubscribeEvent(priority=EventPriority.LOW, receiveCanceled=true) public void featherfall(LivingHurtEvent fEvent){ - + if(!ModConfig.miscellaneous.extraProtectionEffects) + return; //System.out.println("EVENT EEEEEEEEEEEEEEE"); if(!(ModConfig.enabled.AdvancedFeatherFalling)) return; diff --git a/src/main/java/com/Shultrea/Rin/Utility_Sector/ExtraEvent.java b/src/main/java/com/Shultrea/Rin/Utility_Sector/ExtraEvent.java index 0d2a96d..61a4249 100644 --- a/src/main/java/com/Shultrea/Rin/Utility_Sector/ExtraEvent.java +++ b/src/main/java/com/Shultrea/Rin/Utility_Sector/ExtraEvent.java @@ -1,5 +1,6 @@ package com.Shultrea.Rin.Utility_Sector; +import com.Shultrea.Rin.Enchantment_Base_Sector.EnchantmentBase; import com.Shultrea.Rin.Enchantments_Sector.Smc_030; import com.Shultrea.Rin.Main_Sector.ModConfig; import com.Shultrea.Rin.Main_Sector.somanyenchantments; @@ -36,6 +37,9 @@ public void onArrowHit(LivingDamageEvent fEvent){ if(!cause.hasCapability(ArrowPropertiesProvider.ARROWPROPERTIES_CAP, null)) return; + if(EnchantmentBase.isOffensivePetDisallowed(fEvent.getSource().getImmediateSource(), fEvent.getSource().getTrueSource())) + return; + IArrowProperties properties = cause.getCapability(ArrowPropertiesProvider.ARROWPROPERTIES_CAP, null); int flameLevel = properties.getFlameLevel(); diff --git a/src/main/java/com/Shultrea/Rin/Utility_Sector/OtherHandler.java b/src/main/java/com/Shultrea/Rin/Utility_Sector/OtherHandler.java index beef55f..a4098f4 100644 --- a/src/main/java/com/Shultrea/Rin/Utility_Sector/OtherHandler.java +++ b/src/main/java/com/Shultrea/Rin/Utility_Sector/OtherHandler.java @@ -1,5 +1,6 @@ package com.Shultrea.Rin.Utility_Sector; +import com.Shultrea.Rin.Enchantment_Base_Sector.EnchantmentBase; import com.Shultrea.Rin.Enchantments_Sector.Smc_030; import com.Shultrea.Rin.Enchantments_Sector.Smc_040; import com.Shultrea.Rin.Main_Sector.ModConfig; @@ -115,7 +116,8 @@ public void enchHand(LivingHurtEvent fEvent){ if(dmgSource == null) return; - + if(EnchantmentBase.isOffensivePetDisallowed(fEvent.getSource().getImmediateSource(), fEvent.getSource().getTrueSource())) + return; float levelmath = ModConfig.enabled.Mathematics ? EnchantmentHelper.getEnchantmentLevel(Smc_040.Mathematics, dmgSource) : 0; float levelhistory = ModConfig.enabled.History ? EnchantmentHelper.getEnchantmentLevel(Smc_040.History, dmgSource) : 0;