From 12eff188bb5db7f7336604bfc8d3bbb7e6800a19 Mon Sep 17 00:00:00 2001 From: Indyuce Date: Wed, 18 Aug 2021 23:01:39 +0200 Subject: [PATCH] !fuck me --- pom.xml | 2 +- .../java/net/Indyuce/mmoitems/MMOUtils.java | 40 +--- .../mmoitems/{api => }/ability/Ability.java | 62 +++---- .../AbilityMetadata.java} | 62 +++---- .../net/Indyuce/mmoitems/ability/Blink.java | 42 ----- .../Indyuce/mmoitems/ability/Blizzard.java | 89 --------- .../mmoitems/ability/Bouncy_Fireball.java | 97 ---------- .../Indyuce/mmoitems/ability/Bunny_Mode.java | 88 --------- .../mmoitems/ability/Burning_Hands.java | 74 -------- .../mmoitems/ability/Chicken_Wraith.java | 97 ---------- .../mmoitems/ability/Circular_Slash.java | 65 ------- .../mmoitems/ability/Corrupted_Fangs.java | 95 ---------- .../Indyuce/mmoitems/ability/Cursed_Beam.java | 106 ----------- .../Indyuce/mmoitems/ability/Earthquake.java | 75 -------- .../Indyuce/mmoitems/ability/Fire_Meteor.java | 76 -------- .../Indyuce/mmoitems/ability/Firebolt.java | 79 -------- .../net/Indyuce/mmoitems/ability/Firefly.java | 94 ---------- .../ability/FriendlyTargetAbility.java | 22 +++ .../Indyuce/mmoitems/ability/Frog_Mode.java | 58 ------ .../Indyuce/mmoitems/ability/Frozen_Aura.java | 68 ------- .../Indyuce/mmoitems/ability/Grand_Heal.java | 46 ----- .../net/Indyuce/mmoitems/ability/Heal.java | 37 ---- .../mmoitems/ability/Heavy_Charge.java | 68 ------- .../mmoitems/ability/Hoearthquake.java | 64 ------- .../mmoitems/ability/Holy_Missile.java | 83 --------- .../Indyuce/mmoitems/ability/Ice_Crystal.java | 96 ---------- .../Indyuce/mmoitems/ability/ItemAbility.java | 22 +++ .../Indyuce/mmoitems/ability/Item_Bomb.java | 90 --------- .../Indyuce/mmoitems/ability/Item_Throw.java | 91 --------- .../net/Indyuce/mmoitems/ability/Leap.java | 51 ----- .../Indyuce/mmoitems/ability/Light_Dash.java | 65 ------- .../mmoitems/ability/LocationAbility.java | 22 +++ .../mmoitems/ability/Magma_Fissure.java | 69 ------- .../Indyuce/mmoitems/ability/Overload.java | 58 ------ .../mmoitems/ability/Present_Throw.java | 107 ----------- .../Indyuce/mmoitems/ability/Regen_Ally.java | 81 -------- .../Indyuce/mmoitems/ability/Shockwave.java | 73 -------- .../mmoitems/ability/Shulker_Missile.java | 175 ------------------ .../mmoitems/ability/SimpleAbility.java | 24 +++ .../Indyuce/mmoitems/ability/Sky_Smash.java | 56 ------ .../net/Indyuce/mmoitems/ability/Smite.java | 35 ---- .../mmoitems/ability/Snowman_Turret.java | 110 ----------- .../net/Indyuce/mmoitems/ability/Sparkle.java | 62 ------- .../Indyuce/mmoitems/ability/Swiftness.java | 45 ----- .../Indyuce/mmoitems/ability/TNT_Throw.java | 73 -------- .../mmoitems/ability/Tactical_Grenade.java | 89 --------- .../mmoitems/ability/TargetAbility.java | 22 +++ .../mmoitems/ability/Targeted_Fireball.java | 76 -------- .../Indyuce/mmoitems/ability/Throw_Up.java | 73 -------- .../net/Indyuce/mmoitems/ability/Thrust.java | 54 ------ .../mmoitems/ability/VectorAbility.java | 27 +++ .../mmoitems/ability/arcane/Arcane_Rift.java | 79 -------- .../location}/Arcane_Hail.java | 31 ++-- .../{ => list/location}/Black_Hole.java | 32 ++-- .../{ => list/location}/Contamination.java | 42 ++--- .../{onhit => list/location}/Corrosion.java | 29 +-- .../ability/{ => list/location}/Corrupt.java | 33 ++-- .../{onhit => list/location}/Freeze.java | 29 ++- .../{ => list/location}/Freezing_Curse.java | 44 ++--- .../{onhit => list/location}/Ignite.java | 30 +-- .../{ => list/location}/Life_Ender.java | 42 ++--- .../{ => list/location}/Lightning_Beam.java | 38 ++-- .../location}/Minor_Explosion.java | 34 ++-- .../ability/list/location/Snowman_Turret.java | 100 ++++++++++ .../ability/list/misc/Arcane_Rift.java | 73 ++++++++ .../ability/list/misc/Earthquake.java | 72 +++++++ .../ability/list/misc/Hoearthquake.java | 57 ++++++ .../mmoitems/ability/list/misc/Item_Bomb.java | 75 ++++++++ .../ability/list/misc/Item_Throw.java | 73 ++++++++ .../mmoitems/ability/list/misc/Leap.java | 48 +++++ .../ability/list/misc/Regen_Ally.java | 47 +++++ .../mmoitems/ability/list/simple/Blink.java | 32 ++++ .../ability/list/simple/Blizzard.java | 79 ++++++++ .../ability/list/simple/Bunny_Mode.java | 78 ++++++++ .../ability/list/simple/Burning_Hands.java | 66 +++++++ .../ability/list/simple/Chicken_Wraith.java | 87 +++++++++ .../ability/list/simple/Circular_Slash.java | 57 ++++++ .../mmoitems/ability/list/simple/Firefly.java | 85 +++++++++ .../ability/list/simple/Frog_Mode.java | 48 +++++ .../ability/list/simple/Frozen_Aura.java | 59 ++++++ .../ability/list/simple/Grand_Heal.java | 36 ++++ .../mmoitems/ability/list/simple/Heal.java | 27 +++ .../ability/list/simple/Light_Dash.java | 57 ++++++ .../{ => list/simple}/Magical_Path.java | 54 +++--- .../{ => list/simple}/Magical_Shield.java | 61 +++--- .../ability/list/simple/Overload.java | 50 +++++ .../ability/list/simple/Present_Throw.java | 98 ++++++++++ .../{ => list/simple}/Shadow_Veil.java | 69 +++---- .../ability/list/simple/Shockwave.java | 60 ++++++ .../ability/list/simple/Sky_Smash.java | 48 +++++ .../ability/list/simple/Swiftness.java | 35 ++++ .../ability/list/simple/Throw_Up.java | 61 ++++++ .../mmoitems/ability/list/target/Blind.java | 41 ++++ .../ability/list/target/Bloodbath.java | 28 +++ .../mmoitems/ability/list/target/Burn.java | 47 +++++ .../mmoitems/ability/list/target/Confuse.java | 46 +++++ .../ability/list/target/Death_Mark.java | 56 ++++++ .../ability/list/target/Magma_Fissure.java | 61 ++++++ .../mmoitems/ability/list/target/Poison.java | 32 ++++ .../mmoitems/ability/list/target/Shock.java | 57 ++++++ .../mmoitems/ability/list/target/Slow.java | 53 ++++++ .../mmoitems/ability/list/target/Smite.java | 27 +++ .../mmoitems/ability/list/target/Sparkle.java | 54 ++++++ .../ability/list/target/Starfall.java | 55 ++++++ .../mmoitems/ability/list/target/Stun.java | 31 ++++ .../ability/list/target/Tactical_Grenade.java | 82 ++++++++ .../list/target/Targeted_Fireball.java | 67 +++++++ .../ability/list/target/Vampirism.java | 52 ++++++ .../{onhit => list/target}/Weaken_Target.java | 67 +++---- .../mmoitems/ability/list/target/Wither.java | 55 ++++++ .../ability/list/vector/Bouncy_Fireball.java | 88 +++++++++ .../ability/list/vector/Corrupted_Fangs.java | 81 ++++++++ .../ability/list/vector/Cursed_Beam.java | 98 ++++++++++ .../{ => list/vector}/Explosive_Turkey.java | 34 ++-- .../ability/list/vector/Fire_Meteor.java | 68 +++++++ .../ability/list/vector/Firebolt.java | 71 +++++++ .../ability/list/vector/Heavy_Charge.java | 59 ++++++ .../ability/list/vector/Holy_Missile.java | 75 ++++++++ .../ability/list/vector/Ice_Crystal.java | 86 +++++++++ .../ability/list/vector/Shulker_Missile.java | 164 ++++++++++++++++ .../ability/list/vector/TNT_Throw.java | 63 +++++++ .../mmoitems/ability/list/vector/Thrust.java | 46 +++++ .../FriendlyTargetAbilityMetadata.java | 27 +++ .../ability/metadata/ItemAbilityMetadata.java | 31 ++++ .../metadata/LocationAbilityMetadata.java | 40 ++++ .../metadata/SimpleAbilityMetadata.java | 23 +++ .../metadata/TargetAbilityMetadata.java | 27 +++ .../metadata/VectorAbilityMetadata.java | 30 +++ .../Indyuce/mmoitems/ability/onhit/Blind.java | 50 ----- .../mmoitems/ability/onhit/Bloodbath.java | 37 ---- .../Indyuce/mmoitems/ability/onhit/Burn.java | 56 ------ .../mmoitems/ability/onhit/Confuse.java | 55 ------ .../mmoitems/ability/onhit/Death_Mark.java | 65 ------- .../mmoitems/ability/onhit/Poison.java | 41 ---- .../Indyuce/mmoitems/ability/onhit/Shock.java | 66 ------- .../Indyuce/mmoitems/ability/onhit/Slow.java | 62 ------- .../mmoitems/ability/onhit/Starfall.java | 62 ------- .../Indyuce/mmoitems/ability/onhit/Stun.java | 40 ---- .../mmoitems/ability/onhit/Vampirism.java | 61 ------ .../mmoitems/ability/onhit/Wither.java | 65 ------- .../net/Indyuce/mmoitems/api/CustomSound.java | 1 + .../net/Indyuce/mmoitems/api/Element.java | 70 ++++--- .../Indyuce/mmoitems/api/ElementalAttack.java | 35 ++-- .../mmoitems/api/ItemAttackMetadata.java | 84 +++++++++ .../mmoitems/api/ItemAttackResult.java | 102 ---------- .../net/Indyuce/mmoitems/api/MMOItemsAPI.java | 2 +- .../net/Indyuce/mmoitems/api/TypeSet.java | 79 ++++---- .../api/ability/LocationAbilityResult.java | 34 ---- .../api/ability/SimpleAbilityResult.java | 22 --- .../api/ability/TargetAbilityResult.java | 27 --- .../api/ability/VectorAbilityResult.java | 30 --- .../projectile/ProjectileData.java | 20 +- .../api/interaction/weapon/Weapon.java | 20 +- .../weapon/untargeted/Crossbow.java | 11 +- .../interaction/weapon/untargeted/Lute.java | 26 +-- .../interaction/weapon/untargeted/Musket.java | 23 ++- .../interaction/weapon/untargeted/Staff.java | 21 ++- .../interaction/weapon/untargeted/Whip.java | 24 +-- .../untargeted/lute/BruteLuteAttack.java | 28 +-- .../untargeted/lute/CircularLuteAttack.java | 24 +-- .../untargeted/lute/LuteAttackHandler.java | 13 +- .../untargeted/lute/SimpleLuteAttack.java | 22 +-- .../untargeted/lute/SlashLuteAttack.java | 26 +-- .../untargeted/lute/WaveLuteAttack.java | 26 +-- .../untargeted/staff/LightningSpirit.java | 18 +- .../weapon/untargeted/staff/ManaSpirit.java | 24 +-- .../weapon/untargeted/staff/NetherSpirit.java | 23 +-- .../untargeted/staff/StaffAttackHandler.java | 13 +- .../untargeted/staff/SunfireSpirit.java | 23 +-- .../untargeted/staff/ThunderSpirit.java | 23 +-- .../weapon/untargeted/staff/VoidSpirit.java | 18 +- .../weapon/untargeted/staff/XRaySpirit.java | 29 ++- .../api/player/PlayerAbilityData.java | 53 ------ .../mmoitems/api/player/PlayerData.java | 75 ++++---- .../mmoitems/api/player/PlayerStats.java | 61 +----- .../mmoitems/api/util/TemporaryListener.java | 17 +- .../mmoitems/AbilityCommandTreeNode.java | 9 +- .../mmoitems/list/AbilityCommandTreeNode.java | 2 +- .../mmoitems/comp/RealDualWieldHook.java | 26 ++- .../comp/mythicmobs/MythicMobsAbility.java | 88 --------- .../comp/mythicmobs/MythicMobsHook.java | 39 ++-- .../mythicmobs/skill/MythicMobsAbility.java | 76 ++++++++ .../skill/MythicMobsAbilityMetadata.java | 24 +++ .../Indyuce/mmoitems/comp/rpg/HeroesHook.java | 27 ++- .../mmoitems/comp/rpg/SkillAPIHook.java | 30 +-- .../mmoitems/gui/edition/AbilityEdition.java | 4 +- .../gui/edition/AbilityListEdition.java | 4 +- .../mmoitems/listener/ElementListener.java | 1 + .../Indyuce/mmoitems/listener/ItemUse.java | 21 ++- .../mmoitems/listener/PlayerListener.java | 11 +- .../mmoitems/manager/AbilityManager.java | 4 +- .../mmoitems/manager/ConfigManager.java | 4 +- .../mmoitems/manager/EntityManager.java | 50 ++--- .../net/Indyuce/mmoitems/stat/Abilities.java | 5 +- .../mmoitems/stat/data/AbilityData.java | 4 +- .../stat/data/random/RandomAbilityData.java | 4 +- 196 files changed, 4677 insertions(+), 5275 deletions(-) rename src/main/java/net/Indyuce/mmoitems/{api => }/ability/Ability.java (74%) rename src/main/java/net/Indyuce/mmoitems/{api/ability/AbilityResult.java => ability/AbilityMetadata.java} (56%) delete mode 100644 src/main/java/net/Indyuce/mmoitems/ability/Blink.java delete mode 100644 src/main/java/net/Indyuce/mmoitems/ability/Blizzard.java delete mode 100644 src/main/java/net/Indyuce/mmoitems/ability/Bouncy_Fireball.java delete mode 100644 src/main/java/net/Indyuce/mmoitems/ability/Bunny_Mode.java delete mode 100644 src/main/java/net/Indyuce/mmoitems/ability/Burning_Hands.java delete mode 100644 src/main/java/net/Indyuce/mmoitems/ability/Chicken_Wraith.java delete mode 100644 src/main/java/net/Indyuce/mmoitems/ability/Circular_Slash.java delete mode 100644 src/main/java/net/Indyuce/mmoitems/ability/Corrupted_Fangs.java delete mode 100644 src/main/java/net/Indyuce/mmoitems/ability/Cursed_Beam.java delete mode 100644 src/main/java/net/Indyuce/mmoitems/ability/Earthquake.java delete mode 100644 src/main/java/net/Indyuce/mmoitems/ability/Fire_Meteor.java delete mode 100644 src/main/java/net/Indyuce/mmoitems/ability/Firebolt.java delete mode 100644 src/main/java/net/Indyuce/mmoitems/ability/Firefly.java create mode 100644 src/main/java/net/Indyuce/mmoitems/ability/FriendlyTargetAbility.java delete mode 100644 src/main/java/net/Indyuce/mmoitems/ability/Frog_Mode.java delete mode 100644 src/main/java/net/Indyuce/mmoitems/ability/Frozen_Aura.java delete mode 100644 src/main/java/net/Indyuce/mmoitems/ability/Grand_Heal.java delete mode 100644 src/main/java/net/Indyuce/mmoitems/ability/Heal.java delete mode 100644 src/main/java/net/Indyuce/mmoitems/ability/Heavy_Charge.java delete mode 100644 src/main/java/net/Indyuce/mmoitems/ability/Hoearthquake.java delete mode 100644 src/main/java/net/Indyuce/mmoitems/ability/Holy_Missile.java delete mode 100644 src/main/java/net/Indyuce/mmoitems/ability/Ice_Crystal.java create mode 100644 src/main/java/net/Indyuce/mmoitems/ability/ItemAbility.java delete mode 100644 src/main/java/net/Indyuce/mmoitems/ability/Item_Bomb.java delete mode 100644 src/main/java/net/Indyuce/mmoitems/ability/Item_Throw.java delete mode 100644 src/main/java/net/Indyuce/mmoitems/ability/Leap.java delete mode 100644 src/main/java/net/Indyuce/mmoitems/ability/Light_Dash.java create mode 100644 src/main/java/net/Indyuce/mmoitems/ability/LocationAbility.java delete mode 100644 src/main/java/net/Indyuce/mmoitems/ability/Magma_Fissure.java delete mode 100644 src/main/java/net/Indyuce/mmoitems/ability/Overload.java delete mode 100644 src/main/java/net/Indyuce/mmoitems/ability/Present_Throw.java delete mode 100644 src/main/java/net/Indyuce/mmoitems/ability/Regen_Ally.java delete mode 100644 src/main/java/net/Indyuce/mmoitems/ability/Shockwave.java delete mode 100644 src/main/java/net/Indyuce/mmoitems/ability/Shulker_Missile.java create mode 100644 src/main/java/net/Indyuce/mmoitems/ability/SimpleAbility.java delete mode 100644 src/main/java/net/Indyuce/mmoitems/ability/Sky_Smash.java delete mode 100644 src/main/java/net/Indyuce/mmoitems/ability/Smite.java delete mode 100644 src/main/java/net/Indyuce/mmoitems/ability/Snowman_Turret.java delete mode 100644 src/main/java/net/Indyuce/mmoitems/ability/Sparkle.java delete mode 100644 src/main/java/net/Indyuce/mmoitems/ability/Swiftness.java delete mode 100644 src/main/java/net/Indyuce/mmoitems/ability/TNT_Throw.java delete mode 100644 src/main/java/net/Indyuce/mmoitems/ability/Tactical_Grenade.java create mode 100644 src/main/java/net/Indyuce/mmoitems/ability/TargetAbility.java delete mode 100644 src/main/java/net/Indyuce/mmoitems/ability/Targeted_Fireball.java delete mode 100644 src/main/java/net/Indyuce/mmoitems/ability/Throw_Up.java delete mode 100644 src/main/java/net/Indyuce/mmoitems/ability/Thrust.java create mode 100644 src/main/java/net/Indyuce/mmoitems/ability/VectorAbility.java delete mode 100644 src/main/java/net/Indyuce/mmoitems/ability/arcane/Arcane_Rift.java rename src/main/java/net/Indyuce/mmoitems/ability/{arcane => list/location}/Arcane_Hail.java (62%) rename src/main/java/net/Indyuce/mmoitems/ability/{ => list/location}/Black_Hole.java (68%) rename src/main/java/net/Indyuce/mmoitems/ability/{ => list/location}/Contamination.java (58%) rename src/main/java/net/Indyuce/mmoitems/ability/{onhit => list/location}/Corrosion.java (60%) rename src/main/java/net/Indyuce/mmoitems/ability/{ => list/location}/Corrupt.java (55%) rename src/main/java/net/Indyuce/mmoitems/ability/{onhit => list/location}/Freeze.java (65%) rename src/main/java/net/Indyuce/mmoitems/ability/{ => list/location}/Freezing_Curse.java (64%) rename src/main/java/net/Indyuce/mmoitems/ability/{onhit => list/location}/Ignite.java (57%) rename src/main/java/net/Indyuce/mmoitems/ability/{ => list/location}/Life_Ender.java (66%) rename src/main/java/net/Indyuce/mmoitems/ability/{ => list/location}/Lightning_Beam.java (50%) rename src/main/java/net/Indyuce/mmoitems/ability/{onhit => list/location}/Minor_Explosion.java (52%) create mode 100644 src/main/java/net/Indyuce/mmoitems/ability/list/location/Snowman_Turret.java create mode 100644 src/main/java/net/Indyuce/mmoitems/ability/list/misc/Arcane_Rift.java create mode 100644 src/main/java/net/Indyuce/mmoitems/ability/list/misc/Earthquake.java create mode 100644 src/main/java/net/Indyuce/mmoitems/ability/list/misc/Hoearthquake.java create mode 100644 src/main/java/net/Indyuce/mmoitems/ability/list/misc/Item_Bomb.java create mode 100644 src/main/java/net/Indyuce/mmoitems/ability/list/misc/Item_Throw.java create mode 100644 src/main/java/net/Indyuce/mmoitems/ability/list/misc/Leap.java create mode 100644 src/main/java/net/Indyuce/mmoitems/ability/list/misc/Regen_Ally.java create mode 100644 src/main/java/net/Indyuce/mmoitems/ability/list/simple/Blink.java create mode 100644 src/main/java/net/Indyuce/mmoitems/ability/list/simple/Blizzard.java create mode 100644 src/main/java/net/Indyuce/mmoitems/ability/list/simple/Bunny_Mode.java create mode 100644 src/main/java/net/Indyuce/mmoitems/ability/list/simple/Burning_Hands.java create mode 100644 src/main/java/net/Indyuce/mmoitems/ability/list/simple/Chicken_Wraith.java create mode 100644 src/main/java/net/Indyuce/mmoitems/ability/list/simple/Circular_Slash.java create mode 100644 src/main/java/net/Indyuce/mmoitems/ability/list/simple/Firefly.java create mode 100644 src/main/java/net/Indyuce/mmoitems/ability/list/simple/Frog_Mode.java create mode 100644 src/main/java/net/Indyuce/mmoitems/ability/list/simple/Frozen_Aura.java create mode 100644 src/main/java/net/Indyuce/mmoitems/ability/list/simple/Grand_Heal.java create mode 100644 src/main/java/net/Indyuce/mmoitems/ability/list/simple/Heal.java create mode 100644 src/main/java/net/Indyuce/mmoitems/ability/list/simple/Light_Dash.java rename src/main/java/net/Indyuce/mmoitems/ability/{ => list/simple}/Magical_Path.java (61%) rename src/main/java/net/Indyuce/mmoitems/ability/{ => list/simple}/Magical_Shield.java (56%) create mode 100644 src/main/java/net/Indyuce/mmoitems/ability/list/simple/Overload.java create mode 100644 src/main/java/net/Indyuce/mmoitems/ability/list/simple/Present_Throw.java rename src/main/java/net/Indyuce/mmoitems/ability/{ => list/simple}/Shadow_Veil.java (57%) create mode 100644 src/main/java/net/Indyuce/mmoitems/ability/list/simple/Shockwave.java create mode 100644 src/main/java/net/Indyuce/mmoitems/ability/list/simple/Sky_Smash.java create mode 100644 src/main/java/net/Indyuce/mmoitems/ability/list/simple/Swiftness.java create mode 100644 src/main/java/net/Indyuce/mmoitems/ability/list/simple/Throw_Up.java create mode 100644 src/main/java/net/Indyuce/mmoitems/ability/list/target/Blind.java create mode 100644 src/main/java/net/Indyuce/mmoitems/ability/list/target/Bloodbath.java create mode 100644 src/main/java/net/Indyuce/mmoitems/ability/list/target/Burn.java create mode 100644 src/main/java/net/Indyuce/mmoitems/ability/list/target/Confuse.java create mode 100644 src/main/java/net/Indyuce/mmoitems/ability/list/target/Death_Mark.java create mode 100644 src/main/java/net/Indyuce/mmoitems/ability/list/target/Magma_Fissure.java create mode 100644 src/main/java/net/Indyuce/mmoitems/ability/list/target/Poison.java create mode 100644 src/main/java/net/Indyuce/mmoitems/ability/list/target/Shock.java create mode 100644 src/main/java/net/Indyuce/mmoitems/ability/list/target/Slow.java create mode 100644 src/main/java/net/Indyuce/mmoitems/ability/list/target/Smite.java create mode 100644 src/main/java/net/Indyuce/mmoitems/ability/list/target/Sparkle.java create mode 100644 src/main/java/net/Indyuce/mmoitems/ability/list/target/Starfall.java create mode 100644 src/main/java/net/Indyuce/mmoitems/ability/list/target/Stun.java create mode 100644 src/main/java/net/Indyuce/mmoitems/ability/list/target/Tactical_Grenade.java create mode 100644 src/main/java/net/Indyuce/mmoitems/ability/list/target/Targeted_Fireball.java create mode 100644 src/main/java/net/Indyuce/mmoitems/ability/list/target/Vampirism.java rename src/main/java/net/Indyuce/mmoitems/ability/{onhit => list/target}/Weaken_Target.java (66%) create mode 100644 src/main/java/net/Indyuce/mmoitems/ability/list/target/Wither.java create mode 100644 src/main/java/net/Indyuce/mmoitems/ability/list/vector/Bouncy_Fireball.java create mode 100644 src/main/java/net/Indyuce/mmoitems/ability/list/vector/Corrupted_Fangs.java create mode 100644 src/main/java/net/Indyuce/mmoitems/ability/list/vector/Cursed_Beam.java rename src/main/java/net/Indyuce/mmoitems/ability/{ => list/vector}/Explosive_Turkey.java (77%) create mode 100644 src/main/java/net/Indyuce/mmoitems/ability/list/vector/Fire_Meteor.java create mode 100644 src/main/java/net/Indyuce/mmoitems/ability/list/vector/Firebolt.java create mode 100644 src/main/java/net/Indyuce/mmoitems/ability/list/vector/Heavy_Charge.java create mode 100644 src/main/java/net/Indyuce/mmoitems/ability/list/vector/Holy_Missile.java create mode 100644 src/main/java/net/Indyuce/mmoitems/ability/list/vector/Ice_Crystal.java create mode 100644 src/main/java/net/Indyuce/mmoitems/ability/list/vector/Shulker_Missile.java create mode 100644 src/main/java/net/Indyuce/mmoitems/ability/list/vector/TNT_Throw.java create mode 100644 src/main/java/net/Indyuce/mmoitems/ability/list/vector/Thrust.java create mode 100644 src/main/java/net/Indyuce/mmoitems/ability/metadata/FriendlyTargetAbilityMetadata.java create mode 100644 src/main/java/net/Indyuce/mmoitems/ability/metadata/ItemAbilityMetadata.java create mode 100644 src/main/java/net/Indyuce/mmoitems/ability/metadata/LocationAbilityMetadata.java create mode 100644 src/main/java/net/Indyuce/mmoitems/ability/metadata/SimpleAbilityMetadata.java create mode 100644 src/main/java/net/Indyuce/mmoitems/ability/metadata/TargetAbilityMetadata.java create mode 100644 src/main/java/net/Indyuce/mmoitems/ability/metadata/VectorAbilityMetadata.java delete mode 100644 src/main/java/net/Indyuce/mmoitems/ability/onhit/Blind.java delete mode 100644 src/main/java/net/Indyuce/mmoitems/ability/onhit/Bloodbath.java delete mode 100644 src/main/java/net/Indyuce/mmoitems/ability/onhit/Burn.java delete mode 100644 src/main/java/net/Indyuce/mmoitems/ability/onhit/Confuse.java delete mode 100644 src/main/java/net/Indyuce/mmoitems/ability/onhit/Death_Mark.java delete mode 100644 src/main/java/net/Indyuce/mmoitems/ability/onhit/Poison.java delete mode 100644 src/main/java/net/Indyuce/mmoitems/ability/onhit/Shock.java delete mode 100644 src/main/java/net/Indyuce/mmoitems/ability/onhit/Slow.java delete mode 100644 src/main/java/net/Indyuce/mmoitems/ability/onhit/Starfall.java delete mode 100644 src/main/java/net/Indyuce/mmoitems/ability/onhit/Stun.java delete mode 100644 src/main/java/net/Indyuce/mmoitems/ability/onhit/Vampirism.java delete mode 100644 src/main/java/net/Indyuce/mmoitems/ability/onhit/Wither.java create mode 100644 src/main/java/net/Indyuce/mmoitems/api/ItemAttackMetadata.java delete mode 100644 src/main/java/net/Indyuce/mmoitems/api/ItemAttackResult.java delete mode 100644 src/main/java/net/Indyuce/mmoitems/api/ability/LocationAbilityResult.java delete mode 100644 src/main/java/net/Indyuce/mmoitems/api/ability/SimpleAbilityResult.java delete mode 100644 src/main/java/net/Indyuce/mmoitems/api/ability/TargetAbilityResult.java delete mode 100644 src/main/java/net/Indyuce/mmoitems/api/ability/VectorAbilityResult.java delete mode 100644 src/main/java/net/Indyuce/mmoitems/api/player/PlayerAbilityData.java delete mode 100644 src/main/java/net/Indyuce/mmoitems/comp/mythicmobs/MythicMobsAbility.java create mode 100644 src/main/java/net/Indyuce/mmoitems/comp/mythicmobs/skill/MythicMobsAbility.java create mode 100644 src/main/java/net/Indyuce/mmoitems/comp/mythicmobs/skill/MythicMobsAbilityMetadata.java diff --git a/pom.xml b/pom.xml index 082f826d..abc2b7dd 100644 --- a/pom.xml +++ b/pom.xml @@ -129,7 +129,7 @@ io.lumine MythicLib - 1.1.1 + 1.1.2 provided diff --git a/src/main/java/net/Indyuce/mmoitems/MMOUtils.java b/src/main/java/net/Indyuce/mmoitems/MMOUtils.java index bb8c9e00..67e4fb87 100644 --- a/src/main/java/net/Indyuce/mmoitems/MMOUtils.java +++ b/src/main/java/net/Indyuce/mmoitems/MMOUtils.java @@ -146,41 +146,21 @@ public class MMOUtils { return null; } - /** - * @deprecated Not being used internally - */ - @Deprecated - public static String getProgressBar(double ratio, int n, String barChar) { - StringBuilder bar = new StringBuilder(); - for (int k = 0; k < n; k++) - bar.append(barChar); - return bar.substring(0, (int) (ratio * n)) + ChatColor.WHITE + bar.substring((int) (ratio * n)); - } - public static LivingEntity getDamager(EntityDamageByEntityEvent event) { - /* - * check direct damager - */ + // Check direct damager if (event.getDamager() instanceof LivingEntity) return (LivingEntity) event.getDamager(); /* - * checks projectile and add damage type, which supports every vanilla + * Checks projectile and add damage type, which supports every vanilla * projectile like snowballs, tridents and arrows */ if (event.getDamager() instanceof Projectile) { Projectile proj = (Projectile) event.getDamager(); - if (proj.getShooter() instanceof LivingEntity) return (LivingEntity) proj.getShooter(); + if (proj.getShooter() instanceof LivingEntity) + return (LivingEntity) proj.getShooter(); } - /* - * check for last damage - */ - // if (event.getEntity().getLastDamageCause() instanceof - // EntityDamageByEntityEvent && checkLastDamageCause) - // return getDamager(result, (EntityDamageByEntityEvent) - // event.getEntity().getLastDamageCause(), false); - return null; } @@ -205,18 +185,6 @@ public class MMOUtils { caseOnWords(item.getType().name().toLowerCase().replace("_", " ")); } - /** - * Is the player encumbered by carrying two-handed items? - * - * @deprecated Use PlayerData.get(player).areHandsFull() instead - */ - @Deprecated - public static boolean twoHandedCase(Player player) { - - // Straight from player data - return PlayerData.get(player).areHandsFull(); - } - /** * Super useful to display enum names like DIAMOND_SWORD in chat * diff --git a/src/main/java/net/Indyuce/mmoitems/api/ability/Ability.java b/src/main/java/net/Indyuce/mmoitems/ability/Ability.java similarity index 74% rename from src/main/java/net/Indyuce/mmoitems/api/ability/Ability.java rename to src/main/java/net/Indyuce/mmoitems/ability/Ability.java index 2d1c22ba..e5eb6d8a 100644 --- a/src/main/java/net/Indyuce/mmoitems/api/ability/Ability.java +++ b/src/main/java/net/Indyuce/mmoitems/ability/Ability.java @@ -1,29 +1,21 @@ -package net.Indyuce.mmoitems.api.ability; +package net.Indyuce.mmoitems.ability; import net.Indyuce.mmoitems.MMOUtils; -import net.Indyuce.mmoitems.api.ItemAttackResult; -import net.Indyuce.mmoitems.api.player.PlayerStats.CachedStats; +import net.Indyuce.mmoitems.api.ItemAttackMetadata; import net.Indyuce.mmoitems.stat.data.AbilityData; import org.apache.commons.lang.Validate; import org.bukkit.entity.LivingEntity; +import org.jetbrains.annotations.Nullable; import java.util.*; -public abstract class Ability { +public abstract class Ability { private final String name, id; private final List allowedModes; private final Map modifiers = new HashMap<>(); protected static final Random random = new Random(); - @Override - public boolean equals(Object obj) { - if (!(obj instanceof Ability)) { return false; } - - // Same name means same ability - return ((Ability) obj).getName().equals(getName()); - } - public Ability(CastingMode... allowedModes) { this.id = getClass().getSimpleName().toUpperCase().replace("-", "_").replace(" ", "_").replaceAll("[^A-Z_]", ""); this.name = getClass().getSimpleName().replace("_", " "); @@ -88,34 +80,28 @@ public abstract class Ability { /** * The first method called when a player uses an ability. - * - * @param stats - * Cached statistics of the player casting the ability - * @param target - * The eventual ability target - * @param ability - * The ability being cast - * @param result - * The melee attack result, which can be edited to - * increase/decrease final damage dealt + * + * @param attack Information concerning the current player attack as well + * as his MythicLib cached stat map + * @param target The eventual ability target + * @param ability The ability being cast * @return If the ability can be cast or not. AbilityResult should cache any * information used by the ability: target if found, etc. + *

+ * This can also return a null instance which means the ability was not cast. */ - public abstract AbilityResult whenRan(CachedStats stats, LivingEntity target, AbilityData ability, ItemAttackResult result); + @Nullable + public abstract T canBeCast(ItemAttackMetadata attack, LivingEntity target, AbilityData ability); /** * Called when a player successfully casts an ability - * - * @param stats - * Cached statistics of the player casting the ability - * @param ability - * All the information about the ability being cast. This is the - * same instance as the one returned in whenRan(..) - * @param result - * The melee attack result, which can be edited to - * increase/decrease final damage dealt + * + * @param attack Information concerning the current player attack as well + * as his MythicLib cached stat map + * @param ability All the information about the ability being cast. This is the + * same instance as the one returned in whenRan(..) */ - public abstract void whenCast(CachedStats stats, AbilityResult ability, ItemAttackResult result); + public abstract void whenCast(ItemAttackMetadata attack, T ability); public enum CastingMode { @@ -178,4 +164,14 @@ public abstract class Ability { return null; } } + + @Override + public boolean equals(Object obj) { + if (!(obj instanceof Ability)) { + return false; + } + + // Same name means same ability + return ((Ability) obj).getName().equals(getName()); + } } diff --git a/src/main/java/net/Indyuce/mmoitems/api/ability/AbilityResult.java b/src/main/java/net/Indyuce/mmoitems/ability/AbilityMetadata.java similarity index 56% rename from src/main/java/net/Indyuce/mmoitems/api/ability/AbilityResult.java rename to src/main/java/net/Indyuce/mmoitems/ability/AbilityMetadata.java index 405575d4..56075199 100644 --- a/src/main/java/net/Indyuce/mmoitems/api/ability/AbilityResult.java +++ b/src/main/java/net/Indyuce/mmoitems/ability/AbilityMetadata.java @@ -1,31 +1,31 @@ -package net.Indyuce.mmoitems.api.ability; - -import net.Indyuce.mmoitems.stat.data.AbilityData; - -public abstract class AbilityResult { - private final AbilityData ability; - - public AbilityResult(AbilityData ability) { - this.ability = ability; - } - - public AbilityData getAbility() { - return ability; - } - - /** - * @param path - * Path of ability modifier - * @return Calculates a new value for a given ability modifier - */ - public double getModifier(String path) { - return ability.getModifier(path); - } - - /** - * @return If the ability is cast successfully. This method is used to apply - * extra ability conditions (player must be on the ground, must aim - * at an entity..) - */ - public abstract boolean isSuccessful(); -} +package net.Indyuce.mmoitems.ability; + +import net.Indyuce.mmoitems.stat.data.AbilityData; + +public abstract class AbilityMetadata { + private final AbilityData ability; + + public AbilityMetadata(AbilityData ability) { + this.ability = ability; + } + + public AbilityData getAbility() { + return ability; + } + + /** + * @param path + * Path of ability modifier + * @return Calculates a new value for a given ability modifier + */ + public double getModifier(String path) { + return ability.getModifier(path); + } + + /** + * @return If the ability is cast successfully. This method is used to apply + * extra ability conditions (player must be on the ground, must aim + * at an entity..) + */ + public abstract boolean isSuccessful(); +} diff --git a/src/main/java/net/Indyuce/mmoitems/ability/Blink.java b/src/main/java/net/Indyuce/mmoitems/ability/Blink.java deleted file mode 100644 index 415a5fc1..00000000 --- a/src/main/java/net/Indyuce/mmoitems/ability/Blink.java +++ /dev/null @@ -1,42 +0,0 @@ -package net.Indyuce.mmoitems.ability; - -import org.bukkit.Location; -import org.bukkit.Particle; -import org.bukkit.entity.LivingEntity; - -import net.Indyuce.mmoitems.api.ItemAttackResult; -import net.Indyuce.mmoitems.api.ability.Ability; -import net.Indyuce.mmoitems.api.ability.AbilityResult; -import net.Indyuce.mmoitems.api.ability.SimpleAbilityResult; -import net.Indyuce.mmoitems.api.player.PlayerStats.CachedStats; -import net.Indyuce.mmoitems.stat.data.AbilityData; -import io.lumine.mythic.lib.version.VersionSound; - -public class Blink extends Ability { - public Blink() { - super(CastingMode.ON_HIT, CastingMode.WHEN_HIT, CastingMode.LEFT_CLICK, CastingMode.RIGHT_CLICK, CastingMode.SHIFT_LEFT_CLICK, CastingMode.SHIFT_RIGHT_CLICK); - - addModifier("range", 8); - addModifier("cooldown", 10); - addModifier("mana", 0); - addModifier("stamina", 0); - } - - @Override - public AbilityResult whenRan(CachedStats stats, LivingEntity target, AbilityData ability, ItemAttackResult result) { - return new SimpleAbilityResult(ability); - } - - @Override - public void whenCast(CachedStats stats, AbilityResult ability, ItemAttackResult result) { - stats.getPlayer().getWorld().spawnParticle(Particle.EXPLOSION_LARGE, stats.getPlayer().getLocation().add(0, 1, 0), 0); - stats.getPlayer().getWorld().spawnParticle(Particle.SPELL_INSTANT, stats.getPlayer().getLocation().add(0, 1, 0), 32, 0, 0, 0, .1); - stats.getPlayer().getWorld().playSound(stats.getPlayer().getLocation(), VersionSound.ENTITY_ENDERMAN_TELEPORT.toSound(), 1, 1); - Location loc = stats.getPlayer().getTargetBlock(null, (int) ability.getModifier("range")).getLocation().add(0, 1, 0); - loc.setYaw(stats.getPlayer().getLocation().getYaw()); - loc.setPitch(stats.getPlayer().getLocation().getPitch()); - stats.getPlayer().teleport(loc); - stats.getPlayer().getWorld().spawnParticle(Particle.EXPLOSION_LARGE, stats.getPlayer().getLocation().add(0, 1, 0), 0); - stats.getPlayer().getWorld().spawnParticle(Particle.SPELL_INSTANT, stats.getPlayer().getLocation().add(0, 1, 0), 32, 0, 0, 0, .1); - } -} diff --git a/src/main/java/net/Indyuce/mmoitems/ability/Blizzard.java b/src/main/java/net/Indyuce/mmoitems/ability/Blizzard.java deleted file mode 100644 index 003e4b81..00000000 --- a/src/main/java/net/Indyuce/mmoitems/ability/Blizzard.java +++ /dev/null @@ -1,89 +0,0 @@ -package net.Indyuce.mmoitems.ability; - -import java.util.ArrayList; -import java.util.List; -import java.util.UUID; - -import org.bukkit.Location; -import org.bukkit.Sound; -import org.bukkit.entity.LivingEntity; -import org.bukkit.entity.Snowball; -import org.bukkit.event.EventHandler; -import org.bukkit.event.EventPriority; -import org.bukkit.event.entity.EntityDamageByEntityEvent; -import org.bukkit.scheduler.BukkitRunnable; - -import net.Indyuce.mmoitems.MMOItems; -import net.Indyuce.mmoitems.api.ItemAttackResult; -import net.Indyuce.mmoitems.api.ability.Ability; -import net.Indyuce.mmoitems.api.ability.AbilityResult; -import net.Indyuce.mmoitems.api.ability.SimpleAbilityResult; -import net.Indyuce.mmoitems.api.player.PlayerStats.CachedStats; -import net.Indyuce.mmoitems.api.util.TemporaryListener; -import net.Indyuce.mmoitems.stat.data.AbilityData; - -public class Blizzard extends Ability { - public Blizzard() { - super(CastingMode.ON_HIT, CastingMode.WHEN_HIT, CastingMode.LEFT_CLICK, CastingMode.RIGHT_CLICK, CastingMode.SHIFT_LEFT_CLICK, - CastingMode.SHIFT_RIGHT_CLICK); - - addModifier("duration", 2.5); - addModifier("damage", 2); - addModifier("inaccuracy", 10); - addModifier("force", 1); - addModifier("cooldown", 10); - addModifier("mana", 0); - addModifier("stamina", 0); - } - - @Override - public AbilityResult whenRan(CachedStats stats, LivingEntity target, AbilityData ability, ItemAttackResult result) { - return new SimpleAbilityResult(ability); - } - - @Override - public void whenCast(CachedStats stats, AbilityResult ability, ItemAttackResult result) { - double duration = ability.getModifier("duration") * 10; - double force = ability.getModifier("force"); - double inaccuracy = ability.getModifier("inaccuracy"); - - new BukkitRunnable() { - int j = 0; - final SnowballThrower handler = new SnowballThrower(ability.getModifier("damage")); - - public void run() { - if (j++ > duration) { - handler.close(5 * 20); - cancel(); - return; - } - - Location loc = stats.getPlayer().getEyeLocation(); - loc.setPitch((float) (loc.getPitch() + (random.nextDouble() - .5) * inaccuracy)); - loc.setYaw((float) (loc.getYaw() + (random.nextDouble() - .5) * inaccuracy)); - - loc.getWorld().playSound(loc, Sound.ENTITY_SNOWBALL_THROW, 1, 1); - Snowball snowball = stats.getPlayer().launchProjectile(Snowball.class); - snowball.setVelocity(loc.getDirection().multiply(1.3 * force)); - handler.entities.add(snowball.getUniqueId()); - } - }.runTaskTimer(MMOItems.plugin, 0, 2); - } - - public static class SnowballThrower extends TemporaryListener { - private final List entities = new ArrayList<>(); - private final double damage; - - public SnowballThrower(double damage) { - super(EntityDamageByEntityEvent.getHandlerList()); - - this.damage = damage; - } - - @EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true) - public void a(EntityDamageByEntityEvent event) { - if (entities.contains(event.getDamager().getUniqueId())) - event.setDamage(damage); - } - } -} diff --git a/src/main/java/net/Indyuce/mmoitems/ability/Bouncy_Fireball.java b/src/main/java/net/Indyuce/mmoitems/ability/Bouncy_Fireball.java deleted file mode 100644 index f3e5b548..00000000 --- a/src/main/java/net/Indyuce/mmoitems/ability/Bouncy_Fireball.java +++ /dev/null @@ -1,97 +0,0 @@ -package net.Indyuce.mmoitems.ability; - -import org.bukkit.Location; -import org.bukkit.Particle; -import org.bukkit.Sound; -import org.bukkit.entity.Entity; -import org.bukkit.entity.LivingEntity; -import org.bukkit.scheduler.BukkitRunnable; -import org.bukkit.util.Vector; - -import net.Indyuce.mmoitems.MMOItems; -import net.Indyuce.mmoitems.MMOUtils; -import net.Indyuce.mmoitems.api.ItemAttackResult; -import net.Indyuce.mmoitems.api.ability.Ability; -import net.Indyuce.mmoitems.api.ability.AbilityResult; -import net.Indyuce.mmoitems.api.ability.VectorAbilityResult; -import net.Indyuce.mmoitems.api.player.PlayerStats.CachedStats; -import net.Indyuce.mmoitems.stat.data.AbilityData; -import io.lumine.mythic.lib.api.AttackResult; -import io.lumine.mythic.lib.api.DamageType; - -public class Bouncy_Fireball extends Ability { - public Bouncy_Fireball() { - super(CastingMode.ON_HIT, CastingMode.WHEN_HIT, CastingMode.LEFT_CLICK, CastingMode.RIGHT_CLICK, CastingMode.SHIFT_LEFT_CLICK, CastingMode.SHIFT_RIGHT_CLICK); - - addModifier("cooldown", 20); - addModifier("damage", 5); - addModifier("ignite", 40); - addModifier("speed", 1); - addModifier("radius", 4); - addModifier("mana", 0); - addModifier("stamina", 0); - } - - @Override - public AbilityResult whenRan(CachedStats stats, LivingEntity target, AbilityData ability, ItemAttackResult result) { - return new VectorAbilityResult(ability, stats.getPlayer(), target); - } - - @Override - public void whenCast(CachedStats stats, AbilityResult ability, ItemAttackResult result) { - stats.getPlayer().getWorld().playSound(stats.getPlayer().getLocation(), Sound.ENTITY_SNOWBALL_THROW, 2, 0); - new BukkitRunnable() { - int j = 0; - final Vector vec = ((VectorAbilityResult) ability).getTarget().setY(0).normalize().multiply(.5 * ability.getModifier("speed")); - final Location loc = stats.getPlayer().getLocation().clone().add(0, 1.2, 0); - int bounces = 0; - - double y = .3; - - public void run() { - j++; - if (j > 100) { - loc.getWorld().spawnParticle(Particle.SMOKE_LARGE, loc, 32, 0, 0, 0, .05); - loc.getWorld().playSound(loc, Sound.BLOCK_FIRE_EXTINGUISH, 1, 1); - cancel(); - return; - } - - loc.add(vec); - loc.add(0, y, 0); - if (y > -.6) - y -= .05; - - loc.getWorld().spawnParticle(Particle.LAVA, loc, 0); - loc.getWorld().spawnParticle(Particle.FLAME, loc, 4, 0, 0, 0, .03); - loc.getWorld().spawnParticle(Particle.SMOKE_NORMAL, loc, 1, 0, 0, 0, .03); - - if (loc.getBlock().getType().isSolid()) { - loc.add(0, -y, 0); - loc.add(vec.clone().multiply(-1)); - y = .4; - bounces++; - loc.getWorld().playSound(loc, Sound.ENTITY_BLAZE_HURT, 3, 2); - } - - if (bounces > 2) { - double radius = ability.getModifier("radius"); - double damage = ability.getModifier("damage"); - double ignite = ability.getModifier("ignite"); - - for (Entity entity : MMOUtils.getNearbyChunkEntities(loc)) - if (entity.getLocation().distanceSquared(loc) < radius * radius) - if (MMOUtils.canDamage(stats.getPlayer(), entity)) { - new AttackResult(damage, DamageType.SKILL, DamageType.MAGIC, DamageType.PROJECTILE).damage(stats.getPlayer(), (LivingEntity) entity); - entity.setFireTicks((int) (ignite * 20)); - } - - loc.getWorld().spawnParticle(Particle.EXPLOSION_LARGE, loc, 12, 2, 2, 2, 0); - loc.getWorld().spawnParticle(Particle.EXPLOSION_NORMAL, loc, 48, 0, 0, 0, .2); - loc.getWorld().playSound(loc, Sound.ENTITY_GENERIC_EXPLODE, 3, 0); - cancel(); - } - } - }.runTaskTimer(MMOItems.plugin, 0, 1); - } -} diff --git a/src/main/java/net/Indyuce/mmoitems/ability/Bunny_Mode.java b/src/main/java/net/Indyuce/mmoitems/ability/Bunny_Mode.java deleted file mode 100644 index 12948795..00000000 --- a/src/main/java/net/Indyuce/mmoitems/ability/Bunny_Mode.java +++ /dev/null @@ -1,88 +0,0 @@ -package net.Indyuce.mmoitems.ability; - -import org.bukkit.Bukkit; -import org.bukkit.Particle; -import org.bukkit.entity.LivingEntity; -import org.bukkit.entity.Player; -import org.bukkit.event.EventHandler; -import org.bukkit.event.EventPriority; -import org.bukkit.event.entity.EntityDamageEvent; -import org.bukkit.event.entity.EntityDamageEvent.DamageCause; -import org.bukkit.scheduler.BukkitRunnable; - -import net.Indyuce.mmoitems.MMOItems; -import net.Indyuce.mmoitems.api.ItemAttackResult; -import net.Indyuce.mmoitems.api.ability.Ability; -import net.Indyuce.mmoitems.api.ability.AbilityResult; -import net.Indyuce.mmoitems.api.ability.SimpleAbilityResult; -import net.Indyuce.mmoitems.api.player.PlayerStats.CachedStats; -import net.Indyuce.mmoitems.api.util.TemporaryListener; -import net.Indyuce.mmoitems.stat.data.AbilityData; -import io.lumine.mythic.lib.version.VersionSound; - -public class Bunny_Mode extends Ability { - public Bunny_Mode() { - super(CastingMode.ON_HIT, CastingMode.WHEN_HIT, CastingMode.LEFT_CLICK, CastingMode.RIGHT_CLICK, CastingMode.SHIFT_LEFT_CLICK, - CastingMode.SHIFT_RIGHT_CLICK); - - addModifier("duration", 20); - addModifier("jump-force", 1); - addModifier("cooldown", 50); - addModifier("speed", 1); - addModifier("mana", 0); - addModifier("stamina", 0); - } - - @Override - public AbilityResult whenRan(CachedStats stats, LivingEntity target, AbilityData ability, ItemAttackResult result) { - return new SimpleAbilityResult(ability); - } - - @Override - public void whenCast(CachedStats stats, AbilityResult ability, ItemAttackResult result) { - double duration = ability.getModifier("duration") * 20; - double y = ability.getModifier("jump-force"); - double xz = ability.getModifier("speed"); - - new BukkitRunnable() { - int j = 0; - final BunnyHandler handler = new BunnyHandler(stats.getPlayer(), duration); - - public void run() { - if (j++ > duration) { - handler.close(3 * 20); - cancel(); - return; - } - - if (stats.getPlayer().getLocation().add(0, -.5, 0).getBlock().getType().isSolid()) { - stats.getPlayer() - .setVelocity(stats.getPlayer().getEyeLocation().getDirection().setY(0).normalize().multiply(.8 * xz).setY(0.5 * y / xz)); - stats.getPlayer().getWorld().playSound(stats.getPlayer().getLocation(), VersionSound.ENTITY_ENDER_DRAGON_FLAP.toSound(), 2, 1); - for (double a = 0; a < Math.PI * 2; a += Math.PI / 12) - stats.getPlayer().getWorld().spawnParticle(Particle.CLOUD, stats.getPlayer().getLocation(), 0, Math.cos(a), 0, Math.sin(a), - .2); - } - } - }.runTaskTimer(MMOItems.plugin, 0, 1); - - } - - public static class BunnyHandler extends TemporaryListener { - private final Player player; - - public BunnyHandler(Player player, double duration) { - super(EntityDamageEvent.getHandlerList()); - - this.player = player; - - Bukkit.getScheduler().runTaskLater(MMOItems.plugin, (Runnable) this::close, (long) (duration * 20)); - } - - @EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true) - public void a(EntityDamageEvent event) { - if (event.getEntity().equals(player) && event.getCause() == DamageCause.FALL) - event.setCancelled(true); - } - } -} diff --git a/src/main/java/net/Indyuce/mmoitems/ability/Burning_Hands.java b/src/main/java/net/Indyuce/mmoitems/ability/Burning_Hands.java deleted file mode 100644 index 317ba61f..00000000 --- a/src/main/java/net/Indyuce/mmoitems/ability/Burning_Hands.java +++ /dev/null @@ -1,74 +0,0 @@ -package net.Indyuce.mmoitems.ability; - -import org.bukkit.Location; -import org.bukkit.Particle; -import org.bukkit.Sound; -import org.bukkit.entity.Entity; -import org.bukkit.entity.LivingEntity; -import org.bukkit.scheduler.BukkitRunnable; -import org.bukkit.util.Vector; - -import net.Indyuce.mmoitems.MMOItems; -import net.Indyuce.mmoitems.MMOUtils; -import net.Indyuce.mmoitems.api.ItemAttackResult; -import net.Indyuce.mmoitems.api.ability.Ability; -import net.Indyuce.mmoitems.api.ability.AbilityResult; -import net.Indyuce.mmoitems.api.ability.SimpleAbilityResult; -import net.Indyuce.mmoitems.api.player.PlayerStats.CachedStats; -import net.Indyuce.mmoitems.stat.data.AbilityData; -import io.lumine.mythic.lib.api.AttackResult; -import io.lumine.mythic.lib.api.DamageType; - -public class Burning_Hands extends Ability { - public Burning_Hands() { - super(CastingMode.ON_HIT, CastingMode.WHEN_HIT, CastingMode.LEFT_CLICK, CastingMode.RIGHT_CLICK, CastingMode.SHIFT_LEFT_CLICK, - CastingMode.SHIFT_RIGHT_CLICK); - - addModifier("duration", 3); - addModifier("damage", 2); - addModifier("cooldown", 10); - addModifier("mana", 0); - addModifier("stamina", 0); - } - - @Override - public AbilityResult whenRan(CachedStats stats, LivingEntity target, AbilityData ability, ItemAttackResult result) { - return new SimpleAbilityResult(ability); - } - - @Override - public void whenCast(CachedStats stats, AbilityResult ability, ItemAttackResult result) { - double duration = ability.getModifier("duration") * 10; - double damage = ability.getModifier("damage") / 2; - - new BukkitRunnable() { - int j = 0; - - public void run() { - if (j++ > duration) - cancel(); - - Location loc = stats.getPlayer().getLocation().add(0, 1.2, 0); - loc.getWorld().playSound(loc, Sound.BLOCK_FIRE_AMBIENT, 1, 1); - - for (double m = -45; m < 45; m += 5) { - double a = (m + stats.getPlayer().getEyeLocation().getYaw() + 90) * Math.PI / 180; - Vector vec = new Vector(Math.cos(a), (random.nextDouble() - .5) * .2, Math.sin(a)); - Location source = loc.clone().add(vec.clone().setY(0)); - source.getWorld().spawnParticle(Particle.FLAME, source, 0, vec.getX(), vec.getY(), vec.getZ(), .5); - if (j % 2 == 0) - source.getWorld().spawnParticle(Particle.SMOKE_NORMAL, source, 0, vec.getX(), vec.getY(), vec.getZ(), .5); - } - - if (j % 5 == 0) - for (Entity entity : MMOUtils.getNearbyChunkEntities(loc)) - if (entity.getLocation().distanceSquared(loc) < 60 - && stats.getPlayer().getEyeLocation().getDirection() - .angle(entity.getLocation().toVector().subtract(stats.getPlayer().getLocation().toVector())) < Math.PI / 6 - && MMOUtils.canDamage(stats.getPlayer(), entity)) - new AttackResult(damage, DamageType.SKILL, DamageType.MAGIC).damage(stats.getPlayer(), (LivingEntity) entity); - - } - }.runTaskTimer(MMOItems.plugin, 0, 2); - } -} diff --git a/src/main/java/net/Indyuce/mmoitems/ability/Chicken_Wraith.java b/src/main/java/net/Indyuce/mmoitems/ability/Chicken_Wraith.java deleted file mode 100644 index f55eb43d..00000000 --- a/src/main/java/net/Indyuce/mmoitems/ability/Chicken_Wraith.java +++ /dev/null @@ -1,97 +0,0 @@ -package net.Indyuce.mmoitems.ability; - -import java.util.ArrayList; -import java.util.List; - -import org.bukkit.Location; -import org.bukkit.Sound; -import org.bukkit.entity.Egg; -import org.bukkit.entity.LivingEntity; -import org.bukkit.event.EventHandler; -import org.bukkit.event.EventPriority; -import org.bukkit.event.entity.EntityDamageByEntityEvent; -import org.bukkit.event.player.PlayerEggThrowEvent; -import org.bukkit.scheduler.BukkitRunnable; - -import net.Indyuce.mmoitems.MMOItems; -import net.Indyuce.mmoitems.api.ItemAttackResult; -import net.Indyuce.mmoitems.api.ability.Ability; -import net.Indyuce.mmoitems.api.ability.AbilityResult; -import net.Indyuce.mmoitems.api.ability.SimpleAbilityResult; -import net.Indyuce.mmoitems.api.player.PlayerStats.CachedStats; -import net.Indyuce.mmoitems.api.util.TemporaryListener; -import net.Indyuce.mmoitems.stat.data.AbilityData; - -public class Chicken_Wraith extends Ability { - public Chicken_Wraith() { - super(CastingMode.ON_HIT, CastingMode.WHEN_HIT, CastingMode.LEFT_CLICK, CastingMode.RIGHT_CLICK, CastingMode.SHIFT_LEFT_CLICK, - CastingMode.SHIFT_RIGHT_CLICK); - - addModifier("duration", 2.5); - addModifier("damage", 2); - addModifier("inaccuracy", 10); - addModifier("force", 1); - addModifier("cooldown", 10); - addModifier("mana", 0); - addModifier("stamina", 0); - } - - @Override - public AbilityResult whenRan(CachedStats stats, LivingEntity target, AbilityData ability, ItemAttackResult result) { - return new SimpleAbilityResult(ability); - } - - @Override - public void whenCast(CachedStats stats, AbilityResult ability, ItemAttackResult result) { - double duration = ability.getModifier("duration") * 10; - double force = ability.getModifier("force"); - double inaccuracy = ability.getModifier("inaccuracy"); - - new BukkitRunnable() { - int j = 0; - final EggHandler handler = new EggHandler(ability.getModifier("damage")); - - public void run() { - if (j++ > duration) { - handler.close(5 * 20); - cancel(); - return; - } - - Location loc = stats.getPlayer().getEyeLocation(); - loc.setPitch((float) (loc.getPitch() + (random.nextDouble() - .5) * inaccuracy)); - loc.setYaw((float) (loc.getYaw() + (random.nextDouble() - .5) * inaccuracy)); - - loc.getWorld().playSound(loc, Sound.ENTITY_CHICKEN_EGG, 1, 1); - Egg egg = stats.getPlayer().launchProjectile(Egg.class); - egg.setVelocity(loc.getDirection().multiply(1.3 * force)); - - handler.entities.add(egg.getEntityId()); - } - }.runTaskTimer(MMOItems.plugin, 0, 2); - } - - public static class EggHandler extends TemporaryListener { - private final List entities = new ArrayList<>(); - private final double damage; - - public EggHandler(double damage) { - super(EntityDamageByEntityEvent.getHandlerList()); - - this.damage = damage; - } - - @EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true) - public void a(PlayerEggThrowEvent event) { - if (entities.contains(event.getEgg().getEntityId())) { - event.setHatching(false); - } - } - - @EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true) - public void b(EntityDamageByEntityEvent event) { - if (entities.contains(event.getDamager().getEntityId())) - event.setDamage(damage); - } - } -} diff --git a/src/main/java/net/Indyuce/mmoitems/ability/Circular_Slash.java b/src/main/java/net/Indyuce/mmoitems/ability/Circular_Slash.java deleted file mode 100644 index 17a83c7a..00000000 --- a/src/main/java/net/Indyuce/mmoitems/ability/Circular_Slash.java +++ /dev/null @@ -1,65 +0,0 @@ -package net.Indyuce.mmoitems.ability; - -import org.bukkit.Location; -import org.bukkit.Particle; -import org.bukkit.Sound; -import org.bukkit.entity.Entity; -import org.bukkit.entity.LivingEntity; -import org.bukkit.potion.PotionEffect; -import org.bukkit.potion.PotionEffectType; -import org.bukkit.util.Vector; - -import net.Indyuce.mmoitems.MMOUtils; -import net.Indyuce.mmoitems.api.ItemAttackResult; -import net.Indyuce.mmoitems.api.ability.Ability; -import net.Indyuce.mmoitems.api.ability.AbilityResult; -import net.Indyuce.mmoitems.api.ability.SimpleAbilityResult; -import net.Indyuce.mmoitems.api.player.PlayerStats.CachedStats; -import net.Indyuce.mmoitems.stat.data.AbilityData; -import io.lumine.mythic.lib.api.AttackResult; -import io.lumine.mythic.lib.api.DamageType; - -public class Circular_Slash extends Ability { - public Circular_Slash() { - super(CastingMode.ON_HIT, CastingMode.WHEN_HIT, CastingMode.LEFT_CLICK, CastingMode.RIGHT_CLICK, CastingMode.SHIFT_LEFT_CLICK, CastingMode.SHIFT_RIGHT_CLICK); - - addModifier("damage", 6); - addModifier("radius", 3); - addModifier("knockback", 1); - addModifier("cooldown", 10); - addModifier("mana", 0); - addModifier("stamina", 0); - } - - @Override - public AbilityResult whenRan(CachedStats stats, LivingEntity target, AbilityData ability, ItemAttackResult result) { - return new SimpleAbilityResult(ability); - } - - @Override - public void whenCast(CachedStats stats, AbilityResult ability, ItemAttackResult result) { - double damage = ability.getModifier("damage"); - double radius = ability.getModifier("radius"); - double knockback = ability.getModifier("knockback"); - - stats.getPlayer().getWorld().playSound(stats.getPlayer().getLocation(), Sound.ENTITY_ZOMBIE_ATTACK_IRON_DOOR, 2, .5f); - stats.getPlayer().addPotionEffect(new PotionEffect(PotionEffectType.SLOW, 2, 254)); - for (Entity entity : stats.getPlayer().getNearbyEntities(radius, radius, radius)) { - if (MMOUtils.canDamage(stats.getPlayer(), entity)) { - new AttackResult(damage, DamageType.SKILL, DamageType.PHYSICAL).damage(stats.getPlayer(), (LivingEntity) entity); - Vector v1 = entity.getLocation().toVector(); - Vector v2 = stats.getPlayer().getLocation().toVector(); - double y = .5; - Vector v3 = v1.subtract(v2).multiply(.5 * knockback).setY(knockback == 0 ? 0 : y); - entity.setVelocity(v3); - } - } - double step = 12 + (radius * 2.5); - for (double j = 0; j < Math.PI * 2; j += Math.PI / step) { - Location loc = stats.getPlayer().getLocation().clone(); - loc.add(Math.cos(j) * radius, .75, Math.sin(j) * radius); - loc.getWorld().spawnParticle(Particle.SMOKE_LARGE, loc, 0); - } - stats.getPlayer().getWorld().spawnParticle(Particle.EXPLOSION_LARGE, stats.getPlayer().getLocation().add(0, 1, 0), 0); - } -} diff --git a/src/main/java/net/Indyuce/mmoitems/ability/Corrupted_Fangs.java b/src/main/java/net/Indyuce/mmoitems/ability/Corrupted_Fangs.java deleted file mode 100644 index d7af3206..00000000 --- a/src/main/java/net/Indyuce/mmoitems/ability/Corrupted_Fangs.java +++ /dev/null @@ -1,95 +0,0 @@ -package net.Indyuce.mmoitems.ability; - -import java.util.ArrayList; -import java.util.List; - -import org.bukkit.Location; -import org.bukkit.Sound; -import org.bukkit.entity.EntityType; -import org.bukkit.entity.EvokerFangs; -import org.bukkit.entity.LivingEntity; -import org.bukkit.event.EventHandler; -import org.bukkit.event.Listener; -import org.bukkit.event.entity.EntityDamageByEntityEvent; -import org.bukkit.scheduler.BukkitRunnable; -import org.bukkit.util.Vector; - -import net.Indyuce.mmoitems.MMOItems; -import net.Indyuce.mmoitems.MMOUtils; -import net.Indyuce.mmoitems.api.ItemAttackResult; -import net.Indyuce.mmoitems.api.ability.Ability; -import net.Indyuce.mmoitems.api.ability.AbilityResult; -import net.Indyuce.mmoitems.api.ability.VectorAbilityResult; -import net.Indyuce.mmoitems.api.player.PlayerStats.CachedStats; -import net.Indyuce.mmoitems.api.util.TemporaryListener; -import net.Indyuce.mmoitems.stat.data.AbilityData; -import io.lumine.mythic.lib.api.AttackResult; -import io.lumine.mythic.lib.api.DamageType; - -public class Corrupted_Fangs extends Ability implements Listener { - public Corrupted_Fangs() { - super(CastingMode.ON_HIT, CastingMode.WHEN_HIT, CastingMode.LEFT_CLICK, CastingMode.RIGHT_CLICK, CastingMode.SHIFT_LEFT_CLICK, - CastingMode.SHIFT_RIGHT_CLICK); - - addModifier("damage", 5); - addModifier("cooldown", 12); - addModifier("mana", 0); - addModifier("stamina", 0); - addModifier("fangs", 6); - } - - @Override - public AbilityResult whenRan(CachedStats stats, LivingEntity target, AbilityData ability, ItemAttackResult result) { - return new VectorAbilityResult(ability, stats.getPlayer(), target); - } - - @Override - public void whenCast(CachedStats stats, AbilityResult ability, ItemAttackResult result) { - - stats.getPlayer().getWorld().playSound(stats.getPlayer().getLocation(), Sound.ENTITY_WITHER_SHOOT, 2, 2); - new BukkitRunnable() { - double fangAmount = ability.getModifier("fangs"); - final Vector vec = ((VectorAbilityResult) ability).getTarget().setY(0).multiply(2); - final Location loc = stats.getPlayer().getLocation(); - double ti = 0; - final FangsHandler handler = new FangsHandler(stats, ability.getModifier("damage")); - - public void run() { - if (ti++ >= fangAmount) { - handler.close(3 * 20); - cancel(); - return; - } - - loc.add(vec); - EvokerFangs evokerFangs = (EvokerFangs) stats.getPlayer().getWorld().spawnEntity(loc, EntityType.EVOKER_FANGS); - handler.entities.add(evokerFangs.getEntityId()); - } - }.runTaskTimer(MMOItems.plugin, 0, 1); - } - - public class FangsHandler extends TemporaryListener { - private final List entities = new ArrayList<>(); - private final CachedStats stats; - private final double damage; - - public FangsHandler(CachedStats stats, double damage) { - super(EntityDamageByEntityEvent.getHandlerList()); - - this.stats = stats; - this.damage = damage; - } - - @EventHandler - public void a(EntityDamageByEntityEvent event) { - if (event.getDamager() instanceof EvokerFangs && entities.contains(event.getDamager().getEntityId())) { - event.setDamage(0); // Fangs do 6 damage in vanilla so lets set to 0 to not do extra damage - if (MMOUtils.canDamage(stats.getPlayer(), event.getEntity())) { - new AttackResult(damage, DamageType.SKILL, DamageType.MAGIC).damage(stats.getPlayer(), (LivingEntity) event.getEntity()); - } else { - event.setCancelled(true); // Cancel the event if we cannot damage the target such as a player - } - } - } - } -} diff --git a/src/main/java/net/Indyuce/mmoitems/ability/Cursed_Beam.java b/src/main/java/net/Indyuce/mmoitems/ability/Cursed_Beam.java deleted file mode 100644 index 244be480..00000000 --- a/src/main/java/net/Indyuce/mmoitems/ability/Cursed_Beam.java +++ /dev/null @@ -1,106 +0,0 @@ -package net.Indyuce.mmoitems.ability; - -import java.util.List; - -import org.bukkit.Location; -import org.bukkit.Particle; -import org.bukkit.Sound; -import org.bukkit.entity.Entity; -import org.bukkit.entity.LivingEntity; -import org.bukkit.potion.PotionEffect; -import org.bukkit.potion.PotionEffectType; -import org.bukkit.scheduler.BukkitRunnable; -import org.bukkit.util.Vector; - -import net.Indyuce.mmoitems.MMOItems; -import net.Indyuce.mmoitems.MMOUtils; -import net.Indyuce.mmoitems.api.ItemAttackResult; -import net.Indyuce.mmoitems.api.ability.Ability; -import net.Indyuce.mmoitems.api.ability.AbilityResult; -import net.Indyuce.mmoitems.api.ability.VectorAbilityResult; -import net.Indyuce.mmoitems.api.player.PlayerStats.CachedStats; -import net.Indyuce.mmoitems.stat.data.AbilityData; -import io.lumine.mythic.lib.api.AttackResult; -import io.lumine.mythic.lib.api.DamageType; -import io.lumine.mythic.lib.version.VersionSound; - -public class Cursed_Beam extends Ability { - public Cursed_Beam() { - super(CastingMode.ON_HIT, CastingMode.WHEN_HIT, CastingMode.LEFT_CLICK, CastingMode.RIGHT_CLICK, CastingMode.SHIFT_LEFT_CLICK, CastingMode.SHIFT_RIGHT_CLICK); - - addModifier("damage", 8); - addModifier("cooldown", 10); - addModifier("duration", 5); - addModifier("mana", 0); - addModifier("stamina", 0); - } - - @Override - public AbilityResult whenRan(CachedStats stats, LivingEntity target, AbilityData ability, ItemAttackResult result) { - return new VectorAbilityResult(ability, stats.getPlayer(), target); - } - - @Override - public void whenCast(CachedStats stats, AbilityResult ability, ItemAttackResult result) { - double duration = ability.getModifier("duration"); - - stats.getPlayer().getWorld().playSound(stats.getPlayer().getLocation(), Sound.ENTITY_WITHER_SHOOT, 2, 2); - new BukkitRunnable() { - final Vector dir = ((VectorAbilityResult) ability).getTarget().multiply(.3); - final Location loc = stats.getPlayer().getEyeLocation().clone(); - final double r = 0.4; - int ti = 0; - - public void run() { - ti++; - if (ti > 50) - cancel(); - - List entities = MMOUtils.getNearbyChunkEntities(loc); - for (double j = 0; j < 4; j++) { - loc.add(dir); - for (double i = 0; i < Math.PI * 2; i += Math.PI / 6) { - Vector vec = MMOUtils.rotateFunc(new Vector(r * Math.cos(i), r * Math.sin(i), 0), loc); - loc.add(vec); - loc.getWorld().spawnParticle(Particle.SPELL_WITCH, loc, 0); - loc.add(vec.multiply(-1)); - } - - for (Entity target : entities) - if (MMOUtils.canDamage(stats.getPlayer(), loc, target)) { - effect(target); - double damage = ability.getModifier("damage"); - loc.getWorld().playSound(loc, VersionSound.ENTITY_ENDERMAN_TELEPORT.toSound(), 2, .7f); - - for (Entity entity : entities) - if (MMOUtils.canDamage(stats.getPlayer(), entity) && loc.distanceSquared(entity.getLocation().add(0, 1, 0)) < 9) { - new AttackResult(damage, DamageType.SKILL, DamageType.MAGIC, DamageType.PROJECTILE).damage(stats.getPlayer(), (LivingEntity) entity); - ((LivingEntity) entity).addPotionEffect(new PotionEffect(PotionEffectType.BLINDNESS, (int) (duration * 20), 0)); - } - cancel(); - return; - } - } - } - }.runTaskTimer(MMOItems.plugin, 0, 1); - } - - private void effect(Entity ent) { - new BukkitRunnable() { - final Location loc2 = ent.getLocation(); - double y = 0; - - public void run() { - for (int i = 0; i < 3; i++) { - y += .05; - for (int j = 0; j < 2; j++) { - double xz = y * Math.PI * .8 + (j * Math.PI); - loc2.getWorld().spawnParticle(Particle.SPELL_WITCH, loc2.clone().add(Math.cos(xz) * 2.5, y, Math.sin(xz) * 2.5), 0); - } - } - if (y >= 3) - cancel(); - } - }.runTaskTimer(MMOItems.plugin, 0, 1); - } -} diff --git a/src/main/java/net/Indyuce/mmoitems/ability/Earthquake.java b/src/main/java/net/Indyuce/mmoitems/ability/Earthquake.java deleted file mode 100644 index fe00df2d..00000000 --- a/src/main/java/net/Indyuce/mmoitems/ability/Earthquake.java +++ /dev/null @@ -1,75 +0,0 @@ -package net.Indyuce.mmoitems.ability; - -import java.util.ArrayList; -import java.util.List; - -import org.bukkit.Location; -import org.bukkit.Particle; -import org.bukkit.Sound; -import org.bukkit.entity.Entity; -import org.bukkit.entity.LivingEntity; -import org.bukkit.potion.PotionEffect; -import org.bukkit.potion.PotionEffectType; -import org.bukkit.scheduler.BukkitRunnable; -import org.bukkit.util.Vector; - -import net.Indyuce.mmoitems.MMOItems; -import net.Indyuce.mmoitems.MMOUtils; -import net.Indyuce.mmoitems.api.ItemAttackResult; -import net.Indyuce.mmoitems.api.ability.Ability; -import net.Indyuce.mmoitems.api.ability.AbilityResult; -import net.Indyuce.mmoitems.api.ability.SimpleAbilityResult; -import net.Indyuce.mmoitems.api.ability.VectorAbilityResult; -import net.Indyuce.mmoitems.api.player.PlayerStats.CachedStats; -import net.Indyuce.mmoitems.stat.data.AbilityData; -import io.lumine.mythic.lib.api.AttackResult; -import io.lumine.mythic.lib.api.DamageType; - -public class Earthquake extends Ability { - public Earthquake() { - super(CastingMode.ON_HIT, CastingMode.WHEN_HIT, CastingMode.LEFT_CLICK, CastingMode.RIGHT_CLICK, CastingMode.SHIFT_LEFT_CLICK, CastingMode.SHIFT_RIGHT_CLICK); - - addModifier("damage", 3); - addModifier("duration", 2); - addModifier("amplifier", 1); - addModifier("cooldown", 10); - addModifier("mana", 0); - addModifier("stamina", 0); - } - - @Override - public AbilityResult whenRan(CachedStats stats, LivingEntity target, AbilityData ability, ItemAttackResult result) { - return ((LivingEntity) stats.getPlayer()).isOnGround() ? new VectorAbilityResult(ability, stats.getPlayer(), target) : new SimpleAbilityResult(ability, false); - } - - @Override - public void whenCast(CachedStats stats, AbilityResult ability, ItemAttackResult result) { - double damage = ability.getModifier("damage"); - double slowDuration = ability.getModifier("duration"); - double slowAmplifier = ability.getModifier("amplifier"); - - new BukkitRunnable() { - final Vector vec = ((VectorAbilityResult) ability).getTarget().setY(0); - final Location loc = stats.getPlayer().getLocation(); - int ti = 0; - final List hit = new ArrayList<>(); - - public void run() { - ti++; - if (ti > 20) - cancel(); - - loc.add(vec); - loc.getWorld().spawnParticle(Particle.CLOUD, loc, 5, .5, 0, .5, 0); - loc.getWorld().playSound(loc, Sound.BLOCK_GRAVEL_BREAK, 2, 1); - - for (Entity entity : MMOUtils.getNearbyChunkEntities(loc)) - if (MMOUtils.canDamage(stats.getPlayer(), entity) && loc.distanceSquared(entity.getLocation()) < 2 && !hit.contains(entity.getEntityId())) { - hit.add(entity.getEntityId()); - new AttackResult(damage, DamageType.SKILL, DamageType.MAGIC).damage(stats.getPlayer(), (LivingEntity) entity); - ((LivingEntity) entity).addPotionEffect(new PotionEffect(PotionEffectType.SLOW, (int) (slowDuration * 20), (int) slowAmplifier)); - } - } - }.runTaskTimer(MMOItems.plugin, 0, 1); - } -} diff --git a/src/main/java/net/Indyuce/mmoitems/ability/Fire_Meteor.java b/src/main/java/net/Indyuce/mmoitems/ability/Fire_Meteor.java deleted file mode 100644 index a127e54f..00000000 --- a/src/main/java/net/Indyuce/mmoitems/ability/Fire_Meteor.java +++ /dev/null @@ -1,76 +0,0 @@ -package net.Indyuce.mmoitems.ability; - -import org.bukkit.Location; -import org.bukkit.Particle; -import org.bukkit.Sound; -import org.bukkit.block.BlockFace; -import org.bukkit.entity.Entity; -import org.bukkit.entity.LivingEntity; -import org.bukkit.scheduler.BukkitRunnable; -import org.bukkit.util.Vector; - -import net.Indyuce.mmoitems.MMOItems; -import net.Indyuce.mmoitems.MMOUtils; -import net.Indyuce.mmoitems.api.ItemAttackResult; -import net.Indyuce.mmoitems.api.ability.Ability; -import net.Indyuce.mmoitems.api.ability.AbilityResult; -import net.Indyuce.mmoitems.api.ability.VectorAbilityResult; -import net.Indyuce.mmoitems.api.player.PlayerStats.CachedStats; -import net.Indyuce.mmoitems.stat.data.AbilityData; -import io.lumine.mythic.lib.api.AttackResult; -import io.lumine.mythic.lib.api.DamageType; -import io.lumine.mythic.lib.version.VersionSound; - -public class Fire_Meteor extends Ability { - public Fire_Meteor() { - super(CastingMode.ON_HIT, CastingMode.WHEN_HIT, CastingMode.LEFT_CLICK, CastingMode.RIGHT_CLICK, CastingMode.SHIFT_LEFT_CLICK, CastingMode.SHIFT_RIGHT_CLICK); - - addModifier("damage", 6); - addModifier("knockback", 1); - addModifier("radius", 4); - addModifier("cooldown", 10); - addModifier("mana", 0); - addModifier("stamina", 0); - } - - @Override - public AbilityResult whenRan(CachedStats stats, LivingEntity target, AbilityData ability, ItemAttackResult result) { - return new VectorAbilityResult(ability, stats.getPlayer(), target); - } - - @Override - public void whenCast(CachedStats stats, AbilityResult ability, ItemAttackResult result) { - stats.getPlayer().getWorld().playSound(stats.getPlayer().getLocation(), VersionSound.ENTITY_ENDERMAN_TELEPORT.toSound(), 3, 1); - new BukkitRunnable() { - double ti = 0; - final Location loc = stats.getPlayer().getLocation().clone().add(0, 10, 0); - final Vector vec = ((VectorAbilityResult) ability).getTarget().multiply(1.3).setY(-1).normalize(); - - public void run() { - ti++; - if (ti > 40) - cancel(); - - loc.add(vec); - loc.getWorld().spawnParticle(Particle.EXPLOSION_LARGE, loc, 0); - loc.getWorld().spawnParticle(Particle.FLAME, loc, 4, .2, .2, .2, 0); - if (loc.getBlock().getRelative(BlockFace.DOWN).getType().isSolid() || loc.getBlock().getType().isSolid()) { - loc.getWorld().playSound(loc, Sound.ENTITY_GENERIC_EXPLODE, 3, .6f); - loc.getWorld().spawnParticle(Particle.EXPLOSION_LARGE, loc, 10, 2, 2, 2, 0); - loc.getWorld().spawnParticle(Particle.EXPLOSION_NORMAL, loc, 32, 0, 0, 0, .3); - loc.getWorld().spawnParticle(Particle.FLAME, loc, 32, 0, 0, 0, .3); - - double damage = ability.getModifier("damage"); - double knockback = ability.getModifier("knockback"); - double radius = ability.getModifier("radius"); - for (Entity entity : MMOUtils.getNearbyChunkEntities(loc)) - if (MMOUtils.canDamage(stats.getPlayer(), entity) && entity.getLocation().distanceSquared(loc) < radius * radius) { - new AttackResult(damage, DamageType.SKILL, DamageType.MAGIC, DamageType.PROJECTILE).damage(stats.getPlayer(), (LivingEntity) entity); - entity.setVelocity(entity.getLocation().toVector().subtract(loc.toVector()).multiply(.1 * knockback).setY(.4 * knockback)); - } - cancel(); - } - } - }.runTaskTimer(MMOItems.plugin, 0, 1); - } -} diff --git a/src/main/java/net/Indyuce/mmoitems/ability/Firebolt.java b/src/main/java/net/Indyuce/mmoitems/ability/Firebolt.java deleted file mode 100644 index 0d0f8d43..00000000 --- a/src/main/java/net/Indyuce/mmoitems/ability/Firebolt.java +++ /dev/null @@ -1,79 +0,0 @@ -package net.Indyuce.mmoitems.ability; - -import java.util.List; - -import org.bukkit.Location; -import org.bukkit.Particle; -import org.bukkit.Sound; -import org.bukkit.entity.Entity; -import org.bukkit.entity.LivingEntity; -import org.bukkit.scheduler.BukkitRunnable; -import org.bukkit.util.Vector; - -import net.Indyuce.mmoitems.MMOItems; -import net.Indyuce.mmoitems.MMOUtils; -import net.Indyuce.mmoitems.api.ItemAttackResult; -import net.Indyuce.mmoitems.api.ability.Ability; -import net.Indyuce.mmoitems.api.ability.AbilityResult; -import net.Indyuce.mmoitems.api.ability.VectorAbilityResult; -import net.Indyuce.mmoitems.api.player.PlayerStats.CachedStats; -import net.Indyuce.mmoitems.stat.data.AbilityData; -import io.lumine.mythic.lib.api.AttackResult; -import io.lumine.mythic.lib.api.DamageType; -import io.lumine.mythic.lib.version.VersionSound; - -public class Firebolt extends Ability { - public Firebolt() { - super(CastingMode.ON_HIT, CastingMode.WHEN_HIT, CastingMode.LEFT_CLICK, CastingMode.RIGHT_CLICK, CastingMode.SHIFT_LEFT_CLICK, CastingMode.SHIFT_RIGHT_CLICK); - - addModifier("damage", 6); - addModifier("ignite", 3); - addModifier("cooldown", 10); - addModifier("mana", 0); - addModifier("stamina", 0); - } - - @Override - public AbilityResult whenRan(CachedStats stats, LivingEntity target, AbilityData ability, ItemAttackResult result) { - return new VectorAbilityResult(ability, stats.getPlayer(), target); - } - - @Override - public void whenCast(CachedStats stats, AbilityResult ability, ItemAttackResult result) { - stats.getPlayer().getWorld().playSound(stats.getPlayer().getLocation(), VersionSound.ENTITY_FIREWORK_ROCKET_BLAST.toSound(), 1, 1); - new BukkitRunnable() { - final Vector vec = ((VectorAbilityResult) ability).getTarget().multiply(.8); - final Location loc = stats.getPlayer().getEyeLocation(); - int ti = 0; - - public void run() { - ti++; - if (ti > 20) - cancel(); - - List entities = MMOUtils.getNearbyChunkEntities(loc); - loc.getWorld().playSound(loc, Sound.BLOCK_FIRE_AMBIENT, 2, 1); - for (int j = 0; j < 2; j++) { - loc.add(vec); - if (loc.getBlock().getType().isSolid()) - cancel(); - - loc.getWorld().spawnParticle(Particle.FLAME, loc, 5, .12, .12, .12, 0); - if (random.nextDouble() < .3) - loc.getWorld().spawnParticle(Particle.LAVA, loc, 0); - for (Entity target : entities) - if (MMOUtils.canDamage(stats.getPlayer(), loc, target)) { - loc.getWorld().spawnParticle(Particle.FLAME, loc, 32, 0, 0, 0, .1); - loc.getWorld().spawnParticle(Particle.LAVA, loc, 8, 0, 0, 0, 0); - loc.getWorld().spawnParticle(Particle.EXPLOSION_LARGE, loc, 0); - loc.getWorld().playSound(loc, Sound.ENTITY_GENERIC_EXPLODE, 3, 1); - new AttackResult(ability.getModifier("damage"), DamageType.SKILL, DamageType.MAGIC, DamageType.PROJECTILE).damage(stats.getPlayer(), (LivingEntity) target); - target.setFireTicks((int) ability.getModifier("ignite") * 20); - cancel(); - return; - } - } - } - }.runTaskTimer(MMOItems.plugin, 0, 1); - } -} diff --git a/src/main/java/net/Indyuce/mmoitems/ability/Firefly.java b/src/main/java/net/Indyuce/mmoitems/ability/Firefly.java deleted file mode 100644 index f05a90d9..00000000 --- a/src/main/java/net/Indyuce/mmoitems/ability/Firefly.java +++ /dev/null @@ -1,94 +0,0 @@ -package net.Indyuce.mmoitems.ability; - -import org.bukkit.Location; -import org.bukkit.Material; -import org.bukkit.Particle; -import org.bukkit.Sound; -import org.bukkit.entity.Entity; -import org.bukkit.entity.LivingEntity; -import org.bukkit.scheduler.BukkitRunnable; -import org.bukkit.util.Vector; - -import net.Indyuce.mmoitems.MMOItems; -import net.Indyuce.mmoitems.MMOUtils; -import net.Indyuce.mmoitems.api.ItemAttackResult; -import net.Indyuce.mmoitems.api.ability.Ability; -import net.Indyuce.mmoitems.api.ability.AbilityResult; -import net.Indyuce.mmoitems.api.ability.SimpleAbilityResult; -import net.Indyuce.mmoitems.api.player.PlayerStats.CachedStats; -import net.Indyuce.mmoitems.stat.data.AbilityData; -import io.lumine.mythic.lib.api.AttackResult; -import io.lumine.mythic.lib.api.DamageType; -import io.lumine.mythic.lib.version.VersionSound; - -public class Firefly extends Ability { - public Firefly() { - super(CastingMode.ON_HIT, CastingMode.WHEN_HIT, CastingMode.LEFT_CLICK, CastingMode.RIGHT_CLICK, CastingMode.SHIFT_LEFT_CLICK, CastingMode.SHIFT_RIGHT_CLICK); - - addModifier("damage", 6); - addModifier("duration", 2.5); - addModifier("knockback", 1); - addModifier("cooldown", 10); - addModifier("mana", 0); - addModifier("stamina", 0); - } - - @Override - public AbilityResult whenRan(CachedStats stats, LivingEntity target, AbilityData ability, ItemAttackResult result) { - return new SimpleAbilityResult(ability); - } - - @Override - public void whenCast(CachedStats stats, AbilityResult ability, ItemAttackResult result) { - double duration = ability.getModifier("duration") * 20; - - new BukkitRunnable() { - int j = 0; - - public void run() { - j++; - if (j > duration) - cancel(); - - if (stats.getPlayer().getLocation().getBlock().getType() == Material.WATER) { - stats.getPlayer().setVelocity(stats.getPlayer().getVelocity().multiply(3).setY(1.8)); - stats.getPlayer().getWorld().playSound(stats.getPlayer().getLocation(), Sound.BLOCK_FIRE_EXTINGUISH, 1, .5f); - stats.getPlayer().getWorld().spawnParticle(Particle.EXPLOSION_NORMAL, stats.getPlayer().getLocation().add(0, 1, 0), 32, 0, 0, 0, .2); - stats.getPlayer().getWorld().spawnParticle(Particle.CLOUD, stats.getPlayer().getLocation().add(0, 1, 0), 32, 0, 0, 0, .2); - cancel(); - return; - } - - for (Entity entity : stats.getPlayer().getNearbyEntities(1, 1, 1)) - if (MMOUtils.canDamage(stats.getPlayer(), entity)) { - double damage = ability.getModifier("damage"); - double knockback = ability.getModifier("knockback"); - - stats.getPlayer().getWorld().playSound(stats.getPlayer().getLocation(), Sound.ENTITY_ZOMBIE_ATTACK_IRON_DOOR, 1, .5f); - stats.getPlayer().getWorld().spawnParticle(Particle.LAVA, stats.getPlayer().getLocation().add(0, 1, 0), 32); - stats.getPlayer().getWorld().spawnParticle(Particle.SMOKE_LARGE, stats.getPlayer().getLocation().add(0, 1, 0), 24, 0, 0, 0, .3); - stats.getPlayer().getWorld().spawnParticle(Particle.FLAME, stats.getPlayer().getLocation().add(0, 1, 0), 24, 0, 0, 0, .3); - entity.setVelocity(stats.getPlayer().getVelocity().setY(0.3).multiply(1.7 * knockback)); - stats.getPlayer().setVelocity(stats.getPlayer().getEyeLocation().getDirection().multiply(-3).setY(.5)); - new AttackResult(damage, DamageType.SKILL, DamageType.MAGIC).damage(stats.getPlayer(), (LivingEntity) entity); - cancel(); - return; - } - - Location loc = stats.getPlayer().getLocation().add(0, 1, 0); - for (double a = 0; a < Math.PI * 2; a += Math.PI / 9) { - Vector vec = new Vector(.6 * Math.cos(a), .6 * Math.sin(a), 0); - vec = MMOUtils.rotateFunc(vec, loc); - loc.add(vec); - stats.getPlayer().getWorld().spawnParticle(Particle.SMOKE_NORMAL, loc, 0); - if (random.nextDouble() < .3) - stats.getPlayer().getWorld().spawnParticle(Particle.FLAME, loc, 0); - loc.add(vec.multiply(-1)); - } - - stats.getPlayer().setVelocity(stats.getPlayer().getEyeLocation().getDirection()); - stats.getPlayer().getWorld().playSound(stats.getPlayer().getLocation(), VersionSound.ENTITY_FIREWORK_ROCKET_BLAST.toSound(), 1, 1); - } - }.runTaskTimer(MMOItems.plugin, 0, 1); - } -} diff --git a/src/main/java/net/Indyuce/mmoitems/ability/FriendlyTargetAbility.java b/src/main/java/net/Indyuce/mmoitems/ability/FriendlyTargetAbility.java new file mode 100644 index 00000000..230ccffe --- /dev/null +++ b/src/main/java/net/Indyuce/mmoitems/ability/FriendlyTargetAbility.java @@ -0,0 +1,22 @@ +package net.Indyuce.mmoitems.ability; + +import net.Indyuce.mmoitems.ability.metadata.FriendlyTargetAbilityMetadata; +import net.Indyuce.mmoitems.api.ItemAttackMetadata; +import net.Indyuce.mmoitems.stat.data.AbilityData; +import org.bukkit.entity.LivingEntity; + +public abstract class FriendlyTargetAbility extends Ability { + public FriendlyTargetAbility(CastingMode... allowedModes) { + super(allowedModes); + } + + public FriendlyTargetAbility(String id, String name, CastingMode... allowedModes) { + super(id, name, allowedModes); + } + + public FriendlyTargetAbilityMetadata canBeCast(ItemAttackMetadata attack, LivingEntity target, AbilityData ability) { + return new FriendlyTargetAbilityMetadata(ability, attack.getDamager(), target); + } + + public abstract void whenCast(ItemAttackMetadata attack, FriendlyTargetAbilityMetadata ability); +} diff --git a/src/main/java/net/Indyuce/mmoitems/ability/Frog_Mode.java b/src/main/java/net/Indyuce/mmoitems/ability/Frog_Mode.java deleted file mode 100644 index 15dda563..00000000 --- a/src/main/java/net/Indyuce/mmoitems/ability/Frog_Mode.java +++ /dev/null @@ -1,58 +0,0 @@ -package net.Indyuce.mmoitems.ability; - -import org.bukkit.Material; -import org.bukkit.Particle; -import org.bukkit.entity.LivingEntity; -import org.bukkit.event.Listener; -import org.bukkit.scheduler.BukkitRunnable; - -import net.Indyuce.mmoitems.MMOItems; -import net.Indyuce.mmoitems.api.ItemAttackResult; -import net.Indyuce.mmoitems.api.ability.Ability; -import net.Indyuce.mmoitems.api.ability.AbilityResult; -import net.Indyuce.mmoitems.api.ability.SimpleAbilityResult; -import net.Indyuce.mmoitems.api.player.PlayerStats.CachedStats; -import net.Indyuce.mmoitems.stat.data.AbilityData; -import io.lumine.mythic.lib.version.VersionSound; - -public class Frog_Mode extends Ability implements Listener { - public Frog_Mode() { - super(CastingMode.ON_HIT, CastingMode.WHEN_HIT, CastingMode.LEFT_CLICK, CastingMode.RIGHT_CLICK, CastingMode.SHIFT_LEFT_CLICK, CastingMode.SHIFT_RIGHT_CLICK); - - addModifier("duration", 20); - addModifier("jump-force", 1); - addModifier("speed", 1); - addModifier("cooldown", 50); - addModifier("mana", 0); - addModifier("stamina", 0); - } - - @Override - public AbilityResult whenRan(CachedStats stats, LivingEntity target, AbilityData ability, ItemAttackResult result) { - return new SimpleAbilityResult(ability); - } - - @Override - public void whenCast(CachedStats stats, AbilityResult ability, ItemAttackResult result) { - double duration = ability.getModifier("duration") * 20; - double y = ability.getModifier("jump-force"); - double xz = ability.getModifier("speed"); - - new BukkitRunnable() { - int j = 0; - - public void run() { - j++; - if (j > duration) - cancel(); - - if (stats.getPlayer().getLocation().getBlock().getType() == Material.WATER) { - stats.getPlayer().setVelocity(stats.getPlayer().getEyeLocation().getDirection().setY(0).normalize().multiply(.8 * xz).setY(0.5 / xz * y)); - stats.getPlayer().getWorld().playSound(stats.getPlayer().getLocation(), VersionSound.ENTITY_ENDER_DRAGON_FLAP.toSound(), 2, 1); - for (double a = 0; a < Math.PI * 2; a += Math.PI / 12) - stats.getPlayer().getWorld().spawnParticle(Particle.CLOUD, stats.getPlayer().getLocation(), 0, Math.cos(a), 0, Math.sin(a), .2); - } - } - }.runTaskTimer(MMOItems.plugin, 0, 1); - } -} diff --git a/src/main/java/net/Indyuce/mmoitems/ability/Frozen_Aura.java b/src/main/java/net/Indyuce/mmoitems/ability/Frozen_Aura.java deleted file mode 100644 index f553bcc2..00000000 --- a/src/main/java/net/Indyuce/mmoitems/ability/Frozen_Aura.java +++ /dev/null @@ -1,68 +0,0 @@ -package net.Indyuce.mmoitems.ability; - -import org.bukkit.Particle; -import org.bukkit.Sound; -import org.bukkit.entity.Entity; -import org.bukkit.entity.LivingEntity; -import org.bukkit.event.Listener; -import org.bukkit.potion.PotionEffect; -import org.bukkit.potion.PotionEffectType; -import org.bukkit.scheduler.BukkitRunnable; - -import net.Indyuce.mmoitems.MMOItems; -import net.Indyuce.mmoitems.MMOUtils; -import net.Indyuce.mmoitems.api.ItemAttackResult; -import net.Indyuce.mmoitems.api.ability.Ability; -import net.Indyuce.mmoitems.api.ability.AbilityResult; -import net.Indyuce.mmoitems.api.ability.SimpleAbilityResult; -import net.Indyuce.mmoitems.api.player.PlayerStats.CachedStats; -import net.Indyuce.mmoitems.stat.data.AbilityData; - -public class Frozen_Aura extends Ability implements Listener { - public Frozen_Aura() { - super(CastingMode.ON_HIT, CastingMode.WHEN_HIT, CastingMode.LEFT_CLICK, CastingMode.RIGHT_CLICK, CastingMode.SHIFT_LEFT_CLICK, CastingMode.SHIFT_RIGHT_CLICK); - - addModifier("duration", 6); - addModifier("amplifier", 1); - addModifier("radius", 10); - addModifier("cooldown", 10); - addModifier("mana", 0); - addModifier("stamina", 0); - } - - @Override - public AbilityResult whenRan(CachedStats stats, LivingEntity target, AbilityData ability, ItemAttackResult result) { - return new SimpleAbilityResult(ability); - } - - @Override - public void whenCast(CachedStats stats, AbilityResult ability, ItemAttackResult result) { - double duration = ability.getModifier("duration") * 20; - double radiusSquared = Math.pow(ability.getModifier("radius"), 2); - double amplifier = ability.getModifier("amplifier") - 1; - - new BukkitRunnable() { - double j = 0; - int ti = 0; - - public void run() { - if (ti++ > duration) - cancel(); - - j += Math.PI / 60; - for (double k = 0; k < Math.PI * 2; k += Math.PI / 2) - stats.getPlayer().getWorld().spawnParticle(Particle.SPELL_INSTANT, stats.getPlayer().getLocation().add(Math.cos(k + j) * 2, 1 + Math.sin(k + j * 7) / 3, Math.sin(k + j) * 2), 0); - - if (ti % 2 == 0) - stats.getPlayer().getWorld().playSound(stats.getPlayer().getLocation(), Sound.BLOCK_SNOW_BREAK, 1, 1); - - if (ti % 7 == 0) - for (Entity entity : MMOUtils.getNearbyChunkEntities(stats.getPlayer().getLocation())) - if (entity.getLocation().distanceSquared(stats.getPlayer().getLocation()) < radiusSquared && MMOUtils.canDamage(stats.getPlayer(), entity)) { - ((LivingEntity) entity).removePotionEffect(PotionEffectType.SLOW); - ((LivingEntity) entity).addPotionEffect(new PotionEffect(PotionEffectType.SLOW, 40, (int) amplifier)); - } - } - }.runTaskTimer(MMOItems.plugin, 0, 1); - } -} diff --git a/src/main/java/net/Indyuce/mmoitems/ability/Grand_Heal.java b/src/main/java/net/Indyuce/mmoitems/ability/Grand_Heal.java deleted file mode 100644 index f81e52b6..00000000 --- a/src/main/java/net/Indyuce/mmoitems/ability/Grand_Heal.java +++ /dev/null @@ -1,46 +0,0 @@ -package net.Indyuce.mmoitems.ability; - -import org.bukkit.Particle; -import org.bukkit.Sound; -import org.bukkit.entity.Entity; -import org.bukkit.entity.LivingEntity; -import org.bukkit.entity.Player; - -import net.Indyuce.mmoitems.MMOUtils; -import net.Indyuce.mmoitems.api.ItemAttackResult; -import net.Indyuce.mmoitems.api.ability.Ability; -import net.Indyuce.mmoitems.api.ability.AbilityResult; -import net.Indyuce.mmoitems.api.ability.SimpleAbilityResult; -import net.Indyuce.mmoitems.api.player.PlayerStats.CachedStats; -import net.Indyuce.mmoitems.stat.data.AbilityData; - -public class Grand_Heal extends Ability { - public Grand_Heal() { - super(CastingMode.ON_HIT, CastingMode.WHEN_HIT, CastingMode.LEFT_CLICK, CastingMode.RIGHT_CLICK, CastingMode.SHIFT_LEFT_CLICK, CastingMode.SHIFT_RIGHT_CLICK); - - addModifier("heal", 5); - addModifier("radius", 5); - addModifier("cooldown", 15); - addModifier("mana", 0); - addModifier("stamina", 0); - } - - @Override - public AbilityResult whenRan(CachedStats stats, LivingEntity target, AbilityData ability, ItemAttackResult result) { - return new SimpleAbilityResult(ability); - } - - @Override - public void whenCast(CachedStats stats, AbilityResult ability, ItemAttackResult result) { - double heal = ability.getModifier("heal"); - double radius = ability.getModifier("radius"); - - MMOUtils.heal(stats.getPlayer(), heal); - stats.getPlayer().getWorld().playSound(stats.getPlayer().getLocation(), Sound.ENTITY_PLAYER_LEVELUP, 1, 2); - stats.getPlayer().getWorld().spawnParticle(Particle.HEART, stats.getPlayer().getLocation().add(0, .75, 0), 16, 1, 1, 1, 0); - stats.getPlayer().getWorld().spawnParticle(Particle.VILLAGER_HAPPY, stats.getPlayer().getLocation().add(0, .75, 0), 16, 1, 1, 1, 0); - for (Entity entity : stats.getPlayer().getNearbyEntities(radius, radius, radius)) - if (entity instanceof Player) - MMOUtils.heal((Player) entity, heal); - } -} diff --git a/src/main/java/net/Indyuce/mmoitems/ability/Heal.java b/src/main/java/net/Indyuce/mmoitems/ability/Heal.java deleted file mode 100644 index b2e3ee8a..00000000 --- a/src/main/java/net/Indyuce/mmoitems/ability/Heal.java +++ /dev/null @@ -1,37 +0,0 @@ -package net.Indyuce.mmoitems.ability; - -import org.bukkit.Particle; -import org.bukkit.Sound; -import org.bukkit.entity.LivingEntity; - -import net.Indyuce.mmoitems.MMOUtils; -import net.Indyuce.mmoitems.api.ItemAttackResult; -import net.Indyuce.mmoitems.api.ability.Ability; -import net.Indyuce.mmoitems.api.ability.AbilityResult; -import net.Indyuce.mmoitems.api.ability.SimpleAbilityResult; -import net.Indyuce.mmoitems.api.player.PlayerStats.CachedStats; -import net.Indyuce.mmoitems.stat.data.AbilityData; - -public class Heal extends Ability { - public Heal() { - super(CastingMode.ON_HIT, CastingMode.WHEN_HIT, CastingMode.LEFT_CLICK, CastingMode.RIGHT_CLICK, CastingMode.SHIFT_LEFT_CLICK, CastingMode.SHIFT_RIGHT_CLICK); - - addModifier("heal", 4); - addModifier("cooldown", 10); - addModifier("mana", 0); - addModifier("stamina", 0); - } - - @Override - public AbilityResult whenRan(CachedStats stats, LivingEntity target, AbilityData ability, ItemAttackResult result) { - return new SimpleAbilityResult(ability); - } - - @Override - public void whenCast(CachedStats stats, AbilityResult ability, ItemAttackResult result) { - stats.getPlayer().getWorld().playSound(stats.getPlayer().getLocation(), Sound.ENTITY_PLAYER_LEVELUP, 1, 2); - stats.getPlayer().getWorld().spawnParticle(Particle.HEART, stats.getPlayer().getLocation().add(0, .75, 0), 16, 1, 1, 1, 0); - stats.getPlayer().getWorld().spawnParticle(Particle.VILLAGER_HAPPY, stats.getPlayer().getLocation().add(0, .75, 0), 16, 1, 1, 1, 0); - MMOUtils.heal(stats.getPlayer(), ability.getModifier("heal")); - } -} diff --git a/src/main/java/net/Indyuce/mmoitems/ability/Heavy_Charge.java b/src/main/java/net/Indyuce/mmoitems/ability/Heavy_Charge.java deleted file mode 100644 index f913ead3..00000000 --- a/src/main/java/net/Indyuce/mmoitems/ability/Heavy_Charge.java +++ /dev/null @@ -1,68 +0,0 @@ -package net.Indyuce.mmoitems.ability; - -import org.bukkit.Particle; -import org.bukkit.Sound; -import org.bukkit.entity.Entity; -import org.bukkit.entity.LivingEntity; -import org.bukkit.scheduler.BukkitRunnable; -import org.bukkit.util.Vector; - -import net.Indyuce.mmoitems.MMOItems; -import net.Indyuce.mmoitems.MMOUtils; -import net.Indyuce.mmoitems.api.ItemAttackResult; -import net.Indyuce.mmoitems.api.ability.Ability; -import net.Indyuce.mmoitems.api.ability.AbilityResult; -import net.Indyuce.mmoitems.api.ability.VectorAbilityResult; -import net.Indyuce.mmoitems.api.player.PlayerStats.CachedStats; -import net.Indyuce.mmoitems.stat.data.AbilityData; -import io.lumine.mythic.lib.api.AttackResult; -import io.lumine.mythic.lib.api.DamageType; - -public class Heavy_Charge extends Ability { - public Heavy_Charge() { - super(CastingMode.ON_HIT, CastingMode.WHEN_HIT, CastingMode.LEFT_CLICK, CastingMode.RIGHT_CLICK, CastingMode.SHIFT_LEFT_CLICK, CastingMode.SHIFT_RIGHT_CLICK); - - addModifier("damage", 6); - addModifier("knockback", 1); - addModifier("cooldown", 10); - addModifier("mana", 0); - addModifier("stamina", 0); - } - - @Override - public AbilityResult whenRan(CachedStats stats, LivingEntity target, AbilityData ability, ItemAttackResult result) { - return new VectorAbilityResult(ability, stats.getPlayer(), target); - } - - @Override - public void whenCast(CachedStats stats, AbilityResult ability, ItemAttackResult result) { - double knockback = ability.getModifier("knockback"); - - new BukkitRunnable() { - double ti = 0; - final Vector vec = ((VectorAbilityResult) ability).getTarget().setY(-1); - - public void run() { - ti++; - if (ti > 20) - cancel(); - - if (ti < 9) { - stats.getPlayer().setVelocity(vec); - stats.getPlayer().getWorld().spawnParticle(Particle.EXPLOSION_NORMAL, stats.getPlayer().getLocation().add(0, 1, 0), 3, .13, .13, .13, 0); - } - - for (Entity target : stats.getPlayer().getNearbyEntities(1, 1, 1)) - if (MMOUtils.canDamage(stats.getPlayer(), target)) { - stats.getPlayer().getWorld().playSound(stats.getPlayer().getLocation(), Sound.ENTITY_ZOMBIE_ATTACK_IRON_DOOR, 1, 1); - stats.getPlayer().getWorld().spawnParticle(Particle.EXPLOSION_LARGE, target.getLocation().add(0, 1, 0), 0); - target.setVelocity(stats.getPlayer().getVelocity().setY(0.3).multiply(1.7 * knockback)); - stats.getPlayer().setVelocity(stats.getPlayer().getVelocity().setX(0).setY(0).setZ(0)); - new AttackResult(ability.getModifier("damage"), DamageType.SKILL, DamageType.PHYSICAL).damage(stats.getPlayer(), (LivingEntity) target); - cancel(); - break; - } - } - }.runTaskTimer(MMOItems.plugin, 0, 1); - } -} diff --git a/src/main/java/net/Indyuce/mmoitems/ability/Hoearthquake.java b/src/main/java/net/Indyuce/mmoitems/ability/Hoearthquake.java deleted file mode 100644 index c8217f26..00000000 --- a/src/main/java/net/Indyuce/mmoitems/ability/Hoearthquake.java +++ /dev/null @@ -1,64 +0,0 @@ -package net.Indyuce.mmoitems.ability; - -import org.bukkit.Bukkit; -import org.bukkit.Location; -import org.bukkit.Material; -import org.bukkit.Particle; -import org.bukkit.Sound; -import org.bukkit.block.Block; -import org.bukkit.entity.LivingEntity; -import org.bukkit.event.block.BlockBreakEvent; -import org.bukkit.scheduler.BukkitRunnable; -import org.bukkit.util.Vector; - -import net.Indyuce.mmoitems.MMOItems; -import net.Indyuce.mmoitems.api.ItemAttackResult; -import net.Indyuce.mmoitems.api.ability.Ability; -import net.Indyuce.mmoitems.api.ability.AbilityResult; -import net.Indyuce.mmoitems.api.ability.SimpleAbilityResult; -import net.Indyuce.mmoitems.api.player.PlayerStats.CachedStats; -import net.Indyuce.mmoitems.stat.data.AbilityData; - -public class Hoearthquake extends Ability { - public Hoearthquake() { - super(CastingMode.ON_HIT, CastingMode.WHEN_HIT, CastingMode.LEFT_CLICK, CastingMode.RIGHT_CLICK, CastingMode.SHIFT_LEFT_CLICK, CastingMode.SHIFT_RIGHT_CLICK); - - addModifier("cooldown", 10); - addModifier("mana", 0); - addModifier("stamina", 0); - } - - @Override - public AbilityResult whenRan(CachedStats stats, LivingEntity target, AbilityData ability, ItemAttackResult result) { - return new SimpleAbilityResult(ability, ((LivingEntity) stats.getPlayer()).isOnGround()); - } - - @Override - public void whenCast(CachedStats stats, AbilityResult ability, ItemAttackResult result) { - new BukkitRunnable() { - final Vector vec = stats.getPlayer().getEyeLocation().getDirection().setY(0); - final Location loc = stats.getPlayer().getLocation(); - int ti = 0; - - public void run() { - if (ti++ > 20) - cancel(); - - loc.add(vec); - loc.getWorld().playSound(loc, Sound.BLOCK_GRAVEL_BREAK, 2, 1); - loc.getWorld().spawnParticle(Particle.CLOUD, loc, 1, .5, 0, .5, 0); - - for (int x = -1; x < 2; x++) - for (int z = -1; z < 2; z++) { - Block b = loc.clone().add(x, -1, z).getBlock(); - if (b.getType() == Material.GRASS || b.getType() == Material.DIRT) { - BlockBreakEvent event = new BlockBreakEvent(b, stats.getPlayer()); - event.setDropItems(false); - Bukkit.getPluginManager().callEvent(event); - if(!event.isCancelled()) b.setType(Material.FARMLAND); - } - } - } - }.runTaskTimer(MMOItems.plugin, 0, 1); - } -} diff --git a/src/main/java/net/Indyuce/mmoitems/ability/Holy_Missile.java b/src/main/java/net/Indyuce/mmoitems/ability/Holy_Missile.java deleted file mode 100644 index c6b81522..00000000 --- a/src/main/java/net/Indyuce/mmoitems/ability/Holy_Missile.java +++ /dev/null @@ -1,83 +0,0 @@ -package net.Indyuce.mmoitems.ability; - -import java.util.List; - -import org.bukkit.Location; -import org.bukkit.Particle; -import org.bukkit.Sound; -import org.bukkit.entity.Entity; -import org.bukkit.entity.LivingEntity; -import org.bukkit.scheduler.BukkitRunnable; -import org.bukkit.util.Vector; - -import net.Indyuce.mmoitems.MMOItems; -import net.Indyuce.mmoitems.MMOUtils; -import net.Indyuce.mmoitems.api.ItemAttackResult; -import net.Indyuce.mmoitems.api.ability.Ability; -import net.Indyuce.mmoitems.api.ability.AbilityResult; -import net.Indyuce.mmoitems.api.ability.VectorAbilityResult; -import net.Indyuce.mmoitems.api.player.PlayerStats.CachedStats; -import net.Indyuce.mmoitems.stat.data.AbilityData; -import io.lumine.mythic.lib.api.AttackResult; -import io.lumine.mythic.lib.api.DamageType; -import io.lumine.mythic.lib.version.VersionSound; - -public class Holy_Missile extends Ability { - public Holy_Missile() { - super(CastingMode.ON_HIT, CastingMode.WHEN_HIT, CastingMode.LEFT_CLICK, CastingMode.RIGHT_CLICK, CastingMode.SHIFT_LEFT_CLICK, CastingMode.SHIFT_RIGHT_CLICK); - - addModifier("damage", 6); - addModifier("cooldown", 10); - addModifier("duration", 4); - addModifier("mana", 0); - addModifier("stamina", 0); - } - - @Override - public AbilityResult whenRan(CachedStats stats, LivingEntity target, AbilityData ability, ItemAttackResult result) { - return new VectorAbilityResult(ability, stats.getPlayer(), target); - } - - @Override - public void whenCast(CachedStats stats, AbilityResult ability, ItemAttackResult result) { - double duration = ability.getModifier("duration") * 10; - double damage = ability.getModifier("damage"); - - stats.getPlayer().getWorld().playSound(stats.getPlayer().getLocation(), VersionSound.ENTITY_FIREWORK_ROCKET_BLAST.toSound(), 1, 1); - new BukkitRunnable() { - final Vector vec = ((VectorAbilityResult) ability).getTarget().multiply(.45); - final Location loc = stats.getPlayer().getLocation().clone().add(0, 1.3, 0); - double ti = 0; - - public void run() { - if (ti++ > duration) - cancel(); - - loc.getWorld().playSound(loc, VersionSound.BLOCK_NOTE_BLOCK_HAT.toSound(), 2, 1); - List entities = MMOUtils.getNearbyChunkEntities(loc); - for (int j = 0; j < 2; j++) { - loc.add(vec); - if (loc.getBlock().getType().isSolid()) - cancel(); - - for (double i = -Math.PI; i < Math.PI; i += Math.PI / 2) { - Vector v = new Vector(Math.cos(i + ti / 4), Math.sin(i + ti / 4), 0); - v = MMOUtils.rotateFunc(v, loc); - loc.getWorld().spawnParticle(Particle.FIREWORKS_SPARK, loc, 0, v.getX(), v.getY(), v.getZ(), .08); - } - - for (Entity entity : entities) - if (MMOUtils.canDamage(stats.getPlayer(), loc, entity)) { - loc.getWorld().spawnParticle(Particle.EXPLOSION_LARGE, loc, 1); - loc.getWorld().spawnParticle(Particle.FIREWORKS_SPARK, loc, 32, 0, 0, 0, .2); - loc.getWorld().playSound(loc, Sound.ENTITY_GENERIC_EXPLODE, 2, 1); - new AttackResult(damage, DamageType.SKILL, DamageType.MAGIC, DamageType.PROJECTILE).damage(stats.getPlayer(), (LivingEntity) entity); - cancel(); - return; - } - } - } - }.runTaskTimer(MMOItems.plugin, 0, 1); - } -} - diff --git a/src/main/java/net/Indyuce/mmoitems/ability/Ice_Crystal.java b/src/main/java/net/Indyuce/mmoitems/ability/Ice_Crystal.java deleted file mode 100644 index cd6353c0..00000000 --- a/src/main/java/net/Indyuce/mmoitems/ability/Ice_Crystal.java +++ /dev/null @@ -1,96 +0,0 @@ -package net.Indyuce.mmoitems.ability; - -import java.util.List; - -import org.bukkit.Color; -import org.bukkit.Location; -import org.bukkit.Particle; -import org.bukkit.Sound; -import org.bukkit.entity.Entity; -import org.bukkit.entity.LivingEntity; -import org.bukkit.potion.PotionEffect; -import org.bukkit.potion.PotionEffectType; -import org.bukkit.scheduler.BukkitRunnable; -import org.bukkit.util.Vector; - -import net.Indyuce.mmoitems.MMOItems; -import net.Indyuce.mmoitems.MMOUtils; -import net.Indyuce.mmoitems.api.ItemAttackResult; -import net.Indyuce.mmoitems.api.ability.Ability; -import net.Indyuce.mmoitems.api.ability.AbilityResult; -import net.Indyuce.mmoitems.api.ability.VectorAbilityResult; -import net.Indyuce.mmoitems.api.player.PlayerStats.CachedStats; -import net.Indyuce.mmoitems.stat.data.AbilityData; -import io.lumine.mythic.lib.api.AttackResult; -import io.lumine.mythic.lib.api.DamageType; -import io.lumine.mythic.lib.version.VersionSound; - -public class Ice_Crystal extends Ability { - public Ice_Crystal() { - super(CastingMode.ON_HIT, CastingMode.WHEN_HIT, CastingMode.LEFT_CLICK, CastingMode.RIGHT_CLICK, CastingMode.SHIFT_LEFT_CLICK, - CastingMode.SHIFT_RIGHT_CLICK); - - addModifier("damage", 6); - addModifier("duration", 3); - addModifier("amplifier", 1); - addModifier("cooldown", 10); - addModifier("mana", 0); - addModifier("stamina", 0); - } - - @Override - public AbilityResult whenRan(CachedStats stats, LivingEntity target, AbilityData ability, ItemAttackResult result) { - return new VectorAbilityResult(ability, stats.getPlayer(), target); - } - - @Override - public void whenCast(CachedStats stats, AbilityResult ability, ItemAttackResult result) { - stats.getPlayer().getWorld().playSound(stats.getPlayer().getLocation(), VersionSound.ENTITY_FIREWORK_ROCKET_BLAST.toSound(), 1, 1); - new BukkitRunnable() { - final Vector vec = ((VectorAbilityResult) ability).getTarget().multiply(.45); - final Location loc = stats.getPlayer().getEyeLocation().clone().add(0, -.3, 0); - int ti = 0; - - public void run() { - ti++; - if (ti > 25) - cancel(); - - loc.getWorld().playSound(loc, Sound.BLOCK_GLASS_BREAK, 2, 1); - List entities = MMOUtils.getNearbyChunkEntities(loc); - for (int j = 0; j < 3; j++) { - loc.add(vec); - if (loc.getBlock().getType().isSolid()) - cancel(); - - /* - * has a different particle effect since SNOW_DIG is not the - * same as in legacy minecraft, the particle effect is now a - * cross that rotates - */ - for (double r = 0; r < .4; r += .1) - for (double a = 0; a < Math.PI * 2; a += Math.PI / 2) { - Vector vec = MMOUtils.rotateFunc(new Vector(r * Math.cos(a + (double) ti / 10), r * Math.sin(a + (double) ti / 10), 0), - loc); - loc.add(vec); - loc.getWorld().spawnParticle(Particle.REDSTONE, loc, 1, new Particle.DustOptions(Color.WHITE, .7f)); - loc.add(vec.multiply(-1)); - } - - for (Entity entity : entities) - if (MMOUtils.canDamage(stats.getPlayer(), loc, entity)) { - loc.getWorld().spawnParticle(Particle.EXPLOSION_LARGE, loc, 0); - loc.getWorld().spawnParticle(Particle.FIREWORKS_SPARK, loc, 48, 0, 0, 0, .2); - loc.getWorld().playSound(loc, Sound.ENTITY_GENERIC_EXPLODE, 2, 1); - new AttackResult(ability.getModifier("damage"), DamageType.SKILL, DamageType.MAGIC, DamageType.PROJECTILE) - .damage(stats.getPlayer(), (LivingEntity) entity); - ((LivingEntity) entity).addPotionEffect(new PotionEffect(PotionEffectType.SLOW, - (int) (ability.getModifier("duration") * 20), (int) ability.getModifier("amplifier"))); - cancel(); - return; - } - } - } - }.runTaskTimer(MMOItems.plugin, 0, 1); - } -} diff --git a/src/main/java/net/Indyuce/mmoitems/ability/ItemAbility.java b/src/main/java/net/Indyuce/mmoitems/ability/ItemAbility.java new file mode 100644 index 00000000..d7aaba77 --- /dev/null +++ b/src/main/java/net/Indyuce/mmoitems/ability/ItemAbility.java @@ -0,0 +1,22 @@ +package net.Indyuce.mmoitems.ability; + +import net.Indyuce.mmoitems.ability.metadata.ItemAbilityMetadata; +import net.Indyuce.mmoitems.api.ItemAttackMetadata; +import net.Indyuce.mmoitems.stat.data.AbilityData; +import org.bukkit.entity.LivingEntity; + +public abstract class ItemAbility extends Ability { + public ItemAbility(CastingMode... allowedModes) { + super(allowedModes); + } + + public ItemAbility(String id, String name, CastingMode... allowedModes) { + super(id, name, allowedModes); + } + + public ItemAbilityMetadata canBeCast(ItemAttackMetadata attack, LivingEntity target, AbilityData ability) { + return new ItemAbilityMetadata(ability, attack.getDamager(), target); + } + + public abstract void whenCast(ItemAttackMetadata attack, ItemAbilityMetadata ability); +} diff --git a/src/main/java/net/Indyuce/mmoitems/ability/Item_Bomb.java b/src/main/java/net/Indyuce/mmoitems/ability/Item_Bomb.java deleted file mode 100644 index eb723b2a..00000000 --- a/src/main/java/net/Indyuce/mmoitems/ability/Item_Bomb.java +++ /dev/null @@ -1,90 +0,0 @@ -package net.Indyuce.mmoitems.ability; - -import org.bukkit.Material; -import org.bukkit.Particle; -import org.bukkit.Sound; -import org.bukkit.entity.Entity; -import org.bukkit.entity.LivingEntity; -import org.bukkit.event.Listener; -import org.bukkit.inventory.ItemStack; -import org.bukkit.potion.PotionEffect; -import org.bukkit.potion.PotionEffectType; -import org.bukkit.scheduler.BukkitRunnable; - -import net.Indyuce.mmoitems.MMOItems; -import net.Indyuce.mmoitems.MMOUtils; -import net.Indyuce.mmoitems.api.ItemAttackResult; -import net.Indyuce.mmoitems.api.ability.Ability; -import net.Indyuce.mmoitems.api.ability.AbilityResult; -import net.Indyuce.mmoitems.api.ability.VectorAbilityResult; -import net.Indyuce.mmoitems.api.player.PlayerStats.CachedStats; -import net.Indyuce.mmoitems.api.util.NoClipItem; -import net.Indyuce.mmoitems.stat.data.AbilityData; -import io.lumine.mythic.lib.api.AttackResult; -import io.lumine.mythic.lib.api.DamageType; -import io.lumine.mythic.lib.version.VersionSound; - -public class Item_Bomb extends Ability implements Listener { - public Item_Bomb() { - super(CastingMode.ON_HIT, CastingMode.WHEN_HIT, CastingMode.LEFT_CLICK, CastingMode.RIGHT_CLICK, CastingMode.SHIFT_LEFT_CLICK, CastingMode.SHIFT_RIGHT_CLICK); - - addModifier("damage", 7); - addModifier("radius", 6); - addModifier("slow-duration", 4); - addModifier("slow-amplifier", 1); - addModifier("cooldown", 15); - addModifier("mana", 0); - addModifier("stamina", 0); - } - - @Override - public AbilityResult whenRan(CachedStats stats, LivingEntity target, AbilityData ability, ItemAttackResult result) { - return new VectorAbilityResult(ability, stats.getPlayer(), target); - } - - // TODO getItemInMainHand? Breaks the ability when used in the offhand. - @Override - public void whenCast(CachedStats stats, AbilityResult ability, ItemAttackResult result) { - ItemStack itemStack = stats.getPlayer().getInventory().getItemInMainHand().clone(); - if (itemStack == null || itemStack.getType() == Material.AIR) { - result.setSuccessful(false); - return; - } - - final NoClipItem item = new NoClipItem(stats.getPlayer().getLocation().add(0, 1.2, 0), itemStack); - item.getEntity().setVelocity(((VectorAbilityResult) ability).getTarget().multiply(1.3)); - stats.getPlayer().getWorld().playSound(stats.getPlayer().getLocation(), Sound.ENTITY_SNOWBALL_THROW, 2, 0); - - new BukkitRunnable() { - int j = 0; - - public void run() { - if (j++ > 40) { - double radius = ability.getModifier("radius"); - double damage = ability.getModifier("damage"); - double slowDuration = ability.getModifier("slow-duration"); - double slowAmplifier = ability.getModifier("slow-amplifier"); - - for (Entity entity : item.getEntity().getNearbyEntities(radius, radius, radius)) - if (MMOUtils.canDamage(stats.getPlayer(), entity)) { - new AttackResult(damage, DamageType.SKILL, DamageType.PHYSICAL).damage(stats.getPlayer(), (LivingEntity) entity); - ((LivingEntity) entity).removePotionEffect(PotionEffectType.SLOW); - ((LivingEntity) entity).addPotionEffect(new PotionEffect(PotionEffectType.SLOW, (int) (slowDuration * 20), (int) slowAmplifier)); - } - - item.getEntity().getWorld().spawnParticle(Particle.EXPLOSION_LARGE, item.getEntity().getLocation(), 24, 2, 2, 2, 0); - item.getEntity().getWorld().spawnParticle(Particle.EXPLOSION_NORMAL, item.getEntity().getLocation(), 48, 0, 0, 0, .2); - item.getEntity().getWorld().playSound(item.getEntity().getLocation(), Sound.ENTITY_GENERIC_EXPLODE, 3, 0); - - item.close(); - cancel(); - return; - } - - item.getEntity().getWorld().spawnParticle(Particle.SMOKE_LARGE, item.getEntity().getLocation().add(0, .2, 0), 0); - item.getEntity().getWorld().spawnParticle(Particle.FIREWORKS_SPARK, item.getEntity().getLocation().add(0, .2, 0), 1, 0, 0, 0, .1); - item.getEntity().getWorld().playSound(item.getEntity().getLocation(), VersionSound.BLOCK_NOTE_BLOCK_HAT.toSound(), 2, (float) (.5 + (j / 40. * 1.5))); - } - }.runTaskTimer(MMOItems.plugin, 0, 1); - } -} diff --git a/src/main/java/net/Indyuce/mmoitems/ability/Item_Throw.java b/src/main/java/net/Indyuce/mmoitems/ability/Item_Throw.java deleted file mode 100644 index 8457ad4b..00000000 --- a/src/main/java/net/Indyuce/mmoitems/ability/Item_Throw.java +++ /dev/null @@ -1,91 +0,0 @@ -package net.Indyuce.mmoitems.ability; - -import com.google.gson.JsonArray; -import com.google.gson.JsonElement; -import com.google.gson.JsonObject; -import io.lumine.mythic.lib.MythicLib; -import io.lumine.mythic.lib.api.AttackResult; -import io.lumine.mythic.lib.api.DamageType; -import io.lumine.mythic.lib.api.item.NBTItem; -import net.Indyuce.mmoitems.MMOItems; -import net.Indyuce.mmoitems.MMOUtils; -import net.Indyuce.mmoitems.api.ItemAttackResult; -import net.Indyuce.mmoitems.api.ability.Ability; -import net.Indyuce.mmoitems.api.ability.AbilityResult; -import net.Indyuce.mmoitems.api.ability.VectorAbilityResult; -import net.Indyuce.mmoitems.api.player.PlayerStats.CachedStats; -import net.Indyuce.mmoitems.api.util.NoClipItem; -import net.Indyuce.mmoitems.stat.data.AbilityData; -import org.bukkit.Material; -import org.bukkit.Particle; -import org.bukkit.Sound; -import org.bukkit.entity.Entity; -import org.bukkit.entity.LivingEntity; -import org.bukkit.event.Listener; -import org.bukkit.inventory.ItemStack; -import org.bukkit.scheduler.BukkitRunnable; - -public class Item_Throw extends Ability implements Listener { - public Item_Throw() { - super(CastingMode.ON_HIT, CastingMode.WHEN_HIT, CastingMode.LEFT_CLICK, CastingMode.RIGHT_CLICK, CastingMode.SHIFT_LEFT_CLICK, CastingMode.SHIFT_RIGHT_CLICK); - - addModifier("damage", 6); - addModifier("force", 1); - addModifier("cooldown", 10); - addModifier("mana", 0); - addModifier("stamina", 0); - } - - @Override - public AbilityResult whenRan(CachedStats stats, LivingEntity target, AbilityData ability, ItemAttackResult result) { - return new VectorAbilityResult(ability, stats.getPlayer(), target); - } - - @Override - public void whenCast(CachedStats stats, AbilityResult ability, ItemAttackResult result) { - ItemStack itemStack = stats.getPlayer().getInventory().getItemInMainHand().clone(); - NBTItem nbtItem = NBTItem.get(itemStack); - if (itemStack.getType() == Material.AIR || !nbtItem.hasType()) { - result.setSuccessful(false); - return; - } - boolean hasAbility = false; - - for (JsonElement entry : MythicLib.plugin.getJson().parse(nbtItem.getString("MMOITEMS_ABILITY"), JsonArray.class)) { - if (!entry.isJsonObject()) - continue; - - JsonObject object = entry.getAsJsonObject(); - if (object.get("Id").getAsString().equalsIgnoreCase(getID())) { - hasAbility = true; - break; - } - } - - if (!hasAbility) - return; - - final NoClipItem item = new NoClipItem(stats.getPlayer().getLocation().add(0, 1.2, 0), itemStack); - item.getEntity().setVelocity(((VectorAbilityResult) ability).getTarget().multiply(1.5 * ability.getModifier("force"))); - stats.getPlayer().getWorld().playSound(stats.getPlayer().getLocation(), Sound.ENTITY_SNOWBALL_THROW, 1, 0); - new BukkitRunnable() { - double ti = 0; - - public void run() { - ti++; - if (ti > 20 || item.getEntity().isDead()) { - item.close(); - cancel(); - } - - item.getEntity().getWorld().spawnParticle(Particle.CRIT, item.getEntity().getLocation(), 0); - for (Entity target : item.getEntity().getNearbyEntities(1, 1, 1)) - if (MMOUtils.canDamage(stats.getPlayer(), target)) { - new AttackResult(ability.getModifier("damage"), DamageType.SKILL, DamageType.PHYSICAL, DamageType.PROJECTILE).damage(stats.getPlayer(), (LivingEntity) target); - item.close(); - cancel(); - } - } - }.runTaskTimer(MMOItems.plugin, 0, 1); - } -} diff --git a/src/main/java/net/Indyuce/mmoitems/ability/Leap.java b/src/main/java/net/Indyuce/mmoitems/ability/Leap.java deleted file mode 100644 index 6055e63a..00000000 --- a/src/main/java/net/Indyuce/mmoitems/ability/Leap.java +++ /dev/null @@ -1,51 +0,0 @@ -package net.Indyuce.mmoitems.ability; - -import org.bukkit.Particle; -import org.bukkit.entity.LivingEntity; -import org.bukkit.scheduler.BukkitRunnable; -import org.bukkit.util.Vector; - -import net.Indyuce.mmoitems.MMOItems; -import net.Indyuce.mmoitems.api.ItemAttackResult; -import net.Indyuce.mmoitems.api.ability.Ability; -import net.Indyuce.mmoitems.api.ability.AbilityResult; -import net.Indyuce.mmoitems.api.ability.SimpleAbilityResult; -import net.Indyuce.mmoitems.api.player.PlayerStats.CachedStats; -import net.Indyuce.mmoitems.stat.data.AbilityData; -import io.lumine.mythic.lib.version.VersionSound; - -public class Leap extends Ability { - public Leap() { - super(CastingMode.ON_HIT, CastingMode.WHEN_HIT, CastingMode.LEFT_CLICK, CastingMode.RIGHT_CLICK, CastingMode.SHIFT_LEFT_CLICK, CastingMode.SHIFT_RIGHT_CLICK); - - addModifier("force", 1); - addModifier("cooldown", 10); - addModifier("mana", 0); - addModifier("stamina", 0); - } - - @Override - public AbilityResult whenRan(CachedStats stats, LivingEntity target, AbilityData ability, ItemAttackResult result) { - return new SimpleAbilityResult(ability, ((LivingEntity) stats.getPlayer()).isOnGround()); - } - - @Override - public void whenCast(CachedStats stats, AbilityResult ability, ItemAttackResult result) { - stats.getPlayer().getWorld().playSound(stats.getPlayer().getLocation(), VersionSound.ENTITY_ENDER_DRAGON_FLAP.toSound(), 1, 0); - stats.getPlayer().getWorld().spawnParticle(Particle.EXPLOSION_NORMAL, stats.getPlayer().getLocation(), 16, 0, 0, 0.1); - Vector vec = stats.getPlayer().getEyeLocation().getDirection().multiply(2 * ability.getModifier("force")); - vec.setY(vec.getY() / 2); - stats.getPlayer().setVelocity(vec); - new BukkitRunnable() { - double ti = 0; - - public void run() { - ti++; - if (ti > 20) - cancel(); - - stats.getPlayer().getWorld().spawnParticle(Particle.CLOUD, stats.getPlayer().getLocation().add(0, 1, 0), 0); - } - }.runTaskTimer(MMOItems.plugin, 0, 1); - } -} diff --git a/src/main/java/net/Indyuce/mmoitems/ability/Light_Dash.java b/src/main/java/net/Indyuce/mmoitems/ability/Light_Dash.java deleted file mode 100644 index 65fa4d6b..00000000 --- a/src/main/java/net/Indyuce/mmoitems/ability/Light_Dash.java +++ /dev/null @@ -1,65 +0,0 @@ -package net.Indyuce.mmoitems.ability; - -import java.util.ArrayList; -import java.util.List; - -import org.bukkit.Particle; -import org.bukkit.entity.Entity; -import org.bukkit.entity.LivingEntity; -import org.bukkit.scheduler.BukkitRunnable; -import org.bukkit.util.Vector; - -import net.Indyuce.mmoitems.MMOItems; -import net.Indyuce.mmoitems.MMOUtils; -import net.Indyuce.mmoitems.api.ItemAttackResult; -import net.Indyuce.mmoitems.api.ability.Ability; -import net.Indyuce.mmoitems.api.ability.AbilityResult; -import net.Indyuce.mmoitems.api.ability.SimpleAbilityResult; -import net.Indyuce.mmoitems.api.player.PlayerStats.CachedStats; -import net.Indyuce.mmoitems.stat.data.AbilityData; -import io.lumine.mythic.lib.api.AttackResult; -import io.lumine.mythic.lib.api.DamageType; -import io.lumine.mythic.lib.version.VersionSound; - -public class Light_Dash extends Ability { - public Light_Dash() { - super(CastingMode.ON_HIT, CastingMode.WHEN_HIT, CastingMode.LEFT_CLICK, CastingMode.RIGHT_CLICK, CastingMode.SHIFT_LEFT_CLICK, CastingMode.SHIFT_RIGHT_CLICK); - - addModifier("damage", 3); - addModifier("cooldown", 10); - addModifier("length", 1); - addModifier("mana", 0); - addModifier("stamina", 0); - } - - @Override - public AbilityResult whenRan(CachedStats stats, LivingEntity target, AbilityData ability, ItemAttackResult result) { - return new SimpleAbilityResult(ability); - } - - @Override - public void whenCast(CachedStats stats, AbilityResult ability, ItemAttackResult result) { - double damage = ability.getModifier("damage"); - double length = ability.getModifier("length"); - - new BukkitRunnable() { - int j = 0; - final Vector vec = stats.getPlayer().getEyeLocation().getDirection(); - final List hit = new ArrayList<>(); - - public void run() { - if (j++ > 10 * Math.min(10, length)) - cancel(); - - stats.getPlayer().setVelocity(vec); - stats.getPlayer().getWorld().spawnParticle(Particle.SMOKE_LARGE, stats.getPlayer().getLocation().add(0, 1, 0), 0); - stats.getPlayer().getWorld().playSound(stats.getPlayer().getLocation(), VersionSound.ENTITY_ENDER_DRAGON_FLAP.toSound(), 1, 2); - for (Entity entity : stats.getPlayer().getNearbyEntities(1, 1, 1)) - if (!hit.contains(entity.getEntityId()) && MMOUtils.canDamage(stats.getPlayer(), entity)) { - hit.add(entity.getEntityId()); - new AttackResult(damage, DamageType.SKILL, DamageType.PHYSICAL).damage(stats.getPlayer(), (LivingEntity) entity); - } - } - }.runTaskTimer(MMOItems.plugin, 0, 2); - } -} diff --git a/src/main/java/net/Indyuce/mmoitems/ability/LocationAbility.java b/src/main/java/net/Indyuce/mmoitems/ability/LocationAbility.java new file mode 100644 index 00000000..08d3db7b --- /dev/null +++ b/src/main/java/net/Indyuce/mmoitems/ability/LocationAbility.java @@ -0,0 +1,22 @@ +package net.Indyuce.mmoitems.ability; + +import net.Indyuce.mmoitems.ability.metadata.LocationAbilityMetadata; +import net.Indyuce.mmoitems.api.ItemAttackMetadata; +import net.Indyuce.mmoitems.stat.data.AbilityData; +import org.bukkit.entity.LivingEntity; + +public abstract class LocationAbility extends Ability { + public LocationAbility(CastingMode... allowedModes) { + super(allowedModes); + } + + public LocationAbility(String id, String name, CastingMode... allowedModes) { + super(id, name, allowedModes); + } + + public LocationAbilityMetadata canBeCast(ItemAttackMetadata attack, LivingEntity target, AbilityData ability) { + return new LocationAbilityMetadata(ability, attack.getDamager(), target); + } + + public abstract void whenCast(ItemAttackMetadata attack, LocationAbilityMetadata ability); +} diff --git a/src/main/java/net/Indyuce/mmoitems/ability/Magma_Fissure.java b/src/main/java/net/Indyuce/mmoitems/ability/Magma_Fissure.java deleted file mode 100644 index 5297116a..00000000 --- a/src/main/java/net/Indyuce/mmoitems/ability/Magma_Fissure.java +++ /dev/null @@ -1,69 +0,0 @@ -package net.Indyuce.mmoitems.ability; - -import org.bukkit.Location; -import org.bukkit.Particle; -import org.bukkit.Sound; -import org.bukkit.entity.LivingEntity; -import org.bukkit.scheduler.BukkitRunnable; -import org.bukkit.util.Vector; - -import net.Indyuce.mmoitems.MMOItems; -import net.Indyuce.mmoitems.api.ItemAttackResult; -import net.Indyuce.mmoitems.api.ability.Ability; -import net.Indyuce.mmoitems.api.ability.AbilityResult; -import net.Indyuce.mmoitems.api.ability.TargetAbilityResult; -import net.Indyuce.mmoitems.api.player.PlayerStats.CachedStats; -import net.Indyuce.mmoitems.stat.data.AbilityData; -import io.lumine.mythic.lib.api.AttackResult; -import io.lumine.mythic.lib.api.DamageType; -import io.lumine.mythic.lib.version.VersionSound; - -public class Magma_Fissure extends Ability { - public Magma_Fissure() { - super(CastingMode.ON_HIT, CastingMode.WHEN_HIT, CastingMode.LEFT_CLICK, CastingMode.RIGHT_CLICK, CastingMode.SHIFT_LEFT_CLICK, CastingMode.SHIFT_RIGHT_CLICK); - - addModifier("cooldown", 10); - addModifier("mana", 0); - addModifier("stamina", 0); - addModifier("ignite", 4); - addModifier("damage", 4); - } - - @Override - public AbilityResult whenRan(CachedStats stats, LivingEntity target, AbilityData ability, ItemAttackResult result) { - return new TargetAbilityResult(ability, stats.getPlayer(), target); - } - - @Override - public void whenCast(CachedStats stats, AbilityResult ability, ItemAttackResult result) { - LivingEntity target = ((TargetAbilityResult) ability).getTarget(); - - new BukkitRunnable() { - int j = 0; - final Location loc = stats.getPlayer().getLocation().add(0, .2, 0); - - public void run() { - j++; - if (target.isDead() || !target.getWorld().equals(loc.getWorld()) || j > 200) { - cancel(); - return; - } - - Vector vec = target.getLocation().add(0, .2, 0).subtract(loc).toVector().normalize().multiply(.6); - loc.add(vec); - - loc.getWorld().spawnParticle(Particle.LAVA, loc, 2, .2, 0, .2, 0); - loc.getWorld().spawnParticle(Particle.FLAME, loc, 2, .2, 0, .2, 0); - loc.getWorld().spawnParticle(Particle.SMOKE_NORMAL, loc, 2, .2, 0, .2, 0); - loc.getWorld().playSound(loc, VersionSound.BLOCK_NOTE_BLOCK_HAT.toSound(), 1, 1); - - if (target.getLocation().distanceSquared(loc) < 1) { - loc.getWorld().playSound(loc, Sound.ENTITY_BLAZE_HURT, 2, 1); - target.setFireTicks((int) (target.getFireTicks() + ability.getModifier("ignite") * 20)); - new AttackResult(ability.getModifier("damage"), DamageType.SKILL, DamageType.MAGIC).damage(stats.getPlayer(), target); - cancel(); - } - } - }.runTaskTimer(MMOItems.plugin, 0, 1); - } -} \ No newline at end of file diff --git a/src/main/java/net/Indyuce/mmoitems/ability/Overload.java b/src/main/java/net/Indyuce/mmoitems/ability/Overload.java deleted file mode 100644 index 4ec1dfd2..00000000 --- a/src/main/java/net/Indyuce/mmoitems/ability/Overload.java +++ /dev/null @@ -1,58 +0,0 @@ -package net.Indyuce.mmoitems.ability; - -import org.bukkit.Location; -import org.bukkit.Particle; -import org.bukkit.Sound; -import org.bukkit.entity.Entity; -import org.bukkit.entity.LivingEntity; -import org.bukkit.potion.PotionEffect; -import org.bukkit.potion.PotionEffectType; - -import net.Indyuce.mmoitems.MMOUtils; -import net.Indyuce.mmoitems.api.ItemAttackResult; -import net.Indyuce.mmoitems.api.ability.Ability; -import net.Indyuce.mmoitems.api.ability.AbilityResult; -import net.Indyuce.mmoitems.api.ability.SimpleAbilityResult; -import net.Indyuce.mmoitems.api.player.PlayerStats.CachedStats; -import net.Indyuce.mmoitems.stat.data.AbilityData; -import io.lumine.mythic.lib.api.AttackResult; -import io.lumine.mythic.lib.api.DamageType; -import io.lumine.mythic.lib.version.VersionSound; - -public class Overload extends Ability { - public Overload() { - super(CastingMode.ON_HIT, CastingMode.WHEN_HIT, CastingMode.LEFT_CLICK, CastingMode.RIGHT_CLICK, CastingMode.SHIFT_LEFT_CLICK, CastingMode.SHIFT_RIGHT_CLICK); - - addModifier("damage", 6); - addModifier("cooldown", 10); - addModifier("radius", 6); - addModifier("mana", 0); - addModifier("stamina", 0); - } - - @Override - public AbilityResult whenRan(CachedStats stats, LivingEntity target, AbilityData ability, ItemAttackResult result) { - return new SimpleAbilityResult(ability); - } - - @Override - public void whenCast(CachedStats stats, AbilityResult ability, ItemAttackResult result) { - double damage = ability.getModifier("damage"); - double radius = ability.getModifier("radius"); - - stats.getPlayer().getWorld().playSound(stats.getPlayer().getLocation(), Sound.ENTITY_GENERIC_EXPLODE, 2, 0); - stats.getPlayer().getWorld().playSound(stats.getPlayer().getLocation(), VersionSound.ENTITY_FIREWORK_ROCKET_TWINKLE.toSound(), 2, 0); - stats.getPlayer().addPotionEffect(new PotionEffect(PotionEffectType.SLOW, 2, 254)); - - for (Entity entity : stats.getPlayer().getNearbyEntities(radius, radius, radius)) - if (MMOUtils.canDamage(stats.getPlayer(), entity)) - new AttackResult(damage, DamageType.SKILL, DamageType.MAGIC).damage(stats.getPlayer(), (LivingEntity) entity); - - double step = 12 + (radius * 2.5); - for (double j = 0; j < Math.PI * 2; j += Math.PI / step) { - Location loc = stats.getPlayer().getLocation().clone().add(Math.cos(j) * radius, 1, Math.sin(j) * radius); - stats.getPlayer().getWorld().spawnParticle(Particle.CLOUD, loc, 4, 0, 0, 0, .05); - stats.getPlayer().getWorld().spawnParticle(Particle.FIREWORKS_SPARK, loc, 4, 0, 0, 0, .05); - } - } -} diff --git a/src/main/java/net/Indyuce/mmoitems/ability/Present_Throw.java b/src/main/java/net/Indyuce/mmoitems/ability/Present_Throw.java deleted file mode 100644 index b630e716..00000000 --- a/src/main/java/net/Indyuce/mmoitems/ability/Present_Throw.java +++ /dev/null @@ -1,107 +0,0 @@ -package net.Indyuce.mmoitems.ability; - -import java.lang.reflect.Field; -import java.util.UUID; -import java.util.logging.Level; - -import org.bukkit.Particle; -import org.bukkit.Sound; -import org.bukkit.entity.Entity; -import org.bukkit.entity.LivingEntity; -import org.bukkit.inventory.ItemStack; -import org.bukkit.inventory.meta.ItemMeta; -import org.bukkit.scheduler.BukkitRunnable; -import org.yaml.snakeyaml.external.biz.base64Coder.Base64Coder; - -import com.mojang.authlib.GameProfile; -import com.mojang.authlib.properties.Property; - -import net.Indyuce.mmoitems.MMOItems; -import net.Indyuce.mmoitems.MMOUtils; -import net.Indyuce.mmoitems.api.ItemAttackResult; -import net.Indyuce.mmoitems.api.ability.Ability; -import net.Indyuce.mmoitems.api.ability.AbilityResult; -import net.Indyuce.mmoitems.api.ability.SimpleAbilityResult; -import net.Indyuce.mmoitems.api.player.PlayerStats.CachedStats; -import net.Indyuce.mmoitems.api.util.NoClipItem; -import net.Indyuce.mmoitems.stat.data.AbilityData; -import io.lumine.mythic.lib.api.AttackResult; -import io.lumine.mythic.lib.api.DamageType; -import io.lumine.mythic.lib.version.VersionMaterial; -import io.lumine.mythic.lib.version.VersionSound; - -public class Present_Throw extends Ability { - private final ItemStack present = VersionMaterial.PLAYER_HEAD.toItem(); - - public Present_Throw() { - super(CastingMode.ON_HIT, CastingMode.WHEN_HIT, CastingMode.LEFT_CLICK, CastingMode.RIGHT_CLICK, CastingMode.SHIFT_LEFT_CLICK, CastingMode.SHIFT_RIGHT_CLICK); - - addModifier("damage", 6); - addModifier("radius", 4); - addModifier("force", 1); - addModifier("cooldown", 10); - addModifier("mana", 0); - addModifier("stamina", 0); - - ItemMeta presentMeta = present.getItemMeta(); - GameProfile profile = new GameProfile(UUID.randomUUID(), null); - byte[] encodedData = Base64Coder.encodeLines(String.format("{textures:{SKIN:{url:\"%s\"}}}", "http://textures.minecraft.net/texture/47e55fcc809a2ac1861da2a67f7f31bd7237887d162eca1eda526a7512a64910").getBytes()).getBytes(); - profile.getProperties().put("textures", new Property("textures", new String(encodedData))); - - try { - Field profileField = presentMeta.getClass().getDeclaredField("profile"); - profileField.setAccessible(true); - profileField.set(presentMeta, profile); - } catch (NoSuchFieldException | IllegalArgumentException | IllegalAccessException e) { - MMOItems.plugin.getLogger().log(Level.WARNING, "Could not load the skull texture for the Present Throw item ability."); - } - - present.setItemMeta(presentMeta); - } - - @Override - public AbilityResult whenRan(CachedStats stats, LivingEntity target, AbilityData ability, ItemAttackResult result) { - return new SimpleAbilityResult(ability); - } - - @Override - public void whenCast(CachedStats stats, AbilityResult ability, ItemAttackResult result) { - double damage = ability.getModifier("damage"); - double radiusSquared = Math.pow(ability.getModifier("radius"), 2); - - final NoClipItem item = new NoClipItem(stats.getPlayer().getLocation().add(0, 1.2, 0), present); - item.getEntity().setVelocity(stats.getPlayer().getEyeLocation().getDirection().multiply(1.5 * ability.getModifier("force"))); - - /* - * when items are moving through the air, they loose a percent of their - * velocity proportionally to their coordinates in each axis. this means - * that if the trajectory is not affected, the ratio of x/y will always - * be the same. check for any change of that ratio to check for a - * trajectory change - */ - final double trajRatio = item.getEntity().getVelocity().getX() / item.getEntity().getVelocity().getZ(); - stats.getPlayer().getWorld().playSound(stats.getPlayer().getLocation(), Sound.ENTITY_SNOWBALL_THROW, 1, 0); - new BukkitRunnable() { - double ti = 0; - - public void run() { - if (ti++ > 70 || item.getEntity().isDead()) { - item.close(); - cancel(); - } - - double currentTrajRatio = item.getEntity().getVelocity().getX() / item.getEntity().getVelocity().getZ(); - item.getEntity().getWorld().spawnParticle(Particle.SPELL_INSTANT, item.getEntity().getLocation().add(0, .1, 0), 0); - if (item.getEntity().isOnGround() || Math.abs(trajRatio - currentTrajRatio) > .1) { - item.getEntity().getWorld().spawnParticle(Particle.FIREWORKS_SPARK, item.getEntity().getLocation().add(0, .1, 0), 128, 0, 0, 0, .25); - item.getEntity().getWorld().playSound(item.getEntity().getLocation(), VersionSound.ENTITY_FIREWORK_ROCKET_TWINKLE.toSound(), 2, 1.5f); - for (Entity entity : MMOUtils.getNearbyChunkEntities(item.getEntity().getLocation())) - if (entity.getLocation().distanceSquared(item.getEntity().getLocation()) < radiusSquared && MMOUtils.canDamage(stats.getPlayer(), entity)) - new AttackResult(damage, DamageType.SKILL, DamageType.MAGIC, DamageType.PROJECTILE).damage(stats.getPlayer(), (LivingEntity) entity); - item.close(); - cancel(); - } - } - }.runTaskTimer(MMOItems.plugin, 0, 1); - } -} diff --git a/src/main/java/net/Indyuce/mmoitems/ability/Regen_Ally.java b/src/main/java/net/Indyuce/mmoitems/ability/Regen_Ally.java deleted file mode 100644 index ee172bea..00000000 --- a/src/main/java/net/Indyuce/mmoitems/ability/Regen_Ally.java +++ /dev/null @@ -1,81 +0,0 @@ - -package net.Indyuce.mmoitems.ability; - -import org.bukkit.Particle; -import org.bukkit.entity.LivingEntity; -import org.bukkit.entity.Player; -import org.bukkit.scheduler.BukkitRunnable; - -import net.Indyuce.mmoitems.MMOItems; -import net.Indyuce.mmoitems.MMOUtils; -import net.Indyuce.mmoitems.api.ItemAttackResult; -import net.Indyuce.mmoitems.api.ability.Ability; -import net.Indyuce.mmoitems.api.ability.AbilityResult; -import net.Indyuce.mmoitems.api.player.PlayerStats.CachedStats; -import net.Indyuce.mmoitems.stat.data.AbilityData; -import io.lumine.mythic.lib.MythicLib; - -public class Regen_Ally extends Ability { - public Regen_Ally() { - super(CastingMode.ON_HIT, CastingMode.WHEN_HIT, CastingMode.LEFT_CLICK, CastingMode.RIGHT_CLICK, CastingMode.SHIFT_LEFT_CLICK, CastingMode.SHIFT_RIGHT_CLICK); - - addModifier("heal", 7); - addModifier("duration", 3); - addModifier("cooldown", 10); - addModifier("mana", 0); - addModifier("stamina", 0); - } - - @Override - public AbilityResult whenRan(CachedStats stats, LivingEntity target, AbilityData ability, ItemAttackResult result) { - return new FriendlyTargetAbilityResult(ability, stats.getPlayer(), target); - } - - @Override - public void whenCast(CachedStats stats, AbilityResult ability, ItemAttackResult result) { - LivingEntity target = ((FriendlyTargetAbilityResult) ability).getTarget(); - - new BukkitRunnable() { - double ti = 0; - double a = 0; - final double duration = Math.min(ability.getModifier("duration"), 60) * 20; - final double hps = ability.getModifier("heal") / duration * 4; - - public void run() { - ti++; - if (ti > duration || target.isDead()) { - cancel(); - return; - } - - a += Math.PI / 16; - target.getWorld().spawnParticle(Particle.HEART, target.getLocation().add(1.3 * Math.cos(a), .3, 1.3 * Math.sin(a)), 0); - - if (ti % 4 == 0) - MMOUtils.heal(target, hps); - } - }.runTaskTimer(MMOItems.plugin, 0, 1); - } - - /* - * TargetAbilityResult but only targets players - */ - public static class FriendlyTargetAbilityResult extends AbilityResult { - private final LivingEntity target; - - public FriendlyTargetAbilityResult(AbilityData ability, Player caster, LivingEntity target) { - super(ability); - - this.target = target != null ? target : MythicLib.plugin.getVersion().getWrapper().rayTrace(caster, 50, entity -> (entity instanceof Player && MMOUtils.canDamage(caster, entity))).getHit(); - } - - public LivingEntity getTarget() { - return target; - } - - @Override - public boolean isSuccessful() { - return target != null; - } - } -} diff --git a/src/main/java/net/Indyuce/mmoitems/ability/Shockwave.java b/src/main/java/net/Indyuce/mmoitems/ability/Shockwave.java deleted file mode 100644 index d9a0adad..00000000 --- a/src/main/java/net/Indyuce/mmoitems/ability/Shockwave.java +++ /dev/null @@ -1,73 +0,0 @@ -package net.Indyuce.mmoitems.ability; - -import java.util.ArrayList; -import java.util.List; - -import org.bukkit.EntityEffect; -import org.bukkit.Location; -import org.bukkit.Material; -import org.bukkit.Particle; -import org.bukkit.Sound; -import org.bukkit.entity.Entity; -import org.bukkit.entity.LivingEntity; -import org.bukkit.scheduler.BukkitRunnable; -import org.bukkit.util.Vector; - -import net.Indyuce.mmoitems.MMOItems; -import net.Indyuce.mmoitems.MMOUtils; -import net.Indyuce.mmoitems.api.ItemAttackResult; -import net.Indyuce.mmoitems.api.ability.Ability; -import net.Indyuce.mmoitems.api.ability.AbilityResult; -import net.Indyuce.mmoitems.api.ability.SimpleAbilityResult; -import net.Indyuce.mmoitems.api.player.PlayerStats.CachedStats; -import net.Indyuce.mmoitems.stat.data.AbilityData; - -public class Shockwave extends Ability { - public Shockwave() { - super(CastingMode.ON_HIT, CastingMode.WHEN_HIT, CastingMode.LEFT_CLICK, CastingMode.RIGHT_CLICK, CastingMode.SHIFT_LEFT_CLICK, - CastingMode.SHIFT_RIGHT_CLICK); - - addModifier("cooldown", 7.5); - addModifier("knock-up", 1); - addModifier("length", 5); - addModifier("mana", 0); - addModifier("stamina", 0); - } - - @Override - public AbilityResult whenRan(CachedStats stats, LivingEntity target, AbilityData ability, ItemAttackResult result) { - return new SimpleAbilityResult(ability); - } - - @Override - public void whenCast(CachedStats stats, AbilityResult ability, ItemAttackResult result) { - double knockUp = ability.getModifier("knock-up"); - double length = ability.getModifier("length"); - - new BukkitRunnable() { - final Vector vec = stats.getPlayer().getEyeLocation().getDirection().setY(0); - final Location loc = stats.getPlayer().getLocation(); - int ti = 0; - final List hit = new ArrayList<>(); - - public void run() { - ti++; - if (ti >= Math.min(20, length)) - cancel(); - - loc.add(vec); - - loc.getWorld().playSound(loc, Sound.BLOCK_GRAVEL_BREAK, 1, 2); - loc.getWorld().spawnParticle(Particle.BLOCK_CRACK, loc, 12, .5, 0, .5, 0, Material.DIRT.createBlockData()); - - for (Entity ent : MMOUtils.getNearbyChunkEntities(loc)) - if (ent.getLocation().distance(loc) < 1.1 && ent instanceof LivingEntity && !ent.equals(stats.getPlayer()) - && !hit.contains(ent.getEntityId())) { - hit.add(ent.getEntityId()); - ent.playEffect(EntityEffect.HURT); - ent.setVelocity(ent.getVelocity().setY(.4 * knockUp)); - } - } - }.runTaskTimer(MMOItems.plugin, 0, 1); - } -} diff --git a/src/main/java/net/Indyuce/mmoitems/ability/Shulker_Missile.java b/src/main/java/net/Indyuce/mmoitems/ability/Shulker_Missile.java deleted file mode 100644 index b4c09f31..00000000 --- a/src/main/java/net/Indyuce/mmoitems/ability/Shulker_Missile.java +++ /dev/null @@ -1,175 +0,0 @@ -package net.Indyuce.mmoitems.ability; - -import io.lumine.mythic.lib.api.AttackResult; -import io.lumine.mythic.lib.api.DamageType; -import io.lumine.mythic.lib.api.item.NBTItem; -import net.Indyuce.mmoitems.MMOItems; -import net.Indyuce.mmoitems.MMOUtils; -import net.Indyuce.mmoitems.api.ItemAttackResult; -import net.Indyuce.mmoitems.api.ability.Ability; -import net.Indyuce.mmoitems.api.ability.AbilityResult; -import net.Indyuce.mmoitems.api.ability.VectorAbilityResult; -import net.Indyuce.mmoitems.api.interaction.projectile.EntityData; -import net.Indyuce.mmoitems.api.player.PlayerStats.CachedStats; -import net.Indyuce.mmoitems.stat.data.AbilityData; -import org.bukkit.Color; -import org.bukkit.Location; -import org.bukkit.Particle; -import org.bukkit.Sound; -import org.bukkit.entity.EntityType; -import org.bukkit.entity.LivingEntity; -import org.bukkit.entity.ShulkerBullet; -import org.bukkit.event.EventHandler; -import org.bukkit.event.Listener; -import org.bukkit.event.entity.EntityDamageByEntityEvent; -import org.bukkit.potion.PotionEffect; -import org.bukkit.potion.PotionEffectType; -import org.bukkit.scheduler.BukkitRunnable; -import org.bukkit.util.Vector; - -import javax.annotation.Nullable; - -public class Shulker_Missile extends Ability implements Listener { - public Shulker_Missile() { - super(CastingMode.ON_HIT, CastingMode.WHEN_HIT, CastingMode.LEFT_CLICK, CastingMode.RIGHT_CLICK, CastingMode.SHIFT_LEFT_CLICK, - CastingMode.SHIFT_RIGHT_CLICK); - - addModifier("cooldown", 12); - addModifier("damage", 5); - addModifier("effect-duration", 5); - addModifier("duration", 5); - addModifier("mana", 0); - addModifier("stamina", 0); - } - - @Override - public AbilityResult whenRan(CachedStats stats, LivingEntity target, AbilityData ability, ItemAttackResult result) { - return new VectorAbilityResult(ability, stats.getPlayer(), target); - } - - @Override - public void whenCast(CachedStats stats, AbilityResult ability, ItemAttackResult result) { - double duration = ability.getModifier("duration"); - - new BukkitRunnable() { - double n = 0; - - public void run() { - if (n++ > 3) { - cancel(); - return; - } - - Vector vec = ((VectorAbilityResult) ability).getTarget(); - stats.getPlayer().getWorld().playSound(stats.getPlayer().getLocation(), Sound.ENTITY_WITHER_SHOOT, 2, 2); - ShulkerBullet shulkerBullet = (ShulkerBullet) stats.getPlayer().getWorld().spawnEntity(stats.getPlayer().getLocation().add(0, 1, 0), - EntityType.SHULKER_BULLET); - shulkerBullet.setShooter(stats.getPlayer()); - MMOItems.plugin.getEntities().registerCustomEntity(shulkerBullet, new ShulkerMissileEntityData( - new AttackResult(ability.getModifier("damage"), DamageType.SKILL, DamageType.MAGIC, DamageType.PROJECTILE), - ability.getModifier("effect-duration"))); - new BukkitRunnable() { - double ti = 0; - - public void run() { - if (shulkerBullet.isDead() || ti++ >= duration * 20) { - shulkerBullet.remove(); - cancel(); - } else - shulkerBullet.setVelocity(vec); - } - }.runTaskTimer(MMOItems.plugin, 0, 1); - } - }.runTaskTimer(MMOItems.plugin, 0, 3); - } - - @EventHandler - public void a(EntityDamageByEntityEvent event) { - if (event.getDamager() instanceof ShulkerBullet && event.getEntity() instanceof LivingEntity) { - ShulkerBullet damager = (ShulkerBullet) event.getDamager(); - LivingEntity entity = (LivingEntity) event.getEntity(); - if (!MMOItems.plugin.getEntities().isCustomEntity(damager)) - return; - - if (!MMOUtils.canDamage(entity)) { - event.setCancelled(true); - return; - } - - ShulkerMissileEntityData data = (ShulkerMissileEntityData) MMOItems.plugin.getEntities().getEntityData(damager); - - // Void spirit - if (data.isWeaponAttack()) - ((ItemAttackResult) data.result).applyEffects(data.stats, data.weapon, entity); - - event.setDamage(data.result.getDamage()); - - new BukkitRunnable() { - final Location loc = entity.getLocation(); - double y = 0; - - public void run() { - - // Potion effect should apply right after the damage with a 1 tick delay. - if (y == 0) { - entity.removePotionEffect(PotionEffectType.LEVITATION); - entity.addPotionEffect(new PotionEffect(PotionEffectType.LEVITATION, (int) (data.duration * 20), 0)); - } - - for (int j1 = 0; j1 < 3; j1++) { - y += .04; - for (int j = 0; j < 2; j++) { - double xz = y * Math.PI * 1.3 + (j * Math.PI); - loc.getWorld().spawnParticle(Particle.REDSTONE, loc.clone().add(Math.cos(xz), y, Math.sin(xz)), 1, - new Particle.DustOptions(Color.MAROON, 1)); - } - } - if (y >= 2) - cancel(); - } - }.runTaskTimer(MMOItems.plugin, 0, 1); - } - } - - public static class ShulkerMissileEntityData implements EntityData { - private final AttackResult result; - private final double duration; - - @Nullable - private final CachedStats stats; - @Nullable - private final NBTItem weapon; - - /** - * Used for the Shulker missile ability - * - * @param result Attack result - * @param duration Duration of levitation effect in seconds - */ - public ShulkerMissileEntityData(AttackResult result, double duration) { - this(result, duration, null, null); - } - - /** - * Used for the void staff attack spirit (no levitation effect) - * - * @param result Attack result - * @param stats Stats of player attacking - * @param weapon Item used for the attack - */ - public ShulkerMissileEntityData(ItemAttackResult result, CachedStats stats, NBTItem weapon) { - this(result, 0, stats, weapon); - } - - private ShulkerMissileEntityData(AttackResult result, double duration, CachedStats stats, NBTItem weapon) { - this.result = result; - this.duration = duration; - this.stats = stats; - this.weapon = weapon; - } - - public boolean isWeaponAttack() { - return result instanceof ItemAttackResult; - } - } -} diff --git a/src/main/java/net/Indyuce/mmoitems/ability/SimpleAbility.java b/src/main/java/net/Indyuce/mmoitems/ability/SimpleAbility.java new file mode 100644 index 00000000..14ef2bb1 --- /dev/null +++ b/src/main/java/net/Indyuce/mmoitems/ability/SimpleAbility.java @@ -0,0 +1,24 @@ +package net.Indyuce.mmoitems.ability; + +import net.Indyuce.mmoitems.ability.metadata.SimpleAbilityMetadata; +import net.Indyuce.mmoitems.api.ItemAttackMetadata; +import net.Indyuce.mmoitems.stat.data.AbilityData; +import org.bukkit.entity.LivingEntity; + +public abstract class SimpleAbility extends Ability { + public SimpleAbility(CastingMode... allowedModes) { + super(allowedModes); + } + + public SimpleAbility(String id, String name, CastingMode... allowedModes) { + super(id, name, allowedModes); + } + + @Override + public SimpleAbilityMetadata canBeCast(ItemAttackMetadata attack, LivingEntity target, AbilityData ability) { + return new SimpleAbilityMetadata(ability); + } + + @Override + public abstract void whenCast(ItemAttackMetadata attack, SimpleAbilityMetadata ability); +} diff --git a/src/main/java/net/Indyuce/mmoitems/ability/Sky_Smash.java b/src/main/java/net/Indyuce/mmoitems/ability/Sky_Smash.java deleted file mode 100644 index 13ac1012..00000000 --- a/src/main/java/net/Indyuce/mmoitems/ability/Sky_Smash.java +++ /dev/null @@ -1,56 +0,0 @@ -package net.Indyuce.mmoitems.ability; - -import org.bukkit.Location; -import org.bukkit.Particle; -import org.bukkit.Sound; -import org.bukkit.entity.Entity; -import org.bukkit.entity.LivingEntity; -import org.bukkit.potion.PotionEffect; -import org.bukkit.potion.PotionEffectType; - -import net.Indyuce.mmoitems.MMOUtils; -import net.Indyuce.mmoitems.api.ItemAttackResult; -import net.Indyuce.mmoitems.api.ability.Ability; -import net.Indyuce.mmoitems.api.ability.AbilityResult; -import net.Indyuce.mmoitems.api.ability.SimpleAbilityResult; -import net.Indyuce.mmoitems.api.player.PlayerStats.CachedStats; -import net.Indyuce.mmoitems.stat.data.AbilityData; -import io.lumine.mythic.lib.api.AttackResult; -import io.lumine.mythic.lib.api.DamageType; - -public class Sky_Smash extends Ability { - public Sky_Smash() { - super(CastingMode.ON_HIT, CastingMode.WHEN_HIT, CastingMode.LEFT_CLICK, CastingMode.RIGHT_CLICK, CastingMode.SHIFT_LEFT_CLICK, CastingMode.SHIFT_RIGHT_CLICK); - - addModifier("cooldown", 10); - addModifier("damage", 3); - addModifier("knock-up", 1); - addModifier("mana", 0); - addModifier("stamina", 0); - } - - @Override - public AbilityResult whenRan(CachedStats stats, LivingEntity target, AbilityData ability, ItemAttackResult result) { - return new SimpleAbilityResult(ability); - } - - @Override - public void whenCast(CachedStats stats, AbilityResult ability, ItemAttackResult result) { - double damage = ability.getModifier("damage"); - double knockUp = ability.getModifier("knock-up"); - - stats.getPlayer().getWorld().playSound(stats.getPlayer().getLocation(), Sound.ENTITY_ZOMBIE_ATTACK_IRON_DOOR, 2, .5f); - stats.getPlayer().addPotionEffect(new PotionEffect(PotionEffectType.SLOW, 2, 254)); - Location loc = stats.getPlayer().getEyeLocation().add(stats.getPlayer().getEyeLocation().getDirection().multiply(3)); - loc.getWorld().spawnParticle(Particle.EXPLOSION_LARGE, loc, 0); - loc.getWorld().spawnParticle(Particle.SMOKE_LARGE, loc, 16, 0, 0, 0, .1); - - for (Entity entity : MMOUtils.getNearbyChunkEntities(loc)) - if (MMOUtils.canDamage(stats.getPlayer(), entity) && entity.getLocation().distanceSquared(loc) < 10) { - new AttackResult(damage, DamageType.SKILL, DamageType.PHYSICAL).damage(stats.getPlayer(), (LivingEntity) entity); - Location loc1 = stats.getPlayer().getEyeLocation().clone(); - loc1.setPitch(-70); - entity.setVelocity(loc1.getDirection().multiply(1.2 * knockUp)); - } - } -} diff --git a/src/main/java/net/Indyuce/mmoitems/ability/Smite.java b/src/main/java/net/Indyuce/mmoitems/ability/Smite.java deleted file mode 100644 index 574adfe2..00000000 --- a/src/main/java/net/Indyuce/mmoitems/ability/Smite.java +++ /dev/null @@ -1,35 +0,0 @@ -package net.Indyuce.mmoitems.ability; - -import org.bukkit.entity.LivingEntity; - -import net.Indyuce.mmoitems.api.ItemAttackResult; -import net.Indyuce.mmoitems.api.ability.Ability; -import net.Indyuce.mmoitems.api.ability.AbilityResult; -import net.Indyuce.mmoitems.api.ability.TargetAbilityResult; -import net.Indyuce.mmoitems.api.player.PlayerStats.CachedStats; -import net.Indyuce.mmoitems.stat.data.AbilityData; -import io.lumine.mythic.lib.api.AttackResult; -import io.lumine.mythic.lib.api.DamageType; - -public class Smite extends Ability { - public Smite() { - super(CastingMode.ON_HIT, CastingMode.WHEN_HIT, CastingMode.LEFT_CLICK, CastingMode.RIGHT_CLICK, CastingMode.SHIFT_LEFT_CLICK, CastingMode.SHIFT_RIGHT_CLICK); - - addModifier("cooldown", 10); - addModifier("damage", 8); - addModifier("mana", 0); - addModifier("stamina", 0); - } - - @Override - public AbilityResult whenRan(CachedStats stats, LivingEntity target, AbilityData ability, ItemAttackResult result) { - return new TargetAbilityResult(ability, stats.getPlayer(), target); - } - - @Override - public void whenCast(CachedStats stats, AbilityResult ability, ItemAttackResult result) { - LivingEntity target = ((TargetAbilityResult) ability).getTarget(); - new AttackResult(ability.getModifier("damage"), DamageType.SKILL, DamageType.MAGIC).damage(stats.getPlayer(), target); - target.getWorld().strikeLightningEffect(target.getLocation()); - } -} diff --git a/src/main/java/net/Indyuce/mmoitems/ability/Snowman_Turret.java b/src/main/java/net/Indyuce/mmoitems/ability/Snowman_Turret.java deleted file mode 100644 index d8f5f9ab..00000000 --- a/src/main/java/net/Indyuce/mmoitems/ability/Snowman_Turret.java +++ /dev/null @@ -1,110 +0,0 @@ -package net.Indyuce.mmoitems.ability; - -import java.util.ArrayList; -import java.util.List; -import java.util.UUID; - -import org.bukkit.Location; -import org.bukkit.Particle; -import org.bukkit.Sound; -import org.bukkit.entity.Entity; -import org.bukkit.entity.EntityType; -import org.bukkit.entity.LivingEntity; -import org.bukkit.entity.Snowball; -import org.bukkit.entity.Snowman; -import org.bukkit.event.EventHandler; -import org.bukkit.event.EventPriority; -import org.bukkit.event.entity.EntityDamageByEntityEvent; -import org.bukkit.potion.PotionEffect; -import org.bukkit.potion.PotionEffectType; -import org.bukkit.scheduler.BukkitRunnable; - -import net.Indyuce.mmoitems.MMOItems; -import net.Indyuce.mmoitems.MMOUtils; -import net.Indyuce.mmoitems.api.ItemAttackResult; -import net.Indyuce.mmoitems.api.ability.Ability; -import net.Indyuce.mmoitems.api.ability.AbilityResult; -import net.Indyuce.mmoitems.api.ability.LocationAbilityResult; -import net.Indyuce.mmoitems.api.player.PlayerStats.CachedStats; -import net.Indyuce.mmoitems.api.util.TemporaryListener; -import net.Indyuce.mmoitems.stat.data.AbilityData; -import io.lumine.mythic.lib.version.VersionSound; - -public class Snowman_Turret extends Ability { - public Snowman_Turret() { - super(CastingMode.ON_HIT, CastingMode.WHEN_HIT, CastingMode.LEFT_CLICK, CastingMode.RIGHT_CLICK, CastingMode.SHIFT_LEFT_CLICK, - CastingMode.SHIFT_RIGHT_CLICK); - - addModifier("duration", 6); - addModifier("cooldown", 35); - addModifier("damage", 2); - addModifier("radius", 20); - addModifier("mana", 0); - addModifier("stamina", 0); - } - - @Override - public AbilityResult whenRan(CachedStats stats, LivingEntity target, AbilityData ability, ItemAttackResult result) { - return new LocationAbilityResult(ability, stats.getPlayer(), target); - } - - @Override - public void whenCast(CachedStats stats, AbilityResult ability, ItemAttackResult result) { - Location loc = ((LocationAbilityResult) ability).getTarget(); - double duration = Math.min(ability.getModifier("duration") * 20, 300); - double radiusSquared = Math.pow(ability.getModifier("radius"), 2); - - loc.getWorld().playSound(loc, VersionSound.ENTITY_ENDERMAN_TELEPORT.toSound(), 2, 1); - final Snowman snowman = (Snowman) loc.getWorld().spawnEntity(loc.add(0, 1, 0), EntityType.SNOWMAN); - snowman.setInvulnerable(true); - snowman.addPotionEffect(new PotionEffect(PotionEffectType.SLOW, 100000, 254, true)); - new BukkitRunnable() { - int ti = 0; - double j = 0; - final TurretHandler turret = new TurretHandler(ability.getModifier("damage")); - - public void run() { - if (ti++ > duration || stats.getPlayer().isDead() || snowman == null || snowman.isDead()) { - turret.close(3 * 20); - snowman.remove(); - cancel(); - } - - j += Math.PI / 24 % (2 * Math.PI); - for (double k = 0; k < 3; k++) - snowman.getWorld().spawnParticle(Particle.SPELL_INSTANT, - snowman.getLocation().add(Math.cos(j + k / 3 * 2 * Math.PI) * 1.3, 1, Math.sin(j + k / 3 * 2 * Math.PI) * 1.3), 0); - snowman.getWorld().spawnParticle(Particle.SPELL_INSTANT, snowman.getLocation().add(0, 1, 0), 1, 0, 0, 0, .2); - - if (ti % 2 == 0) - for (Entity entity : MMOUtils.getNearbyChunkEntities(snowman.getLocation())) - if (!entity.equals(snowman) && MMOUtils.canDamage(stats.getPlayer(), entity) - && entity.getLocation().distanceSquared(snowman.getLocation()) < radiusSquared) { - snowman.getWorld().playSound(snowman.getLocation(), Sound.ENTITY_SNOWBALL_THROW, 1, 1.3f); - Snowball snowball = snowman.launchProjectile(Snowball.class); - snowball.setVelocity(entity.getLocation().add(0, entity.getHeight() / 2, 0).toVector() - .subtract(snowman.getLocation().add(0, 1, 0).toVector()).normalize().multiply(1.3)); - turret.entities.add(snowball.getUniqueId()); - break; - } - } - }.runTaskTimer(MMOItems.plugin, 0, 1); - } - - public static class TurretHandler extends TemporaryListener { - private final List entities = new ArrayList<>(); - private final double damage; - - public TurretHandler(double damage) { - super(EntityDamageByEntityEvent.getHandlerList()); - - this.damage = damage; - } - - @EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true) - public void a(EntityDamageByEntityEvent event) { - if (entities.contains(event.getDamager().getUniqueId())) - event.setDamage(damage); - } - } -} diff --git a/src/main/java/net/Indyuce/mmoitems/ability/Sparkle.java b/src/main/java/net/Indyuce/mmoitems/ability/Sparkle.java deleted file mode 100644 index f15ab52d..00000000 --- a/src/main/java/net/Indyuce/mmoitems/ability/Sparkle.java +++ /dev/null @@ -1,62 +0,0 @@ -package net.Indyuce.mmoitems.ability; - -import org.bukkit.Location; -import org.bukkit.Particle; -import org.bukkit.entity.ArmorStand; -import org.bukkit.entity.Entity; -import org.bukkit.entity.LivingEntity; -import org.bukkit.util.Vector; - -import net.Indyuce.mmoitems.api.ItemAttackResult; -import net.Indyuce.mmoitems.api.ability.Ability; -import net.Indyuce.mmoitems.api.ability.AbilityResult; -import net.Indyuce.mmoitems.api.ability.TargetAbilityResult; -import net.Indyuce.mmoitems.api.player.PlayerStats.CachedStats; -import net.Indyuce.mmoitems.stat.data.AbilityData; -import io.lumine.mythic.lib.api.AttackResult; -import io.lumine.mythic.lib.api.DamageType; -import io.lumine.mythic.lib.version.VersionSound; - -public class Sparkle extends Ability { - public Sparkle() { - super(CastingMode.ON_HIT, CastingMode.WHEN_HIT, CastingMode.LEFT_CLICK, CastingMode.RIGHT_CLICK, CastingMode.SHIFT_LEFT_CLICK, CastingMode.SHIFT_RIGHT_CLICK); - - addModifier("cooldown", 10); - addModifier("damage", 4); - addModifier("limit", 5); - addModifier("radius", 6); - addModifier("mana", 0); - addModifier("stamina", 0); - } - - @Override - public AbilityResult whenRan(CachedStats stats, LivingEntity target, AbilityData ability, ItemAttackResult result) { - return new TargetAbilityResult(ability, stats.getPlayer(), target); - } - - @Override - public void whenCast(CachedStats stats, AbilityResult ability, ItemAttackResult result) { - LivingEntity target = ((TargetAbilityResult) ability).getTarget(); - double damage = ability.getModifier("damage"); - double radius = ability.getModifier("radius"); - double limit = ability.getModifier("limit"); - - new AttackResult(damage, DamageType.SKILL, DamageType.MAGIC).damage(stats.getPlayer(), target); - target.getWorld().spawnParticle(Particle.EXPLOSION_LARGE, target.getLocation().add(0, 1, 0), 0); - target.getWorld().playSound(target.getLocation(), VersionSound.ENTITY_FIREWORK_ROCKET_TWINKLE.toSound(), 2, 2); - - int count = 0; - for (Entity entity : target.getNearbyEntities(radius, radius, radius)) - if (count < limit && entity instanceof LivingEntity && entity != stats.getPlayer() && !(entity instanceof ArmorStand)) { - count++; - new AttackResult(damage, DamageType.SKILL, DamageType.MAGIC).damage(stats.getPlayer(), (LivingEntity) entity); - entity.getWorld().playSound(entity.getLocation(), VersionSound.ENTITY_FIREWORK_ROCKET_TWINKLE.toSound(), 2, 2); - Location loc_t = target.getLocation().add(0, .75, 0); - Location loc_ent = entity.getLocation().add(0, .75, 0); - for (double j1 = 0; j1 < 1; j1 += .04) { - Vector d = loc_ent.toVector().subtract(loc_t.toVector()); - target.getWorld().spawnParticle(Particle.FIREWORKS_SPARK, loc_t.clone().add(d.multiply(j1)), 3, .1, .1, .1, .008); - } - } - } -} diff --git a/src/main/java/net/Indyuce/mmoitems/ability/Swiftness.java b/src/main/java/net/Indyuce/mmoitems/ability/Swiftness.java deleted file mode 100644 index eeca64de..00000000 --- a/src/main/java/net/Indyuce/mmoitems/ability/Swiftness.java +++ /dev/null @@ -1,45 +0,0 @@ -package net.Indyuce.mmoitems.ability; - -import org.bukkit.Particle; -import org.bukkit.entity.LivingEntity; -import org.bukkit.potion.PotionEffect; -import org.bukkit.potion.PotionEffectType; - -import net.Indyuce.mmoitems.api.ItemAttackResult; -import net.Indyuce.mmoitems.api.ability.Ability; -import net.Indyuce.mmoitems.api.ability.AbilityResult; -import net.Indyuce.mmoitems.api.ability.SimpleAbilityResult; -import net.Indyuce.mmoitems.api.player.PlayerStats.CachedStats; -import net.Indyuce.mmoitems.stat.data.AbilityData; -import io.lumine.mythic.lib.version.VersionSound; - -public class Swiftness extends Ability { - public Swiftness() { - super(CastingMode.ON_HIT, CastingMode.WHEN_HIT, CastingMode.LEFT_CLICK, CastingMode.RIGHT_CLICK, CastingMode.SHIFT_LEFT_CLICK, CastingMode.SHIFT_RIGHT_CLICK); - - addModifier("cooldown", 15); - addModifier("duration", 4); - addModifier("amplifier", 1); - addModifier("mana", 0); - addModifier("stamina", 0); - } - - @Override - public AbilityResult whenRan(CachedStats stats, LivingEntity target, AbilityData ability, ItemAttackResult result) { - return new SimpleAbilityResult(ability); - } - - @Override - public void whenCast(CachedStats stats, AbilityResult ability, ItemAttackResult result) { - double duration = ability.getModifier("duration"); - int amplifier = (int) ability.getModifier("amplifier"); - - stats.getPlayer().getWorld().playSound(stats.getPlayer().getLocation(), VersionSound.ENTITY_ZOMBIE_PIGMAN_ANGRY.toSound(), 1, .3f); - for (double y = 0; y <= 2; y += .2) - for (double j = 0; j < Math.PI * 2; j += Math.PI / 16) - if (random.nextDouble() <= .7) - stats.getPlayer().getWorld().spawnParticle(Particle.SPELL_INSTANT, stats.getPlayer().getLocation().add(Math.cos(j), y, Math.sin(j)), 0); - stats.getPlayer().addPotionEffect(new PotionEffect(PotionEffectType.SPEED, (int) (duration * 20), amplifier)); - stats.getPlayer().addPotionEffect(new PotionEffect(PotionEffectType.JUMP, (int) (duration * 20), amplifier)); - } -} diff --git a/src/main/java/net/Indyuce/mmoitems/ability/TNT_Throw.java b/src/main/java/net/Indyuce/mmoitems/ability/TNT_Throw.java deleted file mode 100644 index 29a270f6..00000000 --- a/src/main/java/net/Indyuce/mmoitems/ability/TNT_Throw.java +++ /dev/null @@ -1,73 +0,0 @@ -package net.Indyuce.mmoitems.ability; - -import org.bukkit.Particle; -import org.bukkit.Sound; -import org.bukkit.entity.EntityType; -import org.bukkit.entity.LivingEntity; -import org.bukkit.entity.Player; -import org.bukkit.entity.TNTPrimed; -import org.bukkit.event.EventHandler; -import org.bukkit.event.EventPriority; -import org.bukkit.event.Listener; -import org.bukkit.event.entity.EntityDamageByEntityEvent; -import org.bukkit.util.Vector; - -import net.Indyuce.mmoitems.MMOUtils; -import net.Indyuce.mmoitems.api.ItemAttackResult; -import net.Indyuce.mmoitems.api.ability.Ability; -import net.Indyuce.mmoitems.api.ability.AbilityResult; -import net.Indyuce.mmoitems.api.ability.VectorAbilityResult; -import net.Indyuce.mmoitems.api.player.PlayerStats.CachedStats; -import net.Indyuce.mmoitems.api.util.TemporaryListener; -import net.Indyuce.mmoitems.stat.data.AbilityData; - -public class TNT_Throw extends Ability implements Listener { - public TNT_Throw() { - super(CastingMode.ON_HIT, CastingMode.WHEN_HIT, CastingMode.LEFT_CLICK, CastingMode.RIGHT_CLICK, CastingMode.SHIFT_LEFT_CLICK, - CastingMode.SHIFT_RIGHT_CLICK); - - addModifier("cooldown", 10); - addModifier("force", 1); - addModifier("mana", 0); - addModifier("stamina", 0); - } - - @Override - public AbilityResult whenRan(CachedStats stats, LivingEntity target, AbilityData ability, ItemAttackResult result) { - return new VectorAbilityResult(ability, stats.getPlayer(), target); - } - - @Override - public void whenCast(CachedStats stats, AbilityResult ability, ItemAttackResult result) { - Vector vec = ((VectorAbilityResult) ability).getTarget().multiply(2 * ability.getModifier("force")); - TNTPrimed tnt = (TNTPrimed) stats.getPlayer().getWorld().spawnEntity(stats.getPlayer().getLocation().add(0, 1, 0), EntityType.PRIMED_TNT); - tnt.setFuseTicks(80); - tnt.setVelocity(vec); - new CancelTeamDamage(stats.getPlayer(), tnt); - stats.getPlayer().getWorld().playSound(stats.getPlayer().getLocation(), Sound.ENTITY_SNOWBALL_THROW, 1, 0); - stats.getPlayer().getWorld().spawnParticle(Particle.EXPLOSION_NORMAL, stats.getPlayer().getLocation().add(0, 1, 0), 12, 0, 0, 0, .1); - } - - /* - * used to cancel team damage and other things - */ - public static class CancelTeamDamage extends TemporaryListener { - private final Player player; - private final TNTPrimed tnt; - - public CancelTeamDamage(Player player, TNTPrimed tnt) { - super(EntityDamageByEntityEvent.getHandlerList()); - - this.player = player; - this.tnt = tnt; - - close(100); - } - - @EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true) - public void a(EntityDamageByEntityEvent event) { - if (event.getDamager().equals(tnt) && !MMOUtils.canDamage(player, event.getEntity())) - event.setCancelled(true); - } - } -} diff --git a/src/main/java/net/Indyuce/mmoitems/ability/Tactical_Grenade.java b/src/main/java/net/Indyuce/mmoitems/ability/Tactical_Grenade.java deleted file mode 100644 index 87d8ef92..00000000 --- a/src/main/java/net/Indyuce/mmoitems/ability/Tactical_Grenade.java +++ /dev/null @@ -1,89 +0,0 @@ -package net.Indyuce.mmoitems.ability; - -import java.util.ArrayList; -import java.util.List; - -import org.bukkit.Location; -import org.bukkit.Particle; -import org.bukkit.Sound; -import org.bukkit.entity.Entity; -import org.bukkit.entity.LivingEntity; -import org.bukkit.scheduler.BukkitRunnable; -import org.bukkit.util.Vector; - -import net.Indyuce.mmoitems.MMOItems; -import net.Indyuce.mmoitems.MMOUtils; -import net.Indyuce.mmoitems.api.ItemAttackResult; -import net.Indyuce.mmoitems.api.ability.Ability; -import net.Indyuce.mmoitems.api.ability.AbilityResult; -import net.Indyuce.mmoitems.api.ability.TargetAbilityResult; -import net.Indyuce.mmoitems.api.player.PlayerStats.CachedStats; -import net.Indyuce.mmoitems.stat.data.AbilityData; -import io.lumine.mythic.lib.api.AttackResult; -import io.lumine.mythic.lib.api.DamageType; - -public class Tactical_Grenade extends Ability { - public Tactical_Grenade() { - super(CastingMode.ON_HIT, CastingMode.WHEN_HIT, CastingMode.LEFT_CLICK, CastingMode.RIGHT_CLICK, CastingMode.SHIFT_LEFT_CLICK, CastingMode.SHIFT_RIGHT_CLICK); - - addModifier("cooldown", 10); - addModifier("mana", 0); - addModifier("stamina", 0); - addModifier("knock-up", 1); - addModifier("damage", 4); - addModifier("radius", 4); - } - - @Override - public AbilityResult whenRan(CachedStats stats, LivingEntity target, AbilityData ability, ItemAttackResult result) { - return new TargetAbilityResult(ability, stats.getPlayer(), target); - } - @Override - public void whenCast(CachedStats stats, AbilityResult ability, ItemAttackResult result) { - LivingEntity target = ((TargetAbilityResult) ability).getTarget(); - - new BukkitRunnable() { - int j = 0; - final Location loc = stats.getPlayer().getLocation().add(0, .1, 0); - final double radius = ability.getModifier("radius"); - final double knockup = .7 * ability.getModifier("knock-up"); - final List hit = new ArrayList<>(); - - public void run() { - j++; - if (target.isDead() || !target.getWorld().equals(loc.getWorld()) || j > 200) { - cancel(); - return; - } - - Vector vec = target.getLocation().add(0, .1, 0).subtract(loc).toVector(); - vec = vec.length() < 3 ? vec : vec.normalize().multiply(3); - loc.add(vec); - - loc.getWorld().spawnParticle(Particle.CLOUD, loc, 32, 1, 0, 1, 0); - loc.getWorld().spawnParticle(Particle.EXPLOSION_NORMAL, loc, 16, 1, 0, 1, .05); - loc.getWorld().playSound(loc, Sound.BLOCK_ANVIL_LAND, 2, 0); - loc.getWorld().playSound(loc, Sound.ENTITY_GENERIC_EXPLODE, 2, 1); - - for (Entity entity : MMOUtils.getNearbyChunkEntities(loc)) - if (!hit.contains(entity.getEntityId()) && MMOUtils.canDamage(stats.getPlayer(), entity) && entity.getLocation().distanceSquared(loc) < radius * radius) { - - /* - * stop the runnable as soon as the grenade finally hits - * the initial target. - */ - hit.add(entity.getEntityId()); - if (entity.equals(target)) - cancel(); - - new AttackResult(ability.getModifier("damage"), DamageType.SKILL, DamageType.MAGIC).damage(stats.getPlayer(), (LivingEntity) entity); - entity.setVelocity(entity.getVelocity().add(offsetVector(knockup))); - } - } - }.runTaskTimer(MMOItems.plugin, 0, 12); - } - - private Vector offsetVector(double y) { - return new Vector(2 * (random.nextDouble() - .5), y, 2 * (random.nextDouble() - .5)); - } -} \ No newline at end of file diff --git a/src/main/java/net/Indyuce/mmoitems/ability/TargetAbility.java b/src/main/java/net/Indyuce/mmoitems/ability/TargetAbility.java new file mode 100644 index 00000000..e9f877cc --- /dev/null +++ b/src/main/java/net/Indyuce/mmoitems/ability/TargetAbility.java @@ -0,0 +1,22 @@ +package net.Indyuce.mmoitems.ability; + +import net.Indyuce.mmoitems.ability.metadata.TargetAbilityMetadata; +import net.Indyuce.mmoitems.api.ItemAttackMetadata; +import net.Indyuce.mmoitems.stat.data.AbilityData; +import org.bukkit.entity.LivingEntity; + +public abstract class TargetAbility extends Ability { + public TargetAbility(CastingMode... allowedModes) { + super(allowedModes); + } + + public TargetAbility(String id, String name, CastingMode... allowedModes) { + super(id, name, allowedModes); + } + + public TargetAbilityMetadata canBeCast(ItemAttackMetadata attack, LivingEntity target, AbilityData ability) { + return new TargetAbilityMetadata(ability, attack.getDamager(), target); + } + + public abstract void whenCast(ItemAttackMetadata attack, TargetAbilityMetadata ability); +} diff --git a/src/main/java/net/Indyuce/mmoitems/ability/Targeted_Fireball.java b/src/main/java/net/Indyuce/mmoitems/ability/Targeted_Fireball.java deleted file mode 100644 index 703a116c..00000000 --- a/src/main/java/net/Indyuce/mmoitems/ability/Targeted_Fireball.java +++ /dev/null @@ -1,76 +0,0 @@ -package net.Indyuce.mmoitems.ability; - -import org.bukkit.Location; -import org.bukkit.Particle; -import org.bukkit.Sound; -import org.bukkit.entity.LivingEntity; -import org.bukkit.scheduler.BukkitRunnable; -import org.bukkit.util.Vector; - -import net.Indyuce.mmoitems.MMOItems; -import net.Indyuce.mmoitems.MMOUtils; -import net.Indyuce.mmoitems.api.ItemAttackResult; -import net.Indyuce.mmoitems.api.ability.Ability; -import net.Indyuce.mmoitems.api.ability.AbilityResult; -import net.Indyuce.mmoitems.api.ability.TargetAbilityResult; -import net.Indyuce.mmoitems.api.player.PlayerStats.CachedStats; -import net.Indyuce.mmoitems.stat.data.AbilityData; -import io.lumine.mythic.lib.api.AttackResult; -import io.lumine.mythic.lib.api.DamageType; -import io.lumine.mythic.lib.version.VersionSound; - -public class Targeted_Fireball extends Ability { - public Targeted_Fireball() { - super(CastingMode.ON_HIT, CastingMode.WHEN_HIT, CastingMode.LEFT_CLICK, CastingMode.RIGHT_CLICK, CastingMode.SHIFT_LEFT_CLICK, - CastingMode.SHIFT_RIGHT_CLICK); - - addModifier("cooldown", 10); - addModifier("mana", 0); - addModifier("stamina", 0); - addModifier("ignite", 4); - addModifier("damage", 4); - } - - @Override - public AbilityResult whenRan(CachedStats stats, LivingEntity target, AbilityData ability, ItemAttackResult result) { - return new TargetAbilityResult(ability, stats.getPlayer(), target); - } - - @Override - public void whenCast(CachedStats stats, AbilityResult ability, ItemAttackResult result) { - LivingEntity target = ((TargetAbilityResult) ability).getTarget(); - - new BukkitRunnable() { - int j = 0; - final Location loc = stats.getPlayer().getLocation().add(0, 1.3, 0); - - public void run() { - j++; - if (target.isDead() || !target.getWorld().equals(loc.getWorld()) || j > 200) { - cancel(); - return; - } - - Vector dir = target.getLocation().add(0, target.getHeight() / 2, 0).subtract(loc).toVector().normalize(); - loc.add(dir.multiply(.6)); - - loc.setDirection(dir); - for (double a = 0; a < Math.PI * 2; a += Math.PI / 6) { - Vector rotated = MMOUtils.rotateFunc(new Vector(Math.cos(a), Math.sin(a), 0), loc); - loc.getWorld().spawnParticle(Particle.FLAME, loc, 0, rotated.getX(), rotated.getY(), rotated.getZ(), .06); - } - - loc.getWorld().playSound(loc, VersionSound.BLOCK_NOTE_BLOCK_HAT.toSound(), 1, 1); - if (target.getLocation().add(0, target.getHeight() / 2, 0).distanceSquared(loc) < 1.3) { - loc.getWorld().spawnParticle(Particle.LAVA, loc, 8); - loc.getWorld().spawnParticle(Particle.FLAME, loc, 32, 0, 0, 0, .1); - loc.getWorld().playSound(loc, Sound.ENTITY_BLAZE_HURT, 2, 1); - target.setFireTicks((int) (target.getFireTicks() + ability.getModifier("ignite") * 20)); - new AttackResult(ability.getModifier("damage"), DamageType.SKILL, DamageType.MAGIC, DamageType.PROJECTILE) - .damage(stats.getPlayer(), target); - cancel(); - } - } - }.runTaskTimer(MMOItems.plugin, 0, 1); - } -} \ No newline at end of file diff --git a/src/main/java/net/Indyuce/mmoitems/ability/Throw_Up.java b/src/main/java/net/Indyuce/mmoitems/ability/Throw_Up.java deleted file mode 100644 index 02a35f68..00000000 --- a/src/main/java/net/Indyuce/mmoitems/ability/Throw_Up.java +++ /dev/null @@ -1,73 +0,0 @@ -package net.Indyuce.mmoitems.ability; - -import org.bukkit.Bukkit; -import org.bukkit.Location; -import org.bukkit.Material; -import org.bukkit.Particle; -import org.bukkit.Sound; -import org.bukkit.entity.Entity; -import org.bukkit.entity.LivingEntity; -import org.bukkit.event.Listener; -import org.bukkit.inventory.ItemStack; -import org.bukkit.scheduler.BukkitRunnable; - -import net.Indyuce.mmoitems.MMOItems; -import net.Indyuce.mmoitems.MMOUtils; -import net.Indyuce.mmoitems.api.ItemAttackResult; -import net.Indyuce.mmoitems.api.ability.Ability; -import net.Indyuce.mmoitems.api.ability.AbilityResult; -import net.Indyuce.mmoitems.api.ability.SimpleAbilityResult; -import net.Indyuce.mmoitems.api.player.PlayerStats.CachedStats; -import net.Indyuce.mmoitems.api.util.NoClipItem; -import net.Indyuce.mmoitems.stat.data.AbilityData; -import io.lumine.mythic.lib.api.AttackResult; -import io.lumine.mythic.lib.api.DamageType; - -public class Throw_Up extends Ability implements Listener { - public Throw_Up() { - super(CastingMode.ON_HIT, CastingMode.WHEN_HIT, CastingMode.LEFT_CLICK, CastingMode.RIGHT_CLICK, CastingMode.SHIFT_LEFT_CLICK, CastingMode.SHIFT_RIGHT_CLICK); - - addModifier("duration", 2.5); - addModifier("damage", 2); - addModifier("cooldown", 10); - addModifier("mana", 0); - addModifier("stamina", 0); - } - - @Override - public AbilityResult whenRan(CachedStats stats, LivingEntity target, AbilityData ability, ItemAttackResult result) { - return new SimpleAbilityResult(ability); - } - - @Override - public void whenCast(CachedStats stats, AbilityResult ability, ItemAttackResult result) { - double duration = ability.getModifier("duration") * 10; - double dps = ability.getModifier("damage") / 2; - - new BukkitRunnable() { - int j = 0; - - public void run() { - j++; - if (j > duration) - cancel(); - - Location loc = stats.getPlayer().getEyeLocation(); - loc.setPitch((float) (loc.getPitch() + (random.nextDouble() - .5) * 30)); - loc.setYaw((float) (loc.getYaw() + (random.nextDouble() - .5) * 30)); - - if (j % 5 == 0) - for (Entity entity : MMOUtils.getNearbyChunkEntities(loc)) - if (entity.getLocation().distanceSquared(loc) < 40 && stats.getPlayer().getEyeLocation().getDirection().angle(entity.getLocation().toVector().subtract(stats.getPlayer().getLocation().toVector())) < Math.PI / 6 && MMOUtils.canDamage(stats.getPlayer(), entity)) - new AttackResult(dps, DamageType.SKILL, DamageType.PHYSICAL, DamageType.PROJECTILE).damage(stats.getPlayer(), (LivingEntity) entity); - - loc.getWorld().playSound(loc, Sound.ENTITY_ZOMBIE_HURT, 1, 1); - - NoClipItem item = new NoClipItem(stats.getPlayer().getLocation().add(0, 1.2, 0), new ItemStack(Material.ROTTEN_FLESH)); - Bukkit.getScheduler().scheduleSyncDelayedTask(MMOItems.plugin, item::close, 40); - item.getEntity().setVelocity(loc.getDirection().multiply(.8)); - stats.getPlayer().getWorld().spawnParticle(Particle.SMOKE_LARGE, stats.getPlayer().getLocation().add(0, 1.2, 0), 0, loc.getDirection().getX(), loc.getDirection().getY(), loc.getDirection().getZ(), 1); - } - }.runTaskTimer(MMOItems.plugin, 0, 2); - } -} diff --git a/src/main/java/net/Indyuce/mmoitems/ability/Thrust.java b/src/main/java/net/Indyuce/mmoitems/ability/Thrust.java deleted file mode 100644 index a8aa7dcc..00000000 --- a/src/main/java/net/Indyuce/mmoitems/ability/Thrust.java +++ /dev/null @@ -1,54 +0,0 @@ -package net.Indyuce.mmoitems.ability; - -import org.bukkit.Location; -import org.bukkit.Particle; -import org.bukkit.Sound; -import org.bukkit.entity.Entity; -import org.bukkit.entity.LivingEntity; -import org.bukkit.potion.PotionEffect; -import org.bukkit.potion.PotionEffectType; -import org.bukkit.util.Vector; - -import net.Indyuce.mmoitems.MMOUtils; -import net.Indyuce.mmoitems.api.ItemAttackResult; -import net.Indyuce.mmoitems.api.ability.Ability; -import net.Indyuce.mmoitems.api.ability.AbilityResult; -import net.Indyuce.mmoitems.api.ability.VectorAbilityResult; -import net.Indyuce.mmoitems.api.player.PlayerStats.CachedStats; -import net.Indyuce.mmoitems.stat.data.AbilityData; -import io.lumine.mythic.lib.api.AttackResult; -import io.lumine.mythic.lib.api.DamageType; - -public class Thrust extends Ability { - public Thrust() { - super(CastingMode.ON_HIT, CastingMode.WHEN_HIT, CastingMode.LEFT_CLICK, CastingMode.RIGHT_CLICK, CastingMode.SHIFT_LEFT_CLICK, CastingMode.SHIFT_RIGHT_CLICK); - - addModifier("cooldown", 10); - addModifier("damage", 6); - addModifier("mana", 0); - addModifier("stamina", 0); - } - - @Override - public AbilityResult whenRan(CachedStats stats, LivingEntity target, AbilityData ability, ItemAttackResult result) { - return new VectorAbilityResult(ability, stats.getPlayer(), target); - } - - @Override - public void whenCast(CachedStats stats, AbilityResult ability, ItemAttackResult result) { - double damage = ability.getModifier("damage"); - - stats.getPlayer().getWorld().playSound(stats.getPlayer().getLocation(), Sound.ENTITY_ZOMBIE_ATTACK_IRON_DOOR, 1, 0); - stats.getPlayer().addPotionEffect(new PotionEffect(PotionEffectType.SLOW, 2, 3)); - - Location loc = stats.getPlayer().getEyeLocation().clone(); - Vector vec = ((VectorAbilityResult) ability).getTarget().multiply(.5); - for (double j = 0; j < 7; j += .5) { - loc.add(vec); - for (Entity entity : MMOUtils.getNearbyChunkEntities(loc)) - if (MMOUtils.canDamage(stats.getPlayer(), loc, entity)) - new AttackResult(damage, DamageType.SKILL, DamageType.PHYSICAL).damage(stats.getPlayer(), (LivingEntity) entity); - loc.getWorld().spawnParticle(Particle.SMOKE_LARGE, loc, 0); - } - } -} diff --git a/src/main/java/net/Indyuce/mmoitems/ability/VectorAbility.java b/src/main/java/net/Indyuce/mmoitems/ability/VectorAbility.java new file mode 100644 index 00000000..308d048d --- /dev/null +++ b/src/main/java/net/Indyuce/mmoitems/ability/VectorAbility.java @@ -0,0 +1,27 @@ +package net.Indyuce.mmoitems.ability; + +import net.Indyuce.mmoitems.ability.list.vector.Firebolt; +import net.Indyuce.mmoitems.ability.metadata.VectorAbilityMetadata; +import net.Indyuce.mmoitems.api.ItemAttackMetadata; +import net.Indyuce.mmoitems.stat.data.AbilityData; +import org.bukkit.entity.LivingEntity; + +/** + * Ability that requires a direction to be cast. For + * instance, a projectile like {@link Firebolt} + */ +public abstract class VectorAbility extends Ability { + public VectorAbility(CastingMode... allowedModes) { + super(allowedModes); + } + + public VectorAbility(String id, String name, CastingMode... allowedModes) { + super(id, name, allowedModes); + } + + public VectorAbilityMetadata canBeCast(ItemAttackMetadata attack, LivingEntity target, AbilityData ability) { + return new VectorAbilityMetadata(ability, attack.getDamager(), target); + } + + public abstract void whenCast(ItemAttackMetadata attack, VectorAbilityMetadata ability); +} diff --git a/src/main/java/net/Indyuce/mmoitems/ability/arcane/Arcane_Rift.java b/src/main/java/net/Indyuce/mmoitems/ability/arcane/Arcane_Rift.java deleted file mode 100644 index 3dc72308..00000000 --- a/src/main/java/net/Indyuce/mmoitems/ability/arcane/Arcane_Rift.java +++ /dev/null @@ -1,79 +0,0 @@ -package net.Indyuce.mmoitems.ability.arcane; - -import java.util.ArrayList; -import java.util.List; - -import org.bukkit.Location; -import org.bukkit.Particle; -import org.bukkit.entity.Entity; -import org.bukkit.entity.LivingEntity; -import org.bukkit.potion.PotionEffect; -import org.bukkit.potion.PotionEffectType; -import org.bukkit.scheduler.BukkitRunnable; -import org.bukkit.util.Vector; - -import net.Indyuce.mmoitems.MMOItems; -import net.Indyuce.mmoitems.MMOUtils; -import net.Indyuce.mmoitems.api.ItemAttackResult; -import net.Indyuce.mmoitems.api.ability.Ability; -import net.Indyuce.mmoitems.api.ability.AbilityResult; -import net.Indyuce.mmoitems.api.ability.SimpleAbilityResult; -import net.Indyuce.mmoitems.api.ability.VectorAbilityResult; -import net.Indyuce.mmoitems.api.player.PlayerStats.CachedStats; -import net.Indyuce.mmoitems.stat.data.AbilityData; -import io.lumine.mythic.lib.api.AttackResult; -import io.lumine.mythic.lib.api.DamageType; -import io.lumine.mythic.lib.version.VersionSound; - -public class Arcane_Rift extends Ability { - public Arcane_Rift() { - super(CastingMode.ON_HIT, CastingMode.WHEN_HIT, CastingMode.LEFT_CLICK, CastingMode.RIGHT_CLICK, CastingMode.SHIFT_LEFT_CLICK, CastingMode.SHIFT_RIGHT_CLICK); - - addModifier("damage", 5); - addModifier("amplifier", 2); - addModifier("cooldown", 10); - addModifier("speed", 1); - addModifier("duration", 1.5); - addModifier("mana", 0); - addModifier("stamina", 0); - } - - @Override - public AbilityResult whenRan(CachedStats stats, LivingEntity target, AbilityData ability, ItemAttackResult result) { - if (!((LivingEntity) stats.getPlayer()).isOnGround()) - return new SimpleAbilityResult(ability, false); - - return new VectorAbilityResult(ability, stats.getPlayer(), target); - } - - @Override - public void whenCast(CachedStats stats, AbilityResult ability, ItemAttackResult result) { - double damage = ability.getModifier("damage"); - double slowDuration = ability.getModifier("duration"); - double slowAmplifier = ability.getModifier("amplifier"); - - stats.getPlayer().getWorld().playSound(stats.getPlayer().getLocation(), VersionSound.ENTITY_ENDERMAN_DEATH.toSound(), 2, .5f); - new BukkitRunnable() { - final Vector vec = ((VectorAbilityResult) ability).getTarget().setY(0).normalize().multiply(.5 * ability.getModifier("speed")); - final Location loc = stats.getPlayer().getLocation(); - int ti = 0; - final int duration = (int) (20 * Math.min(ability.getModifier("duration"), 10.)); - final List hit = new ArrayList<>(); - - public void run() { - if (ti++ > duration) - cancel(); - - loc.add(vec); - loc.getWorld().spawnParticle(Particle.SPELL_WITCH, loc, 5, .5, 0, .5, 0); - - for (Entity entity : MMOUtils.getNearbyChunkEntities(loc)) - if (MMOUtils.canDamage(stats.getPlayer(), entity) && loc.distanceSquared(entity.getLocation()) < 2 && !hit.contains(entity.getEntityId())) { - hit.add(entity.getEntityId()); - new AttackResult(damage, DamageType.SKILL, DamageType.MAGIC).damage(stats.getPlayer(), (LivingEntity) entity); - ((LivingEntity) entity).addPotionEffect(new PotionEffect(PotionEffectType.SLOW, (int) (slowDuration * 20), (int) slowAmplifier)); - } - } - }.runTaskTimer(MMOItems.plugin, 0, 1); - } -} diff --git a/src/main/java/net/Indyuce/mmoitems/ability/arcane/Arcane_Hail.java b/src/main/java/net/Indyuce/mmoitems/ability/list/location/Arcane_Hail.java similarity index 62% rename from src/main/java/net/Indyuce/mmoitems/ability/arcane/Arcane_Hail.java rename to src/main/java/net/Indyuce/mmoitems/ability/list/location/Arcane_Hail.java index 41ad35ea..351cbef6 100644 --- a/src/main/java/net/Indyuce/mmoitems/ability/arcane/Arcane_Hail.java +++ b/src/main/java/net/Indyuce/mmoitems/ability/list/location/Arcane_Hail.java @@ -1,16 +1,14 @@ -package net.Indyuce.mmoitems.ability.arcane; +package net.Indyuce.mmoitems.ability.list.location; -import io.lumine.mythic.lib.api.AttackResult; -import io.lumine.mythic.lib.api.DamageType; +import io.lumine.mythic.lib.damage.AttackMetadata; +import io.lumine.mythic.lib.damage.DamageMetadata; +import io.lumine.mythic.lib.damage.DamageType; import io.lumine.mythic.lib.version.VersionSound; import net.Indyuce.mmoitems.MMOItems; import net.Indyuce.mmoitems.MMOUtils; -import net.Indyuce.mmoitems.api.ItemAttackResult; -import net.Indyuce.mmoitems.api.ability.Ability; -import net.Indyuce.mmoitems.api.ability.AbilityResult; -import net.Indyuce.mmoitems.api.ability.LocationAbilityResult; -import net.Indyuce.mmoitems.api.player.PlayerStats.CachedStats; -import net.Indyuce.mmoitems.stat.data.AbilityData; +import net.Indyuce.mmoitems.ability.LocationAbility; +import net.Indyuce.mmoitems.ability.metadata.LocationAbilityMetadata; +import net.Indyuce.mmoitems.api.ItemAttackMetadata; import org.bukkit.Location; import org.bukkit.Particle; import org.bukkit.entity.Entity; @@ -18,7 +16,7 @@ import org.bukkit.entity.LivingEntity; import org.bukkit.scheduler.BukkitRunnable; import org.bukkit.util.Vector; -public class Arcane_Hail extends Ability { +public class Arcane_Hail extends LocationAbility { public Arcane_Hail() { super(CastingMode.ON_HIT, CastingMode.WHEN_HIT, CastingMode.LEFT_CLICK, CastingMode.RIGHT_CLICK, CastingMode.SHIFT_LEFT_CLICK, CastingMode.SHIFT_RIGHT_CLICK); @@ -31,13 +29,8 @@ public class Arcane_Hail extends Ability { } @Override - public AbilityResult whenRan(CachedStats stats, LivingEntity target, AbilityData ability, ItemAttackResult result) { - return new LocationAbilityResult(ability, stats.getPlayer(), target); - } - - @Override - public void whenCast(CachedStats stats, AbilityResult ability, ItemAttackResult result) { - Location loc = ((LocationAbilityResult) ability).getTarget(); + public void whenCast(ItemAttackMetadata attack, LocationAbilityMetadata ability) { + Location loc = ability.getTarget(); double damage = ability.getModifier("damage"); double duration = ability.getModifier("duration") * 10; @@ -56,8 +49,8 @@ public class Arcane_Hail extends Ability { Location loc1 = loc.clone().add(randomCoordMultiplier() * radius, 0, randomCoordMultiplier() * radius); loc1.getWorld().playSound(loc1, VersionSound.ENTITY_ENDERMAN_HURT.toSound(), 1, 0); for (Entity entity : MMOUtils.getNearbyChunkEntities(loc1)) - if (MMOUtils.canDamage(stats.getPlayer(), entity) && entity.getLocation().distanceSquared(loc1) <= 4) - new AttackResult(damage, DamageType.SKILL, DamageType.MAGIC).damage(stats.getPlayer(), (LivingEntity) entity); + if (MMOUtils.canDamage(attack.getDamager(), entity) && entity.getLocation().distanceSquared(loc1) <= 4) + new AttackMetadata(new DamageMetadata(damage, DamageType.SKILL, DamageType.MAGIC), attack.getStats()).damage((LivingEntity) entity); loc1.getWorld().spawnParticle(Particle.SPELL_WITCH, loc1, 12, 0, 0, 0, .1); loc1.getWorld().spawnParticle(Particle.SMOKE_NORMAL, loc1, 6, 0, 0, 0, .1); diff --git a/src/main/java/net/Indyuce/mmoitems/ability/Black_Hole.java b/src/main/java/net/Indyuce/mmoitems/ability/list/location/Black_Hole.java similarity index 68% rename from src/main/java/net/Indyuce/mmoitems/ability/Black_Hole.java rename to src/main/java/net/Indyuce/mmoitems/ability/list/location/Black_Hole.java index 7b42767a..5c89a185 100644 --- a/src/main/java/net/Indyuce/mmoitems/ability/Black_Hole.java +++ b/src/main/java/net/Indyuce/mmoitems/ability/list/location/Black_Hole.java @@ -1,23 +1,18 @@ -package net.Indyuce.mmoitems.ability; +package net.Indyuce.mmoitems.ability.list.location; +import io.lumine.mythic.lib.version.VersionSound; +import net.Indyuce.mmoitems.MMOItems; +import net.Indyuce.mmoitems.MMOUtils; +import net.Indyuce.mmoitems.ability.LocationAbility; +import net.Indyuce.mmoitems.ability.metadata.LocationAbilityMetadata; +import net.Indyuce.mmoitems.api.ItemAttackMetadata; import org.bukkit.Location; import org.bukkit.Particle; import org.bukkit.entity.Entity; -import org.bukkit.entity.LivingEntity; import org.bukkit.scheduler.BukkitRunnable; import org.bukkit.util.Vector; -import net.Indyuce.mmoitems.MMOItems; -import net.Indyuce.mmoitems.MMOUtils; -import net.Indyuce.mmoitems.api.ItemAttackResult; -import net.Indyuce.mmoitems.api.ability.Ability; -import net.Indyuce.mmoitems.api.ability.AbilityResult; -import net.Indyuce.mmoitems.api.ability.LocationAbilityResult; -import net.Indyuce.mmoitems.api.player.PlayerStats.CachedStats; -import net.Indyuce.mmoitems.stat.data.AbilityData; -import io.lumine.mythic.lib.version.VersionSound; - -public class Black_Hole extends Ability { +public class Black_Hole extends LocationAbility { public Black_Hole() { super(CastingMode.ON_HIT, CastingMode.WHEN_HIT, CastingMode.LEFT_CLICK, CastingMode.RIGHT_CLICK, CastingMode.SHIFT_LEFT_CLICK, CastingMode.SHIFT_RIGHT_CLICK); @@ -29,13 +24,8 @@ public class Black_Hole extends Ability { } @Override - public AbilityResult whenRan(CachedStats stats, LivingEntity target, AbilityData ability, ItemAttackResult result) { - return new LocationAbilityResult(ability, stats.getPlayer(), target); - } - - @Override - public void whenCast(CachedStats stats, AbilityResult ability, ItemAttackResult result) { - Location loc = ((LocationAbilityResult) ability).getTarget(); + public void whenCast(ItemAttackMetadata attack, LocationAbilityMetadata ability) { + Location loc = ability.getTarget(); double duration = ability.getModifier("duration") * 20; double radius = ability.getModifier("radius"); @@ -62,7 +52,7 @@ public class Black_Hole extends Ability { } for (Entity entity : MMOUtils.getNearbyChunkEntities(loc)) - if (entity.getLocation().distanceSquared(loc) < Math.pow(radius, 2) && MMOUtils.canDamage(stats.getPlayer(), entity)) + if (entity.getLocation().distanceSquared(loc) < Math.pow(radius, 2) && MMOUtils.canDamage(attack.getDamager(), entity)) entity.setVelocity(MMOUtils.normalize(loc.clone().subtract(entity.getLocation()).toVector()).multiply(.5)); } }.runTaskTimer(MMOItems.plugin, 0, 1); diff --git a/src/main/java/net/Indyuce/mmoitems/ability/Contamination.java b/src/main/java/net/Indyuce/mmoitems/ability/list/location/Contamination.java similarity index 58% rename from src/main/java/net/Indyuce/mmoitems/ability/Contamination.java rename to src/main/java/net/Indyuce/mmoitems/ability/list/location/Contamination.java index 31f4c973..c005579d 100644 --- a/src/main/java/net/Indyuce/mmoitems/ability/Contamination.java +++ b/src/main/java/net/Indyuce/mmoitems/ability/list/location/Contamination.java @@ -1,5 +1,14 @@ -package net.Indyuce.mmoitems.ability; +package net.Indyuce.mmoitems.ability.list.location; +import io.lumine.mythic.lib.damage.AttackMetadata; +import io.lumine.mythic.lib.damage.DamageMetadata; +import io.lumine.mythic.lib.damage.DamageType; +import io.lumine.mythic.lib.version.VersionSound; +import net.Indyuce.mmoitems.MMOItems; +import net.Indyuce.mmoitems.MMOUtils; +import net.Indyuce.mmoitems.ability.LocationAbility; +import net.Indyuce.mmoitems.ability.metadata.LocationAbilityMetadata; +import net.Indyuce.mmoitems.api.ItemAttackMetadata; import org.bukkit.Color; import org.bukkit.Location; import org.bukkit.Particle; @@ -7,20 +16,7 @@ import org.bukkit.entity.Entity; import org.bukkit.entity.LivingEntity; import org.bukkit.scheduler.BukkitRunnable; -import net.Indyuce.mmoitems.MMOItems; -import net.Indyuce.mmoitems.MMOUtils; -import net.Indyuce.mmoitems.api.ItemAttackResult; -import net.Indyuce.mmoitems.api.ability.Ability; -import net.Indyuce.mmoitems.api.ability.AbilityResult; -import net.Indyuce.mmoitems.api.ability.LocationAbilityResult; -import net.Indyuce.mmoitems.api.player.PlayerStats.CachedStats; -import net.Indyuce.mmoitems.stat.data.AbilityData; -import io.lumine.mythic.lib.MythicLib; -import io.lumine.mythic.lib.api.AttackResult; -import io.lumine.mythic.lib.api.DamageType; -import io.lumine.mythic.lib.version.VersionSound; - -public class Contamination extends Ability { +public class Contamination extends LocationAbility { public Contamination() { super(CastingMode.ON_HIT, CastingMode.WHEN_HIT, CastingMode.LEFT_CLICK, CastingMode.RIGHT_CLICK, CastingMode.SHIFT_LEFT_CLICK, CastingMode.SHIFT_RIGHT_CLICK); @@ -33,21 +29,16 @@ public class Contamination extends Ability { } @Override - public AbilityResult whenRan(CachedStats stats, LivingEntity target, AbilityData ability, ItemAttackResult result) { - return new LocationAbilityResult(ability, stats.getPlayer(), target); - } - - @Override - public void whenCast(CachedStats stats, AbilityResult ability, ItemAttackResult result) { - Location loc = ((LocationAbilityResult) ability).getTarget(); + public void whenCast(ItemAttackMetadata attack, LocationAbilityMetadata ability) { + Location loc = ability.getTarget(); double duration = Math.min(30, ability.getModifier("duration")) * 20; loc.add(0, .1, 0); new BukkitRunnable() { + final double dps = ability.getModifier("damage") / 2; double ti = 0; int j = 0; - final double dps = ability.getModifier("damage") / 2; public void run() { j++; @@ -66,9 +57,8 @@ public class Contamination extends Ability { if (j % 10 == 0) { loc.getWorld().playSound(loc, VersionSound.ENTITY_ENDERMAN_HURT.toSound(), 2, 1); for (Entity entity : MMOUtils.getNearbyChunkEntities(loc)) - if (MMOUtils.canDamage(stats.getPlayer(), entity) && entity.getLocation().distanceSquared(loc) <= 25) - MythicLib.plugin.getDamage().damage(stats.getPlayer(), (LivingEntity) entity, - new AttackResult(dps, DamageType.SKILL, DamageType.MAGIC), false); + if (MMOUtils.canDamage(attack.getDamager(), entity) && entity.getLocation().distanceSquared(loc) <= 25) + new AttackMetadata(new DamageMetadata(dps, DamageType.SKILL, DamageType.MAGIC), attack.getStats()).damage((LivingEntity) entity, false); } } }.runTaskTimer(MMOItems.plugin, 0, 1); diff --git a/src/main/java/net/Indyuce/mmoitems/ability/onhit/Corrosion.java b/src/main/java/net/Indyuce/mmoitems/ability/list/location/Corrosion.java similarity index 60% rename from src/main/java/net/Indyuce/mmoitems/ability/onhit/Corrosion.java rename to src/main/java/net/Indyuce/mmoitems/ability/list/location/Corrosion.java index 638daa59..505966a2 100644 --- a/src/main/java/net/Indyuce/mmoitems/ability/onhit/Corrosion.java +++ b/src/main/java/net/Indyuce/mmoitems/ability/list/location/Corrosion.java @@ -1,5 +1,9 @@ -package net.Indyuce.mmoitems.ability.onhit; +package net.Indyuce.mmoitems.ability.list.location; +import net.Indyuce.mmoitems.MMOUtils; +import net.Indyuce.mmoitems.ability.LocationAbility; +import net.Indyuce.mmoitems.ability.metadata.LocationAbilityMetadata; +import net.Indyuce.mmoitems.api.ItemAttackMetadata; import org.bukkit.Location; import org.bukkit.Particle; import org.bukkit.Sound; @@ -8,15 +12,7 @@ import org.bukkit.entity.LivingEntity; import org.bukkit.potion.PotionEffect; import org.bukkit.potion.PotionEffectType; -import net.Indyuce.mmoitems.MMOUtils; -import net.Indyuce.mmoitems.api.ItemAttackResult; -import net.Indyuce.mmoitems.api.ability.Ability; -import net.Indyuce.mmoitems.api.ability.AbilityResult; -import net.Indyuce.mmoitems.api.ability.LocationAbilityResult; -import net.Indyuce.mmoitems.api.player.PlayerStats.CachedStats; -import net.Indyuce.mmoitems.stat.data.AbilityData; - -public class Corrosion extends Ability { +public class Corrosion extends LocationAbility { public Corrosion() { super(CastingMode.ON_HIT, CastingMode.WHEN_HIT); @@ -29,14 +25,9 @@ public class Corrosion extends Ability { } @Override - public AbilityResult whenRan(CachedStats stats, LivingEntity target, AbilityData ability, ItemAttackResult result) { - return new LocationAbilityResult(ability, stats.getPlayer(), target); - } - - @Override - public void whenCast(CachedStats stats, AbilityResult ability, ItemAttackResult result) { - Location loc = ((LocationAbilityResult) ability).getTarget(); - + public void whenCast(ItemAttackMetadata attack, LocationAbilityMetadata ability) { + Location loc = ability.getTarget(); + int duration = (int) (ability.getModifier("duration") * 20); int amplifier = (int) ability.getModifier("amplifier"); double radiusSquared = Math.pow(ability.getModifier("radius"), 2); @@ -46,7 +37,7 @@ public class Corrosion extends Ability { loc.getWorld().playSound(loc, Sound.BLOCK_BREWING_STAND_BREW, 2, 0); for (Entity entity : MMOUtils.getNearbyChunkEntities(loc)) - if (entity.getLocation().distanceSquared(loc) < radiusSquared && MMOUtils.canDamage(stats.getPlayer(), entity)) { + if (entity.getLocation().distanceSquared(loc) < radiusSquared && MMOUtils.canDamage(attack.getDamager(), entity)) { ((LivingEntity) entity).removePotionEffect(PotionEffectType.POISON); ((LivingEntity) entity).addPotionEffect(new PotionEffect(PotionEffectType.POISON, duration, amplifier)); } diff --git a/src/main/java/net/Indyuce/mmoitems/ability/Corrupt.java b/src/main/java/net/Indyuce/mmoitems/ability/list/location/Corrupt.java similarity index 55% rename from src/main/java/net/Indyuce/mmoitems/ability/Corrupt.java rename to src/main/java/net/Indyuce/mmoitems/ability/list/location/Corrupt.java index 96419b56..29b99687 100644 --- a/src/main/java/net/Indyuce/mmoitems/ability/Corrupt.java +++ b/src/main/java/net/Indyuce/mmoitems/ability/list/location/Corrupt.java @@ -1,15 +1,13 @@ -package net.Indyuce.mmoitems.ability; +package net.Indyuce.mmoitems.ability.list.location; -import io.lumine.mythic.lib.api.AttackResult; -import io.lumine.mythic.lib.api.DamageType; +import io.lumine.mythic.lib.damage.AttackMetadata; +import io.lumine.mythic.lib.damage.DamageMetadata; +import io.lumine.mythic.lib.damage.DamageType; import io.lumine.mythic.lib.version.VersionSound; import net.Indyuce.mmoitems.MMOUtils; -import net.Indyuce.mmoitems.api.ItemAttackResult; -import net.Indyuce.mmoitems.api.ability.Ability; -import net.Indyuce.mmoitems.api.ability.AbilityResult; -import net.Indyuce.mmoitems.api.ability.LocationAbilityResult; -import net.Indyuce.mmoitems.api.player.PlayerStats.CachedStats; -import net.Indyuce.mmoitems.stat.data.AbilityData; +import net.Indyuce.mmoitems.ability.LocationAbility; +import net.Indyuce.mmoitems.ability.metadata.LocationAbilityMetadata; +import net.Indyuce.mmoitems.api.ItemAttackMetadata; import org.bukkit.Color; import org.bukkit.Location; import org.bukkit.Particle; @@ -18,7 +16,7 @@ import org.bukkit.entity.LivingEntity; import org.bukkit.potion.PotionEffect; import org.bukkit.potion.PotionEffectType; -public class Corrupt extends Ability { +public class Corrupt extends LocationAbility { public Corrupt() { super(CastingMode.ON_HIT, CastingMode.WHEN_HIT, CastingMode.LEFT_CLICK, CastingMode.RIGHT_CLICK, CastingMode.SHIFT_LEFT_CLICK, CastingMode.SHIFT_RIGHT_CLICK); @@ -32,13 +30,8 @@ public class Corrupt extends Ability { } @Override - public AbilityResult whenRan(CachedStats stats, LivingEntity target, AbilityData ability, ItemAttackResult result) { - return new LocationAbilityResult(ability, stats.getPlayer(), target); - } - - @Override - public void whenCast(CachedStats stats, AbilityResult ability, ItemAttackResult result) { - Location loc = ((LocationAbilityResult) ability).getTarget(); + public void whenCast(ItemAttackMetadata attack, LocationAbilityMetadata ability) { + Location loc = ability.getTarget(); double damage = ability.getModifier("damage"); double duration = ability.getModifier("duration"); @@ -46,7 +39,7 @@ public class Corrupt extends Ability { double radius = 2.7; loc.add(0, -1, 0); - stats.getPlayer().getWorld().playSound(stats.getPlayer().getLocation(), VersionSound.ENTITY_ENDERMAN_HURT.toSound(), 1, .5f); + attack.getDamager().getWorld().playSound(attack.getDamager().getLocation(), VersionSound.ENTITY_ENDERMAN_HURT.toSound(), 1, .5f); for (double j = 0; j < Math.PI * 2; j += Math.PI / 36) { Location loc1 = loc.clone().add(Math.cos(j) * radius, 1, Math.sin(j) * radius); double y_max = .5 + random.nextDouble(); @@ -55,8 +48,8 @@ public class Corrupt extends Ability { } for (Entity entity : MMOUtils.getNearbyChunkEntities(loc)) - if (MMOUtils.canDamage(stats.getPlayer(), entity) && entity.getLocation().distanceSquared(loc) <= radius * radius) { - new AttackResult(damage, DamageType.SKILL, DamageType.MAGIC).damage(stats.getPlayer(), (LivingEntity) entity); + if (MMOUtils.canDamage(attack.getDamager(), entity) && entity.getLocation().distanceSquared(loc) <= radius * radius) { + new AttackMetadata(new DamageMetadata(damage, DamageType.SKILL, DamageType.MAGIC), attack.getStats()).damage((LivingEntity) entity); ((LivingEntity) entity).removePotionEffect(PotionEffectType.WITHER); ((LivingEntity) entity).addPotionEffect(new PotionEffect(PotionEffectType.WITHER, (int) (duration * 20), (int) amplifier)); } diff --git a/src/main/java/net/Indyuce/mmoitems/ability/onhit/Freeze.java b/src/main/java/net/Indyuce/mmoitems/ability/list/location/Freeze.java similarity index 65% rename from src/main/java/net/Indyuce/mmoitems/ability/onhit/Freeze.java rename to src/main/java/net/Indyuce/mmoitems/ability/list/location/Freeze.java index e6ade957..d3a83c84 100644 --- a/src/main/java/net/Indyuce/mmoitems/ability/onhit/Freeze.java +++ b/src/main/java/net/Indyuce/mmoitems/ability/list/location/Freeze.java @@ -1,5 +1,11 @@ -package net.Indyuce.mmoitems.ability.onhit; +package net.Indyuce.mmoitems.ability.list.location; +import io.lumine.mythic.lib.version.VersionSound; +import net.Indyuce.mmoitems.MMOUtils; +import net.Indyuce.mmoitems.ability.LocationAbility; +import net.Indyuce.mmoitems.ability.metadata.LocationAbilityMetadata; +import net.Indyuce.mmoitems.api.ItemAttackMetadata; +import net.Indyuce.mmoitems.stat.data.AbilityData; import org.bukkit.Location; import org.bukkit.Particle; import org.bukkit.entity.Entity; @@ -7,16 +13,7 @@ import org.bukkit.entity.LivingEntity; import org.bukkit.potion.PotionEffect; import org.bukkit.potion.PotionEffectType; -import net.Indyuce.mmoitems.MMOUtils; -import net.Indyuce.mmoitems.api.ItemAttackResult; -import net.Indyuce.mmoitems.api.ability.Ability; -import net.Indyuce.mmoitems.api.ability.AbilityResult; -import net.Indyuce.mmoitems.api.ability.LocationAbilityResult; -import net.Indyuce.mmoitems.api.player.PlayerStats.CachedStats; -import net.Indyuce.mmoitems.stat.data.AbilityData; -import io.lumine.mythic.lib.version.VersionSound; - -public class Freeze extends Ability { +public class Freeze extends LocationAbility { public Freeze() { super(CastingMode.ON_HIT, CastingMode.WHEN_HIT); @@ -29,13 +26,13 @@ public class Freeze extends Ability { } @Override - public AbilityResult whenRan(CachedStats stats, LivingEntity target, AbilityData ability, ItemAttackResult result) { - return new LocationAbilityResult(ability, stats.getPlayer(), target); + public LocationAbilityMetadata canBeCast(ItemAttackMetadata attack, LivingEntity target, AbilityData ability) { + return new LocationAbilityMetadata(ability, attack.getDamager(), target); } @Override - public void whenCast(CachedStats stats, AbilityResult ability, ItemAttackResult result) { - Location loc = ((LocationAbilityResult) ability).getTarget(); + public void whenCast(ItemAttackMetadata attack, LocationAbilityMetadata ability) { + Location loc = ability.getTarget(); int duration = (int) (ability.getModifier("duration") * 20); int amplifier = (int) (ability.getModifier("amplifier") - 1); @@ -47,7 +44,7 @@ public class Freeze extends Ability { loc.getWorld().playSound(loc, VersionSound.ENTITY_FIREWORK_ROCKET_LARGE_BLAST.toSound(), 2, 1); for (Entity entity : MMOUtils.getNearbyChunkEntities(loc)) - if (entity.getLocation().distanceSquared(loc) < radiusSquared && MMOUtils.canDamage(stats.getPlayer(), entity)) { + if (entity.getLocation().distanceSquared(loc) < radiusSquared && MMOUtils.canDamage(attack.getDamager(), entity)) { ((LivingEntity) entity).removePotionEffect(PotionEffectType.SLOW); ((LivingEntity) entity).addPotionEffect(new PotionEffect(PotionEffectType.SLOW, duration, amplifier)); } diff --git a/src/main/java/net/Indyuce/mmoitems/ability/Freezing_Curse.java b/src/main/java/net/Indyuce/mmoitems/ability/list/location/Freezing_Curse.java similarity index 64% rename from src/main/java/net/Indyuce/mmoitems/ability/Freezing_Curse.java rename to src/main/java/net/Indyuce/mmoitems/ability/list/location/Freezing_Curse.java index e7252ecd..5e7e8dab 100644 --- a/src/main/java/net/Indyuce/mmoitems/ability/Freezing_Curse.java +++ b/src/main/java/net/Indyuce/mmoitems/ability/list/location/Freezing_Curse.java @@ -1,5 +1,14 @@ -package net.Indyuce.mmoitems.ability; +package net.Indyuce.mmoitems.ability.list.location; +import io.lumine.mythic.lib.damage.AttackMetadata; +import io.lumine.mythic.lib.damage.DamageMetadata; +import io.lumine.mythic.lib.damage.DamageType; +import io.lumine.mythic.lib.version.VersionSound; +import net.Indyuce.mmoitems.MMOItems; +import net.Indyuce.mmoitems.MMOUtils; +import net.Indyuce.mmoitems.ability.LocationAbility; +import net.Indyuce.mmoitems.ability.metadata.LocationAbilityMetadata; +import net.Indyuce.mmoitems.api.ItemAttackMetadata; import org.bukkit.Location; import org.bukkit.Particle; import org.bukkit.Sound; @@ -9,19 +18,7 @@ import org.bukkit.potion.PotionEffect; import org.bukkit.potion.PotionEffectType; import org.bukkit.scheduler.BukkitRunnable; -import net.Indyuce.mmoitems.MMOItems; -import net.Indyuce.mmoitems.MMOUtils; -import net.Indyuce.mmoitems.api.ItemAttackResult; -import net.Indyuce.mmoitems.api.ability.Ability; -import net.Indyuce.mmoitems.api.ability.AbilityResult; -import net.Indyuce.mmoitems.api.ability.LocationAbilityResult; -import net.Indyuce.mmoitems.api.player.PlayerStats.CachedStats; -import net.Indyuce.mmoitems.stat.data.AbilityData; -import io.lumine.mythic.lib.api.AttackResult; -import io.lumine.mythic.lib.api.DamageType; -import io.lumine.mythic.lib.version.VersionSound; - -public class Freezing_Curse extends Ability { +public class Freezing_Curse extends LocationAbility { public Freezing_Curse() { super(CastingMode.ON_HIT, CastingMode.WHEN_HIT, CastingMode.LEFT_CLICK, CastingMode.RIGHT_CLICK, CastingMode.SHIFT_LEFT_CLICK, CastingMode.SHIFT_RIGHT_CLICK); @@ -35,20 +32,11 @@ public class Freezing_Curse extends Ability { } @Override - public AbilityResult whenRan(CachedStats stats, LivingEntity target, AbilityData ability, ItemAttackResult result) { - return new LocationAbilityResult(ability, stats.getPlayer(), target); - } - - @Override - public void whenCast(CachedStats stats, AbilityResult ability, ItemAttackResult result) { - Location loc = ((LocationAbilityResult) ability).getTarget(); - if (loc == null) { - result.setSuccessful(false); - return; - } + public void whenCast(ItemAttackMetadata attack, LocationAbilityMetadata ability) { + Location loc = ability.getTarget(); new BukkitRunnable() { - final double rads = Math.toRadians(stats.getPlayer().getEyeLocation().getYaw() - 90); + final double rads = Math.toRadians(attack.getDamager().getEyeLocation().getYaw() - 90); double ti = rads; int j = 0; @@ -72,8 +60,8 @@ public class Freezing_Curse extends Ability { double duration = ability.getModifier("duration"); double damage = ability.getModifier("damage"); for (Entity entity : MMOUtils.getNearbyChunkEntities(loc)) - if (entity.getLocation().distanceSquared(loc) < radius * radius && MMOUtils.canDamage(stats.getPlayer(), entity)) { - new AttackResult(damage, DamageType.SKILL, DamageType.MAGIC).damage(stats.getPlayer(), (LivingEntity) entity); + if (entity.getLocation().distanceSquared(loc) < radius * radius && MMOUtils.canDamage(attack.getDamager(), entity)) { + new AttackMetadata(new DamageMetadata(damage, DamageType.SKILL, DamageType.MAGIC), attack.getStats()).damage((LivingEntity) entity); ((LivingEntity) entity).removePotionEffect(PotionEffectType.SLOW); ((LivingEntity) entity).addPotionEffect(new PotionEffect(PotionEffectType.SLOW, (int) (duration * 20), (int) amplifier)); } diff --git a/src/main/java/net/Indyuce/mmoitems/ability/onhit/Ignite.java b/src/main/java/net/Indyuce/mmoitems/ability/list/location/Ignite.java similarity index 57% rename from src/main/java/net/Indyuce/mmoitems/ability/onhit/Ignite.java rename to src/main/java/net/Indyuce/mmoitems/ability/list/location/Ignite.java index fe12bf69..bc3c3b16 100644 --- a/src/main/java/net/Indyuce/mmoitems/ability/onhit/Ignite.java +++ b/src/main/java/net/Indyuce/mmoitems/ability/list/location/Ignite.java @@ -1,20 +1,15 @@ -package net.Indyuce.mmoitems.ability.onhit; +package net.Indyuce.mmoitems.ability.list.location; +import io.lumine.mythic.lib.version.VersionSound; +import net.Indyuce.mmoitems.MMOUtils; +import net.Indyuce.mmoitems.ability.LocationAbility; +import net.Indyuce.mmoitems.ability.metadata.LocationAbilityMetadata; +import net.Indyuce.mmoitems.api.ItemAttackMetadata; import org.bukkit.Location; import org.bukkit.Particle; import org.bukkit.entity.Entity; -import org.bukkit.entity.LivingEntity; -import net.Indyuce.mmoitems.MMOUtils; -import net.Indyuce.mmoitems.api.ItemAttackResult; -import net.Indyuce.mmoitems.api.ability.Ability; -import net.Indyuce.mmoitems.api.ability.AbilityResult; -import net.Indyuce.mmoitems.api.ability.LocationAbilityResult; -import net.Indyuce.mmoitems.api.player.PlayerStats.CachedStats; -import net.Indyuce.mmoitems.stat.data.AbilityData; -import io.lumine.mythic.lib.version.VersionSound; - -public class Ignite extends Ability { +public class Ignite extends LocationAbility { public Ignite() { super(CastingMode.ON_HIT, CastingMode.WHEN_HIT); @@ -27,13 +22,8 @@ public class Ignite extends Ability { } @Override - public AbilityResult whenRan(CachedStats stats, LivingEntity target, AbilityData ability, ItemAttackResult result) { - return new LocationAbilityResult(ability, stats.getPlayer(), target); - } - - @Override - public void whenCast(CachedStats stats, AbilityResult ability, ItemAttackResult result) { - Location loc = ((LocationAbilityResult) ability).getTarget(); + public void whenCast(ItemAttackMetadata attack, LocationAbilityMetadata ability) { + Location loc = ability.getTarget(); int maxIgnite = (int) (ability.getModifier("max-ignite") * 20); int ignite = (int) (ability.getModifier("duration") * 20); @@ -45,7 +35,7 @@ public class Ignite extends Ability { loc.getWorld().playSound(loc, VersionSound.ENTITY_FIREWORK_ROCKET_LARGE_BLAST.toSound(), 2, 1); for (Entity entity : MMOUtils.getNearbyChunkEntities(loc)) - if (entity.getLocation().distanceSquared(loc) < radiusSquared && MMOUtils.canDamage(stats.getPlayer(), entity)) + if (entity.getLocation().distanceSquared(loc) < radiusSquared && MMOUtils.canDamage(attack.getDamager(), entity)) entity.setFireTicks(Math.min(entity.getFireTicks() + ignite, maxIgnite)); } } diff --git a/src/main/java/net/Indyuce/mmoitems/ability/Life_Ender.java b/src/main/java/net/Indyuce/mmoitems/ability/list/location/Life_Ender.java similarity index 66% rename from src/main/java/net/Indyuce/mmoitems/ability/Life_Ender.java rename to src/main/java/net/Indyuce/mmoitems/ability/list/location/Life_Ender.java index 400e5b1a..727db776 100644 --- a/src/main/java/net/Indyuce/mmoitems/ability/Life_Ender.java +++ b/src/main/java/net/Indyuce/mmoitems/ability/list/location/Life_Ender.java @@ -1,5 +1,14 @@ -package net.Indyuce.mmoitems.ability; +package net.Indyuce.mmoitems.ability.list.location; +import io.lumine.mythic.lib.damage.AttackMetadata; +import io.lumine.mythic.lib.damage.DamageMetadata; +import io.lumine.mythic.lib.damage.DamageType; +import io.lumine.mythic.lib.version.VersionSound; +import net.Indyuce.mmoitems.MMOItems; +import net.Indyuce.mmoitems.MMOUtils; +import net.Indyuce.mmoitems.ability.LocationAbility; +import net.Indyuce.mmoitems.ability.metadata.LocationAbilityMetadata; +import net.Indyuce.mmoitems.api.ItemAttackMetadata; import org.bukkit.Location; import org.bukkit.Particle; import org.bukkit.Sound; @@ -8,19 +17,7 @@ import org.bukkit.entity.LivingEntity; import org.bukkit.scheduler.BukkitRunnable; import org.bukkit.util.Vector; -import net.Indyuce.mmoitems.MMOItems; -import net.Indyuce.mmoitems.MMOUtils; -import net.Indyuce.mmoitems.api.ItemAttackResult; -import net.Indyuce.mmoitems.api.ability.Ability; -import net.Indyuce.mmoitems.api.ability.AbilityResult; -import net.Indyuce.mmoitems.api.ability.LocationAbilityResult; -import net.Indyuce.mmoitems.api.player.PlayerStats.CachedStats; -import net.Indyuce.mmoitems.stat.data.AbilityData; -import io.lumine.mythic.lib.api.AttackResult; -import io.lumine.mythic.lib.api.DamageType; -import io.lumine.mythic.lib.version.VersionSound; - -public class Life_Ender extends Ability { +public class Life_Ender extends LocationAbility { public Life_Ender() { super(CastingMode.ON_HIT, CastingMode.WHEN_HIT, CastingMode.LEFT_CLICK, CastingMode.RIGHT_CLICK, CastingMode.SHIFT_LEFT_CLICK, CastingMode.SHIFT_RIGHT_CLICK); @@ -33,22 +30,17 @@ public class Life_Ender extends Ability { } @Override - public AbilityResult whenRan(CachedStats stats, LivingEntity target, AbilityData ability, ItemAttackResult result) { - return new LocationAbilityResult(ability, stats.getPlayer(), target); - } - - @Override - public void whenCast(CachedStats stats, AbilityResult ability, ItemAttackResult result) { - Location loc = ((LocationAbilityResult) ability).getTarget(); + public void whenCast(ItemAttackMetadata attack, LocationAbilityMetadata ability) { + Location loc = ability.getTarget(); double damage = ability.getModifier("damage"); double knockback = ability.getModifier("knockback"); double radius = ability.getModifier("radius"); - stats.getPlayer().getWorld().playSound(stats.getPlayer().getLocation(), VersionSound.ENTITY_ENDERMAN_TELEPORT.toSound(), 2, 1); + attack.getDamager().getWorld().playSound(attack.getDamager().getLocation(), VersionSound.ENTITY_ENDERMAN_TELEPORT.toSound(), 2, 1); new BukkitRunnable() { - int ti = 0; final Location source = loc.clone().add(5 * Math.cos(random.nextDouble() * 2 * Math.PI), 20, 5 * Math.sin(random.nextDouble() * 2 * Math.PI)); final Vector vec = loc.subtract(source).toVector().multiply((double) 1 / 30); + int ti = 0; public void run() { if (ti == 0) @@ -71,8 +63,8 @@ public class Life_Ender extends Ability { source.getWorld().spawnParticle(Particle.SMOKE_LARGE, source, 0, Math.cos(j), 0, Math.sin(j), .5); for (Entity entity : MMOUtils.getNearbyChunkEntities(source)) - if (entity.getLocation().distanceSquared(source) < radius * radius && MMOUtils.canDamage(stats.getPlayer(), entity)) { - new AttackResult(damage, DamageType.SKILL, DamageType.MAGIC).damage(stats.getPlayer(), (LivingEntity) entity); + if (entity.getLocation().distanceSquared(source) < radius * radius && MMOUtils.canDamage(attack.getDamager(), entity)) { + new AttackMetadata(new DamageMetadata(damage, DamageType.SKILL, DamageType.MAGIC), attack.getStats()).damage((LivingEntity) entity); entity.setVelocity(entity.getLocation().subtract(source).toVector().setY(.75).normalize().multiply(knockback)); } cancel(); diff --git a/src/main/java/net/Indyuce/mmoitems/ability/Lightning_Beam.java b/src/main/java/net/Indyuce/mmoitems/ability/list/location/Lightning_Beam.java similarity index 50% rename from src/main/java/net/Indyuce/mmoitems/ability/Lightning_Beam.java rename to src/main/java/net/Indyuce/mmoitems/ability/list/location/Lightning_Beam.java index aa524f30..f978f409 100644 --- a/src/main/java/net/Indyuce/mmoitems/ability/Lightning_Beam.java +++ b/src/main/java/net/Indyuce/mmoitems/ability/list/location/Lightning_Beam.java @@ -1,23 +1,20 @@ -package net.Indyuce.mmoitems.ability; +package net.Indyuce.mmoitems.ability.list.location; +import io.lumine.mythic.lib.damage.AttackMetadata; +import io.lumine.mythic.lib.damage.DamageMetadata; +import io.lumine.mythic.lib.damage.DamageType; +import io.lumine.mythic.lib.version.VersionSound; +import net.Indyuce.mmoitems.MMOUtils; +import net.Indyuce.mmoitems.ability.LocationAbility; +import net.Indyuce.mmoitems.ability.metadata.LocationAbilityMetadata; +import net.Indyuce.mmoitems.api.ItemAttackMetadata; import org.bukkit.Location; import org.bukkit.Particle; import org.bukkit.entity.Entity; import org.bukkit.entity.LivingEntity; import org.bukkit.util.Vector; -import net.Indyuce.mmoitems.MMOUtils; -import net.Indyuce.mmoitems.api.ItemAttackResult; -import net.Indyuce.mmoitems.api.ability.Ability; -import net.Indyuce.mmoitems.api.ability.AbilityResult; -import net.Indyuce.mmoitems.api.ability.LocationAbilityResult; -import net.Indyuce.mmoitems.api.player.PlayerStats.CachedStats; -import net.Indyuce.mmoitems.stat.data.AbilityData; -import io.lumine.mythic.lib.api.AttackResult; -import io.lumine.mythic.lib.api.DamageType; -import io.lumine.mythic.lib.version.VersionSound; - -public class Lightning_Beam extends Ability { +public class Lightning_Beam extends LocationAbility { public Lightning_Beam() { super(CastingMode.ON_HIT, CastingMode.WHEN_HIT, CastingMode.LEFT_CLICK, CastingMode.RIGHT_CLICK, CastingMode.SHIFT_LEFT_CLICK, CastingMode.SHIFT_RIGHT_CLICK); @@ -29,21 +26,16 @@ public class Lightning_Beam extends Ability { } @Override - public AbilityResult whenRan(CachedStats stats, LivingEntity target, AbilityData ability, ItemAttackResult result) { - return new LocationAbilityResult(ability, stats.getPlayer(), target); - } - - @Override - public void whenCast(CachedStats stats, AbilityResult ability, ItemAttackResult result) { - final Location loc = getFirstNonSolidBlock(((LocationAbilityResult) ability).getTarget()); + public void whenCast(ItemAttackMetadata attack, LocationAbilityMetadata ability) { + final Location loc = getFirstNonSolidBlock(ability.getTarget()); double damage = ability.getModifier("damage"); double radius = ability.getModifier("radius"); for (Entity entity : MMOUtils.getNearbyChunkEntities(loc)) - if (MMOUtils.canDamage(stats.getPlayer(), entity) && entity.getLocation().distanceSquared(loc) <= radius * radius) - new AttackResult(damage, DamageType.SKILL, DamageType.MAGIC).damage(stats.getPlayer(), (LivingEntity) entity); + if (MMOUtils.canDamage(attack.getDamager(), entity) && entity.getLocation().distanceSquared(loc) <= radius * radius) + new AttackMetadata(new DamageMetadata(damage, DamageType.SKILL, DamageType.MAGIC), attack.getStats()).damage((LivingEntity) entity); - stats.getPlayer().getWorld().playSound(stats.getPlayer().getLocation(), VersionSound.ENTITY_FIREWORK_ROCKET_BLAST.toSound(), 1, 0); + attack.getDamager().getWorld().playSound(attack.getDamager().getLocation(), VersionSound.ENTITY_FIREWORK_ROCKET_BLAST.toSound(), 1, 0); loc.getWorld().spawnParticle(Particle.FIREWORKS_SPARK, loc, 64, 0, 0, 0, .2); loc.getWorld().spawnParticle(Particle.EXPLOSION_NORMAL, loc, 32, 0, 0, 0, .2); Vector vec = new Vector(0, .3, 0); diff --git a/src/main/java/net/Indyuce/mmoitems/ability/onhit/Minor_Explosion.java b/src/main/java/net/Indyuce/mmoitems/ability/list/location/Minor_Explosion.java similarity index 52% rename from src/main/java/net/Indyuce/mmoitems/ability/onhit/Minor_Explosion.java rename to src/main/java/net/Indyuce/mmoitems/ability/list/location/Minor_Explosion.java index 2632d6ab..aea18503 100644 --- a/src/main/java/net/Indyuce/mmoitems/ability/onhit/Minor_Explosion.java +++ b/src/main/java/net/Indyuce/mmoitems/ability/list/location/Minor_Explosion.java @@ -1,22 +1,19 @@ -package net.Indyuce.mmoitems.ability.onhit; +package net.Indyuce.mmoitems.ability.list.location; +import io.lumine.mythic.lib.damage.AttackMetadata; +import io.lumine.mythic.lib.damage.DamageMetadata; +import io.lumine.mythic.lib.damage.DamageType; +import net.Indyuce.mmoitems.MMOUtils; +import net.Indyuce.mmoitems.ability.LocationAbility; +import net.Indyuce.mmoitems.ability.metadata.LocationAbilityMetadata; +import net.Indyuce.mmoitems.api.ItemAttackMetadata; import org.bukkit.Location; import org.bukkit.Particle; import org.bukkit.Sound; import org.bukkit.entity.Entity; import org.bukkit.entity.LivingEntity; -import net.Indyuce.mmoitems.MMOUtils; -import net.Indyuce.mmoitems.api.ItemAttackResult; -import net.Indyuce.mmoitems.api.ability.Ability; -import net.Indyuce.mmoitems.api.ability.AbilityResult; -import net.Indyuce.mmoitems.api.ability.LocationAbilityResult; -import net.Indyuce.mmoitems.api.player.PlayerStats.CachedStats; -import net.Indyuce.mmoitems.stat.data.AbilityData; -import io.lumine.mythic.lib.api.AttackResult; -import io.lumine.mythic.lib.api.DamageType; - -public class Minor_Explosion extends Ability { +public class Minor_Explosion extends LocationAbility { public Minor_Explosion() { super(CastingMode.ON_HIT, CastingMode.WHEN_HIT); @@ -29,13 +26,8 @@ public class Minor_Explosion extends Ability { } @Override - public AbilityResult whenRan(CachedStats stats, LivingEntity target, AbilityData ability, ItemAttackResult result) { - return new LocationAbilityResult(ability, stats.getPlayer(), target); - } - - @Override - public void whenCast(CachedStats stats, AbilityResult ability, ItemAttackResult result) { - Location loc = ((LocationAbilityResult) ability).getTarget(); + public void whenCast(ItemAttackMetadata attack, LocationAbilityMetadata ability) { + Location loc = ability.getTarget(); double damage = ability.getModifier("damage"); double radiusSquared = Math.pow(ability.getModifier("radius"), 2); @@ -46,8 +38,8 @@ public class Minor_Explosion extends Ability { loc.getWorld().playSound(loc, Sound.ENTITY_GENERIC_EXPLODE, 2, 1); for (Entity entity : MMOUtils.getNearbyChunkEntities(loc)) - if (entity.getLocation().distanceSquared(loc) < radiusSquared && MMOUtils.canDamage(stats.getPlayer(), entity)) { - new AttackResult(damage, DamageType.SKILL, DamageType.MAGIC).damage(stats.getPlayer(), (LivingEntity) entity); + if (entity.getLocation().distanceSquared(loc) < radiusSquared && MMOUtils.canDamage(attack.getDamager(), entity)) { + new AttackMetadata(new DamageMetadata(damage, DamageType.SKILL, DamageType.MAGIC), attack.getStats()).damage((LivingEntity) entity); entity.setVelocity(MMOUtils.normalize(entity.getLocation().subtract(loc).toVector().setY(0)).setY(.2).multiply(2 * knockback)); } } diff --git a/src/main/java/net/Indyuce/mmoitems/ability/list/location/Snowman_Turret.java b/src/main/java/net/Indyuce/mmoitems/ability/list/location/Snowman_Turret.java new file mode 100644 index 00000000..5c83b5b8 --- /dev/null +++ b/src/main/java/net/Indyuce/mmoitems/ability/list/location/Snowman_Turret.java @@ -0,0 +1,100 @@ +package net.Indyuce.mmoitems.ability.list.location; + +import io.lumine.mythic.lib.version.VersionSound; +import net.Indyuce.mmoitems.MMOItems; +import net.Indyuce.mmoitems.MMOUtils; +import net.Indyuce.mmoitems.ability.LocationAbility; +import net.Indyuce.mmoitems.ability.metadata.LocationAbilityMetadata; +import net.Indyuce.mmoitems.api.ItemAttackMetadata; +import net.Indyuce.mmoitems.api.util.TemporaryListener; +import org.bukkit.Location; +import org.bukkit.Particle; +import org.bukkit.Sound; +import org.bukkit.entity.Entity; +import org.bukkit.entity.EntityType; +import org.bukkit.entity.Snowball; +import org.bukkit.entity.Snowman; +import org.bukkit.event.EventHandler; +import org.bukkit.event.EventPriority; +import org.bukkit.event.entity.EntityDamageByEntityEvent; +import org.bukkit.potion.PotionEffect; +import org.bukkit.potion.PotionEffectType; +import org.bukkit.scheduler.BukkitRunnable; + +import java.util.ArrayList; +import java.util.List; +import java.util.UUID; + +public class Snowman_Turret extends LocationAbility { + public Snowman_Turret() { + super(CastingMode.ON_HIT, CastingMode.WHEN_HIT, CastingMode.LEFT_CLICK, CastingMode.RIGHT_CLICK, CastingMode.SHIFT_LEFT_CLICK, + CastingMode.SHIFT_RIGHT_CLICK); + + addModifier("duration", 6); + addModifier("cooldown", 35); + addModifier("damage", 2); + addModifier("radius", 20); + addModifier("mana", 0); + addModifier("stamina", 0); + } + + @Override + public void whenCast(ItemAttackMetadata attack, LocationAbilityMetadata ability) { + Location loc = ability.getTarget(); + double duration = Math.min(ability.getModifier("duration") * 20, 300); + double radiusSquared = Math.pow(ability.getModifier("radius"), 2); + + loc.getWorld().playSound(loc, VersionSound.ENTITY_ENDERMAN_TELEPORT.toSound(), 2, 1); + final Snowman snowman = (Snowman) loc.getWorld().spawnEntity(loc.add(0, 1, 0), EntityType.SNOWMAN); + snowman.setInvulnerable(true); + snowman.addPotionEffect(new PotionEffect(PotionEffectType.SLOW, 100000, 254, true)); + new BukkitRunnable() { + int ti = 0; + double j = 0; + final TurretHandler turret = new TurretHandler(ability.getModifier("damage")); + + public void run() { + if (ti++ > duration || attack.getDamager().isDead() || snowman == null || snowman.isDead()) { + turret.close(3 * 20); + snowman.remove(); + cancel(); + } + + j += Math.PI / 24 % (2 * Math.PI); + for (double k = 0; k < 3; k++) + snowman.getWorld().spawnParticle(Particle.SPELL_INSTANT, + snowman.getLocation().add(Math.cos(j + k / 3 * 2 * Math.PI) * 1.3, 1, Math.sin(j + k / 3 * 2 * Math.PI) * 1.3), 0); + snowman.getWorld().spawnParticle(Particle.SPELL_INSTANT, snowman.getLocation().add(0, 1, 0), 1, 0, 0, 0, .2); + + if (ti % 2 == 0) + for (Entity entity : MMOUtils.getNearbyChunkEntities(snowman.getLocation())) + if (!entity.equals(snowman) && MMOUtils.canDamage(attack.getDamager(), entity) + && entity.getLocation().distanceSquared(snowman.getLocation()) < radiusSquared) { + snowman.getWorld().playSound(snowman.getLocation(), Sound.ENTITY_SNOWBALL_THROW, 1, 1.3f); + Snowball snowball = snowman.launchProjectile(Snowball.class); + snowball.setVelocity(entity.getLocation().add(0, entity.getHeight() / 2, 0).toVector() + .subtract(snowman.getLocation().add(0, 1, 0).toVector()).normalize().multiply(1.3)); + turret.entities.add(snowball.getUniqueId()); + break; + } + } + }.runTaskTimer(MMOItems.plugin, 0, 1); + } + + public static class TurretHandler extends TemporaryListener { + private final List entities = new ArrayList<>(); + private final double damage; + + public TurretHandler(double damage) { + super(EntityDamageByEntityEvent.getHandlerList()); + + this.damage = damage; + } + + @EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true) + public void a(EntityDamageByEntityEvent event) { + if (entities.contains(event.getDamager().getUniqueId())) + event.setDamage(damage); + } + } +} diff --git a/src/main/java/net/Indyuce/mmoitems/ability/list/misc/Arcane_Rift.java b/src/main/java/net/Indyuce/mmoitems/ability/list/misc/Arcane_Rift.java new file mode 100644 index 00000000..0d1ab45a --- /dev/null +++ b/src/main/java/net/Indyuce/mmoitems/ability/list/misc/Arcane_Rift.java @@ -0,0 +1,73 @@ +package net.Indyuce.mmoitems.ability.list.misc; + +import io.lumine.mythic.lib.damage.AttackMetadata; +import io.lumine.mythic.lib.damage.DamageMetadata; +import io.lumine.mythic.lib.damage.DamageType; +import io.lumine.mythic.lib.version.VersionSound; +import net.Indyuce.mmoitems.MMOItems; +import net.Indyuce.mmoitems.MMOUtils; +import net.Indyuce.mmoitems.ability.Ability; +import net.Indyuce.mmoitems.ability.metadata.VectorAbilityMetadata; +import net.Indyuce.mmoitems.api.ItemAttackMetadata; +import net.Indyuce.mmoitems.stat.data.AbilityData; +import org.bukkit.Location; +import org.bukkit.Particle; +import org.bukkit.entity.Entity; +import org.bukkit.entity.LivingEntity; +import org.bukkit.potion.PotionEffect; +import org.bukkit.potion.PotionEffectType; +import org.bukkit.scheduler.BukkitRunnable; +import org.bukkit.util.Vector; + +import java.util.ArrayList; +import java.util.List; + +public class Arcane_Rift extends Ability { + public Arcane_Rift() { + super(CastingMode.ON_HIT, CastingMode.WHEN_HIT, CastingMode.LEFT_CLICK, CastingMode.RIGHT_CLICK, CastingMode.SHIFT_LEFT_CLICK, CastingMode.SHIFT_RIGHT_CLICK); + + addModifier("damage", 5); + addModifier("amplifier", 2); + addModifier("cooldown", 10); + addModifier("speed", 1); + addModifier("duration", 1.5); + addModifier("mana", 0); + addModifier("stamina", 0); + } + + @Override + public VectorAbilityMetadata canBeCast(ItemAttackMetadata attack, LivingEntity target, AbilityData ability) { + return attack.getDamager().isOnGround() ? new VectorAbilityMetadata(ability, attack.getDamager(), target) : null; + } + + @Override + public void whenCast(ItemAttackMetadata attack, VectorAbilityMetadata ability) { + double damage = ability.getModifier("damage"); + double slowDuration = ability.getModifier("duration"); + double slowAmplifier = ability.getModifier("amplifier"); + + attack.getDamager().getWorld().playSound(attack.getDamager().getLocation(), VersionSound.ENTITY_ENDERMAN_DEATH.toSound(), 2, .5f); + new BukkitRunnable() { + final Vector vec = ability.getTarget().setY(0).normalize().multiply(.5 * ability.getModifier("speed")); + final Location loc = attack.getDamager().getLocation(); + final int duration = (int) (20 * Math.min(ability.getModifier("duration"), 10.)); + final List hit = new ArrayList<>(); + int ti = 0; + + public void run() { + if (ti++ > duration) + cancel(); + + loc.add(vec); + loc.getWorld().spawnParticle(Particle.SPELL_WITCH, loc, 5, .5, 0, .5, 0); + + for (Entity entity : MMOUtils.getNearbyChunkEntities(loc)) + if (MMOUtils.canDamage(attack.getDamager(), entity) && loc.distanceSquared(entity.getLocation()) < 2 && !hit.contains(entity.getEntityId())) { + hit.add(entity.getEntityId()); + new AttackMetadata(new DamageMetadata(damage, DamageType.SKILL, DamageType.MAGIC), attack.getStats()).damage((LivingEntity) entity); + ((LivingEntity) entity).addPotionEffect(new PotionEffect(PotionEffectType.SLOW, (int) (slowDuration * 20), (int) slowAmplifier)); + } + } + }.runTaskTimer(MMOItems.plugin, 0, 1); + } +} diff --git a/src/main/java/net/Indyuce/mmoitems/ability/list/misc/Earthquake.java b/src/main/java/net/Indyuce/mmoitems/ability/list/misc/Earthquake.java new file mode 100644 index 00000000..0758168c --- /dev/null +++ b/src/main/java/net/Indyuce/mmoitems/ability/list/misc/Earthquake.java @@ -0,0 +1,72 @@ +package net.Indyuce.mmoitems.ability.list.misc; + +import io.lumine.mythic.lib.damage.AttackMetadata; +import io.lumine.mythic.lib.damage.DamageMetadata; +import io.lumine.mythic.lib.damage.DamageType; +import net.Indyuce.mmoitems.MMOItems; +import net.Indyuce.mmoitems.MMOUtils; +import net.Indyuce.mmoitems.ability.Ability; +import net.Indyuce.mmoitems.ability.metadata.VectorAbilityMetadata; +import net.Indyuce.mmoitems.api.ItemAttackMetadata; +import net.Indyuce.mmoitems.stat.data.AbilityData; +import org.bukkit.Location; +import org.bukkit.Particle; +import org.bukkit.Sound; +import org.bukkit.entity.Entity; +import org.bukkit.entity.LivingEntity; +import org.bukkit.potion.PotionEffect; +import org.bukkit.potion.PotionEffectType; +import org.bukkit.scheduler.BukkitRunnable; +import org.bukkit.util.Vector; + +import java.util.ArrayList; +import java.util.List; + +public class Earthquake extends Ability { + public Earthquake() { + super(CastingMode.ON_HIT, CastingMode.WHEN_HIT, CastingMode.LEFT_CLICK, CastingMode.RIGHT_CLICK, CastingMode.SHIFT_LEFT_CLICK, CastingMode.SHIFT_RIGHT_CLICK); + + addModifier("damage", 3); + addModifier("duration", 2); + addModifier("amplifier", 1); + addModifier("cooldown", 10); + addModifier("mana", 0); + addModifier("stamina", 0); + } + + @Override + public VectorAbilityMetadata canBeCast(ItemAttackMetadata attack, LivingEntity target, AbilityData ability) { + return attack.getDamager().isOnGround() ? new VectorAbilityMetadata(ability, attack.getDamager(), target) : null; + } + + @Override + public void whenCast(ItemAttackMetadata attack, VectorAbilityMetadata ability) { + double damage = ability.getModifier("damage"); + double slowDuration = ability.getModifier("duration"); + double slowAmplifier = ability.getModifier("amplifier"); + + new BukkitRunnable() { + final Vector vec = ability.getTarget().setY(0); + final Location loc = attack.getDamager().getLocation(); + final List hit = new ArrayList<>(); + int ti = 0; + + public void run() { + ti++; + if (ti > 20) + cancel(); + + loc.add(vec); + loc.getWorld().spawnParticle(Particle.CLOUD, loc, 5, .5, 0, .5, 0); + loc.getWorld().playSound(loc, Sound.BLOCK_GRAVEL_BREAK, 2, 1); + + for (Entity entity : MMOUtils.getNearbyChunkEntities(loc)) + if (MMOUtils.canDamage(attack.getDamager(), entity) && loc.distanceSquared(entity.getLocation()) < 2 && !hit.contains(entity.getEntityId())) { + hit.add(entity.getEntityId()); + new AttackMetadata(new DamageMetadata(damage, DamageType.SKILL, DamageType.MAGIC), attack.getStats()).damage((LivingEntity) entity); + ((LivingEntity) entity).addPotionEffect(new PotionEffect(PotionEffectType.SLOW, (int) (slowDuration * 20), (int) slowAmplifier)); + } + } + }.runTaskTimer(MMOItems.plugin, 0, 1); + } +} diff --git a/src/main/java/net/Indyuce/mmoitems/ability/list/misc/Hoearthquake.java b/src/main/java/net/Indyuce/mmoitems/ability/list/misc/Hoearthquake.java new file mode 100644 index 00000000..d6ddd2f9 --- /dev/null +++ b/src/main/java/net/Indyuce/mmoitems/ability/list/misc/Hoearthquake.java @@ -0,0 +1,57 @@ +package net.Indyuce.mmoitems.ability.list.misc; + +import net.Indyuce.mmoitems.MMOItems; +import net.Indyuce.mmoitems.ability.Ability; +import net.Indyuce.mmoitems.ability.metadata.SimpleAbilityMetadata; +import net.Indyuce.mmoitems.api.ItemAttackMetadata; +import net.Indyuce.mmoitems.stat.data.AbilityData; +import org.bukkit.*; +import org.bukkit.block.Block; +import org.bukkit.entity.LivingEntity; +import org.bukkit.event.block.BlockBreakEvent; +import org.bukkit.scheduler.BukkitRunnable; +import org.bukkit.util.Vector; + +public class Hoearthquake extends Ability { + public Hoearthquake() { + super(CastingMode.ON_HIT, CastingMode.WHEN_HIT, CastingMode.LEFT_CLICK, CastingMode.RIGHT_CLICK, CastingMode.SHIFT_LEFT_CLICK, CastingMode.SHIFT_RIGHT_CLICK); + + addModifier("cooldown", 10); + addModifier("mana", 0); + addModifier("stamina", 0); + } + + @Override + public SimpleAbilityMetadata canBeCast(ItemAttackMetadata attack, LivingEntity target, AbilityData ability) { + return attack.getDamager().isOnGround() ? new SimpleAbilityMetadata(ability) : null; + } + + @Override + public void whenCast(ItemAttackMetadata attack, SimpleAbilityMetadata ability) { + new BukkitRunnable() { + final Vector vec = attack.getDamager().getEyeLocation().getDirection().setY(0); + final Location loc = attack.getDamager().getLocation(); + int ti = 0; + + public void run() { + if (ti++ > 20) + cancel(); + + loc.add(vec); + loc.getWorld().playSound(loc, Sound.BLOCK_GRAVEL_BREAK, 2, 1); + loc.getWorld().spawnParticle(Particle.CLOUD, loc, 1, .5, 0, .5, 0); + + for (int x = -1; x < 2; x++) + for (int z = -1; z < 2; z++) { + Block b = loc.clone().add(x, -1, z).getBlock(); + if (b.getType() == Material.GRASS || b.getType() == Material.DIRT) { + BlockBreakEvent event = new BlockBreakEvent(b, attack.getDamager()); + event.setDropItems(false); + Bukkit.getPluginManager().callEvent(event); + if (!event.isCancelled()) b.setType(Material.FARMLAND); + } + } + } + }.runTaskTimer(MMOItems.plugin, 0, 1); + } +} diff --git a/src/main/java/net/Indyuce/mmoitems/ability/list/misc/Item_Bomb.java b/src/main/java/net/Indyuce/mmoitems/ability/list/misc/Item_Bomb.java new file mode 100644 index 00000000..a0d64bfe --- /dev/null +++ b/src/main/java/net/Indyuce/mmoitems/ability/list/misc/Item_Bomb.java @@ -0,0 +1,75 @@ +package net.Indyuce.mmoitems.ability.list.misc; + +import io.lumine.mythic.lib.damage.AttackMetadata; +import io.lumine.mythic.lib.damage.DamageMetadata; +import io.lumine.mythic.lib.damage.DamageType; +import io.lumine.mythic.lib.version.VersionSound; +import net.Indyuce.mmoitems.MMOItems; +import net.Indyuce.mmoitems.MMOUtils; +import net.Indyuce.mmoitems.ability.ItemAbility; +import net.Indyuce.mmoitems.ability.metadata.ItemAbilityMetadata; +import net.Indyuce.mmoitems.api.ItemAttackMetadata; +import net.Indyuce.mmoitems.api.util.NoClipItem; +import org.bukkit.Particle; +import org.bukkit.Sound; +import org.bukkit.entity.Entity; +import org.bukkit.entity.LivingEntity; +import org.bukkit.event.Listener; +import org.bukkit.inventory.ItemStack; +import org.bukkit.potion.PotionEffect; +import org.bukkit.potion.PotionEffectType; +import org.bukkit.scheduler.BukkitRunnable; + +public class Item_Bomb extends ItemAbility implements Listener { + public Item_Bomb() { + super(CastingMode.ON_HIT, CastingMode.WHEN_HIT, CastingMode.LEFT_CLICK, CastingMode.RIGHT_CLICK, CastingMode.SHIFT_LEFT_CLICK, CastingMode.SHIFT_RIGHT_CLICK); + + addModifier("damage", 7); + addModifier("radius", 6); + addModifier("slow-duration", 4); + addModifier("slow-amplifier", 1); + addModifier("cooldown", 15); + addModifier("mana", 0); + addModifier("stamina", 0); + } + + @Override + public void whenCast(ItemAttackMetadata attack, ItemAbilityMetadata ability) { + ItemStack itemStack = ability.getItem(); + final NoClipItem item = new NoClipItem(attack.getDamager().getLocation().add(0, 1.2, 0), itemStack); + item.getEntity().setVelocity(ability.getTarget().multiply(1.3)); + attack.getDamager().getWorld().playSound(attack.getDamager().getLocation(), Sound.ENTITY_SNOWBALL_THROW, 2, 0); + + new BukkitRunnable() { + int j = 0; + + public void run() { + if (j++ > 40) { + double radius = ability.getModifier("radius"); + double damage = ability.getModifier("damage"); + double slowDuration = ability.getModifier("slow-duration"); + double slowAmplifier = ability.getModifier("slow-amplifier"); + + for (Entity entity : item.getEntity().getNearbyEntities(radius, radius, radius)) + if (MMOUtils.canDamage(attack.getDamager(), entity)) { + new AttackMetadata(new DamageMetadata(damage, DamageType.SKILL, DamageType.PHYSICAL), attack.getStats()).damage((LivingEntity) entity); + ((LivingEntity) entity).removePotionEffect(PotionEffectType.SLOW); + ((LivingEntity) entity).addPotionEffect(new PotionEffect(PotionEffectType.SLOW, (int) (slowDuration * 20), (int) slowAmplifier)); + } + + item.getEntity().getWorld().spawnParticle(Particle.EXPLOSION_LARGE, item.getEntity().getLocation(), 24, 2, 2, 2, 0); + item.getEntity().getWorld().spawnParticle(Particle.EXPLOSION_NORMAL, item.getEntity().getLocation(), 48, 0, 0, 0, .2); + item.getEntity().getWorld().playSound(item.getEntity().getLocation(), Sound.ENTITY_GENERIC_EXPLODE, 3, 0); + + item.close(); + cancel(); + return; + } + + item.getEntity().getWorld().spawnParticle(Particle.SMOKE_LARGE, item.getEntity().getLocation().add(0, .2, 0), 0); + item.getEntity().getWorld().spawnParticle(Particle.FIREWORKS_SPARK, item.getEntity().getLocation().add(0, .2, 0), 1, 0, 0, 0, .1); + item.getEntity().getWorld().playSound(item.getEntity().getLocation(), VersionSound.BLOCK_NOTE_BLOCK_HAT.toSound(), 2, (float) (.5 + (j / 40. * 1.5))); + } + }.runTaskTimer(MMOItems.plugin, 0, 1); + } +} diff --git a/src/main/java/net/Indyuce/mmoitems/ability/list/misc/Item_Throw.java b/src/main/java/net/Indyuce/mmoitems/ability/list/misc/Item_Throw.java new file mode 100644 index 00000000..72077335 --- /dev/null +++ b/src/main/java/net/Indyuce/mmoitems/ability/list/misc/Item_Throw.java @@ -0,0 +1,73 @@ +package net.Indyuce.mmoitems.ability.list.misc; + +import io.lumine.mythic.lib.damage.AttackMetadata; +import io.lumine.mythic.lib.damage.DamageMetadata; +import io.lumine.mythic.lib.damage.DamageType; +import net.Indyuce.mmoitems.MMOItems; +import net.Indyuce.mmoitems.MMOUtils; +import net.Indyuce.mmoitems.ability.ItemAbility; +import net.Indyuce.mmoitems.ability.metadata.ItemAbilityMetadata; +import net.Indyuce.mmoitems.api.ItemAttackMetadata; +import net.Indyuce.mmoitems.api.util.NoClipItem; +import org.bukkit.Particle; +import org.bukkit.Sound; +import org.bukkit.entity.Entity; +import org.bukkit.entity.LivingEntity; +import org.bukkit.event.Listener; +import org.bukkit.inventory.ItemStack; +import org.bukkit.scheduler.BukkitRunnable; + +public class Item_Throw extends ItemAbility implements Listener { + public Item_Throw() { + super(CastingMode.ON_HIT, CastingMode.WHEN_HIT, CastingMode.LEFT_CLICK, CastingMode.RIGHT_CLICK, CastingMode.SHIFT_LEFT_CLICK, CastingMode.SHIFT_RIGHT_CLICK); + + addModifier("damage", 6); + addModifier("force", 1); + addModifier("cooldown", 10); + addModifier("mana", 0); + addModifier("stamina", 0); + } + + @Override + public void whenCast(ItemAttackMetadata attack, ItemAbilityMetadata ability) { + ItemStack itemStack = ability.getItem(); + /*boolean hasAbility = false; + + for (JsonElement entry : MythicLib.plugin.getJson().parse(nbtItem.getString("MMOITEMS_ABILITY"), JsonArray.class)) { + if (!entry.isJsonObject()) + continue; + + JsonObject object = entry.getAsJsonObject(); + if (object.get("Id").getAsString().equalsIgnoreCase(getID())) { + hasAbility = true; + break; + } + } + + if (!hasAbility) + return;*/ + + final NoClipItem item = new NoClipItem(attack.getDamager().getLocation().add(0, 1.2, 0), itemStack); + item.getEntity().setVelocity(ability.getTarget().multiply(1.5 * ability.getModifier("force"))); + attack.getDamager().getWorld().playSound(attack.getDamager().getLocation(), Sound.ENTITY_SNOWBALL_THROW, 1, 0); + new BukkitRunnable() { + double ti = 0; + + public void run() { + ti++; + if (ti > 20 || item.getEntity().isDead()) { + item.close(); + cancel(); + } + + item.getEntity().getWorld().spawnParticle(Particle.CRIT, item.getEntity().getLocation(), 0); + for (Entity target : item.getEntity().getNearbyEntities(1, 1, 1)) + if (MMOUtils.canDamage(attack.getDamager(), target)) { + new AttackMetadata(new DamageMetadata(ability.getModifier("damage"), DamageType.SKILL, DamageType.PHYSICAL, DamageType.PROJECTILE), attack.getStats()).damage((LivingEntity) target); + item.close(); + cancel(); + } + } + }.runTaskTimer(MMOItems.plugin, 0, 1); + } +} diff --git a/src/main/java/net/Indyuce/mmoitems/ability/list/misc/Leap.java b/src/main/java/net/Indyuce/mmoitems/ability/list/misc/Leap.java new file mode 100644 index 00000000..ca40cc1a --- /dev/null +++ b/src/main/java/net/Indyuce/mmoitems/ability/list/misc/Leap.java @@ -0,0 +1,48 @@ +package net.Indyuce.mmoitems.ability.list.misc; + +import io.lumine.mythic.lib.version.VersionSound; +import net.Indyuce.mmoitems.MMOItems; +import net.Indyuce.mmoitems.ability.SimpleAbility; +import net.Indyuce.mmoitems.ability.metadata.SimpleAbilityMetadata; +import net.Indyuce.mmoitems.api.ItemAttackMetadata; +import net.Indyuce.mmoitems.stat.data.AbilityData; +import org.bukkit.Particle; +import org.bukkit.entity.LivingEntity; +import org.bukkit.scheduler.BukkitRunnable; +import org.bukkit.util.Vector; + +public class Leap extends SimpleAbility { + public Leap() { + super(CastingMode.ON_HIT, CastingMode.WHEN_HIT, CastingMode.LEFT_CLICK, CastingMode.RIGHT_CLICK, CastingMode.SHIFT_LEFT_CLICK, CastingMode.SHIFT_RIGHT_CLICK); + + addModifier("force", 1); + addModifier("cooldown", 10); + addModifier("mana", 0); + addModifier("stamina", 0); + } + + @Override + public SimpleAbilityMetadata canBeCast(ItemAttackMetadata attack, LivingEntity target, AbilityData ability) { + return attack.getDamager().isOnGround() ? new SimpleAbilityMetadata(ability) : null; + } + + @Override + public void whenCast(ItemAttackMetadata attack, SimpleAbilityMetadata ability) { + attack.getDamager().getWorld().playSound(attack.getDamager().getLocation(), VersionSound.ENTITY_ENDER_DRAGON_FLAP.toSound(), 1, 0); + attack.getDamager().getWorld().spawnParticle(Particle.EXPLOSION_NORMAL, attack.getDamager().getLocation(), 16, 0, 0, 0.1); + Vector vec = attack.getDamager().getEyeLocation().getDirection().multiply(2 * ability.getModifier("force")); + vec.setY(vec.getY() / 2); + attack.getDamager().setVelocity(vec); + new BukkitRunnable() { + double ti = 0; + + public void run() { + ti++; + if (ti > 20) + cancel(); + + attack.getDamager().getWorld().spawnParticle(Particle.CLOUD, attack.getDamager().getLocation().add(0, 1, 0), 0); + } + }.runTaskTimer(MMOItems.plugin, 0, 1); + } +} diff --git a/src/main/java/net/Indyuce/mmoitems/ability/list/misc/Regen_Ally.java b/src/main/java/net/Indyuce/mmoitems/ability/list/misc/Regen_Ally.java new file mode 100644 index 00000000..c21acffd --- /dev/null +++ b/src/main/java/net/Indyuce/mmoitems/ability/list/misc/Regen_Ally.java @@ -0,0 +1,47 @@ +package net.Indyuce.mmoitems.ability.list.misc; + +import net.Indyuce.mmoitems.MMOItems; +import net.Indyuce.mmoitems.MMOUtils; +import net.Indyuce.mmoitems.ability.FriendlyTargetAbility; +import net.Indyuce.mmoitems.ability.metadata.FriendlyTargetAbilityMetadata; +import net.Indyuce.mmoitems.api.ItemAttackMetadata; +import org.bukkit.Particle; +import org.bukkit.entity.LivingEntity; +import org.bukkit.scheduler.BukkitRunnable; + +public class Regen_Ally extends FriendlyTargetAbility { + public Regen_Ally() { + super(CastingMode.ON_HIT, CastingMode.WHEN_HIT, CastingMode.LEFT_CLICK, CastingMode.RIGHT_CLICK, CastingMode.SHIFT_LEFT_CLICK, CastingMode.SHIFT_RIGHT_CLICK); + + addModifier("heal", 7); + addModifier("duration", 3); + addModifier("cooldown", 10); + addModifier("mana", 0); + addModifier("stamina", 0); + } + + @Override + public void whenCast(ItemAttackMetadata attack, FriendlyTargetAbilityMetadata ability) { + LivingEntity target = ability.getTarget(); + + new BukkitRunnable() { + final double duration = Math.min(ability.getModifier("duration"), 60) * 20; + final double hps = ability.getModifier("heal") / duration * 4; + double ti = 0; + double a = 0; + + public void run() { + if (ti++ > duration || target.isDead()) { + cancel(); + return; + } + + a += Math.PI / 16; + target.getWorld().spawnParticle(Particle.HEART, target.getLocation().add(1.3 * Math.cos(a), .3, 1.3 * Math.sin(a)), 0); + + if (ti % 4 == 0) + MMOUtils.heal(target, hps); + } + }.runTaskTimer(MMOItems.plugin, 0, 1); + } +} diff --git a/src/main/java/net/Indyuce/mmoitems/ability/list/simple/Blink.java b/src/main/java/net/Indyuce/mmoitems/ability/list/simple/Blink.java new file mode 100644 index 00000000..41b1c56c --- /dev/null +++ b/src/main/java/net/Indyuce/mmoitems/ability/list/simple/Blink.java @@ -0,0 +1,32 @@ +package net.Indyuce.mmoitems.ability.list.simple; + +import io.lumine.mythic.lib.version.VersionSound; +import net.Indyuce.mmoitems.ability.SimpleAbility; +import net.Indyuce.mmoitems.ability.metadata.SimpleAbilityMetadata; +import net.Indyuce.mmoitems.api.ItemAttackMetadata; +import org.bukkit.Location; +import org.bukkit.Particle; + +public class Blink extends SimpleAbility { + public Blink() { + super(CastingMode.ON_HIT, CastingMode.WHEN_HIT, CastingMode.LEFT_CLICK, CastingMode.RIGHT_CLICK, CastingMode.SHIFT_LEFT_CLICK, CastingMode.SHIFT_RIGHT_CLICK); + + addModifier("range", 8); + addModifier("cooldown", 10); + addModifier("mana", 0); + addModifier("stamina", 0); + } + + @Override + public void whenCast(ItemAttackMetadata attack, SimpleAbilityMetadata ability) { + attack.getDamager().getWorld().spawnParticle(Particle.EXPLOSION_LARGE, attack.getDamager().getLocation().add(0, 1, 0), 0); + attack.getDamager().getWorld().spawnParticle(Particle.SPELL_INSTANT, attack.getDamager().getLocation().add(0, 1, 0), 32, 0, 0, 0, .1); + attack.getDamager().getWorld().playSound(attack.getDamager().getLocation(), VersionSound.ENTITY_ENDERMAN_TELEPORT.toSound(), 1, 1); + Location loc = attack.getDamager().getTargetBlock(null, (int) ability.getModifier("range")).getLocation().add(0, 1, 0); + loc.setYaw(attack.getDamager().getLocation().getYaw()); + loc.setPitch(attack.getDamager().getLocation().getPitch()); + attack.getDamager().teleport(loc); + attack.getDamager().getWorld().spawnParticle(Particle.EXPLOSION_LARGE, attack.getDamager().getLocation().add(0, 1, 0), 0); + attack.getDamager().getWorld().spawnParticle(Particle.SPELL_INSTANT, attack.getDamager().getLocation().add(0, 1, 0), 32, 0, 0, 0, .1); + } +} diff --git a/src/main/java/net/Indyuce/mmoitems/ability/list/simple/Blizzard.java b/src/main/java/net/Indyuce/mmoitems/ability/list/simple/Blizzard.java new file mode 100644 index 00000000..f5ab4d20 --- /dev/null +++ b/src/main/java/net/Indyuce/mmoitems/ability/list/simple/Blizzard.java @@ -0,0 +1,79 @@ +package net.Indyuce.mmoitems.ability.list.simple; + +import net.Indyuce.mmoitems.MMOItems; +import net.Indyuce.mmoitems.ability.SimpleAbility; +import net.Indyuce.mmoitems.ability.metadata.SimpleAbilityMetadata; +import net.Indyuce.mmoitems.api.ItemAttackMetadata; +import net.Indyuce.mmoitems.api.util.TemporaryListener; +import org.bukkit.Location; +import org.bukkit.Sound; +import org.bukkit.entity.Snowball; +import org.bukkit.event.EventHandler; +import org.bukkit.event.EventPriority; +import org.bukkit.event.entity.EntityDamageByEntityEvent; +import org.bukkit.scheduler.BukkitRunnable; + +import java.util.ArrayList; +import java.util.List; +import java.util.UUID; + +public class Blizzard extends SimpleAbility { + public Blizzard() { + super(CastingMode.ON_HIT, CastingMode.WHEN_HIT, CastingMode.LEFT_CLICK, CastingMode.RIGHT_CLICK, CastingMode.SHIFT_LEFT_CLICK, + CastingMode.SHIFT_RIGHT_CLICK); + + addModifier("duration", 2.5); + addModifier("damage", 2); + addModifier("inaccuracy", 10); + addModifier("force", 1); + addModifier("cooldown", 10); + addModifier("mana", 0); + addModifier("stamina", 0); + } + + @Override + public void whenCast(ItemAttackMetadata attack, SimpleAbilityMetadata ability) { + double duration = ability.getModifier("duration") * 10; + double force = ability.getModifier("force"); + double inaccuracy = ability.getModifier("inaccuracy"); + + new BukkitRunnable() { + final SnowballThrower handler = new SnowballThrower(ability.getModifier("damage")); + int j = 0; + + public void run() { + if (j++ > duration) { + handler.close(5 * 20); + cancel(); + return; + } + + Location loc = attack.getDamager().getEyeLocation(); + loc.setPitch((float) (loc.getPitch() + (random.nextDouble() - .5) * inaccuracy)); + loc.setYaw((float) (loc.getYaw() + (random.nextDouble() - .5) * inaccuracy)); + + loc.getWorld().playSound(loc, Sound.ENTITY_SNOWBALL_THROW, 1, 1); + Snowball snowball = attack.getDamager().launchProjectile(Snowball.class); + snowball.setVelocity(loc.getDirection().multiply(1.3 * force)); + handler.entities.add(snowball.getUniqueId()); + } + }.runTaskTimer(MMOItems.plugin, 0, 2); + } + + public static class SnowballThrower extends TemporaryListener { + private final List entities = new ArrayList<>(); + private final double damage; + + public SnowballThrower(double damage) { + super(EntityDamageByEntityEvent.getHandlerList()); + + this.damage = damage; + } + + @EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true) + public void a(EntityDamageByEntityEvent event) { + if (entities.contains(event.getDamager().getUniqueId())) + event.setDamage(damage); + } + } +} diff --git a/src/main/java/net/Indyuce/mmoitems/ability/list/simple/Bunny_Mode.java b/src/main/java/net/Indyuce/mmoitems/ability/list/simple/Bunny_Mode.java new file mode 100644 index 00000000..619950c1 --- /dev/null +++ b/src/main/java/net/Indyuce/mmoitems/ability/list/simple/Bunny_Mode.java @@ -0,0 +1,78 @@ +package net.Indyuce.mmoitems.ability.list.simple; + +import io.lumine.mythic.lib.version.VersionSound; +import net.Indyuce.mmoitems.MMOItems; +import net.Indyuce.mmoitems.ability.SimpleAbility; +import net.Indyuce.mmoitems.ability.metadata.SimpleAbilityMetadata; +import net.Indyuce.mmoitems.api.ItemAttackMetadata; +import net.Indyuce.mmoitems.api.util.TemporaryListener; +import org.bukkit.Bukkit; +import org.bukkit.Particle; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.EventPriority; +import org.bukkit.event.entity.EntityDamageEvent; +import org.bukkit.event.entity.EntityDamageEvent.DamageCause; +import org.bukkit.scheduler.BukkitRunnable; + +public class Bunny_Mode extends SimpleAbility { + public Bunny_Mode() { + super(CastingMode.ON_HIT, CastingMode.WHEN_HIT, CastingMode.LEFT_CLICK, CastingMode.RIGHT_CLICK, CastingMode.SHIFT_LEFT_CLICK, + CastingMode.SHIFT_RIGHT_CLICK); + + addModifier("duration", 20); + addModifier("jump-force", 1); + addModifier("cooldown", 50); + addModifier("speed", 1); + addModifier("mana", 0); + addModifier("stamina", 0); + } + + @Override + public void whenCast(ItemAttackMetadata attack, SimpleAbilityMetadata ability) { + double duration = ability.getModifier("duration") * 20; + double y = ability.getModifier("jump-force"); + double xz = ability.getModifier("speed"); + + new BukkitRunnable() { + final BunnyHandler handler = new BunnyHandler(attack.getDamager(), duration); + int j = 0; + + public void run() { + if (j++ > duration) { + handler.close(3 * 20); + cancel(); + return; + } + + if (attack.getDamager().getLocation().add(0, -.5, 0).getBlock().getType().isSolid()) { + attack.getDamager() + .setVelocity(attack.getDamager().getEyeLocation().getDirection().setY(0).normalize().multiply(.8 * xz).setY(0.5 * y / xz)); + attack.getDamager().getWorld().playSound(attack.getDamager().getLocation(), VersionSound.ENTITY_ENDER_DRAGON_FLAP.toSound(), 2, 1); + for (double a = 0; a < Math.PI * 2; a += Math.PI / 12) + attack.getDamager().getWorld().spawnParticle(Particle.CLOUD, attack.getDamager().getLocation(), 0, Math.cos(a), 0, Math.sin(a), + .2); + } + } + }.runTaskTimer(MMOItems.plugin, 0, 1); + + } + + public static class BunnyHandler extends TemporaryListener { + private final Player player; + + public BunnyHandler(Player player, double duration) { + super(EntityDamageEvent.getHandlerList()); + + this.player = player; + + Bukkit.getScheduler().runTaskLater(MMOItems.plugin, (Runnable) this::close, (long) (duration * 20)); + } + + @EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true) + public void a(EntityDamageEvent event) { + if (event.getEntity().equals(player) && event.getCause() == DamageCause.FALL) + event.setCancelled(true); + } + } +} diff --git a/src/main/java/net/Indyuce/mmoitems/ability/list/simple/Burning_Hands.java b/src/main/java/net/Indyuce/mmoitems/ability/list/simple/Burning_Hands.java new file mode 100644 index 00000000..8b34d8d3 --- /dev/null +++ b/src/main/java/net/Indyuce/mmoitems/ability/list/simple/Burning_Hands.java @@ -0,0 +1,66 @@ +package net.Indyuce.mmoitems.ability.list.simple; + +import io.lumine.mythic.lib.damage.AttackMetadata; +import io.lumine.mythic.lib.damage.DamageMetadata; +import io.lumine.mythic.lib.damage.DamageType; +import net.Indyuce.mmoitems.MMOItems; +import net.Indyuce.mmoitems.MMOUtils; +import net.Indyuce.mmoitems.ability.SimpleAbility; +import net.Indyuce.mmoitems.ability.metadata.SimpleAbilityMetadata; +import net.Indyuce.mmoitems.api.ItemAttackMetadata; +import org.bukkit.Location; +import org.bukkit.Particle; +import org.bukkit.Sound; +import org.bukkit.entity.Entity; +import org.bukkit.entity.LivingEntity; +import org.bukkit.scheduler.BukkitRunnable; +import org.bukkit.util.Vector; + +public class Burning_Hands extends SimpleAbility { + public Burning_Hands() { + super(CastingMode.ON_HIT, CastingMode.WHEN_HIT, CastingMode.LEFT_CLICK, CastingMode.RIGHT_CLICK, CastingMode.SHIFT_LEFT_CLICK, + CastingMode.SHIFT_RIGHT_CLICK); + + addModifier("duration", 3); + addModifier("damage", 2); + addModifier("cooldown", 10); + addModifier("mana", 0); + addModifier("stamina", 0); + } + + @Override + public void whenCast(ItemAttackMetadata attack, SimpleAbilityMetadata ability) { + double duration = ability.getModifier("duration") * 10; + double damage = ability.getModifier("damage") / 2; + + new BukkitRunnable() { + int j = 0; + + public void run() { + if (j++ > duration) + cancel(); + + Location loc = attack.getDamager().getLocation().add(0, 1.2, 0); + loc.getWorld().playSound(loc, Sound.BLOCK_FIRE_AMBIENT, 1, 1); + + for (double m = -45; m < 45; m += 5) { + double a = (m + attack.getDamager().getEyeLocation().getYaw() + 90) * Math.PI / 180; + Vector vec = new Vector(Math.cos(a), (random.nextDouble() - .5) * .2, Math.sin(a)); + Location source = loc.clone().add(vec.clone().setY(0)); + source.getWorld().spawnParticle(Particle.FLAME, source, 0, vec.getX(), vec.getY(), vec.getZ(), .5); + if (j % 2 == 0) + source.getWorld().spawnParticle(Particle.SMOKE_NORMAL, source, 0, vec.getX(), vec.getY(), vec.getZ(), .5); + } + + if (j % 5 == 0) + for (Entity entity : MMOUtils.getNearbyChunkEntities(loc)) + if (entity.getLocation().distanceSquared(loc) < 60 + && attack.getDamager().getEyeLocation().getDirection() + .angle(entity.getLocation().toVector().subtract(attack.getDamager().getLocation().toVector())) < Math.PI / 6 + && MMOUtils.canDamage(attack.getDamager(), entity)) + new AttackMetadata(new DamageMetadata(damage, DamageType.SKILL, DamageType.MAGIC), attack.getStats()).damage((LivingEntity) entity); + + } + }.runTaskTimer(MMOItems.plugin, 0, 2); + } +} diff --git a/src/main/java/net/Indyuce/mmoitems/ability/list/simple/Chicken_Wraith.java b/src/main/java/net/Indyuce/mmoitems/ability/list/simple/Chicken_Wraith.java new file mode 100644 index 00000000..d2abadce --- /dev/null +++ b/src/main/java/net/Indyuce/mmoitems/ability/list/simple/Chicken_Wraith.java @@ -0,0 +1,87 @@ +package net.Indyuce.mmoitems.ability.list.simple; + +import net.Indyuce.mmoitems.MMOItems; +import net.Indyuce.mmoitems.ability.SimpleAbility; +import net.Indyuce.mmoitems.ability.metadata.SimpleAbilityMetadata; +import net.Indyuce.mmoitems.api.ItemAttackMetadata; +import net.Indyuce.mmoitems.api.util.TemporaryListener; +import org.bukkit.Location; +import org.bukkit.Sound; +import org.bukkit.entity.Egg; +import org.bukkit.event.EventHandler; +import org.bukkit.event.EventPriority; +import org.bukkit.event.entity.EntityDamageByEntityEvent; +import org.bukkit.event.player.PlayerEggThrowEvent; +import org.bukkit.scheduler.BukkitRunnable; + +import java.util.ArrayList; +import java.util.List; + +public class Chicken_Wraith extends SimpleAbility { + public Chicken_Wraith() { + super(CastingMode.ON_HIT, CastingMode.WHEN_HIT, CastingMode.LEFT_CLICK, CastingMode.RIGHT_CLICK, CastingMode.SHIFT_LEFT_CLICK, + CastingMode.SHIFT_RIGHT_CLICK); + + addModifier("duration", 2.5); + addModifier("damage", 2); + addModifier("inaccuracy", 10); + addModifier("force", 1); + addModifier("cooldown", 10); + addModifier("mana", 0); + addModifier("stamina", 0); + } + + @Override + public void whenCast(ItemAttackMetadata attack, SimpleAbilityMetadata ability) { + double duration = ability.getModifier("duration") * 10; + double force = ability.getModifier("force"); + double inaccuracy = ability.getModifier("inaccuracy"); + + new BukkitRunnable() { + final EggHandler handler = new EggHandler(ability.getModifier("damage")); + int j = 0; + + public void run() { + if (j++ > duration) { + handler.close(5 * 20); + cancel(); + return; + } + + Location loc = attack.getDamager().getEyeLocation(); + loc.setPitch((float) (loc.getPitch() + (random.nextDouble() - .5) * inaccuracy)); + loc.setYaw((float) (loc.getYaw() + (random.nextDouble() - .5) * inaccuracy)); + + loc.getWorld().playSound(loc, Sound.ENTITY_CHICKEN_EGG, 1, 1); + Egg egg = attack.getDamager().launchProjectile(Egg.class); + egg.setVelocity(loc.getDirection().multiply(1.3 * force)); + + handler.entities.add(egg.getEntityId()); + } + }.runTaskTimer(MMOItems.plugin, 0, 2); + } + + public static class EggHandler extends TemporaryListener { + private final List entities = new ArrayList<>(); + private final double damage; + + public EggHandler(double damage) { + super(EntityDamageByEntityEvent.getHandlerList()); + + this.damage = damage; + } + + @EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true) + public void a(PlayerEggThrowEvent event) { + if (entities.contains(event.getEgg().getEntityId())) { + event.setHatching(false); + } + } + + @EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true) + public void b(EntityDamageByEntityEvent event) { + if (entities.contains(event.getDamager().getEntityId())) + event.setDamage(damage); + } + } +} diff --git a/src/main/java/net/Indyuce/mmoitems/ability/list/simple/Circular_Slash.java b/src/main/java/net/Indyuce/mmoitems/ability/list/simple/Circular_Slash.java new file mode 100644 index 00000000..a112b980 --- /dev/null +++ b/src/main/java/net/Indyuce/mmoitems/ability/list/simple/Circular_Slash.java @@ -0,0 +1,57 @@ +package net.Indyuce.mmoitems.ability.list.simple; + +import io.lumine.mythic.lib.damage.AttackMetadata; +import io.lumine.mythic.lib.damage.DamageMetadata; +import io.lumine.mythic.lib.damage.DamageType; +import net.Indyuce.mmoitems.MMOUtils; +import net.Indyuce.mmoitems.ability.SimpleAbility; +import net.Indyuce.mmoitems.ability.metadata.SimpleAbilityMetadata; +import net.Indyuce.mmoitems.api.ItemAttackMetadata; +import org.bukkit.Location; +import org.bukkit.Particle; +import org.bukkit.Sound; +import org.bukkit.entity.Entity; +import org.bukkit.entity.LivingEntity; +import org.bukkit.potion.PotionEffect; +import org.bukkit.potion.PotionEffectType; +import org.bukkit.util.Vector; + +public class Circular_Slash extends SimpleAbility { + public Circular_Slash() { + super(CastingMode.ON_HIT, CastingMode.WHEN_HIT, CastingMode.LEFT_CLICK, CastingMode.RIGHT_CLICK, CastingMode.SHIFT_LEFT_CLICK, CastingMode.SHIFT_RIGHT_CLICK); + + addModifier("damage", 6); + addModifier("radius", 3); + addModifier("knockback", 1); + addModifier("cooldown", 10); + addModifier("mana", 0); + addModifier("stamina", 0); + } + + @Override + public void whenCast(ItemAttackMetadata attack, SimpleAbilityMetadata ability) { + double damage = ability.getModifier("damage"); + double radius = ability.getModifier("radius"); + double knockback = ability.getModifier("knockback"); + + attack.getDamager().getWorld().playSound(attack.getDamager().getLocation(), Sound.ENTITY_ZOMBIE_ATTACK_IRON_DOOR, 2, .5f); + attack.getDamager().addPotionEffect(new PotionEffect(PotionEffectType.SLOW, 2, 254)); + for (Entity entity : attack.getDamager().getNearbyEntities(radius, radius, radius)) { + if (MMOUtils.canDamage(attack.getDamager(), entity)) { + new AttackMetadata(new DamageMetadata(damage, DamageType.SKILL, DamageType.PHYSICAL), attack.getStats()).damage((LivingEntity) entity); + Vector v1 = entity.getLocation().toVector(); + Vector v2 = attack.getDamager().getLocation().toVector(); + double y = .5; + Vector v3 = v1.subtract(v2).multiply(.5 * knockback).setY(knockback == 0 ? 0 : y); + entity.setVelocity(v3); + } + } + double step = 12 + (radius * 2.5); + for (double j = 0; j < Math.PI * 2; j += Math.PI / step) { + Location loc = attack.getDamager().getLocation().clone(); + loc.add(Math.cos(j) * radius, .75, Math.sin(j) * radius); + loc.getWorld().spawnParticle(Particle.SMOKE_LARGE, loc, 0); + } + attack.getDamager().getWorld().spawnParticle(Particle.EXPLOSION_LARGE, attack.getDamager().getLocation().add(0, 1, 0), 0); + } +} diff --git a/src/main/java/net/Indyuce/mmoitems/ability/list/simple/Firefly.java b/src/main/java/net/Indyuce/mmoitems/ability/list/simple/Firefly.java new file mode 100644 index 00000000..49cda672 --- /dev/null +++ b/src/main/java/net/Indyuce/mmoitems/ability/list/simple/Firefly.java @@ -0,0 +1,85 @@ +package net.Indyuce.mmoitems.ability.list.simple; + +import io.lumine.mythic.lib.damage.AttackMetadata; +import io.lumine.mythic.lib.damage.DamageMetadata; +import io.lumine.mythic.lib.damage.DamageType; +import io.lumine.mythic.lib.version.VersionSound; +import net.Indyuce.mmoitems.MMOItems; +import net.Indyuce.mmoitems.MMOUtils; +import net.Indyuce.mmoitems.ability.SimpleAbility; +import net.Indyuce.mmoitems.ability.metadata.SimpleAbilityMetadata; +import net.Indyuce.mmoitems.api.ItemAttackMetadata; +import org.bukkit.Location; +import org.bukkit.Material; +import org.bukkit.Particle; +import org.bukkit.Sound; +import org.bukkit.entity.Entity; +import org.bukkit.entity.LivingEntity; +import org.bukkit.scheduler.BukkitRunnable; +import org.bukkit.util.Vector; + +public class Firefly extends SimpleAbility { + public Firefly() { + super(CastingMode.ON_HIT, CastingMode.WHEN_HIT, CastingMode.LEFT_CLICK, CastingMode.RIGHT_CLICK, CastingMode.SHIFT_LEFT_CLICK, CastingMode.SHIFT_RIGHT_CLICK); + + addModifier("damage", 6); + addModifier("duration", 2.5); + addModifier("knockback", 1); + addModifier("cooldown", 10); + addModifier("mana", 0); + addModifier("stamina", 0); + } + + @Override + public void whenCast(ItemAttackMetadata attack, SimpleAbilityMetadata ability) { + double duration = ability.getModifier("duration") * 20; + + new BukkitRunnable() { + int j = 0; + + public void run() { + if (j++ > duration) + cancel(); + + if (attack.getDamager().getLocation().getBlock().getType() == Material.WATER) { + attack.getDamager().setVelocity(attack.getDamager().getVelocity().multiply(3).setY(1.8)); + attack.getDamager().getWorld().playSound(attack.getDamager().getLocation(), Sound.BLOCK_FIRE_EXTINGUISH, 1, .5f); + attack.getDamager().getWorld().spawnParticle(Particle.EXPLOSION_NORMAL, attack.getDamager().getLocation().add(0, 1, 0), 32, 0, 0, 0, .2); + attack.getDamager().getWorld().spawnParticle(Particle.CLOUD, attack.getDamager().getLocation().add(0, 1, 0), 32, 0, 0, 0, .2); + cancel(); + return; + } + + for (Entity entity : attack.getDamager().getNearbyEntities(1, 1, 1)) + if (MMOUtils.canDamage(attack.getDamager(), entity)) { + double damage = ability.getModifier("damage"); + double knockback = ability.getModifier("knockback"); + + attack.getDamager().getWorld().playSound(attack.getDamager().getLocation(), Sound.ENTITY_ZOMBIE_ATTACK_IRON_DOOR, 1, .5f); + attack.getDamager().getWorld().spawnParticle(Particle.LAVA, attack.getDamager().getLocation().add(0, 1, 0), 32); + attack.getDamager().getWorld().spawnParticle(Particle.SMOKE_LARGE, attack.getDamager().getLocation().add(0, 1, 0), 24, 0, 0, 0, .3); + attack.getDamager().getWorld().spawnParticle(Particle.FLAME, attack.getDamager().getLocation().add(0, 1, 0), 24, 0, 0, 0, .3); + entity.setVelocity(attack.getDamager().getVelocity().setY(0.3).multiply(1.7 * knockback)); + attack.getDamager().setVelocity(attack.getDamager().getEyeLocation().getDirection().multiply(-3).setY(.5)); + new AttackMetadata(new DamageMetadata(damage, DamageType.SKILL, DamageType.MAGIC), attack.getStats()).damage((LivingEntity) entity); + cancel(); + return; + } + + Location loc = attack.getDamager().getLocation().add(0, 1, 0); + for (double a = 0; a < Math.PI * 2; a += Math.PI / 9) { + Vector vec = new Vector(.6 * Math.cos(a), .6 * Math.sin(a), 0); + vec = MMOUtils.rotateFunc(vec, loc); + loc.add(vec); + attack.getDamager().getWorld().spawnParticle(Particle.SMOKE_NORMAL, loc, 0); + if (random.nextDouble() < .3) + attack.getDamager().getWorld().spawnParticle(Particle.FLAME, loc, 0); + loc.add(vec.multiply(-1)); + } + + attack.getDamager().setVelocity(attack.getDamager().getEyeLocation().getDirection()); + attack.getDamager().getWorld().playSound(attack.getDamager().getLocation(), VersionSound.ENTITY_FIREWORK_ROCKET_BLAST.toSound(), 1, 1); + } + }.runTaskTimer(MMOItems.plugin, 0, 1); + } +} diff --git a/src/main/java/net/Indyuce/mmoitems/ability/list/simple/Frog_Mode.java b/src/main/java/net/Indyuce/mmoitems/ability/list/simple/Frog_Mode.java new file mode 100644 index 00000000..09cb5a0f --- /dev/null +++ b/src/main/java/net/Indyuce/mmoitems/ability/list/simple/Frog_Mode.java @@ -0,0 +1,48 @@ +package net.Indyuce.mmoitems.ability.list.simple; + +import io.lumine.mythic.lib.version.VersionSound; +import net.Indyuce.mmoitems.MMOItems; +import net.Indyuce.mmoitems.ability.SimpleAbility; +import net.Indyuce.mmoitems.ability.metadata.SimpleAbilityMetadata; +import net.Indyuce.mmoitems.api.ItemAttackMetadata; +import org.bukkit.Material; +import org.bukkit.Particle; +import org.bukkit.event.Listener; +import org.bukkit.scheduler.BukkitRunnable; + +public class Frog_Mode extends SimpleAbility implements Listener { + public Frog_Mode() { + super(CastingMode.ON_HIT, CastingMode.WHEN_HIT, CastingMode.LEFT_CLICK, CastingMode.RIGHT_CLICK, CastingMode.SHIFT_LEFT_CLICK, CastingMode.SHIFT_RIGHT_CLICK); + + addModifier("duration", 20); + addModifier("jump-force", 1); + addModifier("speed", 1); + addModifier("cooldown", 50); + addModifier("mana", 0); + addModifier("stamina", 0); + } + + @Override + public void whenCast(ItemAttackMetadata attack, SimpleAbilityMetadata ability) { + double duration = ability.getModifier("duration") * 20; + double y = ability.getModifier("jump-force"); + double xz = ability.getModifier("speed"); + + new BukkitRunnable() { + int j = 0; + + public void run() { + j++; + if (j > duration) + cancel(); + + if (attack.getDamager().getLocation().getBlock().getType() == Material.WATER) { + attack.getDamager().setVelocity(attack.getDamager().getEyeLocation().getDirection().setY(0).normalize().multiply(.8 * xz).setY(0.5 / xz * y)); + attack.getDamager().getWorld().playSound(attack.getDamager().getLocation(), VersionSound.ENTITY_ENDER_DRAGON_FLAP.toSound(), 2, 1); + for (double a = 0; a < Math.PI * 2; a += Math.PI / 12) + attack.getDamager().getWorld().spawnParticle(Particle.CLOUD, attack.getDamager().getLocation(), 0, Math.cos(a), 0, Math.sin(a), .2); + } + } + }.runTaskTimer(MMOItems.plugin, 0, 1); + } +} diff --git a/src/main/java/net/Indyuce/mmoitems/ability/list/simple/Frozen_Aura.java b/src/main/java/net/Indyuce/mmoitems/ability/list/simple/Frozen_Aura.java new file mode 100644 index 00000000..4aa7ea97 --- /dev/null +++ b/src/main/java/net/Indyuce/mmoitems/ability/list/simple/Frozen_Aura.java @@ -0,0 +1,59 @@ +package net.Indyuce.mmoitems.ability.list.simple; + +import net.Indyuce.mmoitems.MMOItems; +import net.Indyuce.mmoitems.MMOUtils; +import net.Indyuce.mmoitems.ability.SimpleAbility; +import net.Indyuce.mmoitems.ability.metadata.SimpleAbilityMetadata; +import net.Indyuce.mmoitems.api.ItemAttackMetadata; +import org.bukkit.Particle; +import org.bukkit.Sound; +import org.bukkit.entity.Entity; +import org.bukkit.entity.LivingEntity; +import org.bukkit.event.Listener; +import org.bukkit.potion.PotionEffect; +import org.bukkit.potion.PotionEffectType; +import org.bukkit.scheduler.BukkitRunnable; + +public class Frozen_Aura extends SimpleAbility implements Listener { + public Frozen_Aura() { + super(CastingMode.ON_HIT, CastingMode.WHEN_HIT, CastingMode.LEFT_CLICK, CastingMode.RIGHT_CLICK, CastingMode.SHIFT_LEFT_CLICK, CastingMode.SHIFT_RIGHT_CLICK); + + addModifier("duration", 6); + addModifier("amplifier", 1); + addModifier("radius", 10); + addModifier("cooldown", 10); + addModifier("mana", 0); + addModifier("stamina", 0); + } + + @Override + public void whenCast(ItemAttackMetadata attack, SimpleAbilityMetadata ability) { + double duration = ability.getModifier("duration") * 20; + double radiusSquared = Math.pow(ability.getModifier("radius"), 2); + double amplifier = ability.getModifier("amplifier") - 1; + + new BukkitRunnable() { + double j = 0; + int ti = 0; + + public void run() { + if (ti++ > duration) + cancel(); + + j += Math.PI / 60; + for (double k = 0; k < Math.PI * 2; k += Math.PI / 2) + attack.getDamager().getWorld().spawnParticle(Particle.SPELL_INSTANT, attack.getDamager().getLocation().add(Math.cos(k + j) * 2, 1 + Math.sin(k + j * 7) / 3, Math.sin(k + j) * 2), 0); + + if (ti % 2 == 0) + attack.getDamager().getWorld().playSound(attack.getDamager().getLocation(), Sound.BLOCK_SNOW_BREAK, 1, 1); + + if (ti % 7 == 0) + for (Entity entity : MMOUtils.getNearbyChunkEntities(attack.getDamager().getLocation())) + if (entity.getLocation().distanceSquared(attack.getDamager().getLocation()) < radiusSquared && MMOUtils.canDamage(attack.getDamager(), entity)) { + ((LivingEntity) entity).removePotionEffect(PotionEffectType.SLOW); + ((LivingEntity) entity).addPotionEffect(new PotionEffect(PotionEffectType.SLOW, 40, (int) amplifier)); + } + } + }.runTaskTimer(MMOItems.plugin, 0, 1); + } +} diff --git a/src/main/java/net/Indyuce/mmoitems/ability/list/simple/Grand_Heal.java b/src/main/java/net/Indyuce/mmoitems/ability/list/simple/Grand_Heal.java new file mode 100644 index 00000000..d2a627e3 --- /dev/null +++ b/src/main/java/net/Indyuce/mmoitems/ability/list/simple/Grand_Heal.java @@ -0,0 +1,36 @@ +package net.Indyuce.mmoitems.ability.list.simple; + +import net.Indyuce.mmoitems.MMOUtils; +import net.Indyuce.mmoitems.ability.SimpleAbility; +import net.Indyuce.mmoitems.ability.metadata.SimpleAbilityMetadata; +import net.Indyuce.mmoitems.api.ItemAttackMetadata; +import org.bukkit.Particle; +import org.bukkit.Sound; +import org.bukkit.entity.Entity; +import org.bukkit.entity.Player; + +public class Grand_Heal extends SimpleAbility { + public Grand_Heal() { + super(CastingMode.ON_HIT, CastingMode.WHEN_HIT, CastingMode.LEFT_CLICK, CastingMode.RIGHT_CLICK, CastingMode.SHIFT_LEFT_CLICK, CastingMode.SHIFT_RIGHT_CLICK); + + addModifier("heal", 5); + addModifier("radius", 5); + addModifier("cooldown", 15); + addModifier("mana", 0); + addModifier("stamina", 0); + } + + @Override + public void whenCast(ItemAttackMetadata attack, SimpleAbilityMetadata ability) { + double heal = ability.getModifier("heal"); + double radius = ability.getModifier("radius"); + + MMOUtils.heal(attack.getDamager(), heal); + attack.getDamager().getWorld().playSound(attack.getDamager().getLocation(), Sound.ENTITY_PLAYER_LEVELUP, 1, 2); + attack.getDamager().getWorld().spawnParticle(Particle.HEART, attack.getDamager().getLocation().add(0, .75, 0), 16, 1, 1, 1, 0); + attack.getDamager().getWorld().spawnParticle(Particle.VILLAGER_HAPPY, attack.getDamager().getLocation().add(0, .75, 0), 16, 1, 1, 1, 0); + for (Entity entity : attack.getDamager().getNearbyEntities(radius, radius, radius)) + if (entity instanceof Player) + MMOUtils.heal((Player) entity, heal); + } +} diff --git a/src/main/java/net/Indyuce/mmoitems/ability/list/simple/Heal.java b/src/main/java/net/Indyuce/mmoitems/ability/list/simple/Heal.java new file mode 100644 index 00000000..48442fef --- /dev/null +++ b/src/main/java/net/Indyuce/mmoitems/ability/list/simple/Heal.java @@ -0,0 +1,27 @@ +package net.Indyuce.mmoitems.ability.list.simple; + +import net.Indyuce.mmoitems.MMOUtils; +import net.Indyuce.mmoitems.ability.SimpleAbility; +import net.Indyuce.mmoitems.ability.metadata.SimpleAbilityMetadata; +import net.Indyuce.mmoitems.api.ItemAttackMetadata; +import org.bukkit.Particle; +import org.bukkit.Sound; + +public class Heal extends SimpleAbility { + public Heal() { + super(CastingMode.ON_HIT, CastingMode.WHEN_HIT, CastingMode.LEFT_CLICK, CastingMode.RIGHT_CLICK, CastingMode.SHIFT_LEFT_CLICK, CastingMode.SHIFT_RIGHT_CLICK); + + addModifier("heal", 4); + addModifier("cooldown", 10); + addModifier("mana", 0); + addModifier("stamina", 0); + } + + @Override + public void whenCast(ItemAttackMetadata attack, SimpleAbilityMetadata ability) { + attack.getDamager().getWorld().playSound(attack.getDamager().getLocation(), Sound.ENTITY_PLAYER_LEVELUP, 1, 2); + attack.getDamager().getWorld().spawnParticle(Particle.HEART, attack.getDamager().getLocation().add(0, .75, 0), 16, 1, 1, 1, 0); + attack.getDamager().getWorld().spawnParticle(Particle.VILLAGER_HAPPY, attack.getDamager().getLocation().add(0, .75, 0), 16, 1, 1, 1, 0); + MMOUtils.heal(attack.getDamager(), ability.getModifier("heal")); + } +} diff --git a/src/main/java/net/Indyuce/mmoitems/ability/list/simple/Light_Dash.java b/src/main/java/net/Indyuce/mmoitems/ability/list/simple/Light_Dash.java new file mode 100644 index 00000000..d5d2bfb6 --- /dev/null +++ b/src/main/java/net/Indyuce/mmoitems/ability/list/simple/Light_Dash.java @@ -0,0 +1,57 @@ +package net.Indyuce.mmoitems.ability.list.simple; + +import io.lumine.mythic.lib.damage.AttackMetadata; +import io.lumine.mythic.lib.damage.DamageMetadata; +import io.lumine.mythic.lib.damage.DamageType; +import io.lumine.mythic.lib.version.VersionSound; +import net.Indyuce.mmoitems.MMOItems; +import net.Indyuce.mmoitems.MMOUtils; +import net.Indyuce.mmoitems.ability.SimpleAbility; +import net.Indyuce.mmoitems.ability.metadata.SimpleAbilityMetadata; +import net.Indyuce.mmoitems.api.ItemAttackMetadata; +import org.bukkit.Particle; +import org.bukkit.entity.Entity; +import org.bukkit.entity.LivingEntity; +import org.bukkit.scheduler.BukkitRunnable; +import org.bukkit.util.Vector; + +import java.util.ArrayList; +import java.util.List; + +public class Light_Dash extends SimpleAbility { + public Light_Dash() { + super(CastingMode.ON_HIT, CastingMode.WHEN_HIT, CastingMode.LEFT_CLICK, CastingMode.RIGHT_CLICK, CastingMode.SHIFT_LEFT_CLICK, CastingMode.SHIFT_RIGHT_CLICK); + + addModifier("damage", 3); + addModifier("cooldown", 10); + addModifier("length", 1); + addModifier("mana", 0); + addModifier("stamina", 0); + } + + @Override + public void whenCast(ItemAttackMetadata attack, SimpleAbilityMetadata ability) { + double damage = ability.getModifier("damage"); + double length = ability.getModifier("length"); + + new BukkitRunnable() { + final Vector vec = attack.getDamager().getEyeLocation().getDirection(); + final List hit = new ArrayList<>(); + int j = 0; + + public void run() { + if (j++ > 10 * Math.min(10, length)) + cancel(); + + attack.getDamager().setVelocity(vec); + attack.getDamager().getWorld().spawnParticle(Particle.SMOKE_LARGE, attack.getDamager().getLocation().add(0, 1, 0), 0); + attack.getDamager().getWorld().playSound(attack.getDamager().getLocation(), VersionSound.ENTITY_ENDER_DRAGON_FLAP.toSound(), 1, 2); + for (Entity entity : attack.getDamager().getNearbyEntities(1, 1, 1)) + if (!hit.contains(entity.getEntityId()) && MMOUtils.canDamage(attack.getDamager(), entity)) { + hit.add(entity.getEntityId()); + new AttackMetadata(new DamageMetadata(damage, DamageType.SKILL, DamageType.PHYSICAL), attack.getStats()).damage((LivingEntity) entity); + } + } + }.runTaskTimer(MMOItems.plugin, 0, 2); + } +} diff --git a/src/main/java/net/Indyuce/mmoitems/ability/Magical_Path.java b/src/main/java/net/Indyuce/mmoitems/ability/list/simple/Magical_Path.java similarity index 61% rename from src/main/java/net/Indyuce/mmoitems/ability/Magical_Path.java rename to src/main/java/net/Indyuce/mmoitems/ability/list/simple/Magical_Path.java index 7aea81ba..2a0dd3f5 100644 --- a/src/main/java/net/Indyuce/mmoitems/ability/Magical_Path.java +++ b/src/main/java/net/Indyuce/mmoitems/ability/list/simple/Magical_Path.java @@ -1,8 +1,12 @@ -package net.Indyuce.mmoitems.ability; +package net.Indyuce.mmoitems.ability.list.simple; +import io.lumine.mythic.lib.version.VersionSound; +import net.Indyuce.mmoitems.MMOItems; +import net.Indyuce.mmoitems.ability.SimpleAbility; +import net.Indyuce.mmoitems.ability.metadata.SimpleAbilityMetadata; +import net.Indyuce.mmoitems.api.ItemAttackMetadata; import org.bukkit.Bukkit; import org.bukkit.Particle; -import org.bukkit.entity.LivingEntity; import org.bukkit.entity.Player; import org.bukkit.event.EventHandler; import org.bukkit.event.EventPriority; @@ -13,39 +17,25 @@ import org.bukkit.event.entity.EntityDamageEvent.DamageCause; import org.bukkit.event.player.PlayerQuitEvent; import org.bukkit.scheduler.BukkitRunnable; -import net.Indyuce.mmoitems.MMOItems; -import net.Indyuce.mmoitems.api.ItemAttackResult; -import net.Indyuce.mmoitems.api.ability.Ability; -import net.Indyuce.mmoitems.api.ability.AbilityResult; -import net.Indyuce.mmoitems.api.ability.SimpleAbilityResult; -import net.Indyuce.mmoitems.api.player.PlayerStats.CachedStats; -import net.Indyuce.mmoitems.stat.data.AbilityData; -import io.lumine.mythic.lib.version.VersionSound; +public class Magical_Path extends SimpleAbility { + public Magical_Path() { + super(CastingMode.ON_HIT, CastingMode.WHEN_HIT, CastingMode.LEFT_CLICK, CastingMode.RIGHT_CLICK, CastingMode.SHIFT_LEFT_CLICK, CastingMode.SHIFT_RIGHT_CLICK); -public class Magical_Path extends Ability { - public Magical_Path() { - super(CastingMode.ON_HIT, CastingMode.WHEN_HIT, CastingMode.LEFT_CLICK, CastingMode.RIGHT_CLICK, CastingMode.SHIFT_LEFT_CLICK, CastingMode.SHIFT_RIGHT_CLICK); + addModifier("duration", 3); + addModifier("cooldown", 15); + addModifier("mana", 0); + addModifier("stamina", 0); + } - addModifier("duration", 3); - addModifier("cooldown", 15); - addModifier("mana", 0); - addModifier("stamina", 0); - } + @Override + public void whenCast(ItemAttackMetadata attack, SimpleAbilityMetadata ability) { + attack.getDamager().setAllowFlight(true); + attack.getDamager().setFlying(true); + attack.getDamager().setVelocity(attack.getDamager().getVelocity().setY(.5)); + attack.getDamager().getWorld().playSound(attack.getDamager().getLocation(), VersionSound.ENTITY_ENDERMAN_TELEPORT.toSound(), 1, 1); - @Override - public AbilityResult whenRan(CachedStats stats, LivingEntity target, AbilityData ability, ItemAttackResult result) { - return new SimpleAbilityResult(ability); - } - - @Override - public void whenCast(CachedStats stats, AbilityResult ability, ItemAttackResult result) { - stats.getPlayer().setAllowFlight(true); - stats.getPlayer().setFlying(true); - stats.getPlayer().setVelocity(stats.getPlayer().getVelocity().setY(.5)); - stats.getPlayer().getWorld().playSound(stats.getPlayer().getLocation(), VersionSound.ENTITY_ENDERMAN_TELEPORT.toSound(), 1, 1); - - new MagicalPathHandler(stats.getPlayer(), ability.getModifier("duration")); - } + new MagicalPathHandler(attack.getDamager(), ability.getModifier("duration")); + } public static class MagicalPathHandler extends BukkitRunnable implements Listener { private final Player player; diff --git a/src/main/java/net/Indyuce/mmoitems/ability/Magical_Shield.java b/src/main/java/net/Indyuce/mmoitems/ability/list/simple/Magical_Shield.java similarity index 56% rename from src/main/java/net/Indyuce/mmoitems/ability/Magical_Shield.java rename to src/main/java/net/Indyuce/mmoitems/ability/list/simple/Magical_Shield.java index 79b34906..fd809c03 100644 --- a/src/main/java/net/Indyuce/mmoitems/ability/Magical_Shield.java +++ b/src/main/java/net/Indyuce/mmoitems/ability/list/simple/Magical_Shield.java @@ -1,5 +1,11 @@ -package net.Indyuce.mmoitems.ability; +package net.Indyuce.mmoitems.ability.list.simple; +import io.lumine.mythic.lib.version.VersionSound; +import net.Indyuce.mmoitems.MMOItems; +import net.Indyuce.mmoitems.ability.SimpleAbility; +import net.Indyuce.mmoitems.ability.metadata.SimpleAbilityMetadata; +import net.Indyuce.mmoitems.api.ItemAttackMetadata; +import net.Indyuce.mmoitems.stat.data.AbilityData; import org.bukkit.Bukkit; import org.bukkit.Color; import org.bukkit.Location; @@ -12,42 +18,33 @@ import org.bukkit.event.Listener; import org.bukkit.event.entity.EntityDamageEvent; import org.bukkit.scheduler.BukkitRunnable; -import net.Indyuce.mmoitems.MMOItems; -import net.Indyuce.mmoitems.api.ItemAttackResult; -import net.Indyuce.mmoitems.api.ability.Ability; -import net.Indyuce.mmoitems.api.ability.AbilityResult; -import net.Indyuce.mmoitems.api.ability.SimpleAbilityResult; -import net.Indyuce.mmoitems.api.player.PlayerStats.CachedStats; -import net.Indyuce.mmoitems.stat.data.AbilityData; -import io.lumine.mythic.lib.version.VersionSound; +public class Magical_Shield extends SimpleAbility { + public Magical_Shield() { + super(CastingMode.ON_HIT, CastingMode.WHEN_HIT, CastingMode.LEFT_CLICK, CastingMode.RIGHT_CLICK, CastingMode.SHIFT_LEFT_CLICK, + CastingMode.SHIFT_RIGHT_CLICK); -public class Magical_Shield extends Ability { - public Magical_Shield() { - super(CastingMode.ON_HIT, CastingMode.WHEN_HIT, CastingMode.LEFT_CLICK, CastingMode.RIGHT_CLICK, CastingMode.SHIFT_LEFT_CLICK, - CastingMode.SHIFT_RIGHT_CLICK); - - addModifier("power", 40); - addModifier("radius", 5); - addModifier("duration", 5); - addModifier("cooldown", 35); - addModifier("mana", 0); - addModifier("stamina", 0); + addModifier("power", 40); + addModifier("radius", 5); + addModifier("duration", 5); + addModifier("cooldown", 35); + addModifier("mana", 0); + addModifier("stamina", 0); } - @Override - public AbilityResult whenRan(CachedStats stats, LivingEntity target, AbilityData ability, ItemAttackResult result) { - return new SimpleAbilityResult(ability, ((LivingEntity) stats.getPlayer()).isOnGround()); - } + @Override + public SimpleAbilityMetadata canBeCast(ItemAttackMetadata attack, LivingEntity target, AbilityData ability) { + return attack.getDamager().isOnGround() ? new SimpleAbilityMetadata(ability) : null; + } - @Override - public void whenCast(CachedStats stats, AbilityResult ability, ItemAttackResult result) { - double duration = ability.getModifier("duration"); - double radiusSquared = Math.pow(ability.getModifier("radius"), 2); - double power = ability.getModifier("power") / 100; + @Override + public void whenCast(ItemAttackMetadata attack, SimpleAbilityMetadata ability) { + double duration = ability.getModifier("duration"); + double radiusSquared = Math.pow(ability.getModifier("radius"), 2); + double power = ability.getModifier("power") / 100; - stats.getPlayer().getWorld().playSound(stats.getPlayer().getLocation(), VersionSound.ENTITY_ENDERMAN_TELEPORT.toSound(), 3, 0); - new MagicalShield(stats.getPlayer().getLocation().clone(), duration, radiusSquared, power); - } + attack.getDamager().getWorld().playSound(attack.getDamager().getLocation(), VersionSound.ENTITY_ENDERMAN_TELEPORT.toSound(), 3, 0); + new MagicalShield(attack.getDamager().getLocation().clone(), duration, radiusSquared, power); + } public static class MagicalShield extends BukkitRunnable implements Listener { private final Location loc; diff --git a/src/main/java/net/Indyuce/mmoitems/ability/list/simple/Overload.java b/src/main/java/net/Indyuce/mmoitems/ability/list/simple/Overload.java new file mode 100644 index 00000000..d865f305 --- /dev/null +++ b/src/main/java/net/Indyuce/mmoitems/ability/list/simple/Overload.java @@ -0,0 +1,50 @@ +package net.Indyuce.mmoitems.ability.list.simple; + +import io.lumine.mythic.lib.damage.AttackMetadata; +import io.lumine.mythic.lib.damage.DamageMetadata; +import io.lumine.mythic.lib.damage.DamageType; +import io.lumine.mythic.lib.version.VersionSound; +import net.Indyuce.mmoitems.MMOUtils; +import net.Indyuce.mmoitems.ability.SimpleAbility; +import net.Indyuce.mmoitems.ability.metadata.SimpleAbilityMetadata; +import net.Indyuce.mmoitems.api.ItemAttackMetadata; +import org.bukkit.Location; +import org.bukkit.Particle; +import org.bukkit.Sound; +import org.bukkit.entity.Entity; +import org.bukkit.entity.LivingEntity; +import org.bukkit.potion.PotionEffect; +import org.bukkit.potion.PotionEffectType; + +public class Overload extends SimpleAbility { + public Overload() { + super(CastingMode.ON_HIT, CastingMode.WHEN_HIT, CastingMode.LEFT_CLICK, CastingMode.RIGHT_CLICK, CastingMode.SHIFT_LEFT_CLICK, CastingMode.SHIFT_RIGHT_CLICK); + + addModifier("damage", 6); + addModifier("cooldown", 10); + addModifier("radius", 6); + addModifier("mana", 0); + addModifier("stamina", 0); + } + + @Override + public void whenCast(ItemAttackMetadata attack, SimpleAbilityMetadata ability) { + double damage = ability.getModifier("damage"); + double radius = ability.getModifier("radius"); + + attack.getDamager().getWorld().playSound(attack.getDamager().getLocation(), Sound.ENTITY_GENERIC_EXPLODE, 2, 0); + attack.getDamager().getWorld().playSound(attack.getDamager().getLocation(), VersionSound.ENTITY_FIREWORK_ROCKET_TWINKLE.toSound(), 2, 0); + attack.getDamager().addPotionEffect(new PotionEffect(PotionEffectType.SLOW, 2, 254)); + + for (Entity entity : attack.getDamager().getNearbyEntities(radius, radius, radius)) + if (MMOUtils.canDamage(attack.getDamager(), entity)) + new AttackMetadata(new DamageMetadata(damage, DamageType.SKILL, DamageType.MAGIC), attack.getStats()).damage((LivingEntity) entity); + + double step = 12 + (radius * 2.5); + for (double j = 0; j < Math.PI * 2; j += Math.PI / step) { + Location loc = attack.getDamager().getLocation().clone().add(Math.cos(j) * radius, 1, Math.sin(j) * radius); + attack.getDamager().getWorld().spawnParticle(Particle.CLOUD, loc, 4, 0, 0, 0, .05); + attack.getDamager().getWorld().spawnParticle(Particle.FIREWORKS_SPARK, loc, 4, 0, 0, 0, .05); + } + } +} diff --git a/src/main/java/net/Indyuce/mmoitems/ability/list/simple/Present_Throw.java b/src/main/java/net/Indyuce/mmoitems/ability/list/simple/Present_Throw.java new file mode 100644 index 00000000..0a740d8e --- /dev/null +++ b/src/main/java/net/Indyuce/mmoitems/ability/list/simple/Present_Throw.java @@ -0,0 +1,98 @@ +package net.Indyuce.mmoitems.ability.list.simple; + +import com.mojang.authlib.GameProfile; +import com.mojang.authlib.properties.Property; +import io.lumine.mythic.lib.damage.AttackMetadata; +import io.lumine.mythic.lib.damage.DamageMetadata; +import io.lumine.mythic.lib.damage.DamageType; +import io.lumine.mythic.lib.version.VersionMaterial; +import io.lumine.mythic.lib.version.VersionSound; +import net.Indyuce.mmoitems.MMOItems; +import net.Indyuce.mmoitems.MMOUtils; +import net.Indyuce.mmoitems.ability.SimpleAbility; +import net.Indyuce.mmoitems.ability.metadata.SimpleAbilityMetadata; +import net.Indyuce.mmoitems.api.ItemAttackMetadata; +import net.Indyuce.mmoitems.api.util.NoClipItem; +import org.bukkit.Particle; +import org.bukkit.Sound; +import org.bukkit.entity.Entity; +import org.bukkit.entity.LivingEntity; +import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.meta.ItemMeta; +import org.bukkit.scheduler.BukkitRunnable; +import org.yaml.snakeyaml.external.biz.base64Coder.Base64Coder; + +import java.lang.reflect.Field; +import java.util.UUID; +import java.util.logging.Level; + +public class Present_Throw extends SimpleAbility { + private final ItemStack present = VersionMaterial.PLAYER_HEAD.toItem(); + + public Present_Throw() { + super(CastingMode.ON_HIT, CastingMode.WHEN_HIT, CastingMode.LEFT_CLICK, CastingMode.RIGHT_CLICK, CastingMode.SHIFT_LEFT_CLICK, CastingMode.SHIFT_RIGHT_CLICK); + + addModifier("damage", 6); + addModifier("radius", 4); + addModifier("force", 1); + addModifier("cooldown", 10); + addModifier("mana", 0); + addModifier("stamina", 0); + + ItemMeta presentMeta = present.getItemMeta(); + GameProfile profile = new GameProfile(UUID.randomUUID(), null); + byte[] encodedData = Base64Coder.encodeLines(String.format("{textures:{SKIN:{url:\"%s\"}}}", "http://textures.minecraft.net/texture/47e55fcc809a2ac1861da2a67f7f31bd7237887d162eca1eda526a7512a64910").getBytes()).getBytes(); + profile.getProperties().put("textures", new Property("textures", new String(encodedData))); + + try { + Field profileField = presentMeta.getClass().getDeclaredField("profile"); + profileField.setAccessible(true); + profileField.set(presentMeta, profile); + } catch (NoSuchFieldException | IllegalArgumentException | IllegalAccessException e) { + MMOItems.plugin.getLogger().log(Level.WARNING, "Could not load the skull texture for the Present Throw item ability."); + } + + present.setItemMeta(presentMeta); + } + + @Override + public void whenCast(ItemAttackMetadata attack, SimpleAbilityMetadata ability) { + double damage = ability.getModifier("damage"); + double radiusSquared = Math.pow(ability.getModifier("radius"), 2); + + final NoClipItem item = new NoClipItem(attack.getDamager().getLocation().add(0, 1.2, 0), present); + item.getEntity().setVelocity(attack.getDamager().getEyeLocation().getDirection().multiply(1.5 * ability.getModifier("force"))); + + /* + * when items are moving through the air, they loose a percent of their + * velocity proportionally to their coordinates in each axis. this means + * that if the trajectory is not affected, the ratio of x/y will always + * be the same. check for any change of that ratio to check for a + * trajectory change + */ + final double trajRatio = item.getEntity().getVelocity().getX() / item.getEntity().getVelocity().getZ(); + attack.getDamager().getWorld().playSound(attack.getDamager().getLocation(), Sound.ENTITY_SNOWBALL_THROW, 1, 0); + new BukkitRunnable() { + double ti = 0; + + public void run() { + if (ti++ > 70 || item.getEntity().isDead()) { + item.close(); + cancel(); + } + + double currentTrajRatio = item.getEntity().getVelocity().getX() / item.getEntity().getVelocity().getZ(); + item.getEntity().getWorld().spawnParticle(Particle.SPELL_INSTANT, item.getEntity().getLocation().add(0, .1, 0), 0); + if (item.getEntity().isOnGround() || Math.abs(trajRatio - currentTrajRatio) > .1) { + item.getEntity().getWorld().spawnParticle(Particle.FIREWORKS_SPARK, item.getEntity().getLocation().add(0, .1, 0), 128, 0, 0, 0, .25); + item.getEntity().getWorld().playSound(item.getEntity().getLocation(), VersionSound.ENTITY_FIREWORK_ROCKET_TWINKLE.toSound(), 2, 1.5f); + for (Entity entity : MMOUtils.getNearbyChunkEntities(item.getEntity().getLocation())) + if (entity.getLocation().distanceSquared(item.getEntity().getLocation()) < radiusSquared && MMOUtils.canDamage(attack.getDamager(), entity)) + new AttackMetadata(new DamageMetadata(damage, DamageType.SKILL, DamageType.MAGIC, DamageType.PROJECTILE), attack.getStats()).damage((LivingEntity) entity); + item.close(); + cancel(); + } + } + }.runTaskTimer(MMOItems.plugin, 0, 1); + } +} diff --git a/src/main/java/net/Indyuce/mmoitems/ability/Shadow_Veil.java b/src/main/java/net/Indyuce/mmoitems/ability/list/simple/Shadow_Veil.java similarity index 57% rename from src/main/java/net/Indyuce/mmoitems/ability/Shadow_Veil.java rename to src/main/java/net/Indyuce/mmoitems/ability/list/simple/Shadow_Veil.java index de2bea59..0265fe94 100644 --- a/src/main/java/net/Indyuce/mmoitems/ability/Shadow_Veil.java +++ b/src/main/java/net/Indyuce/mmoitems/ability/list/simple/Shadow_Veil.java @@ -1,18 +1,14 @@ -package net.Indyuce.mmoitems.ability; +package net.Indyuce.mmoitems.ability.list.simple; import io.lumine.mythic.lib.api.util.ui.SilentNumbers; -import net.Indyuce.mmoitems.MMOItems; -import net.Indyuce.mmoitems.api.ItemAttackResult; -import net.Indyuce.mmoitems.api.ability.Ability; -import net.Indyuce.mmoitems.api.ability.AbilityResult; -import net.Indyuce.mmoitems.api.ability.SimpleAbilityResult; -import net.Indyuce.mmoitems.api.player.PlayerStats.CachedStats; -import net.Indyuce.mmoitems.stat.data.AbilityData; import io.lumine.mythic.lib.version.VersionSound; +import net.Indyuce.mmoitems.MMOItems; +import net.Indyuce.mmoitems.ability.SimpleAbility; +import net.Indyuce.mmoitems.ability.metadata.SimpleAbilityMetadata; +import net.Indyuce.mmoitems.api.ItemAttackMetadata; import org.bukkit.Bukkit; import org.bukkit.Location; import org.bukkit.Particle; -import org.bukkit.entity.LivingEntity; import org.bukkit.entity.Mob; import org.bukkit.entity.Player; import org.bukkit.event.EventHandler; @@ -21,41 +17,36 @@ import org.bukkit.event.entity.EntityDamageByEntityEvent; import org.bukkit.event.entity.EntityTargetEvent; import org.bukkit.scheduler.BukkitRunnable; -public class Shadow_Veil extends Ability implements Listener { - public Shadow_Veil() { - super(CastingMode.ON_HIT, CastingMode.WHEN_HIT, CastingMode.LEFT_CLICK, CastingMode.RIGHT_CLICK, CastingMode.SHIFT_LEFT_CLICK, - CastingMode.SHIFT_RIGHT_CLICK); +public class Shadow_Veil extends SimpleAbility implements Listener { + public Shadow_Veil() { + super(CastingMode.ON_HIT, CastingMode.WHEN_HIT, CastingMode.LEFT_CLICK, CastingMode.RIGHT_CLICK, CastingMode.SHIFT_LEFT_CLICK, + CastingMode.SHIFT_RIGHT_CLICK); - addModifier("cooldown", 35); - addModifier("duration", 5); - addModifier("deception", 1); - addModifier("mana", 0); - addModifier("stamina", 0); - } + addModifier("cooldown", 35); + addModifier("duration", 5); + addModifier("deception", 1); + addModifier("mana", 0); + addModifier("stamina", 0); + } - @Override - public AbilityResult whenRan(CachedStats stats, LivingEntity target, AbilityData ability, ItemAttackResult result) { - return new SimpleAbilityResult(ability); - } + @Override + public void whenCast(ItemAttackMetadata attack, SimpleAbilityMetadata ability) { + double duration = ability.getModifier("duration"); - @Override - public void whenCast(CachedStats stats, AbilityResult ability, ItemAttackResult result) { - double duration = ability.getModifier("duration"); + attack.getDamager().getWorld().playSound(attack.getDamager().getLocation(), VersionSound.ENTITY_ENDERMAN_TELEPORT.toSound(), 3, 0); + for (Player online : Bukkit.getOnlinePlayers()) + online.hidePlayer(MMOItems.plugin, attack.getDamager()); - stats.getPlayer().getWorld().playSound(stats.getPlayer().getLocation(), VersionSound.ENTITY_ENDERMAN_TELEPORT.toSound(), 3, 0); - for (Player online : Bukkit.getOnlinePlayers()) - online.hidePlayer(MMOItems.plugin, stats.getPlayer()); + /* + * clears the target of any entity around the player + */ + for (Mob serverEntities : attack.getDamager().getWorld().getEntitiesByClass(Mob.class)) + if (serverEntities.getTarget() != null && serverEntities.getTarget().equals(attack.getDamager())) + serverEntities.setTarget(null); - /* - * clears the target of any entity around the player - */ - for (Mob serverEntities : stats.getPlayer().getWorld().getEntitiesByClass(Mob.class)) - if (serverEntities.getTarget() != null && serverEntities.getTarget().equals(stats.getPlayer())) - serverEntities.setTarget(null); - - ShadowVeilHandler svh = new ShadowVeilHandler(stats.getPlayer(), duration); - svh.setDeceptions(SilentNumbers.floor(ability.getModifier("deception"))); - } + ShadowVeilHandler svh = new ShadowVeilHandler(attack.getDamager(), duration); + svh.setDeceptions(SilentNumbers.floor(ability.getModifier("deception"))); + } public static class ShadowVeilHandler extends BukkitRunnable implements Listener { private final Player player; diff --git a/src/main/java/net/Indyuce/mmoitems/ability/list/simple/Shockwave.java b/src/main/java/net/Indyuce/mmoitems/ability/list/simple/Shockwave.java new file mode 100644 index 00000000..01d4d767 --- /dev/null +++ b/src/main/java/net/Indyuce/mmoitems/ability/list/simple/Shockwave.java @@ -0,0 +1,60 @@ +package net.Indyuce.mmoitems.ability.list.simple; + +import net.Indyuce.mmoitems.MMOItems; +import net.Indyuce.mmoitems.MMOUtils; +import net.Indyuce.mmoitems.ability.SimpleAbility; +import net.Indyuce.mmoitems.ability.metadata.SimpleAbilityMetadata; +import net.Indyuce.mmoitems.api.ItemAttackMetadata; +import org.bukkit.*; +import org.bukkit.entity.Entity; +import org.bukkit.entity.LivingEntity; +import org.bukkit.scheduler.BukkitRunnable; +import org.bukkit.util.Vector; + +import java.util.ArrayList; +import java.util.List; + +public class Shockwave extends SimpleAbility { + public Shockwave() { + super(CastingMode.ON_HIT, CastingMode.WHEN_HIT, CastingMode.LEFT_CLICK, CastingMode.RIGHT_CLICK, CastingMode.SHIFT_LEFT_CLICK, + CastingMode.SHIFT_RIGHT_CLICK); + + addModifier("cooldown", 7.5); + addModifier("knock-up", 1); + addModifier("length", 5); + addModifier("mana", 0); + addModifier("stamina", 0); + } + + @Override + public void whenCast(ItemAttackMetadata attack, SimpleAbilityMetadata ability) { + double knockUp = ability.getModifier("knock-up"); + double length = ability.getModifier("length"); + + new BukkitRunnable() { + final Vector vec = attack.getDamager().getEyeLocation().getDirection().setY(0); + final Location loc = attack.getDamager().getLocation(); + final List hit = new ArrayList<>(); + int ti = 0; + + public void run() { + ti++; + if (ti >= Math.min(20, length)) + cancel(); + + loc.add(vec); + + loc.getWorld().playSound(loc, Sound.BLOCK_GRAVEL_BREAK, 1, 2); + loc.getWorld().spawnParticle(Particle.BLOCK_CRACK, loc, 12, .5, 0, .5, 0, Material.DIRT.createBlockData()); + + for (Entity ent : MMOUtils.getNearbyChunkEntities(loc)) + if (ent.getLocation().distance(loc) < 1.1 && ent instanceof LivingEntity && !ent.equals(attack.getDamager()) + && !hit.contains(ent.getEntityId())) { + hit.add(ent.getEntityId()); + ent.playEffect(EntityEffect.HURT); + ent.setVelocity(ent.getVelocity().setY(.4 * knockUp)); + } + } + }.runTaskTimer(MMOItems.plugin, 0, 1); + } +} diff --git a/src/main/java/net/Indyuce/mmoitems/ability/list/simple/Sky_Smash.java b/src/main/java/net/Indyuce/mmoitems/ability/list/simple/Sky_Smash.java new file mode 100644 index 00000000..1fe5a779 --- /dev/null +++ b/src/main/java/net/Indyuce/mmoitems/ability/list/simple/Sky_Smash.java @@ -0,0 +1,48 @@ +package net.Indyuce.mmoitems.ability.list.simple; + +import io.lumine.mythic.lib.damage.AttackMetadata; +import io.lumine.mythic.lib.damage.DamageMetadata; +import io.lumine.mythic.lib.damage.DamageType; +import net.Indyuce.mmoitems.MMOUtils; +import net.Indyuce.mmoitems.ability.SimpleAbility; +import net.Indyuce.mmoitems.ability.metadata.SimpleAbilityMetadata; +import net.Indyuce.mmoitems.api.ItemAttackMetadata; +import org.bukkit.Location; +import org.bukkit.Particle; +import org.bukkit.Sound; +import org.bukkit.entity.Entity; +import org.bukkit.entity.LivingEntity; +import org.bukkit.potion.PotionEffect; +import org.bukkit.potion.PotionEffectType; + +public class Sky_Smash extends SimpleAbility { + public Sky_Smash() { + super(CastingMode.ON_HIT, CastingMode.WHEN_HIT, CastingMode.LEFT_CLICK, CastingMode.RIGHT_CLICK, CastingMode.SHIFT_LEFT_CLICK, CastingMode.SHIFT_RIGHT_CLICK); + + addModifier("cooldown", 10); + addModifier("damage", 3); + addModifier("knock-up", 1); + addModifier("mana", 0); + addModifier("stamina", 0); + } + + @Override + public void whenCast(ItemAttackMetadata attack, SimpleAbilityMetadata ability) { + double damage = ability.getModifier("damage"); + double knockUp = ability.getModifier("knock-up"); + + attack.getDamager().getWorld().playSound(attack.getDamager().getLocation(), Sound.ENTITY_ZOMBIE_ATTACK_IRON_DOOR, 2, .5f); + attack.getDamager().addPotionEffect(new PotionEffect(PotionEffectType.SLOW, 2, 254)); + Location loc = attack.getDamager().getEyeLocation().add(attack.getDamager().getEyeLocation().getDirection().multiply(3)); + loc.getWorld().spawnParticle(Particle.EXPLOSION_LARGE, loc, 0); + loc.getWorld().spawnParticle(Particle.SMOKE_LARGE, loc, 16, 0, 0, 0, .1); + + for (Entity entity : MMOUtils.getNearbyChunkEntities(loc)) + if (MMOUtils.canDamage(attack.getDamager(), entity) && entity.getLocation().distanceSquared(loc) < 10) { + new AttackMetadata(new DamageMetadata(damage, DamageType.SKILL, DamageType.PHYSICAL), attack.getStats()).damage((LivingEntity) entity); + Location loc1 = attack.getDamager().getEyeLocation().clone(); + loc1.setPitch(-70); + entity.setVelocity(loc1.getDirection().multiply(1.2 * knockUp)); + } + } +} diff --git a/src/main/java/net/Indyuce/mmoitems/ability/list/simple/Swiftness.java b/src/main/java/net/Indyuce/mmoitems/ability/list/simple/Swiftness.java new file mode 100644 index 00000000..40ec78ab --- /dev/null +++ b/src/main/java/net/Indyuce/mmoitems/ability/list/simple/Swiftness.java @@ -0,0 +1,35 @@ +package net.Indyuce.mmoitems.ability.list.simple; + +import io.lumine.mythic.lib.version.VersionSound; +import net.Indyuce.mmoitems.ability.SimpleAbility; +import net.Indyuce.mmoitems.ability.metadata.SimpleAbilityMetadata; +import net.Indyuce.mmoitems.api.ItemAttackMetadata; +import org.bukkit.Particle; +import org.bukkit.potion.PotionEffect; +import org.bukkit.potion.PotionEffectType; + +public class Swiftness extends SimpleAbility { + public Swiftness() { + super(CastingMode.ON_HIT, CastingMode.WHEN_HIT, CastingMode.LEFT_CLICK, CastingMode.RIGHT_CLICK, CastingMode.SHIFT_LEFT_CLICK, CastingMode.SHIFT_RIGHT_CLICK); + + addModifier("cooldown", 15); + addModifier("duration", 4); + addModifier("amplifier", 1); + addModifier("mana", 0); + addModifier("stamina", 0); + } + + @Override + public void whenCast(ItemAttackMetadata attack, SimpleAbilityMetadata ability) { + double duration = ability.getModifier("duration"); + int amplifier = (int) ability.getModifier("amplifier"); + + attack.getDamager().getWorld().playSound(attack.getDamager().getLocation(), VersionSound.ENTITY_ZOMBIE_PIGMAN_ANGRY.toSound(), 1, .3f); + for (double y = 0; y <= 2; y += .2) + for (double j = 0; j < Math.PI * 2; j += Math.PI / 16) + if (random.nextDouble() <= .7) + attack.getDamager().getWorld().spawnParticle(Particle.SPELL_INSTANT, attack.getDamager().getLocation().add(Math.cos(j), y, Math.sin(j)), 0); + attack.getDamager().addPotionEffect(new PotionEffect(PotionEffectType.SPEED, (int) (duration * 20), amplifier)); + attack.getDamager().addPotionEffect(new PotionEffect(PotionEffectType.JUMP, (int) (duration * 20), amplifier)); + } +} diff --git a/src/main/java/net/Indyuce/mmoitems/ability/list/simple/Throw_Up.java b/src/main/java/net/Indyuce/mmoitems/ability/list/simple/Throw_Up.java new file mode 100644 index 00000000..197239b9 --- /dev/null +++ b/src/main/java/net/Indyuce/mmoitems/ability/list/simple/Throw_Up.java @@ -0,0 +1,61 @@ +package net.Indyuce.mmoitems.ability.list.simple; + +import io.lumine.mythic.lib.damage.AttackMetadata; +import io.lumine.mythic.lib.damage.DamageMetadata; +import io.lumine.mythic.lib.damage.DamageType; +import net.Indyuce.mmoitems.MMOItems; +import net.Indyuce.mmoitems.MMOUtils; +import net.Indyuce.mmoitems.ability.SimpleAbility; +import net.Indyuce.mmoitems.ability.metadata.SimpleAbilityMetadata; +import net.Indyuce.mmoitems.api.ItemAttackMetadata; +import net.Indyuce.mmoitems.api.util.NoClipItem; +import org.bukkit.*; +import org.bukkit.entity.Entity; +import org.bukkit.entity.LivingEntity; +import org.bukkit.event.Listener; +import org.bukkit.inventory.ItemStack; +import org.bukkit.scheduler.BukkitRunnable; + +public class Throw_Up extends SimpleAbility implements Listener { + public Throw_Up() { + super(CastingMode.ON_HIT, CastingMode.WHEN_HIT, CastingMode.LEFT_CLICK, CastingMode.RIGHT_CLICK, CastingMode.SHIFT_LEFT_CLICK, CastingMode.SHIFT_RIGHT_CLICK); + + addModifier("duration", 2.5); + addModifier("damage", 2); + addModifier("cooldown", 10); + addModifier("mana", 0); + addModifier("stamina", 0); + } + + @Override + public void whenCast(ItemAttackMetadata attack, SimpleAbilityMetadata ability) { + double duration = ability.getModifier("duration") * 10; + double dps = ability.getModifier("damage") / 2; + + new BukkitRunnable() { + int j = 0; + + public void run() { + j++; + if (j > duration) + cancel(); + + Location loc = attack.getDamager().getEyeLocation(); + loc.setPitch((float) (loc.getPitch() + (random.nextDouble() - .5) * 30)); + loc.setYaw((float) (loc.getYaw() + (random.nextDouble() - .5) * 30)); + + if (j % 5 == 0) + for (Entity entity : MMOUtils.getNearbyChunkEntities(loc)) + if (entity.getLocation().distanceSquared(loc) < 40 && attack.getDamager().getEyeLocation().getDirection().angle(entity.getLocation().toVector().subtract(attack.getDamager().getLocation().toVector())) < Math.PI / 6 && MMOUtils.canDamage(attack.getDamager(), entity)) + new AttackMetadata(new DamageMetadata(dps, DamageType.SKILL, DamageType.PHYSICAL, DamageType.PROJECTILE), attack.getStats()).damage((LivingEntity) entity); + + loc.getWorld().playSound(loc, Sound.ENTITY_ZOMBIE_HURT, 1, 1); + + NoClipItem item = new NoClipItem(attack.getDamager().getLocation().add(0, 1.2, 0), new ItemStack(Material.ROTTEN_FLESH)); + Bukkit.getScheduler().scheduleSyncDelayedTask(MMOItems.plugin, item::close, 40); + item.getEntity().setVelocity(loc.getDirection().multiply(.8)); + attack.getDamager().getWorld().spawnParticle(Particle.SMOKE_LARGE, attack.getDamager().getLocation().add(0, 1.2, 0), 0, loc.getDirection().getX(), loc.getDirection().getY(), loc.getDirection().getZ(), 1); + } + }.runTaskTimer(MMOItems.plugin, 0, 2); + } +} diff --git a/src/main/java/net/Indyuce/mmoitems/ability/list/target/Blind.java b/src/main/java/net/Indyuce/mmoitems/ability/list/target/Blind.java new file mode 100644 index 00000000..6f0a412d --- /dev/null +++ b/src/main/java/net/Indyuce/mmoitems/ability/list/target/Blind.java @@ -0,0 +1,41 @@ +package net.Indyuce.mmoitems.ability.list.target; + +import io.lumine.mythic.lib.version.VersionSound; +import net.Indyuce.mmoitems.MMOUtils; +import net.Indyuce.mmoitems.ability.TargetAbility; +import net.Indyuce.mmoitems.ability.metadata.TargetAbilityMetadata; +import net.Indyuce.mmoitems.api.ItemAttackMetadata; +import org.bukkit.Color; +import org.bukkit.Location; +import org.bukkit.Particle; +import org.bukkit.entity.LivingEntity; +import org.bukkit.potion.PotionEffect; +import org.bukkit.potion.PotionEffectType; +import org.bukkit.util.Vector; + +public class Blind extends TargetAbility { + public Blind() { + super(CastingMode.ON_HIT, CastingMode.WHEN_HIT, CastingMode.LEFT_CLICK, CastingMode.RIGHT_CLICK, CastingMode.SHIFT_LEFT_CLICK, + CastingMode.SHIFT_RIGHT_CLICK); + + addModifier("duration", 5); + addModifier("cooldown", 9); + addModifier("mana", 0); + addModifier("stamina", 0); + } + + @Override + public void whenCast(ItemAttackMetadata attack, TargetAbilityMetadata ability) { + LivingEntity target = ability.getTarget(); + + target.getWorld().playSound(target.getLocation(), VersionSound.ENTITY_ENDERMAN_HURT.toSound(), 1, 2); + for (double i = 0; i < Math.PI * 2; i += Math.PI / 24) + for (double j = 0; j < 2; j++) { + Location loc = target.getLocation(); + Vector vec = MMOUtils.rotateFunc(new Vector(Math.cos(i), 1 + Math.cos(i + (Math.PI * j)) * .5, Math.sin(i)), + attack.getDamager().getLocation()); + loc.getWorld().spawnParticle(Particle.REDSTONE, loc.add(vec), 1, new Particle.DustOptions(Color.BLACK, 1)); + } + target.addPotionEffect(new PotionEffect(PotionEffectType.BLINDNESS, (int) (ability.getModifier("duration") * 20), 0)); + } +} diff --git a/src/main/java/net/Indyuce/mmoitems/ability/list/target/Bloodbath.java b/src/main/java/net/Indyuce/mmoitems/ability/list/target/Bloodbath.java new file mode 100644 index 00000000..b8e3487a --- /dev/null +++ b/src/main/java/net/Indyuce/mmoitems/ability/list/target/Bloodbath.java @@ -0,0 +1,28 @@ +package net.Indyuce.mmoitems.ability.list.target; + +import net.Indyuce.mmoitems.ability.TargetAbility; +import net.Indyuce.mmoitems.ability.metadata.TargetAbilityMetadata; +import net.Indyuce.mmoitems.api.ItemAttackMetadata; +import org.bukkit.Effect; +import org.bukkit.Sound; +import org.bukkit.entity.LivingEntity; + +public class Bloodbath extends TargetAbility { + public Bloodbath() { + super(CastingMode.ON_HIT, CastingMode.WHEN_HIT, CastingMode.LEFT_CLICK, CastingMode.RIGHT_CLICK, CastingMode.SHIFT_LEFT_CLICK, CastingMode.SHIFT_RIGHT_CLICK); + + addModifier("amount", 2); + addModifier("cooldown", 8); + addModifier("mana", 0); + addModifier("stamina", 0); + } + + @Override + public void whenCast(ItemAttackMetadata attack, TargetAbilityMetadata ability) { + LivingEntity target = ability.getTarget(); + + target.getWorld().playSound(target.getLocation(), Sound.ENTITY_COW_HURT, 1, 2); + target.getWorld().playEffect(target.getLocation().add(0, 1, 0), Effect.STEP_SOUND, 152); + attack.getDamager().setFoodLevel((int) Math.min(20, attack.getDamager().getFoodLevel() + ability.getModifier("amount"))); + } +} diff --git a/src/main/java/net/Indyuce/mmoitems/ability/list/target/Burn.java b/src/main/java/net/Indyuce/mmoitems/ability/list/target/Burn.java new file mode 100644 index 00000000..8444acae --- /dev/null +++ b/src/main/java/net/Indyuce/mmoitems/ability/list/target/Burn.java @@ -0,0 +1,47 @@ +package net.Indyuce.mmoitems.ability.list.target; + +import net.Indyuce.mmoitems.MMOItems; +import net.Indyuce.mmoitems.ability.TargetAbility; +import net.Indyuce.mmoitems.ability.metadata.TargetAbilityMetadata; +import net.Indyuce.mmoitems.api.ItemAttackMetadata; +import org.bukkit.Location; +import org.bukkit.Particle; +import org.bukkit.Sound; +import org.bukkit.entity.LivingEntity; +import org.bukkit.scheduler.BukkitRunnable; + +public class Burn extends TargetAbility { + public Burn() { + super(CastingMode.ON_HIT, CastingMode.WHEN_HIT, CastingMode.LEFT_CLICK, CastingMode.RIGHT_CLICK, CastingMode.SHIFT_LEFT_CLICK, CastingMode.SHIFT_RIGHT_CLICK); + + addModifier("duration", 3); + addModifier("cooldown", 8); + addModifier("mana", 0); + addModifier("stamina", 0); + } + + @Override + public void whenCast(ItemAttackMetadata attack, TargetAbilityMetadata ability) { + LivingEntity target = ability.getTarget(); + + new BukkitRunnable() { + final Location loc = target.getLocation(); + double y = 0; + + public void run() { + for (int j1 = 0; j1 < 3; j1++) { + y += .04; + for (int j = 0; j < 2; j++) { + double xz = y * Math.PI * 1.3 + (j * Math.PI); + Location loc1 = loc.clone().add(Math.cos(xz), y, Math.sin(xz)); + loc.getWorld().spawnParticle(Particle.FLAME, loc1, 0); + } + } + if (y >= 1.7) + cancel(); + } + }.runTaskTimer(MMOItems.plugin, 0, 1); + target.getWorld().playSound(target.getLocation(), Sound.ENTITY_BLAZE_HURT, 1, 2); + target.setFireTicks((int) (target.getFireTicks() + ability.getModifier("duration") * 20)); + } +} diff --git a/src/main/java/net/Indyuce/mmoitems/ability/list/target/Confuse.java b/src/main/java/net/Indyuce/mmoitems/ability/list/target/Confuse.java new file mode 100644 index 00000000..09bad094 --- /dev/null +++ b/src/main/java/net/Indyuce/mmoitems/ability/list/target/Confuse.java @@ -0,0 +1,46 @@ +package net.Indyuce.mmoitems.ability.list.target; + +import net.Indyuce.mmoitems.MMOItems; +import net.Indyuce.mmoitems.ability.TargetAbility; +import net.Indyuce.mmoitems.ability.metadata.TargetAbilityMetadata; +import net.Indyuce.mmoitems.api.ItemAttackMetadata; +import org.bukkit.Location; +import org.bukkit.Particle; +import org.bukkit.Sound; +import org.bukkit.entity.LivingEntity; +import org.bukkit.scheduler.BukkitRunnable; + +public class Confuse extends TargetAbility { + public Confuse() { + super(CastingMode.ON_HIT, CastingMode.WHEN_HIT, CastingMode.LEFT_CLICK, CastingMode.RIGHT_CLICK, CastingMode.SHIFT_LEFT_CLICK, CastingMode.SHIFT_RIGHT_CLICK); + + addModifier("cooldown", 7); + addModifier("mana", 0); + addModifier("stamina", 0); + } + + @Override + public void whenCast(ItemAttackMetadata attack, TargetAbilityMetadata ability) { + LivingEntity target = ability.getTarget(); + + target.getWorld().playSound(target.getLocation(), Sound.ENTITY_SHEEP_DEATH, 1, 2); + new BukkitRunnable() { + final Location loc = target.getLocation(); + final double rads = Math.toRadians(attack.getDamager().getEyeLocation().getYaw() - 90); + double ti = rads; + + public void run() { + for (int j1 = 0; j1 < 3; j1++) { + ti += Math.PI / 15; + Location loc1 = loc.clone().add(Math.cos(ti), 1, Math.sin(ti)); + loc.getWorld().spawnParticle(Particle.SPELL_WITCH, loc1, 0); + } + if (ti >= Math.PI * 2 + rads) + cancel(); + } + }.runTaskTimer(MMOItems.plugin, 0, 1); + Location loc = target.getLocation().clone(); + loc.setYaw(target.getLocation().getYaw() - 180); + target.teleport(loc); + } +} diff --git a/src/main/java/net/Indyuce/mmoitems/ability/list/target/Death_Mark.java b/src/main/java/net/Indyuce/mmoitems/ability/list/target/Death_Mark.java new file mode 100644 index 00000000..0f9ccc6a --- /dev/null +++ b/src/main/java/net/Indyuce/mmoitems/ability/list/target/Death_Mark.java @@ -0,0 +1,56 @@ +package net.Indyuce.mmoitems.ability.list.target; + +import io.lumine.mythic.lib.damage.AttackMetadata; +import io.lumine.mythic.lib.damage.DamageMetadata; +import io.lumine.mythic.lib.damage.DamageType; +import net.Indyuce.mmoitems.MMOItems; +import net.Indyuce.mmoitems.ability.TargetAbility; +import net.Indyuce.mmoitems.ability.metadata.TargetAbilityMetadata; +import net.Indyuce.mmoitems.api.ItemAttackMetadata; +import org.bukkit.Particle; +import org.bukkit.Sound; +import org.bukkit.entity.LivingEntity; +import org.bukkit.potion.PotionEffect; +import org.bukkit.potion.PotionEffectType; +import org.bukkit.scheduler.BukkitRunnable; + +public class Death_Mark extends TargetAbility { + public Death_Mark() { + super(CastingMode.ON_HIT, CastingMode.WHEN_HIT, CastingMode.LEFT_CLICK, CastingMode.RIGHT_CLICK, CastingMode.SHIFT_LEFT_CLICK, CastingMode.SHIFT_RIGHT_CLICK); + + addModifier("cooldown", 7); + addModifier("damage", 5); + addModifier("duration", 3); + addModifier("amplifier", 1); + addModifier("mana", 0); + addModifier("stamina", 0); + } + + @Override + public void whenCast(ItemAttackMetadata attack, TargetAbilityMetadata ability) { + LivingEntity target = ability.getTarget(); + + double duration = ability.getModifier("duration") * 20; + double dps = ability.getModifier("damage") / duration * 20; + + new BukkitRunnable() { + double ti = 0; + + public void run() { + ti++; + if (ti > duration || target == null || target.isDead()) { + cancel(); + return; + } + + target.getWorld().spawnParticle(Particle.SPELL_MOB, target.getLocation(), 4, .2, 0, .2, 0); + + if (ti % 20 == 0) + new AttackMetadata(new DamageMetadata(dps, DamageType.SKILL, DamageType.MAGIC), attack.getStats()).damage(target); + } + }.runTaskTimer(MMOItems.plugin, 0, 1); + target.getWorld().playSound(target.getLocation(), Sound.ENTITY_BLAZE_HURT, 1, 2); + target.removePotionEffect(PotionEffectType.SLOW); + target.addPotionEffect(new PotionEffect(PotionEffectType.SLOW, (int) duration, (int) ability.getModifier("amplifier"))); + } +} diff --git a/src/main/java/net/Indyuce/mmoitems/ability/list/target/Magma_Fissure.java b/src/main/java/net/Indyuce/mmoitems/ability/list/target/Magma_Fissure.java new file mode 100644 index 00000000..3c821232 --- /dev/null +++ b/src/main/java/net/Indyuce/mmoitems/ability/list/target/Magma_Fissure.java @@ -0,0 +1,61 @@ +package net.Indyuce.mmoitems.ability.list.target; + +import io.lumine.mythic.lib.damage.AttackMetadata; +import io.lumine.mythic.lib.damage.DamageMetadata; +import io.lumine.mythic.lib.damage.DamageType; +import io.lumine.mythic.lib.version.VersionSound; +import net.Indyuce.mmoitems.MMOItems; +import net.Indyuce.mmoitems.ability.TargetAbility; +import net.Indyuce.mmoitems.ability.metadata.TargetAbilityMetadata; +import net.Indyuce.mmoitems.api.ItemAttackMetadata; +import org.bukkit.Location; +import org.bukkit.Particle; +import org.bukkit.Sound; +import org.bukkit.entity.LivingEntity; +import org.bukkit.scheduler.BukkitRunnable; +import org.bukkit.util.Vector; + +public class Magma_Fissure extends TargetAbility { + public Magma_Fissure() { + super(CastingMode.ON_HIT, CastingMode.WHEN_HIT, CastingMode.LEFT_CLICK, CastingMode.RIGHT_CLICK, CastingMode.SHIFT_LEFT_CLICK, CastingMode.SHIFT_RIGHT_CLICK); + + addModifier("cooldown", 10); + addModifier("mana", 0); + addModifier("stamina", 0); + addModifier("ignite", 4); + addModifier("damage", 4); + } + + @Override + public void whenCast(ItemAttackMetadata attack, TargetAbilityMetadata ability) { + LivingEntity target = ability.getTarget(); + + new BukkitRunnable() { + final Location loc = attack.getDamager().getLocation().add(0, .2, 0); + int j = 0; + + public void run() { + j++; + if (target.isDead() || !target.getWorld().equals(loc.getWorld()) || j > 200) { + cancel(); + return; + } + + Vector vec = target.getLocation().add(0, .2, 0).subtract(loc).toVector().normalize().multiply(.6); + loc.add(vec); + + loc.getWorld().spawnParticle(Particle.LAVA, loc, 2, .2, 0, .2, 0); + loc.getWorld().spawnParticle(Particle.FLAME, loc, 2, .2, 0, .2, 0); + loc.getWorld().spawnParticle(Particle.SMOKE_NORMAL, loc, 2, .2, 0, .2, 0); + loc.getWorld().playSound(loc, VersionSound.BLOCK_NOTE_BLOCK_HAT.toSound(), 1, 1); + + if (target.getLocation().distanceSquared(loc) < 1) { + loc.getWorld().playSound(loc, Sound.ENTITY_BLAZE_HURT, 2, 1); + target.setFireTicks((int) (target.getFireTicks() + ability.getModifier("ignite") * 20)); + new AttackMetadata(new DamageMetadata(ability.getModifier("damage"), DamageType.SKILL, DamageType.MAGIC), attack.getStats()).damage(target); + cancel(); + } + } + }.runTaskTimer(MMOItems.plugin, 0, 1); + } +} \ No newline at end of file diff --git a/src/main/java/net/Indyuce/mmoitems/ability/list/target/Poison.java b/src/main/java/net/Indyuce/mmoitems/ability/list/target/Poison.java new file mode 100644 index 00000000..3e0cc0c6 --- /dev/null +++ b/src/main/java/net/Indyuce/mmoitems/ability/list/target/Poison.java @@ -0,0 +1,32 @@ +package net.Indyuce.mmoitems.ability.list.target; + +import net.Indyuce.mmoitems.ability.TargetAbility; +import net.Indyuce.mmoitems.ability.metadata.TargetAbilityMetadata; +import net.Indyuce.mmoitems.api.ItemAttackMetadata; +import org.bukkit.Particle; +import org.bukkit.Sound; +import org.bukkit.entity.LivingEntity; +import org.bukkit.potion.PotionEffect; +import org.bukkit.potion.PotionEffectType; + +public class Poison extends TargetAbility { + public Poison() { + super(CastingMode.ON_HIT, CastingMode.WHEN_HIT, CastingMode.LEFT_CLICK, CastingMode.RIGHT_CLICK, CastingMode.SHIFT_LEFT_CLICK, CastingMode.SHIFT_RIGHT_CLICK); + + addModifier("duration", 4); + addModifier("cooldown", 10); + addModifier("amplifier", 1); + addModifier("mana", 0); + addModifier("stamina", 0); + } + + @Override + public void whenCast(ItemAttackMetadata attack, TargetAbilityMetadata ability) { + LivingEntity target = ability.getTarget(); + + target.getWorld().spawnParticle(Particle.SLIME, target.getLocation().add(0, 1, 0), 32, 1, 1, 1, 0); + target.getWorld().spawnParticle(Particle.VILLAGER_HAPPY, target.getLocation().add(0, 1, 0), 24, 1, 1, 1, 0); + target.getWorld().playSound(target.getLocation(), Sound.BLOCK_BREWING_STAND_BREW, 1.5f, 2); + target.addPotionEffect(new PotionEffect(PotionEffectType.POISON, (int) (ability.getModifier("duration") * 20), (int) ability.getModifier("amplifier"))); + } +} diff --git a/src/main/java/net/Indyuce/mmoitems/ability/list/target/Shock.java b/src/main/java/net/Indyuce/mmoitems/ability/list/target/Shock.java new file mode 100644 index 00000000..0762c886 --- /dev/null +++ b/src/main/java/net/Indyuce/mmoitems/ability/list/target/Shock.java @@ -0,0 +1,57 @@ +package net.Indyuce.mmoitems.ability.list.target; + +import io.lumine.mythic.lib.version.VersionSound; +import net.Indyuce.mmoitems.MMOItems; +import net.Indyuce.mmoitems.ability.TargetAbility; +import net.Indyuce.mmoitems.ability.metadata.TargetAbilityMetadata; +import net.Indyuce.mmoitems.api.ItemAttackMetadata; +import org.bukkit.EntityEffect; +import org.bukkit.Location; +import org.bukkit.Particle; +import org.bukkit.entity.LivingEntity; +import org.bukkit.scheduler.BukkitRunnable; + +public class Shock extends TargetAbility { + public Shock() { + super(CastingMode.ON_HIT, CastingMode.WHEN_HIT, CastingMode.LEFT_CLICK, CastingMode.RIGHT_CLICK, CastingMode.SHIFT_LEFT_CLICK, CastingMode.SHIFT_RIGHT_CLICK); + + addModifier("duration", 2); + addModifier("cooldown", 8); + addModifier("mana", 0); + addModifier("stamina", 0); + } + + @Override + public void whenCast(ItemAttackMetadata attack, TargetAbilityMetadata ability) { + LivingEntity target = ability.getTarget(); + + double duration = ability.getModifier("duration"); + + target.getWorld().playSound(target.getLocation(), VersionSound.ENTITY_ZOMBIE_PIGMAN_ANGRY.toSound(), 1, 2); + new BukkitRunnable() { + final Location loc = target.getLocation(); + final double rads = Math.toRadians(attack.getDamager().getEyeLocation().getYaw() - 90); + double ti = rads; + + public void run() { + for (int j = 0; j < 3; j++) { + ti += Math.PI / 15; + target.getWorld().spawnParticle(Particle.SMOKE_LARGE, loc.clone().add(Math.cos(ti), 1, Math.sin(ti)), 0); + } + if (ti >= Math.PI * 2 + rads) + cancel(); + } + }.runTaskTimer(MMOItems.plugin, 0, 1); + + new BukkitRunnable() { + int ti; + + public void run() { + if (ti++ > (duration > 300 ? 300 : duration * 10) || target.isDead()) + cancel(); + else + target.playEffect(EntityEffect.HURT); + } + }.runTaskTimer(MMOItems.plugin, 0, 2); + } +} diff --git a/src/main/java/net/Indyuce/mmoitems/ability/list/target/Slow.java b/src/main/java/net/Indyuce/mmoitems/ability/list/target/Slow.java new file mode 100644 index 00000000..55e74b25 --- /dev/null +++ b/src/main/java/net/Indyuce/mmoitems/ability/list/target/Slow.java @@ -0,0 +1,53 @@ +package net.Indyuce.mmoitems.ability.list.target; + +import net.Indyuce.mmoitems.MMOItems; +import net.Indyuce.mmoitems.ability.TargetAbility; +import net.Indyuce.mmoitems.ability.metadata.TargetAbilityMetadata; +import net.Indyuce.mmoitems.api.ItemAttackMetadata; +import org.bukkit.Color; +import org.bukkit.Location; +import org.bukkit.Particle; +import org.bukkit.Sound; +import org.bukkit.entity.LivingEntity; +import org.bukkit.potion.PotionEffect; +import org.bukkit.potion.PotionEffectType; +import org.bukkit.scheduler.BukkitRunnable; + +public class Slow extends TargetAbility { + public Slow() { + super(CastingMode.ON_HIT, CastingMode.WHEN_HIT, CastingMode.LEFT_CLICK, CastingMode.RIGHT_CLICK, CastingMode.SHIFT_LEFT_CLICK, + CastingMode.SHIFT_RIGHT_CLICK); + + addModifier("cooldown", 5); + addModifier("duration", 3); + addModifier("amplifier", 1); + addModifier("mana", 0); + addModifier("stamina", 0); + } + + @Override + public void whenCast(ItemAttackMetadata attack, TargetAbilityMetadata ability) { + LivingEntity target = ability.getTarget(); + + new BukkitRunnable() { + final Location loc = target.getLocation(); + double ti = 0; + + public void run() { + ti += Math.PI / 10; + if (ti >= Math.PI * 2) + cancel(); + + for (double j = 0; j < Math.PI * 2; j += Math.PI) + for (double r = 0; r < .7; r += .1) + loc.getWorld().spawnParticle(Particle.REDSTONE, + loc.clone().add(Math.cos((ti / 2) + j + (Math.PI * r)) * r * 2, .1, Math.sin((ti / 2) + j + (Math.PI * r)) * r * 2), + 1, new Particle.DustOptions(Color.WHITE, 1)); + + } + }.runTaskTimer(MMOItems.plugin, 0, 1); + target.getWorld().playSound(target.getLocation(), Sound.ENTITY_LLAMA_ANGRY, 1, 2); + target.addPotionEffect( + new PotionEffect(PotionEffectType.SLOW, (int) (ability.getModifier("duration") * 20), (int) ability.getModifier("amplifier"))); + } +} diff --git a/src/main/java/net/Indyuce/mmoitems/ability/list/target/Smite.java b/src/main/java/net/Indyuce/mmoitems/ability/list/target/Smite.java new file mode 100644 index 00000000..1d9752ef --- /dev/null +++ b/src/main/java/net/Indyuce/mmoitems/ability/list/target/Smite.java @@ -0,0 +1,27 @@ +package net.Indyuce.mmoitems.ability.list.target; + +import io.lumine.mythic.lib.damage.AttackMetadata; +import io.lumine.mythic.lib.damage.DamageMetadata; +import io.lumine.mythic.lib.damage.DamageType; +import net.Indyuce.mmoitems.ability.TargetAbility; +import net.Indyuce.mmoitems.ability.metadata.TargetAbilityMetadata; +import net.Indyuce.mmoitems.api.ItemAttackMetadata; +import org.bukkit.entity.LivingEntity; + +public class Smite extends TargetAbility { + public Smite() { + super(CastingMode.ON_HIT, CastingMode.WHEN_HIT, CastingMode.LEFT_CLICK, CastingMode.RIGHT_CLICK, CastingMode.SHIFT_LEFT_CLICK, CastingMode.SHIFT_RIGHT_CLICK); + + addModifier("cooldown", 10); + addModifier("damage", 8); + addModifier("mana", 0); + addModifier("stamina", 0); + } + + @Override + public void whenCast(ItemAttackMetadata attack, TargetAbilityMetadata ability) { + LivingEntity target = ability.getTarget(); + new AttackMetadata(new DamageMetadata(ability.getModifier("damage"), DamageType.SKILL, DamageType.MAGIC), attack.getStats()).damage(target); + target.getWorld().strikeLightningEffect(target.getLocation()); + } +} diff --git a/src/main/java/net/Indyuce/mmoitems/ability/list/target/Sparkle.java b/src/main/java/net/Indyuce/mmoitems/ability/list/target/Sparkle.java new file mode 100644 index 00000000..1aca0981 --- /dev/null +++ b/src/main/java/net/Indyuce/mmoitems/ability/list/target/Sparkle.java @@ -0,0 +1,54 @@ +package net.Indyuce.mmoitems.ability.list.target; + +import io.lumine.mythic.lib.damage.AttackMetadata; +import io.lumine.mythic.lib.damage.DamageMetadata; +import io.lumine.mythic.lib.damage.DamageType; +import io.lumine.mythic.lib.version.VersionSound; +import net.Indyuce.mmoitems.ability.TargetAbility; +import net.Indyuce.mmoitems.ability.metadata.TargetAbilityMetadata; +import net.Indyuce.mmoitems.api.ItemAttackMetadata; +import org.bukkit.Location; +import org.bukkit.Particle; +import org.bukkit.entity.ArmorStand; +import org.bukkit.entity.Entity; +import org.bukkit.entity.LivingEntity; +import org.bukkit.util.Vector; + +public class Sparkle extends TargetAbility { + public Sparkle() { + super(CastingMode.ON_HIT, CastingMode.WHEN_HIT, CastingMode.LEFT_CLICK, CastingMode.RIGHT_CLICK, CastingMode.SHIFT_LEFT_CLICK, CastingMode.SHIFT_RIGHT_CLICK); + + addModifier("cooldown", 10); + addModifier("damage", 4); + addModifier("limit", 5); + addModifier("radius", 6); + addModifier("mana", 0); + addModifier("stamina", 0); + } + + @Override + public void whenCast(ItemAttackMetadata attack, TargetAbilityMetadata ability) { + LivingEntity target = ability.getTarget(); + double damage = ability.getModifier("damage"); + double radius = ability.getModifier("radius"); + double limit = ability.getModifier("limit"); + + new AttackMetadata(new DamageMetadata(damage, DamageType.SKILL, DamageType.MAGIC), attack.getStats()).damage(target); + target.getWorld().spawnParticle(Particle.EXPLOSION_LARGE, target.getLocation().add(0, 1, 0), 0); + target.getWorld().playSound(target.getLocation(), VersionSound.ENTITY_FIREWORK_ROCKET_TWINKLE.toSound(), 2, 2); + + int count = 0; + for (Entity entity : target.getNearbyEntities(radius, radius, radius)) + if (count < limit && entity instanceof LivingEntity && entity != attack.getDamager() && !(entity instanceof ArmorStand)) { + count++; + new AttackMetadata(new DamageMetadata(damage, DamageType.SKILL, DamageType.MAGIC), attack.getStats()).damage((LivingEntity) entity); + entity.getWorld().playSound(entity.getLocation(), VersionSound.ENTITY_FIREWORK_ROCKET_TWINKLE.toSound(), 2, 2); + Location loc_t = target.getLocation().add(0, .75, 0); + Location loc_ent = entity.getLocation().add(0, .75, 0); + for (double j1 = 0; j1 < 1; j1 += .04) { + Vector d = loc_ent.toVector().subtract(loc_t.toVector()); + target.getWorld().spawnParticle(Particle.FIREWORKS_SPARK, loc_t.clone().add(d.multiply(j1)), 3, .1, .1, .1, .008); + } + } + } +} diff --git a/src/main/java/net/Indyuce/mmoitems/ability/list/target/Starfall.java b/src/main/java/net/Indyuce/mmoitems/ability/list/target/Starfall.java new file mode 100644 index 00000000..466e22d9 --- /dev/null +++ b/src/main/java/net/Indyuce/mmoitems/ability/list/target/Starfall.java @@ -0,0 +1,55 @@ +package net.Indyuce.mmoitems.ability.list.target; + +import io.lumine.mythic.lib.damage.DamageType; +import io.lumine.mythic.lib.version.VersionSound; +import net.Indyuce.mmoitems.MMOItems; +import net.Indyuce.mmoitems.ability.TargetAbility; +import net.Indyuce.mmoitems.ability.metadata.TargetAbilityMetadata; +import net.Indyuce.mmoitems.api.ItemAttackMetadata; +import org.bukkit.Location; +import org.bukkit.Particle; +import org.bukkit.Sound; +import org.bukkit.entity.LivingEntity; +import org.bukkit.scheduler.BukkitRunnable; +import org.bukkit.util.Vector; + +public class Starfall extends TargetAbility { + public Starfall() { + super(CastingMode.ON_HIT); + + addModifier("cooldown", 8); + addModifier("damage", 3.5); + addModifier("mana", 0); + addModifier("stamina", 0); + } + + @Override + public void whenCast(ItemAttackMetadata attack, TargetAbilityMetadata ability) { + LivingEntity target = ability.getTarget(); + + new BukkitRunnable() { + final double ran = random.nextDouble() * Math.PI * 2; + final Location loc = target.getLocation().add(Math.cos(ran) * 3, 6, Math.sin(ran) * 3); + final Vector vec = target.getLocation().add(0, .65, 0).toVector().subtract(loc.toVector()).multiply(.05); + double ti = 0; + + public void run() { + loc.getWorld().playSound(loc, VersionSound.BLOCK_NOTE_BLOCK_HAT.toSound(), 2, 2); + for (int j = 0; j < 2; j++) { + ti += .05; + + loc.add(vec); + loc.getWorld().spawnParticle(Particle.FIREWORKS_SPARK, loc, 1, .04, 0, .04, 0); + if (ti >= 1) { + loc.getWorld().spawnParticle(Particle.FIREWORKS_SPARK, loc, 24, 0, 0, 0, .12); + loc.getWorld().playSound(loc, VersionSound.ENTITY_FIREWORK_ROCKET_BLAST.toSound(), 1, 2); + cancel(); + } + } + } + }.runTaskTimer(MMOItems.plugin, 0, 1); + target.getWorld().playSound(target.getLocation(), Sound.ENTITY_WITHER_SHOOT, 2, 2); + + attack.getDamage().add(ability.getModifier("damage"), DamageType.SKILL, DamageType.MAGIC); + } +} diff --git a/src/main/java/net/Indyuce/mmoitems/ability/list/target/Stun.java b/src/main/java/net/Indyuce/mmoitems/ability/list/target/Stun.java new file mode 100644 index 00000000..e5042808 --- /dev/null +++ b/src/main/java/net/Indyuce/mmoitems/ability/list/target/Stun.java @@ -0,0 +1,31 @@ +package net.Indyuce.mmoitems.ability.list.target; + +import net.Indyuce.mmoitems.ability.TargetAbility; +import net.Indyuce.mmoitems.ability.metadata.TargetAbilityMetadata; +import net.Indyuce.mmoitems.api.ItemAttackMetadata; +import org.bukkit.Effect; +import org.bukkit.Sound; +import org.bukkit.entity.LivingEntity; +import org.bukkit.potion.PotionEffect; +import org.bukkit.potion.PotionEffectType; + +public class Stun extends TargetAbility { + public Stun() { + super(CastingMode.ON_HIT, CastingMode.WHEN_HIT, CastingMode.LEFT_CLICK, CastingMode.RIGHT_CLICK, CastingMode.SHIFT_LEFT_CLICK, CastingMode.SHIFT_RIGHT_CLICK); + + addModifier("cooldown", 10); + addModifier("duration", 2); + addModifier("mana", 0); + addModifier("stamina", 0); + } + + @Override + public void whenCast(ItemAttackMetadata attack, TargetAbilityMetadata ability) { + LivingEntity target = ability.getTarget(); + + target.getWorld().playSound(target.getLocation(), Sound.BLOCK_ANVIL_LAND, 1, 2); + target.getWorld().playEffect(target.getLocation(), Effect.STEP_SOUND, 42); + target.getWorld().playEffect(target.getLocation().add(0, 1, 0), Effect.STEP_SOUND, 42); + target.addPotionEffect(new PotionEffect(PotionEffectType.SLOW, (int) (ability.getModifier("duration") * 20), 254)); + } +} diff --git a/src/main/java/net/Indyuce/mmoitems/ability/list/target/Tactical_Grenade.java b/src/main/java/net/Indyuce/mmoitems/ability/list/target/Tactical_Grenade.java new file mode 100644 index 00000000..41cf0765 --- /dev/null +++ b/src/main/java/net/Indyuce/mmoitems/ability/list/target/Tactical_Grenade.java @@ -0,0 +1,82 @@ +package net.Indyuce.mmoitems.ability.list.target; + +import io.lumine.mythic.lib.damage.AttackMetadata; +import io.lumine.mythic.lib.damage.DamageMetadata; +import io.lumine.mythic.lib.damage.DamageType; +import net.Indyuce.mmoitems.MMOItems; +import net.Indyuce.mmoitems.MMOUtils; +import net.Indyuce.mmoitems.ability.TargetAbility; +import net.Indyuce.mmoitems.ability.metadata.TargetAbilityMetadata; +import net.Indyuce.mmoitems.api.ItemAttackMetadata; +import org.bukkit.Location; +import org.bukkit.Particle; +import org.bukkit.Sound; +import org.bukkit.entity.Entity; +import org.bukkit.entity.LivingEntity; +import org.bukkit.scheduler.BukkitRunnable; +import org.bukkit.util.Vector; + +import java.util.ArrayList; +import java.util.List; + +public class Tactical_Grenade extends TargetAbility { + public Tactical_Grenade() { + super(CastingMode.ON_HIT, CastingMode.WHEN_HIT, CastingMode.LEFT_CLICK, CastingMode.RIGHT_CLICK, CastingMode.SHIFT_LEFT_CLICK, CastingMode.SHIFT_RIGHT_CLICK); + + addModifier("cooldown", 10); + addModifier("mana", 0); + addModifier("stamina", 0); + addModifier("knock-up", 1); + addModifier("damage", 4); + addModifier("radius", 4); + } + + @Override + public void whenCast(ItemAttackMetadata attack, TargetAbilityMetadata ability) { + LivingEntity target = ability.getTarget(); + + new BukkitRunnable() { + final Location loc = attack.getDamager().getLocation().add(0, .1, 0); + final double radius = ability.getModifier("radius"); + final double knockup = .7 * ability.getModifier("knock-up"); + final List hit = new ArrayList<>(); + int j = 0; + + public void run() { + j++; + if (target.isDead() || !target.getWorld().equals(loc.getWorld()) || j > 200) { + cancel(); + return; + } + + Vector vec = target.getLocation().add(0, .1, 0).subtract(loc).toVector(); + vec = vec.length() < 3 ? vec : vec.normalize().multiply(3); + loc.add(vec); + + loc.getWorld().spawnParticle(Particle.CLOUD, loc, 32, 1, 0, 1, 0); + loc.getWorld().spawnParticle(Particle.EXPLOSION_NORMAL, loc, 16, 1, 0, 1, .05); + loc.getWorld().playSound(loc, Sound.BLOCK_ANVIL_LAND, 2, 0); + loc.getWorld().playSound(loc, Sound.ENTITY_GENERIC_EXPLODE, 2, 1); + + for (Entity entity : MMOUtils.getNearbyChunkEntities(loc)) + if (!hit.contains(entity.getEntityId()) && MMOUtils.canDamage(attack.getDamager(), entity) && entity.getLocation().distanceSquared(loc) < radius * radius) { + + /* + * stop the runnable as soon as the grenade finally hits + * the initial target. + */ + hit.add(entity.getEntityId()); + if (entity.equals(target)) + cancel(); + + new AttackMetadata(new DamageMetadata(ability.getModifier("damage"), DamageType.SKILL, DamageType.MAGIC), attack.getStats()).damage((LivingEntity) entity); + entity.setVelocity(entity.getVelocity().add(offsetVector(knockup))); + } + } + }.runTaskTimer(MMOItems.plugin, 0, 12); + } + + private Vector offsetVector(double y) { + return new Vector(2 * (random.nextDouble() - .5), y, 2 * (random.nextDouble() - .5)); + } +} \ No newline at end of file diff --git a/src/main/java/net/Indyuce/mmoitems/ability/list/target/Targeted_Fireball.java b/src/main/java/net/Indyuce/mmoitems/ability/list/target/Targeted_Fireball.java new file mode 100644 index 00000000..fb16cbc9 --- /dev/null +++ b/src/main/java/net/Indyuce/mmoitems/ability/list/target/Targeted_Fireball.java @@ -0,0 +1,67 @@ +package net.Indyuce.mmoitems.ability.list.target; + +import io.lumine.mythic.lib.damage.AttackMetadata; +import io.lumine.mythic.lib.damage.DamageMetadata; +import io.lumine.mythic.lib.damage.DamageType; +import io.lumine.mythic.lib.version.VersionSound; +import net.Indyuce.mmoitems.MMOItems; +import net.Indyuce.mmoitems.MMOUtils; +import net.Indyuce.mmoitems.ability.TargetAbility; +import net.Indyuce.mmoitems.ability.metadata.TargetAbilityMetadata; +import net.Indyuce.mmoitems.api.ItemAttackMetadata; +import org.bukkit.Location; +import org.bukkit.Particle; +import org.bukkit.Sound; +import org.bukkit.entity.LivingEntity; +import org.bukkit.scheduler.BukkitRunnable; +import org.bukkit.util.Vector; + +public class Targeted_Fireball extends TargetAbility { + public Targeted_Fireball() { + super(CastingMode.ON_HIT, CastingMode.WHEN_HIT, CastingMode.LEFT_CLICK, CastingMode.RIGHT_CLICK, CastingMode.SHIFT_LEFT_CLICK, + CastingMode.SHIFT_RIGHT_CLICK); + + addModifier("cooldown", 10); + addModifier("mana", 0); + addModifier("stamina", 0); + addModifier("ignite", 4); + addModifier("damage", 4); + } + + @Override + public void whenCast(ItemAttackMetadata attack, TargetAbilityMetadata ability) { + LivingEntity target = ability.getTarget(); + + new BukkitRunnable() { + final Location loc = attack.getDamager().getLocation().add(0, 1.3, 0); + int j = 0; + + public void run() { + j++; + if (target.isDead() || !target.getWorld().equals(loc.getWorld()) || j > 200) { + cancel(); + return; + } + + Vector dir = target.getLocation().add(0, target.getHeight() / 2, 0).subtract(loc).toVector().normalize(); + loc.add(dir.multiply(.6)); + + loc.setDirection(dir); + for (double a = 0; a < Math.PI * 2; a += Math.PI / 6) { + Vector rotated = MMOUtils.rotateFunc(new Vector(Math.cos(a), Math.sin(a), 0), loc); + loc.getWorld().spawnParticle(Particle.FLAME, loc, 0, rotated.getX(), rotated.getY(), rotated.getZ(), .06); + } + + loc.getWorld().playSound(loc, VersionSound.BLOCK_NOTE_BLOCK_HAT.toSound(), 1, 1); + if (target.getLocation().add(0, target.getHeight() / 2, 0).distanceSquared(loc) < 1.3) { + loc.getWorld().spawnParticle(Particle.LAVA, loc, 8); + loc.getWorld().spawnParticle(Particle.FLAME, loc, 32, 0, 0, 0, .1); + loc.getWorld().playSound(loc, Sound.ENTITY_BLAZE_HURT, 2, 1); + target.setFireTicks((int) (target.getFireTicks() + ability.getModifier("ignite") * 20)); + new AttackMetadata(new DamageMetadata(ability.getModifier("damage"), DamageType.SKILL, DamageType.MAGIC, DamageType.PROJECTILE), attack.getStats()).damage(target); + cancel(); + } + } + }.runTaskTimer(MMOItems.plugin, 0, 1); + } +} \ No newline at end of file diff --git a/src/main/java/net/Indyuce/mmoitems/ability/list/target/Vampirism.java b/src/main/java/net/Indyuce/mmoitems/ability/list/target/Vampirism.java new file mode 100644 index 00000000..0f14dd48 --- /dev/null +++ b/src/main/java/net/Indyuce/mmoitems/ability/list/target/Vampirism.java @@ -0,0 +1,52 @@ +package net.Indyuce.mmoitems.ability.list.target; + +import net.Indyuce.mmoitems.MMOItems; +import net.Indyuce.mmoitems.MMOUtils; +import net.Indyuce.mmoitems.ability.TargetAbility; +import net.Indyuce.mmoitems.ability.metadata.TargetAbilityMetadata; +import net.Indyuce.mmoitems.api.ItemAttackMetadata; +import org.bukkit.Color; +import org.bukkit.Location; +import org.bukkit.Particle; +import org.bukkit.Sound; +import org.bukkit.entity.LivingEntity; +import org.bukkit.scheduler.BukkitRunnable; + +public class Vampirism extends TargetAbility { + public Vampirism() { + super(CastingMode.ON_HIT, CastingMode.WHEN_HIT, CastingMode.LEFT_CLICK, CastingMode.RIGHT_CLICK, CastingMode.SHIFT_LEFT_CLICK, + CastingMode.SHIFT_RIGHT_CLICK); + + addModifier("cooldown", 8); + addModifier("drain", 10); + addModifier("mana", 0); + addModifier("stamina", 0); + } + + @Override + public void whenCast(ItemAttackMetadata attack, TargetAbilityMetadata ability) { + LivingEntity target = ability.getTarget(); + + new BukkitRunnable() { + final Location loc = target.getLocation(); + double ti = 0; + double dis = 0; + + public void run() { + for (int j1 = 0; j1 < 4; j1++) { + ti += .75; + dis += ti <= 10 ? .15 : -.15; + + for (double j = 0; j < Math.PI * 2; j += Math.PI / 4) + loc.getWorld().spawnParticle(Particle.REDSTONE, + loc.clone().add(Math.cos(j + (ti / 20)) * dis, 0, Math.sin(j + (ti / 20)) * dis), 1, + new Particle.DustOptions(Color.RED, 1)); + } + if (ti >= 17) + cancel(); + } + }.runTaskTimer(MMOItems.plugin, 0, 1); + target.getWorld().playSound(target.getLocation(), Sound.ENTITY_WITCH_DRINK, 1, 2); + MMOUtils.heal(attack.getDamager(), attack.getDamage().getDamage() * ability.getModifier("drain") / 100); + } +} diff --git a/src/main/java/net/Indyuce/mmoitems/ability/onhit/Weaken_Target.java b/src/main/java/net/Indyuce/mmoitems/ability/list/target/Weaken_Target.java similarity index 66% rename from src/main/java/net/Indyuce/mmoitems/ability/onhit/Weaken_Target.java rename to src/main/java/net/Indyuce/mmoitems/ability/list/target/Weaken_Target.java index 8dd4d642..a9ed450e 100644 --- a/src/main/java/net/Indyuce/mmoitems/ability/onhit/Weaken_Target.java +++ b/src/main/java/net/Indyuce/mmoitems/ability/list/target/Weaken_Target.java @@ -1,9 +1,10 @@ -package net.Indyuce.mmoitems.ability.onhit; - -import java.util.HashMap; -import java.util.Map; -import java.util.UUID; +package net.Indyuce.mmoitems.ability.list.target; +import io.lumine.mythic.lib.version.VersionSound; +import net.Indyuce.mmoitems.MMOItems; +import net.Indyuce.mmoitems.ability.TargetAbility; +import net.Indyuce.mmoitems.ability.metadata.TargetAbilityMetadata; +import net.Indyuce.mmoitems.api.ItemAttackMetadata; import org.bukkit.Color; import org.bukkit.Location; import org.bukkit.Material; @@ -19,46 +20,36 @@ import org.bukkit.event.player.PlayerItemConsumeEvent; import org.bukkit.inventory.ItemStack; import org.bukkit.scheduler.BukkitRunnable; -import net.Indyuce.mmoitems.MMOItems; -import net.Indyuce.mmoitems.api.ItemAttackResult; -import net.Indyuce.mmoitems.api.ability.Ability; -import net.Indyuce.mmoitems.api.ability.AbilityResult; -import net.Indyuce.mmoitems.api.ability.TargetAbilityResult; -import net.Indyuce.mmoitems.api.player.PlayerStats.CachedStats; -import net.Indyuce.mmoitems.stat.data.AbilityData; -import io.lumine.mythic.lib.version.VersionSound; +import java.util.HashMap; +import java.util.Map; +import java.util.UUID; -public class Weaken_Target extends Ability implements Listener { - public final Map marked = new HashMap<>(); +public class Weaken_Target extends TargetAbility implements Listener { + public final Map marked = new HashMap<>(); - public Weaken_Target() { - super(CastingMode.ON_HIT, CastingMode.WHEN_HIT); + public Weaken_Target() { + super(CastingMode.ON_HIT, CastingMode.WHEN_HIT); - addModifier("duration", 4); - addModifier("extra-damage", 40); - addModifier("cooldown", 10); - addModifier("mana", 0); - addModifier("stamina", 0); + addModifier("duration", 4); + addModifier("extra-damage", 40); + addModifier("cooldown", 10); + addModifier("mana", 0); + addModifier("stamina", 0); } - @Override - public AbilityResult whenRan(CachedStats stats, LivingEntity target, AbilityData ability, ItemAttackResult result) { - return new TargetAbilityResult(ability, stats.getPlayer(), target); - } + @Override + public void whenCast(ItemAttackMetadata attack, TargetAbilityMetadata ability) { + LivingEntity target = ability.getTarget(); - @Override - public void whenCast(CachedStats stats, AbilityResult ability, ItemAttackResult result) { - LivingEntity target = ((TargetAbilityResult) ability).getTarget(); + marked.put(target.getUniqueId(), new WeakenedInfo(ability.getModifier("extra-damage"))); + effect(target.getLocation()); + target.getWorld().playSound(target.getLocation(), VersionSound.ENTITY_ENDERMAN_HURT.toSound(), 2, 1.5f); - marked.put(target.getUniqueId(), new WeakenedInfo(ability.getModifier("extra-damage"))); - effect(target.getLocation()); - target.getWorld().playSound(target.getLocation(), VersionSound.ENTITY_ENDERMAN_HURT.toSound(), 2, 1.5f); - - /* - * display particles until the entity is hit again and eventually remove - * the mark from the entity - */ - new BukkitRunnable() { + /* + * display particles until the entity is hit again and eventually remove + * the mark from the entity + */ + new BukkitRunnable() { final long duration = (long) (ability.getModifier("duration") * 1000); public void run() { diff --git a/src/main/java/net/Indyuce/mmoitems/ability/list/target/Wither.java b/src/main/java/net/Indyuce/mmoitems/ability/list/target/Wither.java new file mode 100644 index 00000000..973f7ece --- /dev/null +++ b/src/main/java/net/Indyuce/mmoitems/ability/list/target/Wither.java @@ -0,0 +1,55 @@ +package net.Indyuce.mmoitems.ability.list.target; + +import net.Indyuce.mmoitems.MMOItems; +import net.Indyuce.mmoitems.ability.TargetAbility; +import net.Indyuce.mmoitems.ability.metadata.TargetAbilityMetadata; +import net.Indyuce.mmoitems.api.ItemAttackMetadata; +import org.bukkit.Color; +import org.bukkit.Location; +import org.bukkit.Particle; +import org.bukkit.Sound; +import org.bukkit.entity.LivingEntity; +import org.bukkit.potion.PotionEffect; +import org.bukkit.potion.PotionEffectType; +import org.bukkit.scheduler.BukkitRunnable; + +public class Wither extends TargetAbility { + public Wither() { + super(CastingMode.ON_HIT, CastingMode.WHEN_HIT, CastingMode.LEFT_CLICK, CastingMode.RIGHT_CLICK, CastingMode.SHIFT_LEFT_CLICK, + CastingMode.SHIFT_RIGHT_CLICK); + + addModifier("cooldown", 8); + addModifier("duration", 3); + addModifier("amplifier", 1); + addModifier("mana", 0); + addModifier("stamina", 0); + } + + @Override + public void whenCast(ItemAttackMetadata attack, TargetAbilityMetadata ability) { + LivingEntity target = ability.getTarget(); + + new BukkitRunnable() { + final Location loc = target.getLocation(); + double y = 0; + + public void run() { + if (y > 3) + cancel(); + + for (int j1 = 0; j1 < 3; j1++) { + y += .07; + for (int j = 0; j < 3; j++) { + double a = y * Math.PI + (j * Math.PI * 2 / 3); + double x = Math.cos(a) * (3 - y) / 2.5; + double z = Math.sin(a) * (3 - y) / 2.5; + loc.getWorld().spawnParticle(Particle.REDSTONE, loc.clone().add(x, y, z), 1, new Particle.DustOptions(Color.BLACK, 1)); + } + } + } + }.runTaskTimer(MMOItems.plugin, 0, 1); + target.getWorld().playSound(target.getLocation(), Sound.ENTITY_WITHER_SHOOT, 2, 2); + target.addPotionEffect( + new PotionEffect(PotionEffectType.WITHER, (int) (ability.getModifier("duration") * 20), (int) ability.getModifier("amplifier"))); + } +} diff --git a/src/main/java/net/Indyuce/mmoitems/ability/list/vector/Bouncy_Fireball.java b/src/main/java/net/Indyuce/mmoitems/ability/list/vector/Bouncy_Fireball.java new file mode 100644 index 00000000..bfe625fd --- /dev/null +++ b/src/main/java/net/Indyuce/mmoitems/ability/list/vector/Bouncy_Fireball.java @@ -0,0 +1,88 @@ +package net.Indyuce.mmoitems.ability.list.vector; + +import io.lumine.mythic.lib.damage.AttackMetadata; +import io.lumine.mythic.lib.damage.DamageMetadata; +import io.lumine.mythic.lib.damage.DamageType; +import net.Indyuce.mmoitems.MMOItems; +import net.Indyuce.mmoitems.MMOUtils; +import net.Indyuce.mmoitems.ability.VectorAbility; +import net.Indyuce.mmoitems.ability.metadata.VectorAbilityMetadata; +import net.Indyuce.mmoitems.api.ItemAttackMetadata; +import org.bukkit.Location; +import org.bukkit.Particle; +import org.bukkit.Sound; +import org.bukkit.entity.Entity; +import org.bukkit.entity.LivingEntity; +import org.bukkit.scheduler.BukkitRunnable; +import org.bukkit.util.Vector; + +public class Bouncy_Fireball extends VectorAbility { + public Bouncy_Fireball() { + super(CastingMode.ON_HIT, CastingMode.WHEN_HIT, CastingMode.LEFT_CLICK, CastingMode.RIGHT_CLICK, CastingMode.SHIFT_LEFT_CLICK, CastingMode.SHIFT_RIGHT_CLICK); + + addModifier("cooldown", 20); + addModifier("damage", 5); + addModifier("ignite", 40); + addModifier("speed", 1); + addModifier("radius", 4); + addModifier("mana", 0); + addModifier("stamina", 0); + } + + @Override + public void whenCast(ItemAttackMetadata attack, VectorAbilityMetadata ability) { + attack.getDamager().getWorld().playSound(attack.getDamager().getLocation(), Sound.ENTITY_SNOWBALL_THROW, 2, 0); + new BukkitRunnable() { + final Vector vec = ability.getTarget().setY(0).normalize().multiply(.5 * ability.getModifier("speed")); + final Location loc = attack.getDamager().getLocation().clone().add(0, 1.2, 0); + int j = 0; + int bounces = 0; + + double y = .3; + + public void run() { + if (j++ > 100) { + loc.getWorld().spawnParticle(Particle.SMOKE_LARGE, loc, 32, 0, 0, 0, .05); + loc.getWorld().playSound(loc, Sound.BLOCK_FIRE_EXTINGUISH, 1, 1); + cancel(); + return; + } + + loc.add(vec); + loc.add(0, y, 0); + if (y > -.6) + y -= .05; + + loc.getWorld().spawnParticle(Particle.LAVA, loc, 0); + loc.getWorld().spawnParticle(Particle.FLAME, loc, 4, 0, 0, 0, .03); + loc.getWorld().spawnParticle(Particle.SMOKE_NORMAL, loc, 1, 0, 0, 0, .03); + + if (loc.getBlock().getType().isSolid()) { + loc.add(0, -y, 0); + loc.add(vec.clone().multiply(-1)); + y = .4; + bounces++; + loc.getWorld().playSound(loc, Sound.ENTITY_BLAZE_HURT, 3, 2); + } + + if (bounces > 2) { + double radius = ability.getModifier("radius"); + double damage = ability.getModifier("damage"); + double ignite = ability.getModifier("ignite"); + + for (Entity entity : MMOUtils.getNearbyChunkEntities(loc)) + if (entity.getLocation().distanceSquared(loc) < radius * radius) + if (MMOUtils.canDamage(attack.getDamager(), entity)) { + new AttackMetadata(new DamageMetadata(damage, DamageType.SKILL, DamageType.MAGIC, DamageType.PROJECTILE), attack.getStats()).damage((LivingEntity) entity); + entity.setFireTicks((int) (ignite * 20)); + } + + loc.getWorld().spawnParticle(Particle.EXPLOSION_LARGE, loc, 12, 2, 2, 2, 0); + loc.getWorld().spawnParticle(Particle.EXPLOSION_NORMAL, loc, 48, 0, 0, 0, .2); + loc.getWorld().playSound(loc, Sound.ENTITY_GENERIC_EXPLODE, 3, 0); + cancel(); + } + } + }.runTaskTimer(MMOItems.plugin, 0, 1); + } +} diff --git a/src/main/java/net/Indyuce/mmoitems/ability/list/vector/Corrupted_Fangs.java b/src/main/java/net/Indyuce/mmoitems/ability/list/vector/Corrupted_Fangs.java new file mode 100644 index 00000000..49c130a8 --- /dev/null +++ b/src/main/java/net/Indyuce/mmoitems/ability/list/vector/Corrupted_Fangs.java @@ -0,0 +1,81 @@ +package net.Indyuce.mmoitems.ability.list.vector; + +import net.Indyuce.mmoitems.MMOItems; +import net.Indyuce.mmoitems.MMOUtils; +import net.Indyuce.mmoitems.ability.VectorAbility; +import net.Indyuce.mmoitems.ability.metadata.VectorAbilityMetadata; +import net.Indyuce.mmoitems.api.ItemAttackMetadata; +import net.Indyuce.mmoitems.api.util.TemporaryListener; +import org.bukkit.Location; +import org.bukkit.Sound; +import org.bukkit.entity.EntityType; +import org.bukkit.entity.EvokerFangs; +import org.bukkit.entity.LivingEntity; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; +import org.bukkit.event.entity.EntityDamageByEntityEvent; +import org.bukkit.scheduler.BukkitRunnable; +import org.bukkit.util.Vector; + +import java.util.HashSet; +import java.util.Set; + +public class Corrupted_Fangs extends VectorAbility implements Listener { + public Corrupted_Fangs() { + super(CastingMode.ON_HIT, CastingMode.WHEN_HIT, CastingMode.LEFT_CLICK, CastingMode.RIGHT_CLICK, CastingMode.SHIFT_LEFT_CLICK, + CastingMode.SHIFT_RIGHT_CLICK); + + addModifier("damage", 5); + addModifier("cooldown", 12); + addModifier("mana", 0); + addModifier("stamina", 0); + addModifier("fangs", 6); + } + + @Override + public void whenCast(ItemAttackMetadata attack, VectorAbilityMetadata ability) { + attack.getDamager().getWorld().playSound(attack.getDamager().getLocation(), Sound.ENTITY_WITHER_SHOOT, 2, 2); + new BukkitRunnable() { + final Vector vec = ability.getTarget().setY(0).multiply(2); + final Location loc = attack.getDamager().getLocation(); + final FangsHandler handler = new FangsHandler(attack, ability.getModifier("damage")); + final double fangAmount = ability.getModifier("fangs"); + double ti = 0; + + public void run() { + if (ti++ >= fangAmount) { + handler.close(3 * 20); + cancel(); + return; + } + + loc.add(vec); + EvokerFangs evokerFangs = (EvokerFangs) attack.getDamager().getWorld().spawnEntity(loc, EntityType.EVOKER_FANGS); + handler.entities.add(evokerFangs.getEntityId()); + } + }.runTaskTimer(MMOItems.plugin, 0, 1); + } + + public class FangsHandler extends TemporaryListener { + private final Set entities = new HashSet<>(); + private final ItemAttackMetadata attackMeta; + private final double damage; + + public FangsHandler(ItemAttackMetadata attackMeta, double damage) { + super(EntityDamageByEntityEvent.getHandlerList()); + + this.attackMeta = attackMeta; + this.damage = damage; + } + + @EventHandler + public void a(EntityDamageByEntityEvent event) { + if (event.getDamager() instanceof EvokerFangs && entities.contains(event.getDamager().getEntityId())) { + event.setCancelled(true); + + if (MMOUtils.canDamage(attackMeta.getDamager(), event.getEntity())) + attackMeta.damage((LivingEntity) event.getEntity()); + } + } + } +} diff --git a/src/main/java/net/Indyuce/mmoitems/ability/list/vector/Cursed_Beam.java b/src/main/java/net/Indyuce/mmoitems/ability/list/vector/Cursed_Beam.java new file mode 100644 index 00000000..dab3fb0d --- /dev/null +++ b/src/main/java/net/Indyuce/mmoitems/ability/list/vector/Cursed_Beam.java @@ -0,0 +1,98 @@ +package net.Indyuce.mmoitems.ability.list.vector; + +import io.lumine.mythic.lib.damage.AttackMetadata; +import io.lumine.mythic.lib.damage.DamageMetadata; +import io.lumine.mythic.lib.damage.DamageType; +import io.lumine.mythic.lib.version.VersionSound; +import net.Indyuce.mmoitems.MMOItems; +import net.Indyuce.mmoitems.MMOUtils; +import net.Indyuce.mmoitems.ability.VectorAbility; +import net.Indyuce.mmoitems.ability.metadata.VectorAbilityMetadata; +import net.Indyuce.mmoitems.api.ItemAttackMetadata; +import org.bukkit.Location; +import org.bukkit.Particle; +import org.bukkit.Sound; +import org.bukkit.entity.Entity; +import org.bukkit.entity.LivingEntity; +import org.bukkit.potion.PotionEffect; +import org.bukkit.potion.PotionEffectType; +import org.bukkit.scheduler.BukkitRunnable; +import org.bukkit.util.Vector; + +import java.util.List; + +public class Cursed_Beam extends VectorAbility { + public Cursed_Beam() { + super(CastingMode.ON_HIT, CastingMode.WHEN_HIT, CastingMode.LEFT_CLICK, CastingMode.RIGHT_CLICK, CastingMode.SHIFT_LEFT_CLICK, CastingMode.SHIFT_RIGHT_CLICK); + + addModifier("damage", 8); + addModifier("cooldown", 10); + addModifier("duration", 5); + addModifier("mana", 0); + addModifier("stamina", 0); + } + + @Override + public void whenCast(ItemAttackMetadata attack, VectorAbilityMetadata ability) { + double duration = ability.getModifier("duration"); + + attack.getDamager().getWorld().playSound(attack.getDamager().getLocation(), Sound.ENTITY_WITHER_SHOOT, 2, 2); + new BukkitRunnable() { + final Vector dir = ability.getTarget().multiply(.3); + final Location loc = attack.getDamager().getEyeLocation().clone(); + final double r = 0.4; + int ti = 0; + + public void run() { + ti++; + if (ti > 50) + cancel(); + + List entities = MMOUtils.getNearbyChunkEntities(loc); + for (double j = 0; j < 4; j++) { + loc.add(dir); + for (double i = 0; i < Math.PI * 2; i += Math.PI / 6) { + Vector vec = MMOUtils.rotateFunc(new Vector(r * Math.cos(i), r * Math.sin(i), 0), loc); + loc.add(vec); + loc.getWorld().spawnParticle(Particle.SPELL_WITCH, loc, 0); + loc.add(vec.multiply(-1)); + } + + for (Entity target : entities) + if (MMOUtils.canDamage(attack.getDamager(), loc, target)) { + effect(target); + double damage = ability.getModifier("damage"); + loc.getWorld().playSound(loc, VersionSound.ENTITY_ENDERMAN_TELEPORT.toSound(), 2, .7f); + + for (Entity entity : entities) + if (MMOUtils.canDamage(attack.getDamager(), entity) && loc.distanceSquared(entity.getLocation().add(0, 1, 0)) < 9) { + new AttackMetadata(new DamageMetadata(damage, DamageType.SKILL, DamageType.MAGIC, DamageType.PROJECTILE), attack.getStats()).damage((LivingEntity) entity); + ((LivingEntity) entity).addPotionEffect(new PotionEffect(PotionEffectType.BLINDNESS, (int) (duration * 20), 0)); + } + cancel(); + return; + } + } + } + }.runTaskTimer(MMOItems.plugin, 0, 1); + } + + private void effect(Entity ent) { + new BukkitRunnable() { + final Location loc2 = ent.getLocation(); + double y = 0; + + public void run() { + for (int i = 0; i < 3; i++) { + y += .05; + for (int j = 0; j < 2; j++) { + double xz = y * Math.PI * .8 + (j * Math.PI); + loc2.getWorld().spawnParticle(Particle.SPELL_WITCH, loc2.clone().add(Math.cos(xz) * 2.5, y, Math.sin(xz) * 2.5), 0); + } + } + if (y >= 3) + cancel(); + } + }.runTaskTimer(MMOItems.plugin, 0, 1); + } +} diff --git a/src/main/java/net/Indyuce/mmoitems/ability/Explosive_Turkey.java b/src/main/java/net/Indyuce/mmoitems/ability/list/vector/Explosive_Turkey.java similarity index 77% rename from src/main/java/net/Indyuce/mmoitems/ability/Explosive_Turkey.java rename to src/main/java/net/Indyuce/mmoitems/ability/list/vector/Explosive_Turkey.java index 97be213a..778387e1 100644 --- a/src/main/java/net/Indyuce/mmoitems/ability/Explosive_Turkey.java +++ b/src/main/java/net/Indyuce/mmoitems/ability/list/vector/Explosive_Turkey.java @@ -1,16 +1,14 @@ -package net.Indyuce.mmoitems.ability; +package net.Indyuce.mmoitems.ability.list.vector; -import io.lumine.mythic.lib.api.AttackResult; -import io.lumine.mythic.lib.api.DamageType; +import io.lumine.mythic.lib.damage.AttackMetadata; +import io.lumine.mythic.lib.damage.DamageMetadata; +import io.lumine.mythic.lib.damage.DamageType; import net.Indyuce.mmoitems.MMOItems; import net.Indyuce.mmoitems.MMOUtils; -import net.Indyuce.mmoitems.api.ItemAttackResult; -import net.Indyuce.mmoitems.api.ability.Ability; -import net.Indyuce.mmoitems.api.ability.AbilityResult; -import net.Indyuce.mmoitems.api.ability.SimpleAbilityResult; -import net.Indyuce.mmoitems.api.player.PlayerStats.CachedStats; +import net.Indyuce.mmoitems.ability.VectorAbility; +import net.Indyuce.mmoitems.ability.metadata.VectorAbilityMetadata; +import net.Indyuce.mmoitems.api.ItemAttackMetadata; import net.Indyuce.mmoitems.api.util.TemporaryListener; -import net.Indyuce.mmoitems.stat.data.AbilityData; import org.bukkit.Particle; import org.bukkit.Sound; import org.bukkit.attribute.Attribute; @@ -24,7 +22,7 @@ import org.bukkit.event.entity.EntityDeathEvent; import org.bukkit.scheduler.BukkitRunnable; import org.bukkit.util.Vector; -public class Explosive_Turkey extends Ability implements Listener { +public class Explosive_Turkey extends VectorAbility implements Listener { public Explosive_Turkey() { super(CastingMode.ON_HIT, CastingMode.WHEN_HIT, CastingMode.LEFT_CLICK, CastingMode.RIGHT_CLICK, CastingMode.SHIFT_LEFT_CLICK, CastingMode.SHIFT_RIGHT_CLICK); @@ -39,20 +37,15 @@ public class Explosive_Turkey extends Ability implements Listener { } @Override - public AbilityResult whenRan(CachedStats stats, LivingEntity target, AbilityData ability, ItemAttackResult result) { - return new SimpleAbilityResult(ability); - } - - @Override - public void whenCast(CachedStats stats, AbilityResult ability, ItemAttackResult result) { + public void whenCast(ItemAttackMetadata attack, VectorAbilityMetadata ability) { double duration = ability.getModifier("duration") * 10; double damage = ability.getModifier("damage"); double radiusSquared = Math.pow(ability.getModifier("radius"), 2); double knockback = ability.getModifier("knockback"); - Vector vec = stats.getPlayer().getEyeLocation().getDirection().clone().multiply(.6); + Vector vec = ability.getTarget().normalize().multiply(.6); - Chicken chicken = (Chicken) stats.getPlayer().getWorld().spawnEntity(stats.getPlayer().getLocation().add(0, 1.3, 0).add(vec), + Chicken chicken = (Chicken) attack.getDamager().getWorld().spawnEntity(attack.getDamager().getLocation().add(0, 1.3, 0).add(vec), EntityType.CHICKEN); ChickenHandler chickenHandler = new ChickenHandler(chicken); chicken.setInvulnerable(true); @@ -103,9 +96,8 @@ public class Explosive_Turkey extends Ability implements Listener { chicken.getWorld().playSound(chicken.getLocation(), Sound.ENTITY_GENERIC_EXPLODE, 2, 1.5f); for (Entity entity : MMOUtils.getNearbyChunkEntities(chicken.getLocation())) if (!entity.isDead() && entity.getLocation().distanceSquared(chicken.getLocation()) < radiusSquared - && MMOUtils.canDamage(stats.getPlayer(), entity)) { - new AttackResult(damage, DamageType.SKILL, DamageType.MAGIC, DamageType.PROJECTILE).damage(stats.getPlayer(), - (LivingEntity) entity); + && MMOUtils.canDamage(attack.getDamager(), entity)) { + new AttackMetadata(new DamageMetadata(damage, DamageType.SKILL, DamageType.MAGIC, DamageType.PROJECTILE), attack.getStats()).damage((LivingEntity) entity); entity.setVelocity(entity.getLocation().toVector().subtract(chicken.getLocation().toVector()).multiply(.1 * knockback) .setY(.4 * knockback)); } diff --git a/src/main/java/net/Indyuce/mmoitems/ability/list/vector/Fire_Meteor.java b/src/main/java/net/Indyuce/mmoitems/ability/list/vector/Fire_Meteor.java new file mode 100644 index 00000000..65168aa0 --- /dev/null +++ b/src/main/java/net/Indyuce/mmoitems/ability/list/vector/Fire_Meteor.java @@ -0,0 +1,68 @@ +package net.Indyuce.mmoitems.ability.list.vector; + +import io.lumine.mythic.lib.damage.AttackMetadata; +import io.lumine.mythic.lib.damage.DamageMetadata; +import io.lumine.mythic.lib.damage.DamageType; +import io.lumine.mythic.lib.version.VersionSound; +import net.Indyuce.mmoitems.MMOItems; +import net.Indyuce.mmoitems.MMOUtils; +import net.Indyuce.mmoitems.ability.VectorAbility; +import net.Indyuce.mmoitems.ability.metadata.VectorAbilityMetadata; +import net.Indyuce.mmoitems.api.ItemAttackMetadata; +import org.bukkit.Location; +import org.bukkit.Particle; +import org.bukkit.Sound; +import org.bukkit.block.BlockFace; +import org.bukkit.entity.Entity; +import org.bukkit.entity.LivingEntity; +import org.bukkit.scheduler.BukkitRunnable; +import org.bukkit.util.Vector; + +public class Fire_Meteor extends VectorAbility { + public Fire_Meteor() { + super(CastingMode.ON_HIT, CastingMode.WHEN_HIT, CastingMode.LEFT_CLICK, CastingMode.RIGHT_CLICK, CastingMode.SHIFT_LEFT_CLICK, CastingMode.SHIFT_RIGHT_CLICK); + + addModifier("damage", 6); + addModifier("knockback", 1); + addModifier("radius", 4); + addModifier("cooldown", 10); + addModifier("mana", 0); + addModifier("stamina", 0); + } + + @Override + public void whenCast(ItemAttackMetadata attack, VectorAbilityMetadata ability) { + attack.getDamager().getWorld().playSound(attack.getDamager().getLocation(), VersionSound.ENTITY_ENDERMAN_TELEPORT.toSound(), 3, 1); + new BukkitRunnable() { + final Location loc = attack.getDamager().getLocation().clone().add(0, 10, 0); + final Vector vec = ability.getTarget().multiply(1.3).setY(-1).normalize(); + double ti = 0; + + public void run() { + ti++; + if (ti > 40) + cancel(); + + loc.add(vec); + loc.getWorld().spawnParticle(Particle.EXPLOSION_LARGE, loc, 0); + loc.getWorld().spawnParticle(Particle.FLAME, loc, 4, .2, .2, .2, 0); + if (loc.getBlock().getRelative(BlockFace.DOWN).getType().isSolid() || loc.getBlock().getType().isSolid()) { + loc.getWorld().playSound(loc, Sound.ENTITY_GENERIC_EXPLODE, 3, .6f); + loc.getWorld().spawnParticle(Particle.EXPLOSION_LARGE, loc, 10, 2, 2, 2, 0); + loc.getWorld().spawnParticle(Particle.EXPLOSION_NORMAL, loc, 32, 0, 0, 0, .3); + loc.getWorld().spawnParticle(Particle.FLAME, loc, 32, 0, 0, 0, .3); + + double damage = ability.getModifier("damage"); + double knockback = ability.getModifier("knockback"); + double radius = ability.getModifier("radius"); + for (Entity entity : MMOUtils.getNearbyChunkEntities(loc)) + if (MMOUtils.canDamage(attack.getDamager(), entity) && entity.getLocation().distanceSquared(loc) < radius * radius) { + new AttackMetadata(new DamageMetadata(damage, DamageType.SKILL, DamageType.MAGIC, DamageType.PROJECTILE), attack.getStats()).damage((LivingEntity) entity); + entity.setVelocity(entity.getLocation().toVector().subtract(loc.toVector()).multiply(.1 * knockback).setY(.4 * knockback)); + } + cancel(); + } + } + }.runTaskTimer(MMOItems.plugin, 0, 1); + } +} diff --git a/src/main/java/net/Indyuce/mmoitems/ability/list/vector/Firebolt.java b/src/main/java/net/Indyuce/mmoitems/ability/list/vector/Firebolt.java new file mode 100644 index 00000000..8f4ee5fb --- /dev/null +++ b/src/main/java/net/Indyuce/mmoitems/ability/list/vector/Firebolt.java @@ -0,0 +1,71 @@ +package net.Indyuce.mmoitems.ability.list.vector; + +import io.lumine.mythic.lib.damage.AttackMetadata; +import io.lumine.mythic.lib.damage.DamageMetadata; +import io.lumine.mythic.lib.damage.DamageType; +import io.lumine.mythic.lib.version.VersionSound; +import net.Indyuce.mmoitems.MMOItems; +import net.Indyuce.mmoitems.MMOUtils; +import net.Indyuce.mmoitems.ability.VectorAbility; +import net.Indyuce.mmoitems.ability.metadata.VectorAbilityMetadata; +import net.Indyuce.mmoitems.api.ItemAttackMetadata; +import org.bukkit.Location; +import org.bukkit.Particle; +import org.bukkit.Sound; +import org.bukkit.entity.Entity; +import org.bukkit.entity.LivingEntity; +import org.bukkit.scheduler.BukkitRunnable; +import org.bukkit.util.Vector; + +import java.util.List; + +public class Firebolt extends VectorAbility { + public Firebolt() { + super(CastingMode.ON_HIT, CastingMode.WHEN_HIT, CastingMode.LEFT_CLICK, CastingMode.RIGHT_CLICK, CastingMode.SHIFT_LEFT_CLICK, CastingMode.SHIFT_RIGHT_CLICK); + + addModifier("damage", 6); + addModifier("ignite", 3); + addModifier("cooldown", 10); + addModifier("mana", 0); + addModifier("stamina", 0); + } + + @Override + public void whenCast(ItemAttackMetadata attack, VectorAbilityMetadata ability) { + attack.getDamager().getWorld().playSound(attack.getDamager().getLocation(), VersionSound.ENTITY_FIREWORK_ROCKET_BLAST.toSound(), 1, 1); + new BukkitRunnable() { + final Vector vec = ability.getTarget().multiply(.8); + final Location loc = attack.getDamager().getEyeLocation(); + int ti = 0; + + public void run() { + ti++; + if (ti > 20) + cancel(); + + List entities = MMOUtils.getNearbyChunkEntities(loc); + loc.getWorld().playSound(loc, Sound.BLOCK_FIRE_AMBIENT, 2, 1); + for (int j = 0; j < 2; j++) { + loc.add(vec); + if (loc.getBlock().getType().isSolid()) + cancel(); + + loc.getWorld().spawnParticle(Particle.FLAME, loc, 5, .12, .12, .12, 0); + if (random.nextDouble() < .3) + loc.getWorld().spawnParticle(Particle.LAVA, loc, 0); + for (Entity target : entities) + if (MMOUtils.canDamage(attack.getDamager(), loc, target)) { + loc.getWorld().spawnParticle(Particle.FLAME, loc, 32, 0, 0, 0, .1); + loc.getWorld().spawnParticle(Particle.LAVA, loc, 8, 0, 0, 0, 0); + loc.getWorld().spawnParticle(Particle.EXPLOSION_LARGE, loc, 0); + loc.getWorld().playSound(loc, Sound.ENTITY_GENERIC_EXPLODE, 3, 1); + new AttackMetadata(new DamageMetadata(ability.getModifier("damage"), DamageType.SKILL, DamageType.MAGIC, DamageType.PROJECTILE), attack.getStats()).damage((LivingEntity) target); + target.setFireTicks((int) ability.getModifier("ignite") * 20); + cancel(); + return; + } + } + } + }.runTaskTimer(MMOItems.plugin, 0, 1); + } +} diff --git a/src/main/java/net/Indyuce/mmoitems/ability/list/vector/Heavy_Charge.java b/src/main/java/net/Indyuce/mmoitems/ability/list/vector/Heavy_Charge.java new file mode 100644 index 00000000..44006ced --- /dev/null +++ b/src/main/java/net/Indyuce/mmoitems/ability/list/vector/Heavy_Charge.java @@ -0,0 +1,59 @@ +package net.Indyuce.mmoitems.ability.list.vector; + +import io.lumine.mythic.lib.damage.AttackMetadata; +import io.lumine.mythic.lib.damage.DamageMetadata; +import io.lumine.mythic.lib.damage.DamageType; +import net.Indyuce.mmoitems.MMOItems; +import net.Indyuce.mmoitems.MMOUtils; +import net.Indyuce.mmoitems.ability.VectorAbility; +import net.Indyuce.mmoitems.ability.metadata.VectorAbilityMetadata; +import net.Indyuce.mmoitems.api.ItemAttackMetadata; +import org.bukkit.Particle; +import org.bukkit.Sound; +import org.bukkit.entity.Entity; +import org.bukkit.entity.LivingEntity; +import org.bukkit.scheduler.BukkitRunnable; +import org.bukkit.util.Vector; + +public class Heavy_Charge extends VectorAbility { + public Heavy_Charge() { + super(CastingMode.ON_HIT, CastingMode.WHEN_HIT, CastingMode.LEFT_CLICK, CastingMode.RIGHT_CLICK, CastingMode.SHIFT_LEFT_CLICK, CastingMode.SHIFT_RIGHT_CLICK); + + addModifier("damage", 6); + addModifier("knockback", 1); + addModifier("cooldown", 10); + addModifier("mana", 0); + addModifier("stamina", 0); + } + + @Override + public void whenCast(ItemAttackMetadata attack, VectorAbilityMetadata ability) { + double knockback = ability.getModifier("knockback"); + + new BukkitRunnable() { + final Vector vec = ability.getTarget().setY(-1); + double ti = 0; + + public void run() { + if (ti++ > 20) + cancel(); + + if (ti < 9) { + attack.getDamager().setVelocity(vec); + attack.getDamager().getWorld().spawnParticle(Particle.EXPLOSION_NORMAL, attack.getDamager().getLocation().add(0, 1, 0), 3, .13, .13, .13, 0); + } + + for (Entity target : attack.getDamager().getNearbyEntities(1, 1, 1)) + if (MMOUtils.canDamage(attack.getDamager(), target)) { + attack.getDamager().getWorld().playSound(attack.getDamager().getLocation(), Sound.ENTITY_ZOMBIE_ATTACK_IRON_DOOR, 1, 1); + attack.getDamager().getWorld().spawnParticle(Particle.EXPLOSION_LARGE, target.getLocation().add(0, 1, 0), 0); + target.setVelocity(attack.getDamager().getVelocity().setY(0.3).multiply(1.7 * knockback)); + attack.getDamager().setVelocity(attack.getDamager().getVelocity().setX(0).setY(0).setZ(0)); + new AttackMetadata(new DamageMetadata(ability.getModifier("damage"), DamageType.SKILL, DamageType.PHYSICAL), attack.getStats()).damage((LivingEntity) target); + cancel(); + break; + } + } + }.runTaskTimer(MMOItems.plugin, 0, 1); + } +} diff --git a/src/main/java/net/Indyuce/mmoitems/ability/list/vector/Holy_Missile.java b/src/main/java/net/Indyuce/mmoitems/ability/list/vector/Holy_Missile.java new file mode 100644 index 00000000..c5f53a72 --- /dev/null +++ b/src/main/java/net/Indyuce/mmoitems/ability/list/vector/Holy_Missile.java @@ -0,0 +1,75 @@ +package net.Indyuce.mmoitems.ability.list.vector; + +import io.lumine.mythic.lib.damage.AttackMetadata; +import io.lumine.mythic.lib.damage.DamageMetadata; +import io.lumine.mythic.lib.damage.DamageType; +import io.lumine.mythic.lib.version.VersionSound; +import net.Indyuce.mmoitems.MMOItems; +import net.Indyuce.mmoitems.MMOUtils; +import net.Indyuce.mmoitems.ability.VectorAbility; +import net.Indyuce.mmoitems.ability.metadata.VectorAbilityMetadata; +import net.Indyuce.mmoitems.api.ItemAttackMetadata; +import org.bukkit.Location; +import org.bukkit.Particle; +import org.bukkit.Sound; +import org.bukkit.entity.Entity; +import org.bukkit.entity.LivingEntity; +import org.bukkit.scheduler.BukkitRunnable; +import org.bukkit.util.Vector; + +import java.util.List; + +public class Holy_Missile extends VectorAbility { + public Holy_Missile() { + super(CastingMode.ON_HIT, CastingMode.WHEN_HIT, CastingMode.LEFT_CLICK, CastingMode.RIGHT_CLICK, CastingMode.SHIFT_LEFT_CLICK, CastingMode.SHIFT_RIGHT_CLICK); + + addModifier("damage", 6); + addModifier("cooldown", 10); + addModifier("duration", 4); + addModifier("mana", 0); + addModifier("stamina", 0); + } + + @Override + public void whenCast(ItemAttackMetadata attack, VectorAbilityMetadata ability) { + double duration = ability.getModifier("duration") * 10; + double damage = ability.getModifier("damage"); + + attack.getDamager().getWorld().playSound(attack.getDamager().getLocation(), VersionSound.ENTITY_FIREWORK_ROCKET_BLAST.toSound(), 1, 1); + new BukkitRunnable() { + final Vector vec = ability.getTarget().multiply(.45); + final Location loc = attack.getDamager().getLocation().clone().add(0, 1.3, 0); + double ti = 0; + + public void run() { + if (ti++ > duration) + cancel(); + + loc.getWorld().playSound(loc, VersionSound.BLOCK_NOTE_BLOCK_HAT.toSound(), 2, 1); + List entities = MMOUtils.getNearbyChunkEntities(loc); + for (int j = 0; j < 2; j++) { + loc.add(vec); + if (loc.getBlock().getType().isSolid()) + cancel(); + + for (double i = -Math.PI; i < Math.PI; i += Math.PI / 2) { + Vector v = new Vector(Math.cos(i + ti / 4), Math.sin(i + ti / 4), 0); + v = MMOUtils.rotateFunc(v, loc); + loc.getWorld().spawnParticle(Particle.FIREWORKS_SPARK, loc, 0, v.getX(), v.getY(), v.getZ(), .08); + } + + for (Entity entity : entities) + if (MMOUtils.canDamage(attack.getDamager(), loc, entity)) { + loc.getWorld().spawnParticle(Particle.EXPLOSION_LARGE, loc, 1); + loc.getWorld().spawnParticle(Particle.FIREWORKS_SPARK, loc, 32, 0, 0, 0, .2); + loc.getWorld().playSound(loc, Sound.ENTITY_GENERIC_EXPLODE, 2, 1); + new AttackMetadata(new DamageMetadata(damage, DamageType.SKILL, DamageType.MAGIC, DamageType.PROJECTILE), attack.getStats()).damage((LivingEntity) entity); + cancel(); + return; + } + } + } + }.runTaskTimer(MMOItems.plugin, 0, 1); + } +} + diff --git a/src/main/java/net/Indyuce/mmoitems/ability/list/vector/Ice_Crystal.java b/src/main/java/net/Indyuce/mmoitems/ability/list/vector/Ice_Crystal.java new file mode 100644 index 00000000..955bf0b7 --- /dev/null +++ b/src/main/java/net/Indyuce/mmoitems/ability/list/vector/Ice_Crystal.java @@ -0,0 +1,86 @@ +package net.Indyuce.mmoitems.ability.list.vector; + +import io.lumine.mythic.lib.damage.AttackMetadata; +import io.lumine.mythic.lib.damage.DamageMetadata; +import io.lumine.mythic.lib.damage.DamageType; +import io.lumine.mythic.lib.version.VersionSound; +import net.Indyuce.mmoitems.MMOItems; +import net.Indyuce.mmoitems.MMOUtils; +import net.Indyuce.mmoitems.ability.VectorAbility; +import net.Indyuce.mmoitems.ability.metadata.VectorAbilityMetadata; +import net.Indyuce.mmoitems.api.ItemAttackMetadata; +import org.bukkit.Color; +import org.bukkit.Location; +import org.bukkit.Particle; +import org.bukkit.Sound; +import org.bukkit.entity.Entity; +import org.bukkit.entity.LivingEntity; +import org.bukkit.potion.PotionEffect; +import org.bukkit.potion.PotionEffectType; +import org.bukkit.scheduler.BukkitRunnable; +import org.bukkit.util.Vector; + +import java.util.List; + +public class Ice_Crystal extends VectorAbility { + public Ice_Crystal() { + super(CastingMode.ON_HIT, CastingMode.WHEN_HIT, CastingMode.LEFT_CLICK, CastingMode.RIGHT_CLICK, CastingMode.SHIFT_LEFT_CLICK, + CastingMode.SHIFT_RIGHT_CLICK); + + addModifier("damage", 6); + addModifier("duration", 3); + addModifier("amplifier", 1); + addModifier("cooldown", 10); + addModifier("mana", 0); + addModifier("stamina", 0); + } + + @Override + public void whenCast(ItemAttackMetadata attack, VectorAbilityMetadata ability) { + attack.getDamager().getWorld().playSound(attack.getDamager().getLocation(), VersionSound.ENTITY_FIREWORK_ROCKET_BLAST.toSound(), 1, 1); + new BukkitRunnable() { + final Vector vec = ability.getTarget().multiply(.45); + final Location loc = attack.getDamager().getEyeLocation().clone().add(0, -.3, 0); + int ti = 0; + + public void run() { + if (ti++ > 25) + cancel(); + + loc.getWorld().playSound(loc, Sound.BLOCK_GLASS_BREAK, 2, 1); + List entities = MMOUtils.getNearbyChunkEntities(loc); + for (int j = 0; j < 3; j++) { + loc.add(vec); + if (loc.getBlock().getType().isSolid()) + cancel(); + + /* + * has a different particle effect since SNOW_DIG is not the + * same as in legacy minecraft, the particle effect is now a + * cross that rotates + */ + for (double r = 0; r < .4; r += .1) + for (double a = 0; a < Math.PI * 2; a += Math.PI / 2) { + Vector vec = MMOUtils.rotateFunc(new Vector(r * Math.cos(a + (double) ti / 10), r * Math.sin(a + (double) ti / 10), 0), + loc); + loc.add(vec); + loc.getWorld().spawnParticle(Particle.REDSTONE, loc, 1, new Particle.DustOptions(Color.WHITE, .7f)); + loc.add(vec.multiply(-1)); + } + + for (Entity entity : entities) + if (MMOUtils.canDamage(attack.getDamager(), loc, entity)) { + loc.getWorld().spawnParticle(Particle.EXPLOSION_LARGE, loc, 0); + loc.getWorld().spawnParticle(Particle.FIREWORKS_SPARK, loc, 48, 0, 0, 0, .2); + loc.getWorld().playSound(loc, Sound.ENTITY_GENERIC_EXPLODE, 2, 1); + new AttackMetadata(new DamageMetadata(ability.getModifier("damage"), DamageType.SKILL, DamageType.MAGIC, DamageType.PROJECTILE), attack.getStats()).damage((LivingEntity) entity); + ((LivingEntity) entity).addPotionEffect(new PotionEffect(PotionEffectType.SLOW, + (int) (ability.getModifier("duration") * 20), (int) ability.getModifier("amplifier"))); + cancel(); + return; + } + } + } + }.runTaskTimer(MMOItems.plugin, 0, 1); + } +} diff --git a/src/main/java/net/Indyuce/mmoitems/ability/list/vector/Shulker_Missile.java b/src/main/java/net/Indyuce/mmoitems/ability/list/vector/Shulker_Missile.java new file mode 100644 index 00000000..4377556d --- /dev/null +++ b/src/main/java/net/Indyuce/mmoitems/ability/list/vector/Shulker_Missile.java @@ -0,0 +1,164 @@ +package net.Indyuce.mmoitems.ability.list.vector; + +import io.lumine.mythic.lib.api.item.NBTItem; +import io.lumine.mythic.lib.damage.DamageMetadata; +import io.lumine.mythic.lib.damage.DamageType; +import net.Indyuce.mmoitems.MMOItems; +import net.Indyuce.mmoitems.MMOUtils; +import net.Indyuce.mmoitems.ability.VectorAbility; +import net.Indyuce.mmoitems.ability.metadata.VectorAbilityMetadata; +import net.Indyuce.mmoitems.api.ItemAttackMetadata; +import net.Indyuce.mmoitems.api.interaction.projectile.EntityData; +import org.bukkit.Color; +import org.bukkit.Location; +import org.bukkit.Particle; +import org.bukkit.Sound; +import org.bukkit.entity.EntityType; +import org.bukkit.entity.LivingEntity; +import org.bukkit.entity.ShulkerBullet; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; +import org.bukkit.event.entity.EntityDamageByEntityEvent; +import org.bukkit.potion.PotionEffect; +import org.bukkit.potion.PotionEffectType; +import org.bukkit.scheduler.BukkitRunnable; +import org.bukkit.util.Vector; + +import javax.annotation.Nullable; + +public class Shulker_Missile extends VectorAbility implements Listener { + public Shulker_Missile() { + super(CastingMode.ON_HIT, CastingMode.WHEN_HIT, CastingMode.LEFT_CLICK, CastingMode.RIGHT_CLICK, CastingMode.SHIFT_LEFT_CLICK, + CastingMode.SHIFT_RIGHT_CLICK); + + addModifier("cooldown", 12); + addModifier("damage", 5); + addModifier("effect-duration", 5); + addModifier("duration", 5); + addModifier("mana", 0); + addModifier("stamina", 0); + } + + @Override + public void whenCast(ItemAttackMetadata attack, VectorAbilityMetadata ability) { + double duration = ability.getModifier("duration"); + + new BukkitRunnable() { + double n = 0; + + public void run() { + if (n++ > 3) { + cancel(); + return; + } + + Vector vec = ability.getTarget(); + attack.getDamager().getWorld().playSound(attack.getDamager().getLocation(), Sound.ENTITY_WITHER_SHOOT, 2, 2); + ShulkerBullet shulkerBullet = (ShulkerBullet) attack.getDamager().getWorld().spawnEntity(attack.getDamager().getLocation().add(0, 1, 0), + EntityType.SHULKER_BULLET); + shulkerBullet.setShooter(attack.getDamager()); + + ItemAttackMetadata attackMeta = new ItemAttackMetadata(new DamageMetadata(ability.getModifier("damage"), DamageType.SKILL, DamageType.MAGIC, DamageType.PROJECTILE), attack.getStats()); + MMOItems.plugin.getEntities().registerCustomEntity(shulkerBullet, new ShulkerMissileEntityData(attackMeta, ability.getModifier("effect-duration"))); + + new BukkitRunnable() { + double ti = 0; + + public void run() { + if (shulkerBullet.isDead() || ti++ >= duration * 20) { + shulkerBullet.remove(); + cancel(); + } else + shulkerBullet.setVelocity(vec); + } + }.runTaskTimer(MMOItems.plugin, 0, 1); + } + }.runTaskTimer(MMOItems.plugin, 0, 3); + } + + @EventHandler + public void a(EntityDamageByEntityEvent event) { + if (event.getDamager() instanceof ShulkerBullet && event.getEntity() instanceof LivingEntity) { + ShulkerBullet damager = (ShulkerBullet) event.getDamager(); + LivingEntity entity = (LivingEntity) event.getEntity(); + if (!MMOItems.plugin.getEntities().isCustomEntity(damager)) + return; + + if (!MMOUtils.canDamage(entity)) { + event.setCancelled(true); + return; + } + + ShulkerMissileEntityData data = (ShulkerMissileEntityData) MMOItems.plugin.getEntities().getEntityData(damager); + + // Void spirit + if (data.isWeaponAttack()) + data.attackMeta.applyEffects(data.weapon, entity); + + event.setDamage(data.attackMeta.getDamage().getDamage()); + + new BukkitRunnable() { + final Location loc = entity.getLocation(); + double y = 0; + + public void run() { + + // Potion effect should apply right after the damage with a 1 tick delay. + if (y == 0) { + entity.removePotionEffect(PotionEffectType.LEVITATION); + entity.addPotionEffect(new PotionEffect(PotionEffectType.LEVITATION, (int) (data.duration * 20), 0)); + } + + for (int j1 = 0; j1 < 3; j1++) { + y += .04; + for (int j = 0; j < 2; j++) { + double xz = y * Math.PI * 1.3 + (j * Math.PI); + loc.getWorld().spawnParticle(Particle.REDSTONE, loc.clone().add(Math.cos(xz), y, Math.sin(xz)), 1, + new Particle.DustOptions(Color.MAROON, 1)); + } + } + if (y >= 2) + cancel(); + } + }.runTaskTimer(MMOItems.plugin, 0, 1); + } + } + + public static class ShulkerMissileEntityData implements EntityData { + private final ItemAttackMetadata attackMeta; + private final double duration; + + @Nullable + private final NBTItem weapon; + + /** + * Used for the Shulker missile ability + * + * @param attackMeta Attack meta + * @param duration Duration of levitation effect in seconds + */ + public ShulkerMissileEntityData(ItemAttackMetadata attackMeta, double duration) { + this(attackMeta, duration, null); + } + + /** + * Used for the void staff attack spirit (no levitation effect) + * + * @param attackMeta Attack meta + * @param weapon Item used for the attack + */ + public ShulkerMissileEntityData(ItemAttackMetadata attackMeta, NBTItem weapon) { + this(attackMeta, 0, weapon); + } + + private ShulkerMissileEntityData(ItemAttackMetadata attackMeta, double duration, NBTItem weapon) { + this.attackMeta = attackMeta; + this.duration = duration; + this.weapon = weapon; + } + + public boolean isWeaponAttack() { + return attackMeta.getDamage().hasType(DamageType.WEAPON); + } + } +} diff --git a/src/main/java/net/Indyuce/mmoitems/ability/list/vector/TNT_Throw.java b/src/main/java/net/Indyuce/mmoitems/ability/list/vector/TNT_Throw.java new file mode 100644 index 00000000..3ebd6543 --- /dev/null +++ b/src/main/java/net/Indyuce/mmoitems/ability/list/vector/TNT_Throw.java @@ -0,0 +1,63 @@ +package net.Indyuce.mmoitems.ability.list.vector; + +import net.Indyuce.mmoitems.MMOUtils; +import net.Indyuce.mmoitems.ability.VectorAbility; +import net.Indyuce.mmoitems.ability.metadata.VectorAbilityMetadata; +import net.Indyuce.mmoitems.api.ItemAttackMetadata; +import net.Indyuce.mmoitems.api.util.TemporaryListener; +import org.bukkit.Particle; +import org.bukkit.Sound; +import org.bukkit.entity.EntityType; +import org.bukkit.entity.Player; +import org.bukkit.entity.TNTPrimed; +import org.bukkit.event.EventHandler; +import org.bukkit.event.EventPriority; +import org.bukkit.event.Listener; +import org.bukkit.event.entity.EntityDamageByEntityEvent; +import org.bukkit.util.Vector; + +public class TNT_Throw extends VectorAbility implements Listener { + public TNT_Throw() { + super(CastingMode.ON_HIT, CastingMode.WHEN_HIT, CastingMode.LEFT_CLICK, CastingMode.RIGHT_CLICK, CastingMode.SHIFT_LEFT_CLICK, + CastingMode.SHIFT_RIGHT_CLICK); + + addModifier("cooldown", 10); + addModifier("force", 1); + addModifier("mana", 0); + addModifier("stamina", 0); + } + + @Override + public void whenCast(ItemAttackMetadata attack, VectorAbilityMetadata ability) { + Vector vec = ability.getTarget().multiply(2 * ability.getModifier("force")); + TNTPrimed tnt = (TNTPrimed) attack.getDamager().getWorld().spawnEntity(attack.getDamager().getLocation().add(0, 1, 0), EntityType.PRIMED_TNT); + tnt.setFuseTicks(80); + tnt.setVelocity(vec); + new CancelTeamDamage(attack.getDamager(), tnt); + attack.getDamager().getWorld().playSound(attack.getDamager().getLocation(), Sound.ENTITY_SNOWBALL_THROW, 1, 0); + attack.getDamager().getWorld().spawnParticle(Particle.EXPLOSION_NORMAL, attack.getDamager().getLocation().add(0, 1, 0), 12, 0, 0, 0, .1); + } + + /* + * used to cancel team damage and other things + */ + public static class CancelTeamDamage extends TemporaryListener { + private final Player player; + private final TNTPrimed tnt; + + public CancelTeamDamage(Player player, TNTPrimed tnt) { + super(EntityDamageByEntityEvent.getHandlerList()); + + this.player = player; + this.tnt = tnt; + + close(100); + } + + @EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true) + public void a(EntityDamageByEntityEvent event) { + if (event.getDamager().equals(tnt) && !MMOUtils.canDamage(player, event.getEntity())) + event.setCancelled(true); + } + } +} diff --git a/src/main/java/net/Indyuce/mmoitems/ability/list/vector/Thrust.java b/src/main/java/net/Indyuce/mmoitems/ability/list/vector/Thrust.java new file mode 100644 index 00000000..769a825b --- /dev/null +++ b/src/main/java/net/Indyuce/mmoitems/ability/list/vector/Thrust.java @@ -0,0 +1,46 @@ +package net.Indyuce.mmoitems.ability.list.vector; + +import io.lumine.mythic.lib.damage.AttackMetadata; +import io.lumine.mythic.lib.damage.DamageMetadata; +import io.lumine.mythic.lib.damage.DamageType; +import net.Indyuce.mmoitems.MMOUtils; +import net.Indyuce.mmoitems.ability.VectorAbility; +import net.Indyuce.mmoitems.ability.metadata.VectorAbilityMetadata; +import net.Indyuce.mmoitems.api.ItemAttackMetadata; +import org.bukkit.Location; +import org.bukkit.Particle; +import org.bukkit.Sound; +import org.bukkit.entity.Entity; +import org.bukkit.entity.LivingEntity; +import org.bukkit.potion.PotionEffect; +import org.bukkit.potion.PotionEffectType; +import org.bukkit.util.Vector; + +public class Thrust extends VectorAbility { + public Thrust() { + super(CastingMode.ON_HIT, CastingMode.WHEN_HIT, CastingMode.LEFT_CLICK, CastingMode.RIGHT_CLICK, CastingMode.SHIFT_LEFT_CLICK, CastingMode.SHIFT_RIGHT_CLICK); + + addModifier("cooldown", 10); + addModifier("damage", 6); + addModifier("mana", 0); + addModifier("stamina", 0); + } + + @Override + public void whenCast(ItemAttackMetadata attack, VectorAbilityMetadata ability) { + double damage = ability.getModifier("damage"); + + attack.getDamager().getWorld().playSound(attack.getDamager().getLocation(), Sound.ENTITY_ZOMBIE_ATTACK_IRON_DOOR, 1, 0); + attack.getDamager().addPotionEffect(new PotionEffect(PotionEffectType.SLOW, 2, 3)); + + Location loc = attack.getDamager().getEyeLocation().clone(); + Vector vec = ability.getTarget().multiply(.5); + for (double j = 0; j < 7; j += .5) { + loc.add(vec); + for (Entity entity : MMOUtils.getNearbyChunkEntities(loc)) + if (MMOUtils.canDamage(attack.getDamager(), loc, entity)) + new AttackMetadata(new DamageMetadata(damage, DamageType.SKILL, DamageType.PHYSICAL), attack.getStats()).damage((LivingEntity) entity); + loc.getWorld().spawnParticle(Particle.SMOKE_LARGE, loc, 0); + } + } +} diff --git a/src/main/java/net/Indyuce/mmoitems/ability/metadata/FriendlyTargetAbilityMetadata.java b/src/main/java/net/Indyuce/mmoitems/ability/metadata/FriendlyTargetAbilityMetadata.java new file mode 100644 index 00000000..b63c7824 --- /dev/null +++ b/src/main/java/net/Indyuce/mmoitems/ability/metadata/FriendlyTargetAbilityMetadata.java @@ -0,0 +1,27 @@ +package net.Indyuce.mmoitems.ability.metadata; + +import io.lumine.mythic.lib.MythicLib; +import net.Indyuce.mmoitems.MMOUtils; +import net.Indyuce.mmoitems.ability.AbilityMetadata; +import net.Indyuce.mmoitems.stat.data.AbilityData; +import org.bukkit.entity.LivingEntity; +import org.bukkit.entity.Player; + +public class FriendlyTargetAbilityMetadata extends AbilityMetadata { + private final LivingEntity target; + + public FriendlyTargetAbilityMetadata(AbilityData ability, Player caster, LivingEntity target) { + super(ability); + + this.target = target != null ? target : MythicLib.plugin.getVersion().getWrapper().rayTrace(caster, 50, entity -> (entity instanceof Player && MMOUtils.canDamage(caster, entity))).getHit(); + } + + public LivingEntity getTarget() { + return target; + } + + @Override + public boolean isSuccessful() { + return target != null; + } +} \ No newline at end of file diff --git a/src/main/java/net/Indyuce/mmoitems/ability/metadata/ItemAbilityMetadata.java b/src/main/java/net/Indyuce/mmoitems/ability/metadata/ItemAbilityMetadata.java new file mode 100644 index 00000000..903f0d5a --- /dev/null +++ b/src/main/java/net/Indyuce/mmoitems/ability/metadata/ItemAbilityMetadata.java @@ -0,0 +1,31 @@ +package net.Indyuce.mmoitems.ability.metadata; + +import net.Indyuce.mmoitems.stat.data.AbilityData; +import org.bukkit.entity.LivingEntity; +import org.bukkit.entity.Player; +import org.bukkit.inventory.ItemStack; + +/** + * Item that requires to throw the item in hand. + * This takes as input the player's main hand item and + * also takes the direction where he's looking + */ +public class ItemAbilityMetadata extends VectorAbilityMetadata { + private final ItemStack item; + + public ItemAbilityMetadata(AbilityData ability, Player caster, LivingEntity target) { + super(ability, caster, target); + + // TODO getItemInMainHand? Breaks the ability when used in the offhand. + item = caster.getInventory().getItemInMainHand(); + } + + public ItemStack getItem() { + return item; + } + + @Override + public boolean isSuccessful() { + return item != null; + } +} \ No newline at end of file diff --git a/src/main/java/net/Indyuce/mmoitems/ability/metadata/LocationAbilityMetadata.java b/src/main/java/net/Indyuce/mmoitems/ability/metadata/LocationAbilityMetadata.java new file mode 100644 index 00000000..028a6aba --- /dev/null +++ b/src/main/java/net/Indyuce/mmoitems/ability/metadata/LocationAbilityMetadata.java @@ -0,0 +1,40 @@ +package net.Indyuce.mmoitems.ability.metadata; + +import net.Indyuce.mmoitems.ability.AbilityMetadata; +import net.Indyuce.mmoitems.ability.list.location.Minor_Explosion; +import net.Indyuce.mmoitems.stat.data.AbilityData; +import org.bukkit.Location; +import org.bukkit.Material; +import org.bukkit.entity.LivingEntity; +import org.bukkit.entity.Player; + +/** + * Ability that requires a target location, for + * instance {@link Minor_Explosion} + */ +public class LocationAbilityMetadata extends AbilityMetadata { + private final Location target; + + public LocationAbilityMetadata(AbilityData ability, Player caster, LivingEntity target) { + super(ability); + + this.target = getTargetLocation(caster, target); + } + + public Location getTarget() { + return target; + } + + @Override + public boolean isSuccessful() { + return target != null; + } + + public Location getTargetLocation(Player player, LivingEntity entity) { + if (entity != null) + return entity.getLocation(); + + Location loc = player.getTargetBlock(null, 50).getLocation(); + return loc.getBlock().getType() == Material.AIR ? null : loc.add(.5, 1, .5); + } +} diff --git a/src/main/java/net/Indyuce/mmoitems/ability/metadata/SimpleAbilityMetadata.java b/src/main/java/net/Indyuce/mmoitems/ability/metadata/SimpleAbilityMetadata.java new file mode 100644 index 00000000..34a72841 --- /dev/null +++ b/src/main/java/net/Indyuce/mmoitems/ability/metadata/SimpleAbilityMetadata.java @@ -0,0 +1,23 @@ +package net.Indyuce.mmoitems.ability.metadata; + +import net.Indyuce.mmoitems.ability.AbilityMetadata; +import net.Indyuce.mmoitems.stat.data.AbilityData; + +public class SimpleAbilityMetadata extends AbilityMetadata { + private final boolean successful; + + public SimpleAbilityMetadata(AbilityData ability) { + this(ability, true); + } + + public SimpleAbilityMetadata(AbilityData ability, boolean successful) { + super(ability); + + this.successful = successful; + } + + @Override + public boolean isSuccessful() { + return successful; + } +} diff --git a/src/main/java/net/Indyuce/mmoitems/ability/metadata/TargetAbilityMetadata.java b/src/main/java/net/Indyuce/mmoitems/ability/metadata/TargetAbilityMetadata.java new file mode 100644 index 00000000..6a3e2b73 --- /dev/null +++ b/src/main/java/net/Indyuce/mmoitems/ability/metadata/TargetAbilityMetadata.java @@ -0,0 +1,27 @@ +package net.Indyuce.mmoitems.ability.metadata; + +import io.lumine.mythic.lib.MythicLib; +import net.Indyuce.mmoitems.MMOUtils; +import net.Indyuce.mmoitems.ability.AbilityMetadata; +import net.Indyuce.mmoitems.stat.data.AbilityData; +import org.bukkit.entity.LivingEntity; +import org.bukkit.entity.Player; + +public class TargetAbilityMetadata extends AbilityMetadata { + private final LivingEntity target; + + public TargetAbilityMetadata(AbilityData ability, Player caster, LivingEntity target) { + super(ability); + + this.target = target != null ? target : MythicLib.plugin.getVersion().getWrapper().rayTrace(caster, 50, entity -> MMOUtils.canDamage(caster, entity)).getHit(); + } + + public LivingEntity getTarget() { + return target; + } + + @Override + public boolean isSuccessful() { + return target != null; + } +} diff --git a/src/main/java/net/Indyuce/mmoitems/ability/metadata/VectorAbilityMetadata.java b/src/main/java/net/Indyuce/mmoitems/ability/metadata/VectorAbilityMetadata.java new file mode 100644 index 00000000..612e5434 --- /dev/null +++ b/src/main/java/net/Indyuce/mmoitems/ability/metadata/VectorAbilityMetadata.java @@ -0,0 +1,30 @@ +package net.Indyuce.mmoitems.ability.metadata; + +import net.Indyuce.mmoitems.ability.AbilityMetadata; +import net.Indyuce.mmoitems.stat.data.AbilityData; +import org.bukkit.entity.LivingEntity; +import org.bukkit.entity.Player; +import org.bukkit.util.Vector; + +public class VectorAbilityMetadata extends AbilityMetadata { + private final Vector target; + + public VectorAbilityMetadata(AbilityData ability, Player caster, LivingEntity target) { + super(ability); + + this.target = getTargetDirection(caster, target); + } + + public Vector getTarget() { + return target; + } + + @Override + public boolean isSuccessful() { + return true; + } + + public Vector getTargetDirection(Player player, LivingEntity target) { + return target == null ? player.getEyeLocation().getDirection() : target.getLocation().add(0, target.getHeight() / 2, 0).subtract(player.getLocation().add(0, 1.3, 0)).toVector().normalize(); + } +} diff --git a/src/main/java/net/Indyuce/mmoitems/ability/onhit/Blind.java b/src/main/java/net/Indyuce/mmoitems/ability/onhit/Blind.java deleted file mode 100644 index 05e4d1bd..00000000 --- a/src/main/java/net/Indyuce/mmoitems/ability/onhit/Blind.java +++ /dev/null @@ -1,50 +0,0 @@ -package net.Indyuce.mmoitems.ability.onhit; - -import org.bukkit.Color; -import org.bukkit.Location; -import org.bukkit.Particle; -import org.bukkit.entity.LivingEntity; -import org.bukkit.potion.PotionEffect; -import org.bukkit.potion.PotionEffectType; -import org.bukkit.util.Vector; - -import net.Indyuce.mmoitems.MMOUtils; -import net.Indyuce.mmoitems.api.ItemAttackResult; -import net.Indyuce.mmoitems.api.ability.Ability; -import net.Indyuce.mmoitems.api.ability.AbilityResult; -import net.Indyuce.mmoitems.api.ability.TargetAbilityResult; -import net.Indyuce.mmoitems.api.player.PlayerStats.CachedStats; -import net.Indyuce.mmoitems.stat.data.AbilityData; -import io.lumine.mythic.lib.version.VersionSound; - -public class Blind extends Ability { - public Blind() { - super(CastingMode.ON_HIT, CastingMode.WHEN_HIT, CastingMode.LEFT_CLICK, CastingMode.RIGHT_CLICK, CastingMode.SHIFT_LEFT_CLICK, - CastingMode.SHIFT_RIGHT_CLICK); - - addModifier("duration", 5); - addModifier("cooldown", 9); - addModifier("mana", 0); - addModifier("stamina", 0); - } - - @Override - public AbilityResult whenRan(CachedStats stats, LivingEntity target, AbilityData ability, ItemAttackResult result) { - return new TargetAbilityResult(ability, stats.getPlayer(), target); - } - - @Override - public void whenCast(CachedStats stats, AbilityResult ability, ItemAttackResult result) { - LivingEntity target = ((TargetAbilityResult) ability).getTarget(); - - target.getWorld().playSound(target.getLocation(), VersionSound.ENTITY_ENDERMAN_HURT.toSound(), 1, 2); - for (double i = 0; i < Math.PI * 2; i += Math.PI / 24) - for (double j = 0; j < 2; j++) { - Location loc = target.getLocation(); - Vector vec = MMOUtils.rotateFunc(new Vector(Math.cos(i), 1 + Math.cos(i + (Math.PI * j)) * .5, Math.sin(i)), - stats.getPlayer().getLocation()); - loc.getWorld().spawnParticle(Particle.REDSTONE, loc.add(vec), 1, new Particle.DustOptions(Color.BLACK, 1)); - } - target.addPotionEffect(new PotionEffect(PotionEffectType.BLINDNESS, (int) (ability.getModifier("duration") * 20), 0)); - } -} diff --git a/src/main/java/net/Indyuce/mmoitems/ability/onhit/Bloodbath.java b/src/main/java/net/Indyuce/mmoitems/ability/onhit/Bloodbath.java deleted file mode 100644 index fd2d9d75..00000000 --- a/src/main/java/net/Indyuce/mmoitems/ability/onhit/Bloodbath.java +++ /dev/null @@ -1,37 +0,0 @@ -package net.Indyuce.mmoitems.ability.onhit; - -import org.bukkit.Effect; -import org.bukkit.Sound; -import org.bukkit.entity.LivingEntity; - -import net.Indyuce.mmoitems.api.ItemAttackResult; -import net.Indyuce.mmoitems.api.ability.Ability; -import net.Indyuce.mmoitems.api.ability.AbilityResult; -import net.Indyuce.mmoitems.api.ability.TargetAbilityResult; -import net.Indyuce.mmoitems.api.player.PlayerStats.CachedStats; -import net.Indyuce.mmoitems.stat.data.AbilityData; - -public class Bloodbath extends Ability { - public Bloodbath() { - super(CastingMode.ON_HIT, CastingMode.WHEN_HIT, CastingMode.LEFT_CLICK, CastingMode.RIGHT_CLICK, CastingMode.SHIFT_LEFT_CLICK, CastingMode.SHIFT_RIGHT_CLICK); - - addModifier("amount", 2); - addModifier("cooldown", 8); - addModifier("mana", 0); - addModifier("stamina", 0); - } - - @Override - public AbilityResult whenRan(CachedStats stats, LivingEntity target, AbilityData ability, ItemAttackResult result) { - return new TargetAbilityResult(ability, stats.getPlayer(), target); - } - - @Override - public void whenCast(CachedStats stats, AbilityResult ability, ItemAttackResult result) { - LivingEntity target = ((TargetAbilityResult) ability).getTarget(); - - target.getWorld().playSound(target.getLocation(), Sound.ENTITY_COW_HURT, 1, 2); - target.getWorld().playEffect(target.getLocation().add(0, 1, 0), Effect.STEP_SOUND, 152); - stats.getPlayer().setFoodLevel((int) Math.min(20, stats.getPlayer().getFoodLevel() + ability.getModifier("amount"))); - } -} diff --git a/src/main/java/net/Indyuce/mmoitems/ability/onhit/Burn.java b/src/main/java/net/Indyuce/mmoitems/ability/onhit/Burn.java deleted file mode 100644 index 1758b5f8..00000000 --- a/src/main/java/net/Indyuce/mmoitems/ability/onhit/Burn.java +++ /dev/null @@ -1,56 +0,0 @@ -package net.Indyuce.mmoitems.ability.onhit; - -import org.bukkit.Location; -import org.bukkit.Particle; -import org.bukkit.Sound; -import org.bukkit.entity.LivingEntity; -import org.bukkit.scheduler.BukkitRunnable; - -import net.Indyuce.mmoitems.MMOItems; -import net.Indyuce.mmoitems.api.ItemAttackResult; -import net.Indyuce.mmoitems.api.ability.Ability; -import net.Indyuce.mmoitems.api.ability.AbilityResult; -import net.Indyuce.mmoitems.api.ability.TargetAbilityResult; -import net.Indyuce.mmoitems.api.player.PlayerStats.CachedStats; -import net.Indyuce.mmoitems.stat.data.AbilityData; - -public class Burn extends Ability { - public Burn() { - super(CastingMode.ON_HIT, CastingMode.WHEN_HIT, CastingMode.LEFT_CLICK, CastingMode.RIGHT_CLICK, CastingMode.SHIFT_LEFT_CLICK, CastingMode.SHIFT_RIGHT_CLICK); - - addModifier("duration", 3); - addModifier("cooldown", 8); - addModifier("mana", 0); - addModifier("stamina", 0); - } - - @Override - public AbilityResult whenRan(CachedStats stats, LivingEntity target, AbilityData ability, ItemAttackResult result) { - return new TargetAbilityResult(ability, stats.getPlayer(), target); - } - - @Override - public void whenCast(CachedStats stats, AbilityResult ability, ItemAttackResult result) { - LivingEntity target = ((TargetAbilityResult) ability).getTarget(); - - new BukkitRunnable() { - final Location loc = target.getLocation(); - double y = 0; - - public void run() { - for (int j1 = 0; j1 < 3; j1++) { - y += .04; - for (int j = 0; j < 2; j++) { - double xz = y * Math.PI * 1.3 + (j * Math.PI); - Location loc1 = loc.clone().add(Math.cos(xz), y, Math.sin(xz)); - loc.getWorld().spawnParticle(Particle.FLAME, loc1, 0); - } - } - if (y >= 1.7) - cancel(); - } - }.runTaskTimer(MMOItems.plugin, 0, 1); - target.getWorld().playSound(target.getLocation(), Sound.ENTITY_BLAZE_HURT, 1, 2); - target.setFireTicks((int) (target.getFireTicks() + ability.getModifier("duration") * 20)); - } -} diff --git a/src/main/java/net/Indyuce/mmoitems/ability/onhit/Confuse.java b/src/main/java/net/Indyuce/mmoitems/ability/onhit/Confuse.java deleted file mode 100644 index 59cafe0e..00000000 --- a/src/main/java/net/Indyuce/mmoitems/ability/onhit/Confuse.java +++ /dev/null @@ -1,55 +0,0 @@ -package net.Indyuce.mmoitems.ability.onhit; - -import org.bukkit.Location; -import org.bukkit.Particle; -import org.bukkit.Sound; -import org.bukkit.entity.LivingEntity; -import org.bukkit.scheduler.BukkitRunnable; - -import net.Indyuce.mmoitems.MMOItems; -import net.Indyuce.mmoitems.api.ItemAttackResult; -import net.Indyuce.mmoitems.api.ability.Ability; -import net.Indyuce.mmoitems.api.ability.AbilityResult; -import net.Indyuce.mmoitems.api.ability.TargetAbilityResult; -import net.Indyuce.mmoitems.api.player.PlayerStats.CachedStats; -import net.Indyuce.mmoitems.stat.data.AbilityData; - -public class Confuse extends Ability { - public Confuse() { - super(CastingMode.ON_HIT, CastingMode.WHEN_HIT, CastingMode.LEFT_CLICK, CastingMode.RIGHT_CLICK, CastingMode.SHIFT_LEFT_CLICK, CastingMode.SHIFT_RIGHT_CLICK); - - addModifier("cooldown", 7); - addModifier("mana", 0); - addModifier("stamina", 0); - } - - @Override - public AbilityResult whenRan(CachedStats stats, LivingEntity target, AbilityData ability, ItemAttackResult result) { - return new TargetAbilityResult(ability, stats.getPlayer(), target); - } - - @Override - public void whenCast(CachedStats stats, AbilityResult ability, ItemAttackResult result) { - LivingEntity target = ((TargetAbilityResult) ability).getTarget(); - - target.getWorld().playSound(target.getLocation(), Sound.ENTITY_SHEEP_DEATH, 1, 2); - new BukkitRunnable() { - final Location loc = target.getLocation(); - final double rads = Math.toRadians(stats.getPlayer().getEyeLocation().getYaw() - 90); - double ti = rads; - - public void run() { - for (int j1 = 0; j1 < 3; j1++) { - ti += Math.PI / 15; - Location loc1 = loc.clone().add(Math.cos(ti), 1, Math.sin(ti)); - loc.getWorld().spawnParticle(Particle.SPELL_WITCH, loc1, 0); - } - if (ti >= Math.PI * 2 + rads) - cancel(); - } - }.runTaskTimer(MMOItems.plugin, 0, 1); - Location loc = target.getLocation().clone(); - loc.setYaw(target.getLocation().getYaw() - 180); - target.teleport(loc); - } -} diff --git a/src/main/java/net/Indyuce/mmoitems/ability/onhit/Death_Mark.java b/src/main/java/net/Indyuce/mmoitems/ability/onhit/Death_Mark.java deleted file mode 100644 index efccca52..00000000 --- a/src/main/java/net/Indyuce/mmoitems/ability/onhit/Death_Mark.java +++ /dev/null @@ -1,65 +0,0 @@ -package net.Indyuce.mmoitems.ability.onhit; - -import org.bukkit.Particle; -import org.bukkit.Sound; -import org.bukkit.entity.LivingEntity; -import org.bukkit.potion.PotionEffect; -import org.bukkit.potion.PotionEffectType; -import org.bukkit.scheduler.BukkitRunnable; - -import net.Indyuce.mmoitems.MMOItems; -import net.Indyuce.mmoitems.api.ItemAttackResult; -import net.Indyuce.mmoitems.api.ability.Ability; -import net.Indyuce.mmoitems.api.ability.AbilityResult; -import net.Indyuce.mmoitems.api.ability.TargetAbilityResult; -import net.Indyuce.mmoitems.api.player.PlayerStats.CachedStats; -import net.Indyuce.mmoitems.stat.data.AbilityData; -import io.lumine.mythic.lib.MythicLib; -import io.lumine.mythic.lib.api.AttackResult; -import io.lumine.mythic.lib.api.DamageType; - -public class Death_Mark extends Ability { - public Death_Mark() { - super(CastingMode.ON_HIT, CastingMode.WHEN_HIT, CastingMode.LEFT_CLICK, CastingMode.RIGHT_CLICK, CastingMode.SHIFT_LEFT_CLICK, CastingMode.SHIFT_RIGHT_CLICK); - - addModifier("cooldown", 7); - addModifier("damage", 5); - addModifier("duration", 3); - addModifier("amplifier", 1); - addModifier("mana", 0); - addModifier("stamina", 0); - } - - @Override - public AbilityResult whenRan(CachedStats stats, LivingEntity target, AbilityData ability, ItemAttackResult result) { - return new TargetAbilityResult(ability, stats.getPlayer(), target); - } - - @Override - public void whenCast(CachedStats stats, AbilityResult ability, ItemAttackResult result) { - LivingEntity target = ((TargetAbilityResult) ability).getTarget(); - - double duration = ability.getModifier("duration") * 20; - double dps = ability.getModifier("damage") / duration * 20; - - new BukkitRunnable() { - double ti = 0; - - public void run() { - ti++; - if (ti > duration || target == null || target.isDead()) { - cancel(); - return; - } - - target.getWorld().spawnParticle(Particle.SPELL_MOB, target.getLocation(), 4, .2, 0, .2, 0); - - if (ti % 20 == 0) - MythicLib.plugin.getDamage().damage(stats.getPlayer(), target, new AttackResult(dps, DamageType.SKILL, DamageType.MAGIC), false); - } - }.runTaskTimer(MMOItems.plugin, 0, 1); - target.getWorld().playSound(target.getLocation(), Sound.ENTITY_BLAZE_HURT, 1, 2); - target.removePotionEffect(PotionEffectType.SLOW); - target.addPotionEffect(new PotionEffect(PotionEffectType.SLOW, (int) duration, (int) ability.getModifier("amplifier"))); - } -} diff --git a/src/main/java/net/Indyuce/mmoitems/ability/onhit/Poison.java b/src/main/java/net/Indyuce/mmoitems/ability/onhit/Poison.java deleted file mode 100644 index 15767e3d..00000000 --- a/src/main/java/net/Indyuce/mmoitems/ability/onhit/Poison.java +++ /dev/null @@ -1,41 +0,0 @@ -package net.Indyuce.mmoitems.ability.onhit; - -import org.bukkit.Particle; -import org.bukkit.Sound; -import org.bukkit.entity.LivingEntity; -import org.bukkit.potion.PotionEffect; -import org.bukkit.potion.PotionEffectType; - -import net.Indyuce.mmoitems.api.ItemAttackResult; -import net.Indyuce.mmoitems.api.ability.Ability; -import net.Indyuce.mmoitems.api.ability.AbilityResult; -import net.Indyuce.mmoitems.api.ability.TargetAbilityResult; -import net.Indyuce.mmoitems.api.player.PlayerStats.CachedStats; -import net.Indyuce.mmoitems.stat.data.AbilityData; - -public class Poison extends Ability { - public Poison() { - super(CastingMode.ON_HIT, CastingMode.WHEN_HIT, CastingMode.LEFT_CLICK, CastingMode.RIGHT_CLICK, CastingMode.SHIFT_LEFT_CLICK, CastingMode.SHIFT_RIGHT_CLICK); - - addModifier("duration", 4); - addModifier("cooldown", 10); - addModifier("amplifier", 1); - addModifier("mana", 0); - addModifier("stamina", 0); - } - - @Override - public AbilityResult whenRan(CachedStats stats, LivingEntity target, AbilityData ability, ItemAttackResult result) { - return new TargetAbilityResult(ability, stats.getPlayer(), target); - } - - @Override - public void whenCast(CachedStats stats, AbilityResult ability, ItemAttackResult result) { - LivingEntity target = ((TargetAbilityResult) ability).getTarget(); - - target.getWorld().spawnParticle(Particle.SLIME, target.getLocation().add(0, 1, 0), 32, 1, 1, 1, 0); - target.getWorld().spawnParticle(Particle.VILLAGER_HAPPY, target.getLocation().add(0, 1, 0), 24, 1, 1, 1, 0); - target.getWorld().playSound(target.getLocation(), Sound.BLOCK_BREWING_STAND_BREW, 1.5f, 2); - target.addPotionEffect(new PotionEffect(PotionEffectType.POISON, (int) (ability.getModifier("duration") * 20), (int) ability.getModifier("amplifier"))); - } -} diff --git a/src/main/java/net/Indyuce/mmoitems/ability/onhit/Shock.java b/src/main/java/net/Indyuce/mmoitems/ability/onhit/Shock.java deleted file mode 100644 index 533b86bf..00000000 --- a/src/main/java/net/Indyuce/mmoitems/ability/onhit/Shock.java +++ /dev/null @@ -1,66 +0,0 @@ -package net.Indyuce.mmoitems.ability.onhit; - -import org.bukkit.EntityEffect; -import org.bukkit.Location; -import org.bukkit.Particle; -import org.bukkit.entity.LivingEntity; -import org.bukkit.scheduler.BukkitRunnable; - -import net.Indyuce.mmoitems.MMOItems; -import net.Indyuce.mmoitems.api.ItemAttackResult; -import net.Indyuce.mmoitems.api.ability.Ability; -import net.Indyuce.mmoitems.api.ability.AbilityResult; -import net.Indyuce.mmoitems.api.ability.TargetAbilityResult; -import net.Indyuce.mmoitems.api.player.PlayerStats.CachedStats; -import net.Indyuce.mmoitems.stat.data.AbilityData; -import io.lumine.mythic.lib.version.VersionSound; - -public class Shock extends Ability { - public Shock() { - super(CastingMode.ON_HIT, CastingMode.WHEN_HIT, CastingMode.LEFT_CLICK, CastingMode.RIGHT_CLICK, CastingMode.SHIFT_LEFT_CLICK, CastingMode.SHIFT_RIGHT_CLICK); - - addModifier("duration", 2); - addModifier("cooldown", 8); - addModifier("mana", 0); - addModifier("stamina", 0); - } - - @Override - public AbilityResult whenRan(CachedStats stats, LivingEntity target, AbilityData ability, ItemAttackResult result) { - return new TargetAbilityResult(ability, stats.getPlayer(), target); - } - - @Override - public void whenCast(CachedStats stats, AbilityResult ability, ItemAttackResult result) { - LivingEntity target = ((TargetAbilityResult) ability).getTarget(); - - double duration = ability.getModifier("duration"); - - target.getWorld().playSound(target.getLocation(), VersionSound.ENTITY_ZOMBIE_PIGMAN_ANGRY.toSound(), 1, 2); - new BukkitRunnable() { - final Location loc = target.getLocation(); - final double rads = Math.toRadians(stats.getPlayer().getEyeLocation().getYaw() - 90); - double ti = rads; - - public void run() { - for (int j = 0; j < 3; j++) { - ti += Math.PI / 15; - target.getWorld().spawnParticle(Particle.SMOKE_LARGE, loc.clone().add(Math.cos(ti), 1, Math.sin(ti)), 0); - } - if (ti >= Math.PI * 2 + rads) - cancel(); - } - }.runTaskTimer(MMOItems.plugin, 0, 1); - - new BukkitRunnable() { - int ti; - - public void run() { - if (ti++ > (duration > 300 ? 300 : duration * 10) || target.isDead()) - cancel(); - else - target.playEffect(EntityEffect.HURT); - } - }.runTaskTimer(MMOItems.plugin, 0, 2); - } -} diff --git a/src/main/java/net/Indyuce/mmoitems/ability/onhit/Slow.java b/src/main/java/net/Indyuce/mmoitems/ability/onhit/Slow.java deleted file mode 100644 index cf003f56..00000000 --- a/src/main/java/net/Indyuce/mmoitems/ability/onhit/Slow.java +++ /dev/null @@ -1,62 +0,0 @@ -package net.Indyuce.mmoitems.ability.onhit; - -import org.bukkit.Color; -import org.bukkit.Location; -import org.bukkit.Particle; -import org.bukkit.Sound; -import org.bukkit.entity.LivingEntity; -import org.bukkit.potion.PotionEffect; -import org.bukkit.potion.PotionEffectType; -import org.bukkit.scheduler.BukkitRunnable; - -import net.Indyuce.mmoitems.MMOItems; -import net.Indyuce.mmoitems.api.ItemAttackResult; -import net.Indyuce.mmoitems.api.ability.Ability; -import net.Indyuce.mmoitems.api.ability.AbilityResult; -import net.Indyuce.mmoitems.api.ability.TargetAbilityResult; -import net.Indyuce.mmoitems.api.player.PlayerStats.CachedStats; -import net.Indyuce.mmoitems.stat.data.AbilityData; - -public class Slow extends Ability { - public Slow() { - super(CastingMode.ON_HIT, CastingMode.WHEN_HIT, CastingMode.LEFT_CLICK, CastingMode.RIGHT_CLICK, CastingMode.SHIFT_LEFT_CLICK, - CastingMode.SHIFT_RIGHT_CLICK); - - addModifier("cooldown", 5); - addModifier("duration", 3); - addModifier("amplifier", 1); - addModifier("mana", 0); - addModifier("stamina", 0); - } - - @Override - public AbilityResult whenRan(CachedStats stats, LivingEntity target, AbilityData ability, ItemAttackResult result) { - return new TargetAbilityResult(ability, stats.getPlayer(), target); - } - - @Override - public void whenCast(CachedStats stats, AbilityResult ability, ItemAttackResult result) { - LivingEntity target = ((TargetAbilityResult) ability).getTarget(); - - new BukkitRunnable() { - final Location loc = target.getLocation(); - double ti = 0; - - public void run() { - ti += Math.PI / 10; - if (ti >= Math.PI * 2) - cancel(); - - for (double j = 0; j < Math.PI * 2; j += Math.PI) - for (double r = 0; r < .7; r += .1) - loc.getWorld().spawnParticle(Particle.REDSTONE, - loc.clone().add(Math.cos((ti / 2) + j + (Math.PI * r)) * r * 2, .1, Math.sin((ti / 2) + j + (Math.PI * r)) * r * 2), - 1, new Particle.DustOptions(Color.WHITE, 1)); - - } - }.runTaskTimer(MMOItems.plugin, 0, 1); - target.getWorld().playSound(target.getLocation(), Sound.ENTITY_LLAMA_ANGRY, 1, 2); - target.addPotionEffect( - new PotionEffect(PotionEffectType.SLOW, (int) (ability.getModifier("duration") * 20), (int) ability.getModifier("amplifier"))); - } -} diff --git a/src/main/java/net/Indyuce/mmoitems/ability/onhit/Starfall.java b/src/main/java/net/Indyuce/mmoitems/ability/onhit/Starfall.java deleted file mode 100644 index 0d6ab02f..00000000 --- a/src/main/java/net/Indyuce/mmoitems/ability/onhit/Starfall.java +++ /dev/null @@ -1,62 +0,0 @@ -package net.Indyuce.mmoitems.ability.onhit; - -import org.bukkit.Location; -import org.bukkit.Particle; -import org.bukkit.Sound; -import org.bukkit.entity.LivingEntity; -import org.bukkit.scheduler.BukkitRunnable; -import org.bukkit.util.Vector; - -import net.Indyuce.mmoitems.MMOItems; -import net.Indyuce.mmoitems.api.ItemAttackResult; -import net.Indyuce.mmoitems.api.ability.Ability; -import net.Indyuce.mmoitems.api.ability.AbilityResult; -import net.Indyuce.mmoitems.api.ability.TargetAbilityResult; -import net.Indyuce.mmoitems.api.player.PlayerStats.CachedStats; -import net.Indyuce.mmoitems.stat.data.AbilityData; -import io.lumine.mythic.lib.version.VersionSound; - -public class Starfall extends Ability { - public Starfall() { - super(CastingMode.ON_HIT); - - addModifier("cooldown", 8); - addModifier("damage", 3.5); - addModifier("mana", 0); - addModifier("stamina", 0); - } - - @Override - public AbilityResult whenRan(CachedStats stats, LivingEntity target, AbilityData ability, ItemAttackResult result) { - return new TargetAbilityResult(ability, stats.getPlayer(), target); - } - - @Override - public void whenCast(CachedStats stats, AbilityResult ability, ItemAttackResult result) { - LivingEntity target = ((TargetAbilityResult) ability).getTarget(); - - new BukkitRunnable() { - final double ran = random.nextDouble() * Math.PI * 2; - final Location loc = target.getLocation().add(Math.cos(ran) * 3, 6, Math.sin(ran) * 3); - final Vector vec = target.getLocation().add(0, .65, 0).toVector().subtract(loc.toVector()).multiply(.05); - double ti = 0; - - public void run() { - loc.getWorld().playSound(loc, VersionSound.BLOCK_NOTE_BLOCK_HAT.toSound(), 2, 2); - for (int j = 0; j < 2; j++) { - ti += .05; - - loc.add(vec); - loc.getWorld().spawnParticle(Particle.FIREWORKS_SPARK, loc, 1, .04, 0, .04, 0); - if (ti >= 1) { - loc.getWorld().spawnParticle(Particle.FIREWORKS_SPARK, loc, 24, 0, 0, 0, .12); - loc.getWorld().playSound(loc, VersionSound.ENTITY_FIREWORK_ROCKET_BLAST.toSound(), 1, 2); - cancel(); - } - } - } - }.runTaskTimer(MMOItems.plugin, 0, 1); - target.getWorld().playSound(target.getLocation(), Sound.ENTITY_WITHER_SHOOT, 2, 2); - result.addDamage(ability.getModifier("damage")); - } -} diff --git a/src/main/java/net/Indyuce/mmoitems/ability/onhit/Stun.java b/src/main/java/net/Indyuce/mmoitems/ability/onhit/Stun.java deleted file mode 100644 index 6d92b7fe..00000000 --- a/src/main/java/net/Indyuce/mmoitems/ability/onhit/Stun.java +++ /dev/null @@ -1,40 +0,0 @@ -package net.Indyuce.mmoitems.ability.onhit; - -import org.bukkit.Effect; -import org.bukkit.Sound; -import org.bukkit.entity.LivingEntity; -import org.bukkit.potion.PotionEffect; -import org.bukkit.potion.PotionEffectType; - -import net.Indyuce.mmoitems.api.ItemAttackResult; -import net.Indyuce.mmoitems.api.ability.Ability; -import net.Indyuce.mmoitems.api.ability.AbilityResult; -import net.Indyuce.mmoitems.api.ability.TargetAbilityResult; -import net.Indyuce.mmoitems.api.player.PlayerStats.CachedStats; -import net.Indyuce.mmoitems.stat.data.AbilityData; - -public class Stun extends Ability { - public Stun() { - super(CastingMode.ON_HIT, CastingMode.WHEN_HIT, CastingMode.LEFT_CLICK, CastingMode.RIGHT_CLICK, CastingMode.SHIFT_LEFT_CLICK, CastingMode.SHIFT_RIGHT_CLICK); - - addModifier("cooldown", 10); - addModifier("duration", 2); - addModifier("mana", 0); - addModifier("stamina", 0); - } - - @Override - public AbilityResult whenRan(CachedStats stats, LivingEntity target, AbilityData ability, ItemAttackResult result) { - return new TargetAbilityResult(ability, stats.getPlayer(), target); - } - - @Override - public void whenCast(CachedStats stats, AbilityResult ability, ItemAttackResult result) { - LivingEntity target = ((TargetAbilityResult) ability).getTarget(); - - target.getWorld().playSound(target.getLocation(), Sound.BLOCK_ANVIL_LAND, 1, 2); - target.getWorld().playEffect(target.getLocation(), Effect.STEP_SOUND, 42); - target.getWorld().playEffect(target.getLocation().add(0, 1, 0), Effect.STEP_SOUND, 42); - target.addPotionEffect(new PotionEffect(PotionEffectType.SLOW, (int) (ability.getModifier("duration") * 20), 254)); - } -} diff --git a/src/main/java/net/Indyuce/mmoitems/ability/onhit/Vampirism.java b/src/main/java/net/Indyuce/mmoitems/ability/onhit/Vampirism.java deleted file mode 100644 index adfa226b..00000000 --- a/src/main/java/net/Indyuce/mmoitems/ability/onhit/Vampirism.java +++ /dev/null @@ -1,61 +0,0 @@ -package net.Indyuce.mmoitems.ability.onhit; - -import org.bukkit.Color; -import org.bukkit.Location; -import org.bukkit.Particle; -import org.bukkit.Sound; -import org.bukkit.entity.LivingEntity; -import org.bukkit.scheduler.BukkitRunnable; - -import net.Indyuce.mmoitems.MMOItems; -import net.Indyuce.mmoitems.MMOUtils; -import net.Indyuce.mmoitems.api.ItemAttackResult; -import net.Indyuce.mmoitems.api.ability.Ability; -import net.Indyuce.mmoitems.api.ability.AbilityResult; -import net.Indyuce.mmoitems.api.ability.TargetAbilityResult; -import net.Indyuce.mmoitems.api.player.PlayerStats.CachedStats; -import net.Indyuce.mmoitems.stat.data.AbilityData; - -public class Vampirism extends Ability { - public Vampirism() { - super(CastingMode.ON_HIT, CastingMode.WHEN_HIT, CastingMode.LEFT_CLICK, CastingMode.RIGHT_CLICK, CastingMode.SHIFT_LEFT_CLICK, - CastingMode.SHIFT_RIGHT_CLICK); - - addModifier("cooldown", 8); - addModifier("drain", 10); - addModifier("mana", 0); - addModifier("stamina", 0); - } - - @Override - public AbilityResult whenRan(CachedStats stats, LivingEntity target, AbilityData ability, ItemAttackResult result) { - return new TargetAbilityResult(ability, stats.getPlayer(), target); - } - - @Override - public void whenCast(CachedStats stats, AbilityResult ability, ItemAttackResult result) { - LivingEntity target = ((TargetAbilityResult) ability).getTarget(); - - new BukkitRunnable() { - double ti = 0; - final Location loc = target.getLocation(); - double dis = 0; - - public void run() { - for (int j1 = 0; j1 < 4; j1++) { - ti += .75; - dis += ti <= 10 ? .15 : -.15; - - for (double j = 0; j < Math.PI * 2; j += Math.PI / 4) - loc.getWorld().spawnParticle(Particle.REDSTONE, - loc.clone().add(Math.cos(j + (ti / 20)) * dis, 0, Math.sin(j + (ti / 20)) * dis), 1, - new Particle.DustOptions(Color.RED, 1)); - } - if (ti >= 17) - cancel(); - } - }.runTaskTimer(MMOItems.plugin, 0, 1); - target.getWorld().playSound(target.getLocation(), Sound.ENTITY_WITCH_DRINK, 1, 2); - MMOUtils.heal(stats.getPlayer(), result.getDamage() * ability.getModifier("drain") / 100); - } -} diff --git a/src/main/java/net/Indyuce/mmoitems/ability/onhit/Wither.java b/src/main/java/net/Indyuce/mmoitems/ability/onhit/Wither.java deleted file mode 100644 index cd7f5065..00000000 --- a/src/main/java/net/Indyuce/mmoitems/ability/onhit/Wither.java +++ /dev/null @@ -1,65 +0,0 @@ -package net.Indyuce.mmoitems.ability.onhit; - -import org.bukkit.Color; -import org.bukkit.Location; -import org.bukkit.Particle; -import org.bukkit.Sound; -import org.bukkit.entity.LivingEntity; -import org.bukkit.potion.PotionEffect; -import org.bukkit.potion.PotionEffectType; -import org.bukkit.scheduler.BukkitRunnable; - -import net.Indyuce.mmoitems.MMOItems; -import net.Indyuce.mmoitems.api.ItemAttackResult; -import net.Indyuce.mmoitems.api.ability.Ability; -import net.Indyuce.mmoitems.api.ability.AbilityResult; -import net.Indyuce.mmoitems.api.ability.TargetAbilityResult; -import net.Indyuce.mmoitems.api.player.PlayerStats.CachedStats; -import net.Indyuce.mmoitems.stat.data.AbilityData; - -@SuppressWarnings("unused") -public class Wither extends Ability { - public Wither() { - super(CastingMode.ON_HIT, CastingMode.WHEN_HIT, CastingMode.LEFT_CLICK, CastingMode.RIGHT_CLICK, CastingMode.SHIFT_LEFT_CLICK, - CastingMode.SHIFT_RIGHT_CLICK); - - addModifier("cooldown", 8); - addModifier("duration", 3); - addModifier("amplifier", 1); - addModifier("mana", 0); - addModifier("stamina", 0); - } - - @Override - public AbilityResult whenRan(CachedStats stats, LivingEntity target, AbilityData ability, ItemAttackResult result) { - return new TargetAbilityResult(ability, stats.getPlayer(), target); - } - - @Override - public void whenCast(CachedStats stats, AbilityResult ability, ItemAttackResult result) { - LivingEntity target = ((TargetAbilityResult) ability).getTarget(); - - new BukkitRunnable() { - final Location loc = target.getLocation(); - double y = 0; - - public void run() { - if (y > 3) - cancel(); - - for (int j1 = 0; j1 < 3; j1++) { - y += .07; - for (int j = 0; j < 3; j++) { - double a = y * Math.PI + (j * Math.PI * 2 / 3); - double x = Math.cos(a) * (3 - y) / 2.5; - double z = Math.sin(a) * (3 - y) / 2.5; - loc.getWorld().spawnParticle(Particle.REDSTONE, loc.clone().add(x, y, z), 1, new Particle.DustOptions(Color.BLACK, 1)); - } - } - } - }.runTaskTimer(MMOItems.plugin, 0, 1); - target.getWorld().playSound(target.getLocation(), Sound.ENTITY_WITHER_SHOOT, 2, 2); - target.addPotionEffect( - new PotionEffect(PotionEffectType.WITHER, (int) (ability.getModifier("duration") * 20), (int) ability.getModifier("amplifier"))); - } -} diff --git a/src/main/java/net/Indyuce/mmoitems/api/CustomSound.java b/src/main/java/net/Indyuce/mmoitems/api/CustomSound.java index 0821ba7e..7ac86cb2 100644 --- a/src/main/java/net/Indyuce/mmoitems/api/CustomSound.java +++ b/src/main/java/net/Indyuce/mmoitems/api/CustomSound.java @@ -1,5 +1,6 @@ package net.Indyuce.mmoitems.api; +import io.lumine.mythic.lib.damage.AttackMetadata; import org.bukkit.Material; import org.bukkit.inventory.ItemStack; diff --git a/src/main/java/net/Indyuce/mmoitems/api/Element.java b/src/main/java/net/Indyuce/mmoitems/api/Element.java index 5c1a2189..cf59babf 100644 --- a/src/main/java/net/Indyuce/mmoitems/api/Element.java +++ b/src/main/java/net/Indyuce/mmoitems/api/Element.java @@ -1,12 +1,14 @@ package net.Indyuce.mmoitems.api; -import org.bukkit.ChatColor; -import org.bukkit.Color; -import org.bukkit.EntityEffect; -import org.bukkit.Location; -import org.bukkit.Material; -import org.bukkit.Particle; -import org.bukkit.Sound; +import io.lumine.mythic.lib.MythicLib; +import io.lumine.mythic.lib.damage.DamageMetadata; +import io.lumine.mythic.lib.damage.DamageType; +import io.lumine.mythic.lib.version.VersionMaterial; +import io.lumine.mythic.lib.version.VersionSound; +import net.Indyuce.mmoitems.MMOItems; +import net.Indyuce.mmoitems.MMOUtils; +import net.Indyuce.mmoitems.listener.ElementListener; +import org.bukkit.*; import org.bukkit.entity.Entity; import org.bukkit.entity.LivingEntity; import org.bukkit.inventory.ItemStack; @@ -16,24 +18,16 @@ import org.bukkit.scheduler.BukkitRunnable; import org.bukkit.util.Consumer; import org.bukkit.util.Vector; -import net.Indyuce.mmoitems.MMOItems; -import net.Indyuce.mmoitems.MMOUtils; -import net.Indyuce.mmoitems.api.player.PlayerStats.CachedStats; -import net.Indyuce.mmoitems.listener.ElementListener; -import io.lumine.mythic.lib.api.DamageType; -import io.lumine.mythic.lib.version.VersionMaterial; -import io.lumine.mythic.lib.version.VersionSound; - public enum Element { - FIRE(Material.BLAZE_POWDER, ChatColor.DARK_RED, new ElementParticle(Particle.FLAME, .05f, 8), (stats, result, target, attack, absolute) -> { + FIRE(Material.BLAZE_POWDER, ChatColor.DARK_RED, new ElementParticle(Particle.FLAME, .05f, 8), (attack, target, damage, absolute) -> { target.getWorld().spawnParticle(Particle.LAVA, target.getLocation().add(0, target.getHeight() / 2, 0), 14); target.getWorld().playSound(target.getLocation(), Sound.ENTITY_BLAZE_HURT, 2, .8f); - target.setFireTicks((int) (attack * 2)); - result.addDamage(absolute); + target.setFireTicks((int) (damage * 2)); + attack.getDamage().add(absolute); }, 19, 25), ICE(VersionMaterial.SNOWBALL.toMaterial(), ChatColor.AQUA, new ElementParticle(Particle.BLOCK_CRACK, .07f, 16, Material.ICE), - (stats, result, target, attack, absolute) -> { + (attack, target, damage, absolute) -> { new BukkitRunnable() { double y = 0; final Location loc = target.getLocation(); @@ -49,52 +43,52 @@ public enum Element { } }.runTaskTimer(MMOItems.plugin, 0, 1); target.getWorld().playSound(target.getLocation(), Sound.BLOCK_GLASS_BREAK, 2, 0); - target.addPotionEffect(new PotionEffect(PotionEffectType.SLOW, (int) (attack * 1.5), 5)); - result.addDamage(absolute); + target.addPotionEffect(new PotionEffect(PotionEffectType.SLOW, (int) (damage * 1.5), 5)); + attack.getDamage().add(absolute); }, 20, 24), - WIND(Material.FEATHER, ChatColor.GRAY, new ElementParticle(Particle.EXPLOSION_NORMAL, .06f, 8), (stats, result, target, attack, absolute) -> { + WIND(Material.FEATHER, ChatColor.GRAY, new ElementParticle(Particle.EXPLOSION_NORMAL, .06f, 8), (attack, target, damage, absolute) -> { target.getWorld().playSound(target.getLocation(), VersionSound.ENTITY_ENDER_DRAGON_GROWL.toSound(), 2, 2f); - Vector vec = target.getLocation().subtract(stats.getPlayer().getLocation()).toVector().normalize().multiply(1.7).setY(.5); + Vector vec = target.getLocation().subtract(attack.getDamager().getLocation()).toVector().normalize().multiply(1.7).setY(.5); target.setVelocity(vec); for (Entity entity : target.getNearbyEntities(3, 1, 3)) - if (MMOUtils.canDamage(stats.getPlayer(), entity)) { + if (MMOUtils.canDamage(attack.getDamager(), entity)) { entity.playEffect(EntityEffect.HURT); entity.setVelocity(vec); } - result.addDamage(absolute); + attack.getDamage().add(absolute); for (double k = 0; k < Math.PI * 2; k += Math.PI / 16) target.getWorld().spawnParticle(Particle.CLOUD, target.getLocation().add(0, target.getHeight() / 2, 0), 0, Math.cos(k), .01, Math.sin(k), .15); }, 28, 34), EARTH(VersionMaterial.OAK_SAPLING.toMaterial(), ChatColor.GREEN, new ElementParticle(Particle.BLOCK_CRACK, .05f, 24, Material.DIRT), - (stats, result, target, attack, absolute) -> { + (attack, target, damage, absolute) -> { target.getWorld().playSound(target.getLocation(), Sound.BLOCK_GRASS_BREAK, 2, 0); target.getWorld().spawnParticle(Particle.BLOCK_CRACK, target.getLocation().add(0, .1, 0), 64, 1, 0, 1, Material.DIRT.createBlockData()); - result.addDamage(absolute); + attack.getDamage().add(absolute); target.setVelocity(new Vector(0, 1, 0)); for (Entity entity : target.getNearbyEntities(3, 1, 3)) - if (MMOUtils.canDamage(stats.getPlayer(), entity)) + if (MMOUtils.canDamage(attack.getDamager(), entity)) entity.setVelocity(new Vector(0, 1, 0)); }, 29, 33), - THUNDER(VersionMaterial.GUNPOWDER.toMaterial(), ChatColor.YELLOW, new ElementParticle(Particle.FIREWORKS_SPARK, .05f, 8), (stats, result, target, attack, absolute) -> { + THUNDER(VersionMaterial.GUNPOWDER.toMaterial(), ChatColor.YELLOW, new ElementParticle(Particle.FIREWORKS_SPARK, .05f, 8), (attack, target, damage, absolute) -> { target.getWorld().playSound(target.getLocation(), VersionSound.ENTITY_FIREWORK_ROCKET_LARGE_BLAST.toSound(), 2, 0); for (Entity entity : target.getNearbyEntities(3, 2, 3)) - if (MMOUtils.canDamage(stats.getPlayer(), entity)) - new ItemAttackResult(result.getDamage() * attack / 100, DamageType.WEAPON).damage(stats.getPlayer(), (LivingEntity) entity); + if (MMOUtils.canDamage(attack.getDamager(), entity)) + MythicLib.plugin.getDamage().damage(new ItemAttackMetadata(new DamageMetadata(attack.getDamage().getDamage() * damage / 100, DamageType.WEAPON), attack.getStats()), (LivingEntity) entity); - result.addDamage(absolute); + attack.getDamage().add(absolute); for (double k = 0; k < Math.PI * 2; k += Math.PI / 16) target.getWorld().spawnParticle(Particle.FIREWORKS_SPARK, target.getLocation().add(0, target.getHeight() / 2, 0), 0, Math.cos(k), .01, Math.sin(k), .18); }, 30, 32), WATER(VersionMaterial.LILY_PAD.toMaterial(), ChatColor.BLUE, new ElementParticle(Particle.BLOCK_CRACK, .07f, 32, Material.WATER), - (stats, result, target, attack, absolute) -> { + (attack, target, damage, absolute) -> { ElementListener.weaken(target); new BukkitRunnable() { double step = Math.PI / 2; @@ -112,12 +106,12 @@ public enum Element { }, 37, 43), LIGHTNESS(Material.GLOWSTONE_DUST, ChatColor.WHITE, new ElementParticle(Particle.BLOCK_CRACK, .07f, 32, Material.WHITE_WOOL), - (stats, result, target, damage, absolute) -> { - + (attack, target, damage, absolute) -> { + // TODO }, 38, 42), - DARKNESS(Material.COAL, ChatColor.DARK_GRAY, new ElementParticle(Particle.BLOCK_CRACK, .07f, 32, Material.COAL_BLOCK), (stats, result, target, damage, absolute) -> { - + DARKNESS(Material.COAL, ChatColor.DARK_GRAY, new ElementParticle(Particle.BLOCK_CRACK, .07f, 32, Material.COAL_BLOCK), (attack, target, damage, absolute) -> { + // TODO }, 39, 41), ; @@ -169,7 +163,7 @@ public enum Element { } public interface ElementHandler { - void elementAttack(CachedStats stats, ItemAttackResult result, LivingEntity target, double damage, double absolute); + void elementAttack(ItemAttackMetadata attack, LivingEntity target, double damage, double absolute); } public static class ElementParticle { diff --git a/src/main/java/net/Indyuce/mmoitems/api/ElementalAttack.java b/src/main/java/net/Indyuce/mmoitems/api/ElementalAttack.java index 74f8b6b6..f751e4e8 100644 --- a/src/main/java/net/Indyuce/mmoitems/api/ElementalAttack.java +++ b/src/main/java/net/Indyuce/mmoitems/api/ElementalAttack.java @@ -1,27 +1,26 @@ package net.Indyuce.mmoitems.api; +import io.lumine.mythic.lib.MythicLib; +import io.lumine.mythic.lib.api.item.NBTItem; +import net.Indyuce.mmoitems.api.player.PlayerData.CooldownType; +import org.bukkit.entity.LivingEntity; +import org.bukkit.inventory.ItemStack; + import java.util.HashMap; import java.util.Map; import java.util.Random; -import org.bukkit.entity.LivingEntity; -import org.bukkit.inventory.ItemStack; - -import net.Indyuce.mmoitems.api.player.PlayerData.CooldownType; -import net.Indyuce.mmoitems.api.player.PlayerStats.CachedStats; -import io.lumine.mythic.lib.MythicLib; -import io.lumine.mythic.lib.api.item.NBTItem; - public class ElementalAttack { private final Map relative = new HashMap<>(); private final Map absolute = new HashMap<>(); - private final ItemAttackResult result; + private final ItemAttackMetadata attack; private final LivingEntity target; private static final Random random = new Random(); - public ElementalAttack(NBTItem item, ItemAttackResult result, LivingEntity target) { - this.result = result; + // TODO rework this shit + public ElementalAttack(NBTItem item, ItemAttackMetadata attack, LivingEntity target) { + this.attack = attack; this.target = target; for (Element element : Element.values()) { @@ -29,14 +28,14 @@ public class ElementalAttack { if (damage > 0) { relative.put(element, damage); - double abs = damage / 100 * result.getDamage(); - result.addDamage(-abs); + double abs = damage / 100 * attack.getDamage().getDamage(); + attack.getDamage().add(-abs); absolute.put(element, abs); } } } - public void apply(CachedStats stats) { + public void apply() { // elemental defense for (ItemStack equip : target.getEquipment().getArmorContents()) { @@ -53,12 +52,12 @@ public class ElementalAttack { // elemental attacks double p = 1; - if (!stats.getData().isOnCooldown(CooldownType.ELEMENTAL_ATTACK)) + if (!attack.getPlayerData().isOnCooldown(CooldownType.ELEMENTAL_ATTACK)) for (Element element : relative.keySet()) { double damage = relative.get(element); if (random.nextDouble() < (damage / 100 / p)) { - stats.getData().applyCooldown(CooldownType.ELEMENTAL_ATTACK, 2); - element.getHandler().elementAttack(stats, result, target, damage, absolute.get(element)); + attack.getPlayerData().applyCooldown(CooldownType.ELEMENTAL_ATTACK, 2); + element.getHandler().elementAttack(attack, target, damage, absolute.get(element)); break; } p -= damage / 100; @@ -67,7 +66,7 @@ public class ElementalAttack { for (Element element : absolute.keySet()) { double damage = absolute.get(element); if (damage > 0) { - result.addDamage(damage); + attack.getDamage().add(damage); element.getParticle().displayParticle(target); } } diff --git a/src/main/java/net/Indyuce/mmoitems/api/ItemAttackMetadata.java b/src/main/java/net/Indyuce/mmoitems/api/ItemAttackMetadata.java new file mode 100644 index 00000000..16400c8c --- /dev/null +++ b/src/main/java/net/Indyuce/mmoitems/api/ItemAttackMetadata.java @@ -0,0 +1,84 @@ +package net.Indyuce.mmoitems.api; + +import io.lumine.mythic.lib.MythicLib; +import io.lumine.mythic.lib.api.item.NBTItem; +import io.lumine.mythic.lib.api.stat.StatMap; +import io.lumine.mythic.lib.damage.AttackMetadata; +import io.lumine.mythic.lib.damage.DamageMetadata; +import io.lumine.mythic.lib.damage.DamageType; +import net.Indyuce.mmoitems.ability.Ability; +import net.Indyuce.mmoitems.api.player.PlayerData; +import org.bukkit.entity.LivingEntity; + +/** + * The attack metadata used here in MMOItems. It + * extends the default attack metadata from MythicLib + * to benefit from all its methods + */ +public class ItemAttackMetadata extends AttackMetadata { + public ItemAttackMetadata(DamageMetadata damage, StatMap.CachedStatMap damager) { + super(damage, damager); + } + + public PlayerData getPlayerData() { + return PlayerData.get(getDamager().getUniqueId()); + } + + @Override + public ItemAttackMetadata setSuccessful(boolean successful) { + super.setSuccessful(successful); + return this; + } + + /** + * Applies on-hit effects and deals damage to the target + * + * @param item The item being used + * @param target The entity target + */ + public void applyEffectsAndDamage(NBTItem item, LivingEntity target) { + MythicLib.plugin.getDamage().damage(applyEffects(item, target), target, true); + } + + /** + * Applies all necessary on-hit effects for any type of damage. + * Makes things much easier for untargeted weapons like staffs + * + * @param item The item being used + * @param target The entity target + * @return The unedited attack result + */ + public ItemAttackMetadata applyEffects(NBTItem item, LivingEntity target) { + if (getDamage().hasType(DamageType.WEAPON)) { + applyElementalEffects(item, target); + applyOnHitEffects(target); + } + return this; + } + + /** + * Applies MMOItem specific on-hit effects like elemental damage. + * + * @param item The item being used + * @param target The entity target + * @return The unedited attack result + */ + @SuppressWarnings("UnusedReturnValue") + public ItemAttackMetadata applyElementalEffects(NBTItem item, LivingEntity target) { + new ElementalAttack(item, this, target).apply(); + return this; + } + + /** + * This method is called when a player uses ANY weapon, vanilla or custom. + * It does not take into input any weapon as it just applies non weapon + * specific on-hit effects + * + * @param target The entity target + * @return The unedited attack result + */ + public ItemAttackMetadata applyOnHitEffects(LivingEntity target) { + getPlayerData().castAbilities(this, target, Ability.CastingMode.ON_HIT); + return this; + } +} diff --git a/src/main/java/net/Indyuce/mmoitems/api/ItemAttackResult.java b/src/main/java/net/Indyuce/mmoitems/api/ItemAttackResult.java deleted file mode 100644 index 0e2db378..00000000 --- a/src/main/java/net/Indyuce/mmoitems/api/ItemAttackResult.java +++ /dev/null @@ -1,102 +0,0 @@ -package net.Indyuce.mmoitems.api; - -import io.lumine.mythic.lib.MythicLib; -import io.lumine.mythic.lib.api.AttackResult; -import io.lumine.mythic.lib.api.DamageType; -import io.lumine.mythic.lib.api.item.NBTItem; -import net.Indyuce.mmoitems.api.ability.Ability.CastingMode; -import net.Indyuce.mmoitems.api.player.PlayerStats.CachedStats; -import org.bukkit.entity.LivingEntity; - -public class ItemAttackResult extends AttackResult { - public ItemAttackResult(boolean successful, DamageType... types) { - super(successful, 0, types); - } - - public ItemAttackResult(double damage, DamageType... types) { - super(true, damage, types); - } - - public ItemAttackResult(ItemAttackResult result) { - super(result); - } - - @Override - public ItemAttackResult clone() { - return new ItemAttackResult(this); - } - - @Override - public ItemAttackResult setSuccessful(boolean successful) { - return (ItemAttackResult) super.setSuccessful(successful); - } - - @Override - public ItemAttackResult multiplyDamage(double coef) { - return (ItemAttackResult) super.multiplyDamage(coef); - } - - /** - * Applies on-hit effects and deals damage to the target - * - * @param stats - * Player doing the attack - * @param item - * The item being used - * @param target - * The entity target - */ - public void applyEffectsAndDamage(CachedStats stats, NBTItem item, LivingEntity target) { - MythicLib.plugin.getDamage().damage(stats.getPlayer(), target, applyEffects(stats, item, target)); - } - - /** - * Applies all necessary on-hit effects for any type of damage. Makes things - * much easier for untargeted weapons like staffs - * - * @param stats - * Player doing the attack - * @param item - * The item being used - * @param target - * The entity target - * @return The unedited attack result - */ - public ItemAttackResult applyEffects(CachedStats stats, NBTItem item, LivingEntity target) { - if (hasType(DamageType.WEAPON)) { - applyElementalEffects(stats, item, target); - applyOnHitEffects(stats, target); - } - return this; - } - - /** - * Applies MMOItem specific on-hit effects like elemental damage. - * - * @param stats Player doing the attack - * @param item The item being used - * @param target The entity target - * @return The unedited attack result - */ - @SuppressWarnings("UnusedReturnValue") - public ItemAttackResult applyElementalEffects(CachedStats stats, NBTItem item, LivingEntity target) { - new ElementalAttack(item, this, target).apply(stats); - return this; - } - - /** - * This method is called when a player uses ANY weapon, vanilla or custom. - * It does not take into input any weapon as it just applies non weapon - * specific on-hit effects - * - * @param stats - * Player doing the attack - * @param target - * The entity target - * @return The unedited attack result - */ - public ItemAttackResult applyOnHitEffects(CachedStats stats, LivingEntity target) { - stats.getData().castAbilities(stats, target, this, CastingMode.ON_HIT); - return this; - } -} diff --git a/src/main/java/net/Indyuce/mmoitems/api/MMOItemsAPI.java b/src/main/java/net/Indyuce/mmoitems/api/MMOItemsAPI.java index 5c7bc90f..86dd0980 100644 --- a/src/main/java/net/Indyuce/mmoitems/api/MMOItemsAPI.java +++ b/src/main/java/net/Indyuce/mmoitems/api/MMOItemsAPI.java @@ -1,7 +1,7 @@ package net.Indyuce.mmoitems.api; import net.Indyuce.mmoitems.MMOItems; -import net.Indyuce.mmoitems.api.ability.Ability; +import net.Indyuce.mmoitems.ability.Ability; import org.bukkit.plugin.java.JavaPlugin; public class MMOItemsAPI { diff --git a/src/main/java/net/Indyuce/mmoitems/api/TypeSet.java b/src/main/java/net/Indyuce/mmoitems/api/TypeSet.java index 22e775a3..8c50b4cd 100644 --- a/src/main/java/net/Indyuce/mmoitems/api/TypeSet.java +++ b/src/main/java/net/Indyuce/mmoitems/api/TypeSet.java @@ -2,12 +2,10 @@ package net.Indyuce.mmoitems.api; import io.lumine.mythic.lib.api.stat.modifier.ModifierSource; import io.lumine.mythic.lib.version.VersionSound; -import net.Indyuce.mmoitems.ItemStats; import net.Indyuce.mmoitems.MMOItems; import net.Indyuce.mmoitems.MMOUtils; import net.Indyuce.mmoitems.api.interaction.weapon.Weapon; import net.Indyuce.mmoitems.api.player.PlayerData.CooldownType; -import net.Indyuce.mmoitems.api.player.PlayerStats.CachedStats; import org.bukkit.Location; import org.bukkit.Particle; import org.bukkit.Sound; @@ -24,12 +22,12 @@ public enum TypeSet { * Slashing weapons deal damage in a cone behind the player's initial * target, which makes it a deadly AoE weapon for warriors */ - SLASHING(ModifierSource.MELEE_WEAPON, (stats, target, weapon, result) -> { - if (!MMOItems.plugin.getConfig().getBoolean("item-ability.slashing.enabled") || stats.getData().isOnCooldown(CooldownType.SET_TYPE_ATTACK)) + SLASHING(ModifierSource.MELEE_WEAPON, (attack, target, weapon) -> { + if (!MMOItems.plugin.getConfig().getBoolean("item-ability.slashing.enabled") || attack.getPlayerData().isOnCooldown(CooldownType.SET_TYPE_ATTACK)) return; - stats.getData().applyCooldown(CooldownType.SET_TYPE_ATTACK, MMOItems.plugin.getConfig().getDouble("item-ability.slashing.cooldown")); - Location loc = stats.getPlayer().getLocation().clone().add(0, 1.3, 0); + attack.getPlayerData().applyCooldown(CooldownType.SET_TYPE_ATTACK, MMOItems.plugin.getConfig().getDouble("item-ability.slashing.cooldown")); + Location loc = attack.getDamager().getLocation().clone().add(0, 1.3, 0); final double a1 = (loc.getYaw() + 90) / 180 * Math.PI, p = -loc.getPitch() / 180 * Math.PI; for (double r = 1; r < 5; r += .3) @@ -38,10 +36,13 @@ public enum TypeSet { for (Entity entity : MMOUtils.getNearbyChunkEntities(loc)) if (entity.getLocation().distanceSquared(loc) < 40 - && stats.getPlayer().getEyeLocation().getDirection() - .angle(entity.getLocation().subtract(stats.getPlayer().getLocation()).toVector()) < Math.PI / 3 - && MMOUtils.canDamage(stats.getPlayer(), entity) && !entity.equals(target)) - result.clone().multiplyDamage(.4).applyEffectsAndDamage(stats, weapon.getNBTItem(), (LivingEntity) entity); + && attack.getDamager().getEyeLocation().getDirection() + .angle(entity.getLocation().subtract(attack.getDamager().getLocation()).toVector()) < Math.PI / 3 + && MMOUtils.canDamage(attack.getDamager(), entity) && !entity.equals(target)) { + ItemAttackMetadata subAttack = new ItemAttackMetadata(attack.getDamage().clone(), attack.getStats()); + subAttack.getDamage().multiply(.4); + subAttack.applyEffectsAndDamage(weapon.getNBTItem(), (LivingEntity) entity); + } }), /** @@ -50,12 +51,12 @@ public enum TypeSet { * increased which makes it a perfect 'double or nothing' weapon for * assassins */ - PIERCING(ModifierSource.MELEE_WEAPON, (stats, target, weapon, result) -> { - if (!MMOItems.plugin.getConfig().getBoolean("item-ability.piercing.enabled") || stats.getData().isOnCooldown(CooldownType.SET_TYPE_ATTACK)) + PIERCING(ModifierSource.MELEE_WEAPON, (attack, target, weapon) -> { + if (!MMOItems.plugin.getConfig().getBoolean("item-ability.piercing.enabled") || attack.getPlayerData().isOnCooldown(CooldownType.SET_TYPE_ATTACK)) return; - stats.getData().applyCooldown(CooldownType.SET_TYPE_ATTACK, MMOItems.plugin.getConfig().getDouble("item-ability.piercing.cooldown")); - Location loc = stats.getPlayer().getLocation().clone().add(0, 1.3, 0); + attack.getPlayerData().applyCooldown(CooldownType.SET_TYPE_ATTACK, MMOItems.plugin.getConfig().getDouble("item-ability.piercing.cooldown")); + Location loc = attack.getDamager().getLocation().clone().add(0, 1.3, 0); final double a1 = (loc.getYaw() + 90) / 180 * Math.PI, p = -loc.getPitch() / 180 * Math.PI; for (double r = 1; r < 5; r += .3) @@ -63,38 +64,48 @@ public enum TypeSet { loc.getWorld().spawnParticle(Particle.CRIT, loc.clone().add(Math.cos(a + a1) * r, Math.sin(p) * r, Math.sin(a + a1) * r), 0); for (Entity entity : MMOUtils.getNearbyChunkEntities(loc)) - if (entity.getLocation().distanceSquared(stats.getPlayer().getLocation()) < 40 - && stats.getPlayer().getEyeLocation().getDirection() - .angle(entity.getLocation().toVector().subtract(stats.getPlayer().getLocation().toVector())) < Math.PI / 18 - && MMOUtils.canDamage(stats.getPlayer(), entity) && !entity.equals(target)) - result.clone().multiplyDamage(.4).applyEffectsAndDamage(stats, weapon.getNBTItem(), (LivingEntity) entity); + if (entity.getLocation().distanceSquared(attack.getDamager().getLocation()) < 40 + && attack.getDamager().getEyeLocation().getDirection() + .angle(entity.getLocation().toVector().subtract(attack.getDamager().getLocation().toVector())) < Math.PI / 18 + && MMOUtils.canDamage(attack.getDamager(), entity) && !entity.equals(target)) { + ItemAttackMetadata subAttack = new ItemAttackMetadata(attack.getDamage().clone(), attack.getStats()); + subAttack.getDamage().multiply(.4); + subAttack.applyEffectsAndDamage(weapon.getNBTItem(), (LivingEntity) entity); + } }), /** * Blunt weapons are like 1.9 sweep attacks. They damage all enemies nearby * and apply a slight knockback */ - BLUNT(ModifierSource.MELEE_WEAPON, (stats, target, weapon, result) -> { + BLUNT(ModifierSource.MELEE_WEAPON, (attack, target, weapon) -> { final Random random = new Random(); float pitchRange = 0.7f + random.nextFloat() * (0.9f - 0.7f); - if (MMOItems.plugin.getConfig().getBoolean("item-ability.blunt.aoe.enabled") && !stats.getData().isOnCooldown(CooldownType.SPECIAL_ATTACK)) { - stats.getData().applyCooldown(CooldownType.SPECIAL_ATTACK, MMOItems.plugin.getConfig().getDouble("item-ability.blunt.aoe.cooldown")); + if (MMOItems.plugin.getConfig().getBoolean("item-ability.blunt.aoe.enabled") + && !attack.getPlayerData().isOnCooldown(CooldownType.SPECIAL_ATTACK)) { + + attack.getPlayerData().applyCooldown(CooldownType.SPECIAL_ATTACK, MMOItems.plugin.getConfig().getDouble("item-ability.blunt.aoe.cooldown")); target.getWorld().playSound(target.getLocation(), Sound.BLOCK_ANVIL_LAND, 0.6f, pitchRange); target.getWorld().spawnParticle(Particle.EXPLOSION_LARGE, target.getLocation().add(0, 1, 0), 0); - double bluntPower = stats.getStat(ItemStats.BLUNT_POWER); + double bluntPower = attack.getStats().getStat("BLUNT_POWER"); if (bluntPower > 0) { - double bluntRating = weapon.getValue(stats.getStat(ItemStats.BLUNT_RATING), + double bluntRating = weapon.getValue(attack.getStats().getStat("BLUNT_RATING"), MMOItems.plugin.getConfig().getDouble("default.blunt-rating")) / 100; for (Entity entity : target.getNearbyEntities(bluntPower, bluntPower, bluntPower)) - if (MMOUtils.canDamage(stats.getPlayer(), entity) && !entity.equals(target)) - result.clone().multiplyDamage(bluntRating).applyEffectsAndDamage(stats, weapon.getNBTItem(), (LivingEntity) entity); + if (MMOUtils.canDamage(attack.getDamager(), entity) && !entity.equals(target)) { + ItemAttackMetadata subAttack = new ItemAttackMetadata(attack.getDamage().clone(), attack.getStats()); + subAttack.getDamage().multiply(bluntRating); + subAttack.applyEffectsAndDamage(weapon.getNBTItem(), (LivingEntity) entity); + } } } - if (MMOItems.plugin.getConfig().getBoolean("item-ability.blunt.stun.enabled") && !stats.getData().isOnCooldown(CooldownType.SPECIAL_ATTACK) + if (MMOItems.plugin.getConfig().getBoolean("item-ability.blunt.stun.enabled") + && !attack.getPlayerData().isOnCooldown(CooldownType.SPECIAL_ATTACK) && random.nextDouble() < MMOItems.plugin.getConfig().getDouble("item-ability.blunt.stun.chance") / 100) { - stats.getData().applyCooldown(CooldownType.SPECIAL_ATTACK, MMOItems.plugin.getConfig().getDouble("item-ability.blunt.stun.cooldown")); + + attack.getPlayerData().applyCooldown(CooldownType.SPECIAL_ATTACK, MMOItems.plugin.getConfig().getDouble("item-ability.blunt.stun.cooldown")); target.getWorld().playSound(target.getLocation(), VersionSound.ENTITY_ZOMBIE_ATTACK_WOODEN_DOOR.toSound(), 1, 2); target.removePotionEffect(PotionEffectType.SLOW); target.removePotionEffect(PotionEffectType.BLINDNESS); @@ -132,14 +143,14 @@ public enum TypeSet { */ private final ModifierSource modifierSource; - private final SetAttackHandler attackHandler; + private final SetAttackHandler attackHandler; private final String name; private TypeSet(ModifierSource modifierSource) { this(modifierSource, null); } - private TypeSet(ModifierSource modifierSource, SetAttackHandler attackHandler) { + private TypeSet(ModifierSource modifierSource, SetAttackHandler attackHandler) { this.attackHandler = attackHandler; this.modifierSource = modifierSource; @@ -154,8 +165,8 @@ public enum TypeSet { return attackHandler != null; } - public void applyAttackEffect(CachedStats playerStats, LivingEntity target, Weapon weapon, ItemAttackResult result) { - attackHandler.apply(playerStats, target, weapon, result); + public void applyAttackEffect(ItemAttackMetadata attackMeta, LivingEntity target, Weapon weapon) { + attackHandler.apply(attackMeta, target, weapon); } public String getName() { @@ -163,7 +174,7 @@ public enum TypeSet { } @FunctionalInterface - interface SetAttackHandler { - void apply(A a, B b, C c, D d); + interface SetAttackHandler { + void apply(A a, B b, C c); } } diff --git a/src/main/java/net/Indyuce/mmoitems/api/ability/LocationAbilityResult.java b/src/main/java/net/Indyuce/mmoitems/api/ability/LocationAbilityResult.java deleted file mode 100644 index deb0d17c..00000000 --- a/src/main/java/net/Indyuce/mmoitems/api/ability/LocationAbilityResult.java +++ /dev/null @@ -1,34 +0,0 @@ -package net.Indyuce.mmoitems.api.ability; - -import net.Indyuce.mmoitems.stat.data.AbilityData; -import org.bukkit.Location; -import org.bukkit.Material; -import org.bukkit.entity.LivingEntity; -import org.bukkit.entity.Player; - -public class LocationAbilityResult extends AbilityResult { - private final Location target; - - public LocationAbilityResult(AbilityData ability, Player caster, LivingEntity target) { - super(ability); - - this.target = getTargetLocation(caster, target); - } - - public Location getTarget() { - return target; - } - - @Override - public boolean isSuccessful() { - return target != null; - } - - private Location getTargetLocation(Player player, LivingEntity entity) { - if (entity != null) - return entity.getLocation(); - - Location loc = player.getTargetBlock(null, 50).getLocation(); - return loc.getBlock().getType() == Material.AIR ? null : loc.add(.5, 1, .5); - } -} diff --git a/src/main/java/net/Indyuce/mmoitems/api/ability/SimpleAbilityResult.java b/src/main/java/net/Indyuce/mmoitems/api/ability/SimpleAbilityResult.java deleted file mode 100644 index ce29f59d..00000000 --- a/src/main/java/net/Indyuce/mmoitems/api/ability/SimpleAbilityResult.java +++ /dev/null @@ -1,22 +0,0 @@ -package net.Indyuce.mmoitems.api.ability; - -import net.Indyuce.mmoitems.stat.data.AbilityData; - -public class SimpleAbilityResult extends AbilityResult { - private final boolean successful; - - public SimpleAbilityResult(AbilityData ability) { - this(ability, true); - } - - public SimpleAbilityResult(AbilityData ability, boolean successful) { - super(ability); - - this.successful = successful; - } - - @Override - public boolean isSuccessful() { - return successful; - } -} diff --git a/src/main/java/net/Indyuce/mmoitems/api/ability/TargetAbilityResult.java b/src/main/java/net/Indyuce/mmoitems/api/ability/TargetAbilityResult.java deleted file mode 100644 index d2de107e..00000000 --- a/src/main/java/net/Indyuce/mmoitems/api/ability/TargetAbilityResult.java +++ /dev/null @@ -1,27 +0,0 @@ -package net.Indyuce.mmoitems.api.ability; - -import org.bukkit.entity.LivingEntity; -import org.bukkit.entity.Player; - -import net.Indyuce.mmoitems.MMOUtils; -import net.Indyuce.mmoitems.stat.data.AbilityData; -import io.lumine.mythic.lib.MythicLib; - -public class TargetAbilityResult extends AbilityResult { - private final LivingEntity target; - - public TargetAbilityResult(AbilityData ability, Player caster, LivingEntity target) { - super(ability); - - this.target = target != null ? target : MythicLib.plugin.getVersion().getWrapper().rayTrace(caster, 50, entity -> MMOUtils.canDamage(caster, entity)).getHit(); - } - - public LivingEntity getTarget() { - return target; - } - - @Override - public boolean isSuccessful() { - return target != null; - } -} diff --git a/src/main/java/net/Indyuce/mmoitems/api/ability/VectorAbilityResult.java b/src/main/java/net/Indyuce/mmoitems/api/ability/VectorAbilityResult.java deleted file mode 100644 index abbfd63b..00000000 --- a/src/main/java/net/Indyuce/mmoitems/api/ability/VectorAbilityResult.java +++ /dev/null @@ -1,30 +0,0 @@ -package net.Indyuce.mmoitems.api.ability; - -import org.bukkit.entity.LivingEntity; -import org.bukkit.entity.Player; -import org.bukkit.util.Vector; - -import net.Indyuce.mmoitems.stat.data.AbilityData; - -public class VectorAbilityResult extends AbilityResult { - private final Vector target; - - public VectorAbilityResult(AbilityData ability, Player caster, LivingEntity target) { - super(ability); - - this.target = getTargetDirection(caster, target); - } - - public Vector getTarget() { - return target; - } - - @Override - public boolean isSuccessful() { - return true; - } - - protected Vector getTargetDirection(Player player, LivingEntity target) { - return target == null ? player.getEyeLocation().getDirection() : target.getLocation().add(0, target.getHeight() / 2, 0).subtract(player.getLocation().add(0, 1.3, 0)).toVector().normalize(); - } -} diff --git a/src/main/java/net/Indyuce/mmoitems/api/interaction/projectile/ProjectileData.java b/src/main/java/net/Indyuce/mmoitems/api/interaction/projectile/ProjectileData.java index c8593241..0aff5ac4 100644 --- a/src/main/java/net/Indyuce/mmoitems/api/interaction/projectile/ProjectileData.java +++ b/src/main/java/net/Indyuce/mmoitems/api/interaction/projectile/ProjectileData.java @@ -1,24 +1,22 @@ package net.Indyuce.mmoitems.api.interaction.projectile; -import org.bukkit.entity.LivingEntity; -import org.bukkit.potion.PotionEffectType; - import com.google.gson.JsonArray; import com.google.gson.JsonElement; import com.google.gson.JsonObject; - -import net.Indyuce.mmoitems.api.player.PlayerStats.CachedStats; -import net.Indyuce.mmoitems.stat.data.PotionEffectData; import io.lumine.mythic.lib.MythicLib; import io.lumine.mythic.lib.api.item.NBTItem; +import net.Indyuce.mmoitems.api.ItemAttackMetadata; +import net.Indyuce.mmoitems.stat.data.PotionEffectData; +import org.bukkit.entity.LivingEntity; +import org.bukkit.potion.PotionEffectType; public class ProjectileData { private final NBTItem sourceItem; - private final CachedStats playerStats; + private final ItemAttackMetadata attackMeta; private final boolean customWeapon; - public ProjectileData(NBTItem sourceItem, CachedStats playerStats, boolean customWeapon) { - this.playerStats = playerStats; + public ProjectileData(NBTItem sourceItem, ItemAttackMetadata attackMeta, boolean customWeapon) { + this.attackMeta = attackMeta; this.sourceItem = sourceItem; this.customWeapon = customWeapon; } @@ -27,8 +25,8 @@ public class ProjectileData { return sourceItem; } - public CachedStats getPlayerStats() { - return playerStats; + public ItemAttackMetadata getAttackMetadata() { + return attackMeta; } /* diff --git a/src/main/java/net/Indyuce/mmoitems/api/interaction/weapon/Weapon.java b/src/main/java/net/Indyuce/mmoitems/api/interaction/weapon/Weapon.java index b2ea55fb..04cb7412 100644 --- a/src/main/java/net/Indyuce/mmoitems/api/interaction/weapon/Weapon.java +++ b/src/main/java/net/Indyuce/mmoitems/api/interaction/weapon/Weapon.java @@ -3,12 +3,10 @@ package net.Indyuce.mmoitems.api.interaction.weapon; import io.lumine.mythic.lib.api.item.NBTItem; import net.Indyuce.mmoitems.ItemStats; import net.Indyuce.mmoitems.MMOItems; -import net.Indyuce.mmoitems.MMOUtils; -import net.Indyuce.mmoitems.api.ItemAttackResult; +import net.Indyuce.mmoitems.api.ItemAttackMetadata; import net.Indyuce.mmoitems.api.interaction.UseItem; import net.Indyuce.mmoitems.api.player.PlayerData; import net.Indyuce.mmoitems.api.player.PlayerData.CooldownType; -import net.Indyuce.mmoitems.api.player.PlayerStats.CachedStats; import net.Indyuce.mmoitems.api.util.message.Message; import net.Indyuce.mmoitems.comp.flags.FlagPlugin; import net.Indyuce.mmoitems.comp.flags.FlagPlugin.CustomFlag; @@ -90,23 +88,19 @@ public class Weapon extends UseItem { return true; } - public ItemAttackResult handleTargetedAttack(CachedStats stats, LivingEntity target, ItemAttackResult result) { + public ItemAttackMetadata handleTargetedAttack(ItemAttackMetadata attackMeta, LivingEntity target) { - /* - * Handle weapon cooldown, mana and stamina costs - */ + // Handle weapon cooldown, mana and stamina costs double attackSpeed = getNBTItem().getStat(ItemStats.ATTACK_SPEED.getId()); attackSpeed = attackSpeed == 0 ? 1.493 : 1 / attackSpeed; if (!applyWeaponCosts()) - return result.setSuccessful(false); + return attackMeta.setSuccessful(false); - /* - * Handle item set attack effects - */ + // Handle item set attack effects if (getMMOItem().getType().getItemSet().hasAttackEffect() && !getNBTItem().getBoolean("MMOITEMS_DISABLE_ATTACK_PASSIVE")) - getMMOItem().getType().getItemSet().applyAttackEffect(stats, target, this, result); + getMMOItem().getType().getItemSet().applyAttackEffect(attackMeta, target, this); - return result; + return attackMeta; } protected Location getGround(Location loc) { diff --git a/src/main/java/net/Indyuce/mmoitems/api/interaction/weapon/untargeted/Crossbow.java b/src/main/java/net/Indyuce/mmoitems/api/interaction/weapon/untargeted/Crossbow.java index fec6da8b..1d8516bd 100644 --- a/src/main/java/net/Indyuce/mmoitems/api/interaction/weapon/untargeted/Crossbow.java +++ b/src/main/java/net/Indyuce/mmoitems/api/interaction/weapon/untargeted/Crossbow.java @@ -1,12 +1,11 @@ package net.Indyuce.mmoitems.api.interaction.weapon.untargeted; +import io.lumine.mythic.lib.api.item.NBTItem; +import io.lumine.mythic.lib.api.stat.StatMap; import net.Indyuce.mmoitems.ItemStats; import net.Indyuce.mmoitems.MMOItems; import net.Indyuce.mmoitems.api.interaction.util.UntargetedDurabilityItem; import net.Indyuce.mmoitems.api.player.PlayerData.CooldownType; -import net.Indyuce.mmoitems.api.player.PlayerStats; -import net.Indyuce.mmoitems.listener.ItemUse; -import io.lumine.mythic.lib.api.item.NBTItem; import org.bukkit.GameMode; import org.bukkit.Material; import org.bukkit.Sound; @@ -27,8 +26,8 @@ public class Crossbow extends UntargetedWeapon { if (getPlayer().getGameMode() != GameMode.CREATIVE && !getPlayer().getInventory().containsAtLeast(new ItemStack(Material.ARROW), 1)) return; - PlayerStats stats = getPlayerData().getStats(); - if (!applyWeaponCosts(1 / getValue(stats.getStat(ItemStats.ATTACK_SPEED), MMOItems.plugin.getConfig().getDouble("default.attack-speed")), + StatMap.CachedStatMap stats = getPlayerData().getStats().newTemporary(io.lumine.mythic.lib.api.player.EquipmentSlot.fromBukkit(slot)); + if (!applyWeaponCosts(1 / getValue(stats.getStat("ATTACK_SPEED"), MMOItems.plugin.getConfig().getDouble("default.attack-speed")), CooldownType.ATTACK)) return; @@ -50,6 +49,6 @@ public class Crossbow extends UntargetedWeapon { getPlayer().getEyeLocation().getDirection().multiply(3 * getValue(getNBTItem().getStat(ItemStats.ARROW_VELOCITY.getId()), 1))); getPlayer().setVelocity(getPlayer().getVelocity().setX(0).setZ(0)); - MMOItems.plugin.getEntities().registerCustomProjectile(getNBTItem(), stats.newTemporary(io.lumine.mythic.lib.api.player.EquipmentSlot.fromBukkit(slot)), arrow, true); + MMOItems.plugin.getEntities().registerCustomProjectile(getNBTItem(), stats, arrow, true); } } diff --git a/src/main/java/net/Indyuce/mmoitems/api/interaction/weapon/untargeted/Lute.java b/src/main/java/net/Indyuce/mmoitems/api/interaction/weapon/untargeted/Lute.java index 0586ff30..72a70f87 100644 --- a/src/main/java/net/Indyuce/mmoitems/api/interaction/weapon/untargeted/Lute.java +++ b/src/main/java/net/Indyuce/mmoitems/api/interaction/weapon/untargeted/Lute.java @@ -2,19 +2,19 @@ package net.Indyuce.mmoitems.api.interaction.weapon.untargeted; import com.google.gson.JsonObject; import io.lumine.mythic.lib.MythicLib; +import io.lumine.mythic.lib.api.item.NBTItem; +import io.lumine.mythic.lib.api.stat.StatMap; +import io.lumine.mythic.lib.damage.DamageMetadata; +import io.lumine.mythic.lib.damage.DamageType; +import io.lumine.mythic.lib.version.VersionSound; import net.Indyuce.mmoitems.ItemStats; import net.Indyuce.mmoitems.MMOItems; import net.Indyuce.mmoitems.MMOUtils; -import net.Indyuce.mmoitems.api.ItemAttackResult; +import net.Indyuce.mmoitems.api.ItemAttackMetadata; import net.Indyuce.mmoitems.api.interaction.util.UntargetedDurabilityItem; import net.Indyuce.mmoitems.api.player.PlayerData.CooldownType; -import net.Indyuce.mmoitems.api.player.PlayerStats.CachedStats; import net.Indyuce.mmoitems.api.util.SoundReader; -import net.Indyuce.mmoitems.listener.ItemUse; import net.Indyuce.mmoitems.stat.LuteAttackEffectStat.LuteAttackEffect; -import io.lumine.mythic.lib.api.DamageType; -import io.lumine.mythic.lib.api.item.NBTItem; -import io.lumine.mythic.lib.version.VersionSound; import net.Indyuce.mmoitems.stat.data.ProjectileParticlesData; import org.bukkit.Location; import org.bukkit.Particle; @@ -35,8 +35,8 @@ public class Lute extends UntargetedWeapon { @Override public void untargetedAttack(EquipmentSlot slot) { - CachedStats stats = getPlayerData().getStats().newTemporary(io.lumine.mythic.lib.api.player.EquipmentSlot.fromBukkit(slot)); - double attackSpeed = 1 / getValue(stats.getStat(ItemStats.ATTACK_SPEED), MMOItems.plugin.getConfig().getDouble("default.attack-speed")); + StatMap.CachedStatMap stats = getPlayerData().getStats().newTemporary(io.lumine.mythic.lib.api.player.EquipmentSlot.fromBukkit(slot)); + double attackSpeed = 1 / getValue(stats.getStat("ATTACK_SPEED"), MMOItems.plugin.getConfig().getDouble("default.attack-speed")); if (!applyWeaponCosts(attackSpeed, CooldownType.ATTACK)) return; @@ -47,14 +47,17 @@ public class Lute extends UntargetedWeapon { if (durItem.isValid()) durItem.decreaseDurability(1).update(); - double attackDamage = getValue(stats.getStat(ItemStats.ATTACK_DAMAGE), 1); + double attackDamage = getValue(stats.getStat("ATTACK_DAMAGE"), 7); double range = getValue(getNBTItem().getStat(ItemStats.RANGE.getId()), MMOItems.plugin.getConfig().getDouble("default.range")); Vector weight = new Vector(0, -.003 * getNBTItem().getStat(ItemStats.NOTE_WEIGHT.getId()), 0); + // Attack meta + ItemAttackMetadata attackMeta = new ItemAttackMetadata(new DamageMetadata(attackDamage, DamageType.WEAPON, DamageType.MAGIC, DamageType.PROJECTILE), stats); + LuteAttackEffect effect = LuteAttackEffect.get(getNBTItem()); SoundReader sound = new SoundReader(getNBTItem().getString("MMOITEMS_LUTE_ATTACK_SOUND"), VersionSound.BLOCK_NOTE_BLOCK_BELL.toSound()); if (effect != null) { - effect.getAttack().handle(stats, getNBTItem(), attackDamage, range, weight, sound); + effect.getAttack().handle(attackMeta, getNBTItem(), attackDamage, range, weight, sound); return; } @@ -99,8 +102,7 @@ public class Lute extends UntargetedWeapon { for (Entity target : entities) if (MMOUtils.canDamage(getPlayer(), loc, target)) { - new ItemAttackResult(attackDamage, DamageType.WEAPON, DamageType.PROJECTILE, DamageType.MAGIC) - .applyEffectsAndDamage(stats, getNBTItem(), (LivingEntity) target); + attackMeta.applyEffectsAndDamage(getNBTItem(), (LivingEntity) target); cancel(); return; } diff --git a/src/main/java/net/Indyuce/mmoitems/api/interaction/weapon/untargeted/Musket.java b/src/main/java/net/Indyuce/mmoitems/api/interaction/weapon/untargeted/Musket.java index d321d715..3d9a5dc2 100644 --- a/src/main/java/net/Indyuce/mmoitems/api/interaction/weapon/untargeted/Musket.java +++ b/src/main/java/net/Indyuce/mmoitems/api/interaction/weapon/untargeted/Musket.java @@ -1,17 +1,17 @@ package net.Indyuce.mmoitems.api.interaction.weapon.untargeted; import io.lumine.mythic.lib.MythicLib; -import io.lumine.mythic.lib.api.DamageType; import io.lumine.mythic.lib.api.MMORayTraceResult; import io.lumine.mythic.lib.api.item.NBTItem; +import io.lumine.mythic.lib.api.stat.StatMap; +import io.lumine.mythic.lib.damage.DamageMetadata; +import io.lumine.mythic.lib.damage.DamageType; import net.Indyuce.mmoitems.ItemStats; import net.Indyuce.mmoitems.MMOItems; import net.Indyuce.mmoitems.MMOUtils; -import net.Indyuce.mmoitems.api.ItemAttackResult; +import net.Indyuce.mmoitems.api.ItemAttackMetadata; import net.Indyuce.mmoitems.api.interaction.util.UntargetedDurabilityItem; import net.Indyuce.mmoitems.api.player.PlayerData.CooldownType; -import net.Indyuce.mmoitems.api.player.PlayerStats.CachedStats; -import net.Indyuce.mmoitems.listener.ItemUse; import org.bukkit.Color; import org.bukkit.Location; import org.bukkit.Sound; @@ -26,9 +26,9 @@ public class Musket extends UntargetedWeapon { @Override public void untargetedAttack(EquipmentSlot slot) { - CachedStats stats = getPlayerData().getStats().newTemporary(io.lumine.mythic.lib.api.player.EquipmentSlot.fromBukkit(slot)); + StatMap.CachedStatMap stats = getPlayerData().getStats().newTemporary(io.lumine.mythic.lib.api.player.EquipmentSlot.fromBukkit(slot)); - if (!applyWeaponCosts(1 / getValue(stats.getStat(ItemStats.ATTACK_SPEED), MMOItems.plugin.getConfig().getDouble("default.attack-speed")), + if (!applyWeaponCosts(1 / getValue(stats.getStat("ATTACK_SPEED"), MMOItems.plugin.getConfig().getDouble("default.attack-speed")), CooldownType.ATTACK)) return; @@ -39,7 +39,7 @@ public class Musket extends UntargetedWeapon { if (durItem.isValid()) durItem.decreaseDurability(1).update(); - double attackDamage = stats.getStat(ItemStats.ATTACK_DAMAGE); + double attackDamage = stats.getStat("ATTACK_DAMAGE"); double range = getValue(getNBTItem().getStat(ItemStats.RANGE.getId()), MMOItems.plugin.getConfig().getDouble("default.range")); double recoil = getValue(getNBTItem().getStat(ItemStats.RECOIL.getId()), MMOItems.plugin.getConfig().getDouble("default.recoil")); @@ -58,13 +58,12 @@ public class Musket extends UntargetedWeapon { MMORayTraceResult trace = MythicLib.plugin.getVersion().getWrapper().rayTrace(stats.getPlayer(), vec, range, entity -> MMOUtils.canDamage(stats.getPlayer(), entity)); - if (trace.hasHit()) - new ItemAttackResult(attackDamage, DamageType.WEAPON, DamageType.PROJECTILE, DamageType.PHYSICAL).applyEffectsAndDamage(stats, - getNBTItem(), trace.getHit()); + if (trace.hasHit()) { + ItemAttackMetadata attackMeta = new ItemAttackMetadata(new DamageMetadata(attackDamage, DamageType.WEAPON, DamageType.PROJECTILE, DamageType.PHYSICAL), stats); + attackMeta.applyEffectsAndDamage(getNBTItem(), trace.getHit()); + } trace.draw(loc, vec, 2, Color.BLACK); getPlayer().getWorld().playSound(getPlayer().getLocation(), Sound.ENTITY_ZOMBIE_ATTACK_IRON_DOOR, 2, 2); - - } } diff --git a/src/main/java/net/Indyuce/mmoitems/api/interaction/weapon/untargeted/Staff.java b/src/main/java/net/Indyuce/mmoitems/api/interaction/weapon/untargeted/Staff.java index 01d3115f..85163fbc 100644 --- a/src/main/java/net/Indyuce/mmoitems/api/interaction/weapon/untargeted/Staff.java +++ b/src/main/java/net/Indyuce/mmoitems/api/interaction/weapon/untargeted/Staff.java @@ -1,17 +1,18 @@ package net.Indyuce.mmoitems.api.interaction.weapon.untargeted; import io.lumine.mythic.lib.MythicLib; -import io.lumine.mythic.lib.api.DamageType; import io.lumine.mythic.lib.api.MMORayTraceResult; import io.lumine.mythic.lib.api.item.NBTItem; +import io.lumine.mythic.lib.api.stat.StatMap; +import io.lumine.mythic.lib.damage.DamageMetadata; +import io.lumine.mythic.lib.damage.DamageType; import io.lumine.mythic.lib.version.VersionSound; import net.Indyuce.mmoitems.ItemStats; import net.Indyuce.mmoitems.MMOItems; import net.Indyuce.mmoitems.MMOUtils; -import net.Indyuce.mmoitems.api.ItemAttackResult; +import net.Indyuce.mmoitems.api.ItemAttackMetadata; import net.Indyuce.mmoitems.api.interaction.util.UntargetedDurabilityItem; import net.Indyuce.mmoitems.api.player.PlayerData.CooldownType; -import net.Indyuce.mmoitems.api.player.PlayerStats.CachedStats; import net.Indyuce.mmoitems.stat.StaffSpiritStat.StaffSpirit; import org.bukkit.EntityEffect; import org.bukkit.Location; @@ -30,8 +31,8 @@ public class Staff extends UntargetedWeapon { @Override public void untargetedAttack(EquipmentSlot slot) { - CachedStats stats = getPlayerData().getStats().newTemporary(io.lumine.mythic.lib.api.player.EquipmentSlot.fromBukkit(slot)); - if (!applyWeaponCosts(1 / getValue(stats.getStat(ItemStats.ATTACK_SPEED), MMOItems.plugin.getConfig().getDouble("default.attack-speed")), + StatMap.CachedStatMap stats = getPlayerData().getStats().newTemporary(io.lumine.mythic.lib.api.player.EquipmentSlot.fromBukkit(slot)); + if (!applyWeaponCosts(1 / getValue(stats.getStat("ATTACK_SPEED"), MMOItems.plugin.getConfig().getDouble("default.attack-speed")), CooldownType.ATTACK)) return; @@ -42,12 +43,15 @@ public class Staff extends UntargetedWeapon { if (durItem.isValid()) durItem.decreaseDurability(1).update(); - double attackDamage = getValue(stats.getStat(ItemStats.ATTACK_DAMAGE), 1); + double attackDamage = getValue(stats.getStat("ATTACK_DAMAGE"), 1); double range = getValue(getNBTItem().getStat(ItemStats.RANGE.getId()), MMOItems.plugin.getConfig().getDouble("default.range")); + // Attack meta + ItemAttackMetadata attackMeta = new ItemAttackMetadata(new DamageMetadata(attackDamage, DamageType.WEAPON, DamageType.PROJECTILE, DamageType.MAGIC), stats); + StaffSpirit spirit = StaffSpirit.get(getNBTItem()); if (spirit != null) { - spirit.getAttack().handle(stats, getNBTItem(), attackDamage, range); + spirit.getAttack().handle(attackMeta, getNBTItem(), attackDamage, range); return; } @@ -57,8 +61,7 @@ public class Staff extends UntargetedWeapon { MMORayTraceResult trace = MythicLib.plugin.getVersion().getWrapper().rayTrace(stats.getPlayer(), range, entity -> MMOUtils.canDamage(stats.getPlayer(), entity)); if (trace.hasHit()) - new ItemAttackResult(attackDamage, DamageType.WEAPON, DamageType.PROJECTILE, DamageType.MAGIC).applyEffectsAndDamage(stats, getNBTItem(), - trace.getHit()); + attackMeta.applyEffectsAndDamage(getNBTItem(), trace.getHit()); trace.draw(loc, getPlayer().getEyeLocation().getDirection(), 2, (tick) -> tick.getWorld().spawnParticle(Particle.EXPLOSION_NORMAL, tick, 0, .1, .1, .1, 0)); getPlayer().getWorld().playSound(getPlayer().getLocation(), VersionSound.ENTITY_FIREWORK_ROCKET_TWINKLE.toSound(), 2, 2); diff --git a/src/main/java/net/Indyuce/mmoitems/api/interaction/weapon/untargeted/Whip.java b/src/main/java/net/Indyuce/mmoitems/api/interaction/weapon/untargeted/Whip.java index 0b3daace..a07d8f44 100644 --- a/src/main/java/net/Indyuce/mmoitems/api/interaction/weapon/untargeted/Whip.java +++ b/src/main/java/net/Indyuce/mmoitems/api/interaction/weapon/untargeted/Whip.java @@ -1,17 +1,18 @@ package net.Indyuce.mmoitems.api.interaction.weapon.untargeted; +import io.lumine.mythic.lib.MythicLib; +import io.lumine.mythic.lib.api.MMORayTraceResult; +import io.lumine.mythic.lib.api.item.NBTItem; +import io.lumine.mythic.lib.api.stat.StatMap; +import io.lumine.mythic.lib.damage.DamageMetadata; +import io.lumine.mythic.lib.damage.DamageType; +import io.lumine.mythic.lib.version.VersionSound; import net.Indyuce.mmoitems.ItemStats; import net.Indyuce.mmoitems.MMOItems; import net.Indyuce.mmoitems.MMOUtils; -import net.Indyuce.mmoitems.api.ItemAttackResult; +import net.Indyuce.mmoitems.api.ItemAttackMetadata; import net.Indyuce.mmoitems.api.interaction.util.UntargetedDurabilityItem; import net.Indyuce.mmoitems.api.player.PlayerData.CooldownType; -import net.Indyuce.mmoitems.api.player.PlayerStats.CachedStats; -import io.lumine.mythic.lib.MythicLib; -import io.lumine.mythic.lib.api.DamageType; -import io.lumine.mythic.lib.api.MMORayTraceResult; -import io.lumine.mythic.lib.api.item.NBTItem; -import io.lumine.mythic.lib.version.VersionSound; import org.bukkit.Location; import org.bukkit.Particle; import org.bukkit.entity.Player; @@ -26,8 +27,8 @@ public class Whip extends UntargetedWeapon { @Override public void untargetedAttack(EquipmentSlot slot) { - CachedStats stats = getPlayerData().getStats().newTemporary(io.lumine.mythic.lib.api.player.EquipmentSlot.fromBukkit(slot)); - if (!applyWeaponCosts(1 / getValue(stats.getStat(ItemStats.ATTACK_SPEED), MMOItems.plugin.getConfig().getDouble("default.attack-speed")), + StatMap.CachedStatMap stats = getPlayerData().getStats().newTemporary(io.lumine.mythic.lib.api.player.EquipmentSlot.fromBukkit(slot)); + if (!applyWeaponCosts(1 / getValue(stats.getStat("ATTACK_SPEED"), MMOItems.plugin.getConfig().getDouble("default.attack-speed")), CooldownType.ATTACK)) return; @@ -38,7 +39,7 @@ public class Whip extends UntargetedWeapon { if (durItem.isValid()) durItem.decreaseDurability(1).update(); - double attackDamage = getValue(stats.getStat(ItemStats.ATTACK_DAMAGE), 1); + double attackDamage = getValue(stats.getStat("ATTACK_DAMAGE"), 7); double range = getValue(getNBTItem().getStat(ItemStats.RANGE.getId()), MMOItems.plugin.getConfig().getDouble("default.range")); double a = Math.toRadians(getPlayer().getEyeLocation().getYaw() + 160); @@ -47,8 +48,7 @@ public class Whip extends UntargetedWeapon { MMORayTraceResult trace = MythicLib.plugin.getVersion().getWrapper().rayTrace(stats.getPlayer(), range, entity -> MMOUtils.canDamage(stats.getPlayer(), entity)); if (trace.hasHit()) - new ItemAttackResult(attackDamage, DamageType.WEAPON, DamageType.PROJECTILE, DamageType.PHYSICAL).applyEffectsAndDamage(stats, - getNBTItem(), trace.getHit()); + new ItemAttackMetadata(new DamageMetadata(attackDamage, DamageType.WEAPON, DamageType.PROJECTILE, DamageType.PHYSICAL), stats).applyEffects(getNBTItem(), trace.getHit()); trace.draw(loc, getPlayer().getEyeLocation().getDirection(), 2, (tick) -> tick.getWorld().spawnParticle(Particle.CRIT, tick, 0, .1, .1, .1, 0)); getPlayer().getWorld().playSound(getPlayer().getLocation(), VersionSound.ENTITY_FIREWORK_ROCKET_BLAST.toSound(), 1, 2); diff --git a/src/main/java/net/Indyuce/mmoitems/api/interaction/weapon/untargeted/lute/BruteLuteAttack.java b/src/main/java/net/Indyuce/mmoitems/api/interaction/weapon/untargeted/lute/BruteLuteAttack.java index d7b9d001..94f4f1a1 100644 --- a/src/main/java/net/Indyuce/mmoitems/api/interaction/weapon/untargeted/lute/BruteLuteAttack.java +++ b/src/main/java/net/Indyuce/mmoitems/api/interaction/weapon/untargeted/lute/BruteLuteAttack.java @@ -2,13 +2,13 @@ package net.Indyuce.mmoitems.api.interaction.weapon.untargeted.lute; import com.google.gson.JsonObject; import io.lumine.mythic.lib.MythicLib; +import io.lumine.mythic.lib.api.item.NBTItem; +import io.lumine.mythic.lib.damage.DamageMetadata; +import io.lumine.mythic.lib.damage.DamageType; import net.Indyuce.mmoitems.MMOItems; import net.Indyuce.mmoitems.MMOUtils; -import net.Indyuce.mmoitems.api.ItemAttackResult; -import net.Indyuce.mmoitems.api.player.PlayerStats.CachedStats; +import net.Indyuce.mmoitems.api.ItemAttackMetadata; import net.Indyuce.mmoitems.api.util.SoundReader; -import io.lumine.mythic.lib.api.DamageType; -import io.lumine.mythic.lib.api.item.NBTItem; import net.Indyuce.mmoitems.stat.data.ProjectileParticlesData; import org.bukkit.Location; import org.bukkit.Particle; @@ -22,14 +22,15 @@ import java.util.List; public class BruteLuteAttack implements LuteAttackHandler { @Override - public void handle(CachedStats stats, NBTItem nbt, double attackDamage, double range, Vector weight, SoundReader sound) { + public void handle(ItemAttackMetadata attack, NBTItem nbt, double attackDamage, double range, Vector weight, SoundReader sound) { new BukkitRunnable() { - final Vector vec = stats.getPlayer().getEyeLocation().getDirection().multiply(.4); - final Location loc = stats.getPlayer().getEyeLocation(); + final Vector vec = attack.getDamager().getEyeLocation().getDirection().multiply(.4); + final Location loc = attack.getDamager().getEyeLocation(); int ti = 0; public void run() { - if (ti++ > range) cancel(); + if (ti++ > range) + cancel(); List entities = MMOUtils.getNearbyChunkEntities(loc); for (int j = 0; j < 3; j++) { @@ -47,21 +48,20 @@ public class BruteLuteAttack implements LuteAttackHandler { double red = Double.parseDouble(String.valueOf(obj.get("Red"))); double green = Double.parseDouble(String.valueOf(obj.get("Green"))); double blue = Double.parseDouble(String.valueOf(obj.get("Blue"))); - ProjectileParticlesData.shootParticle(stats.getPlayer(), particle, loc, red, green, blue); + ProjectileParticlesData.shootParticle(attack.getDamager(), particle, loc, red, green, blue); // If it's not colored, just shoot the particle } else { - ProjectileParticlesData.shootParticle(stats.getPlayer(), particle, loc, 0, 0, 0); + ProjectileParticlesData.shootParticle(attack.getDamager(), particle, loc, 0, 0, 0); } // If no particle has been provided via projectile particle attribute, default to this particle - } else { + } else loc.getWorld().spawnParticle(Particle.NOTE, loc, 2, .1, .1, .1, 0); - } if (j == 0) sound.play(loc, 2, (float) (.5 + (double) ti / range)); for (Entity target : entities) - if (MMOUtils.canDamage(stats.getPlayer(), loc, target)) { - new ItemAttackResult(attackDamage, DamageType.WEAPON, DamageType.PROJECTILE).applyEffectsAndDamage(stats, nbt, (LivingEntity) target); + if (MMOUtils.canDamage(attack.getDamager(), loc, target)) { + new ItemAttackMetadata(new DamageMetadata(attackDamage, DamageType.WEAPON, DamageType.PHYSICAL, DamageType.PROJECTILE), attack.getStats()).applyEffectsAndDamage(nbt, (LivingEntity) target); cancel(); return; } diff --git a/src/main/java/net/Indyuce/mmoitems/api/interaction/weapon/untargeted/lute/CircularLuteAttack.java b/src/main/java/net/Indyuce/mmoitems/api/interaction/weapon/untargeted/lute/CircularLuteAttack.java index cfe0df7e..fbec713c 100644 --- a/src/main/java/net/Indyuce/mmoitems/api/interaction/weapon/untargeted/lute/CircularLuteAttack.java +++ b/src/main/java/net/Indyuce/mmoitems/api/interaction/weapon/untargeted/lute/CircularLuteAttack.java @@ -2,12 +2,12 @@ package net.Indyuce.mmoitems.api.interaction.weapon.untargeted.lute; import com.google.gson.JsonObject; import io.lumine.mythic.lib.MythicLib; -import io.lumine.mythic.lib.api.DamageType; import io.lumine.mythic.lib.api.item.NBTItem; +import io.lumine.mythic.lib.damage.DamageMetadata; +import io.lumine.mythic.lib.damage.DamageType; import net.Indyuce.mmoitems.MMOItems; import net.Indyuce.mmoitems.MMOUtils; -import net.Indyuce.mmoitems.api.ItemAttackResult; -import net.Indyuce.mmoitems.api.player.PlayerStats.CachedStats; +import net.Indyuce.mmoitems.api.ItemAttackMetadata; import net.Indyuce.mmoitems.api.util.SoundReader; import net.Indyuce.mmoitems.stat.data.ProjectileParticlesData; import org.bukkit.Location; @@ -22,10 +22,10 @@ import java.util.List; public class CircularLuteAttack implements LuteAttackHandler { @Override - public void handle(CachedStats stats, NBTItem nbt, double attackDamage, double range, Vector weight, SoundReader sound) { + public void handle(ItemAttackMetadata attack, NBTItem nbt, double attackDamage, double range, Vector weight, SoundReader sound) { new BukkitRunnable() { - final Vector vec = stats.getPlayer().getEyeLocation().getDirection().multiply(.4); - final Location loc = stats.getPlayer().getEyeLocation(); + final Vector vec = attack.getDamager().getEyeLocation().getDirection().multiply(.4); + final Location loc = attack.getDamager().getEyeLocation(); int ti = 0; public void run() { @@ -51,12 +51,12 @@ public class CircularLuteAttack implements LuteAttackHandler { double red = Double.parseDouble(String.valueOf(obj.get("Red"))); double green = Double.parseDouble(String.valueOf(obj.get("Green"))); double blue = Double.parseDouble(String.valueOf(obj.get("Blue"))); - ProjectileParticlesData.shootParticle(stats.getPlayer(), particle, loc.clone().add(vec), red, green, blue); - ProjectileParticlesData.shootParticle(stats.getPlayer(), particle, loc.clone().add(vec.multiply(-1)), red, green, blue); + ProjectileParticlesData.shootParticle(attack.getDamager(), particle, loc.clone().add(vec), red, green, blue); + ProjectileParticlesData.shootParticle(attack.getDamager(), particle, loc.clone().add(vec.multiply(-1)), red, green, blue); // If it's not colored, just shoot the particle } else { - ProjectileParticlesData.shootParticle(stats.getPlayer(), particle, loc.clone().add(vec), 0, 0, 0); - ProjectileParticlesData.shootParticle(stats.getPlayer(), particle, loc.clone().add(vec.multiply(-1)), 0, 0, 0); + ProjectileParticlesData.shootParticle(attack.getDamager(), particle, loc.clone().add(vec), 0, 0, 0); + ProjectileParticlesData.shootParticle(attack.getDamager(), particle, loc.clone().add(vec.multiply(-1)), 0, 0, 0); } // If no particle has been provided via projectile particle attribute, default to this particle } else { @@ -67,8 +67,8 @@ public class CircularLuteAttack implements LuteAttackHandler { if (j == 0) sound.play(loc, 2, (float) (.5 + (double) ti / range)); for (Entity target : entities) - if (MMOUtils.canDamage(stats.getPlayer(), loc, target)) { - new ItemAttackResult(attackDamage, DamageType.WEAPON, DamageType.PROJECTILE).applyEffectsAndDamage(stats, nbt, (LivingEntity) target); + if (MMOUtils.canDamage(attack.getDamager(), loc, target)) { + new ItemAttackMetadata(new DamageMetadata(attackDamage, DamageType.WEAPON, DamageType.PROJECTILE), attack.getStats()).applyEffectsAndDamage(nbt, (LivingEntity) target); cancel(); return; } diff --git a/src/main/java/net/Indyuce/mmoitems/api/interaction/weapon/untargeted/lute/LuteAttackHandler.java b/src/main/java/net/Indyuce/mmoitems/api/interaction/weapon/untargeted/lute/LuteAttackHandler.java index 1d2c49d6..6a960c64 100644 --- a/src/main/java/net/Indyuce/mmoitems/api/interaction/weapon/untargeted/lute/LuteAttackHandler.java +++ b/src/main/java/net/Indyuce/mmoitems/api/interaction/weapon/untargeted/lute/LuteAttackHandler.java @@ -1,15 +1,14 @@ package net.Indyuce.mmoitems.api.interaction.weapon.untargeted.lute; +import io.lumine.mythic.lib.api.item.NBTItem; +import net.Indyuce.mmoitems.api.ItemAttackMetadata; +import net.Indyuce.mmoitems.api.util.SoundReader; +import org.bukkit.util.Vector; + import java.util.Random; -import org.bukkit.util.Vector; - -import net.Indyuce.mmoitems.api.player.PlayerStats.CachedStats; -import net.Indyuce.mmoitems.api.util.SoundReader; -import io.lumine.mythic.lib.api.item.NBTItem; - public interface LuteAttackHandler { - void handle(CachedStats stats, NBTItem nbt, double attackDamage, double range, Vector weight, SoundReader sound); + void handle(ItemAttackMetadata attackMeta, NBTItem nbt, double attackDamage, double range, Vector weight, SoundReader sound); Random random = new Random(); } diff --git a/src/main/java/net/Indyuce/mmoitems/api/interaction/weapon/untargeted/lute/SimpleLuteAttack.java b/src/main/java/net/Indyuce/mmoitems/api/interaction/weapon/untargeted/lute/SimpleLuteAttack.java index 2efee7fd..bee54842 100644 --- a/src/main/java/net/Indyuce/mmoitems/api/interaction/weapon/untargeted/lute/SimpleLuteAttack.java +++ b/src/main/java/net/Indyuce/mmoitems/api/interaction/weapon/untargeted/lute/SimpleLuteAttack.java @@ -2,13 +2,13 @@ package net.Indyuce.mmoitems.api.interaction.weapon.untargeted.lute; import com.google.gson.JsonObject; import io.lumine.mythic.lib.MythicLib; +import io.lumine.mythic.lib.api.item.NBTItem; +import io.lumine.mythic.lib.damage.DamageMetadata; +import io.lumine.mythic.lib.damage.DamageType; import net.Indyuce.mmoitems.MMOItems; import net.Indyuce.mmoitems.MMOUtils; -import net.Indyuce.mmoitems.api.ItemAttackResult; -import net.Indyuce.mmoitems.api.player.PlayerStats.CachedStats; +import net.Indyuce.mmoitems.api.ItemAttackMetadata; import net.Indyuce.mmoitems.api.util.SoundReader; -import io.lumine.mythic.lib.api.DamageType; -import io.lumine.mythic.lib.api.item.NBTItem; import net.Indyuce.mmoitems.stat.data.ProjectileParticlesData; import org.bukkit.Location; import org.bukkit.Particle; @@ -22,10 +22,10 @@ import java.util.List; public class SimpleLuteAttack implements LuteAttackHandler { @Override - public void handle(CachedStats stats, NBTItem nbt, double attackDamage, double range, Vector weight, SoundReader sound) { + public void handle(ItemAttackMetadata attack, NBTItem nbt, double attackDamage, double range, Vector weight, SoundReader sound) { new BukkitRunnable() { - final Vector vec = stats.getPlayer().getEyeLocation().getDirection().multiply(.4); - final Location loc = stats.getPlayer().getEyeLocation(); + final Vector vec = attack.getDamager().getEyeLocation().getDirection().multiply(.4); + final Location loc = attack.getDamager().getEyeLocation(); int ti = 0; public void run() { @@ -47,10 +47,10 @@ public class SimpleLuteAttack implements LuteAttackHandler { double red = Double.parseDouble(String.valueOf(obj.get("Red"))); double green = Double.parseDouble(String.valueOf(obj.get("Green"))); double blue = Double.parseDouble(String.valueOf(obj.get("Blue"))); - ProjectileParticlesData.shootParticle(stats.getPlayer(), particle, loc, red, green, blue); + ProjectileParticlesData.shootParticle(attack.getDamager(), particle, loc, red, green, blue); // If it's not colored, just shoot the particle } else { - ProjectileParticlesData.shootParticle(stats.getPlayer(), particle, loc, 0, 0, 0); + ProjectileParticlesData.shootParticle(attack.getDamager(), particle, loc, 0, 0, 0); } // If no particle has been provided via projectile particle attribute, default to this particle } else { @@ -60,8 +60,8 @@ public class SimpleLuteAttack implements LuteAttackHandler { if (j == 0) sound.play(loc, 2, (float) (.5 + (double) ti / range)); for (Entity target : entities) - if (MMOUtils.canDamage(stats.getPlayer(), loc, target)) { - new ItemAttackResult(attackDamage, DamageType.WEAPON, DamageType.PROJECTILE).applyEffectsAndDamage(stats, nbt, (LivingEntity) target); + if (MMOUtils.canDamage(attack.getDamager(), loc, target)) { + new ItemAttackMetadata(new DamageMetadata(attackDamage, DamageType.WEAPON, DamageType.PROJECTILE), attack.getStats()).applyEffectsAndDamage(nbt, (LivingEntity) target); cancel(); return; } diff --git a/src/main/java/net/Indyuce/mmoitems/api/interaction/weapon/untargeted/lute/SlashLuteAttack.java b/src/main/java/net/Indyuce/mmoitems/api/interaction/weapon/untargeted/lute/SlashLuteAttack.java index 3a8da868..51b9e3ff 100644 --- a/src/main/java/net/Indyuce/mmoitems/api/interaction/weapon/untargeted/lute/SlashLuteAttack.java +++ b/src/main/java/net/Indyuce/mmoitems/api/interaction/weapon/untargeted/lute/SlashLuteAttack.java @@ -2,13 +2,13 @@ package net.Indyuce.mmoitems.api.interaction.weapon.untargeted.lute; import com.google.gson.JsonObject; import io.lumine.mythic.lib.MythicLib; +import io.lumine.mythic.lib.api.item.NBTItem; +import io.lumine.mythic.lib.damage.DamageMetadata; +import io.lumine.mythic.lib.damage.DamageType; import net.Indyuce.mmoitems.MMOItems; import net.Indyuce.mmoitems.MMOUtils; -import net.Indyuce.mmoitems.api.ItemAttackResult; -import net.Indyuce.mmoitems.api.player.PlayerStats.CachedStats; +import net.Indyuce.mmoitems.api.ItemAttackMetadata; import net.Indyuce.mmoitems.api.util.SoundReader; -import io.lumine.mythic.lib.api.DamageType; -import io.lumine.mythic.lib.api.item.NBTItem; import net.Indyuce.mmoitems.stat.data.ProjectileParticlesData; import org.bukkit.Location; import org.bukkit.Particle; @@ -20,10 +20,10 @@ import org.bukkit.util.Vector; public class SlashLuteAttack implements LuteAttackHandler { @Override - public void handle(CachedStats stats, NBTItem nbt, double attackDamage, double range, Vector weight, SoundReader sound) { + public void handle(ItemAttackMetadata attack, NBTItem nbt, double attackDamage, double range, Vector weight, SoundReader sound) { new BukkitRunnable() { - final Vector vec = stats.getPlayer().getEyeLocation().getDirection(); - final Location loc = stats.getPlayer().getLocation().add(0, 1.3, 0); + final Vector vec = attack.getDamager().getEyeLocation().getDirection(); + final Location loc = attack.getDamager().getLocation().add(0, 1.3, 0); double ti = 1; public void run() { @@ -34,7 +34,7 @@ public class SlashLuteAttack implements LuteAttackHandler { if (random.nextBoolean()) { loc.setDirection(vec); loc.setYaw(loc.getYaw() + k); - loc.setPitch(stats.getPlayer().getEyeLocation().getPitch()); + loc.setPitch(attack.getDamager().getEyeLocation().getPitch()); if (nbt.hasTag("MMOITEMS_PROJECTILE_PARTICLES")) { JsonObject obj = MythicLib.plugin.getJson().parse(nbt.getString("MMOITEMS_PROJECTILE_PARTICLES"), JsonObject.class); @@ -44,10 +44,10 @@ public class SlashLuteAttack implements LuteAttackHandler { double red = Double.parseDouble(String.valueOf(obj.get("Red"))); double green = Double.parseDouble(String.valueOf(obj.get("Green"))); double blue = Double.parseDouble(String.valueOf(obj.get("Blue"))); - ProjectileParticlesData.shootParticle(stats.getPlayer(), particle, loc.clone().add(loc.getDirection().multiply(1.5 * ti)), red, green, blue); + ProjectileParticlesData.shootParticle(attack.getDamager(), particle, loc.clone().add(loc.getDirection().multiply(1.5 * ti)), red, green, blue); // If it's not colored, just shoot the particle } else { - ProjectileParticlesData.shootParticle(stats.getPlayer(), particle, loc.clone().add(loc.getDirection().multiply(1.5 * ti)), 0, 0, 0); + ProjectileParticlesData.shootParticle(attack.getDamager(), particle, loc.clone().add(loc.getDirection().multiply(1.5 * ti)), 0, 0, 0); } // If no particle has been provided via projectile particle attribute, default to this particle } else { @@ -57,8 +57,8 @@ public class SlashLuteAttack implements LuteAttackHandler { } }.runTaskTimer(MMOItems.plugin, 0, 1); - for (Entity entity : MMOUtils.getNearbyChunkEntities(stats.getPlayer().getLocation())) - if (entity.getLocation().distanceSquared(stats.getPlayer().getLocation()) < 40 && stats.getPlayer().getEyeLocation().getDirection().angle(entity.getLocation().toVector().subtract(stats.getPlayer().getLocation().toVector())) < Math.PI / 6 && MMOUtils.canDamage(stats.getPlayer(), entity)) - new ItemAttackResult(attackDamage, DamageType.WEAPON, DamageType.PROJECTILE).applyEffectsAndDamage(stats, nbt, (LivingEntity) entity); + for (Entity entity : MMOUtils.getNearbyChunkEntities(attack.getDamager().getLocation())) + if (entity.getLocation().distanceSquared(attack.getDamager().getLocation()) < 40 && attack.getDamager().getEyeLocation().getDirection().angle(entity.getLocation().toVector().subtract(attack.getDamager().getLocation().toVector())) < Math.PI / 6 && MMOUtils.canDamage(attack.getDamager(), entity)) + new ItemAttackMetadata(new DamageMetadata(attackDamage, DamageType.WEAPON, DamageType.PROJECTILE), attack.getStats()).applyEffectsAndDamage(nbt, (LivingEntity) entity); } } diff --git a/src/main/java/net/Indyuce/mmoitems/api/interaction/weapon/untargeted/lute/WaveLuteAttack.java b/src/main/java/net/Indyuce/mmoitems/api/interaction/weapon/untargeted/lute/WaveLuteAttack.java index a1b2b1d5..d58d199a 100644 --- a/src/main/java/net/Indyuce/mmoitems/api/interaction/weapon/untargeted/lute/WaveLuteAttack.java +++ b/src/main/java/net/Indyuce/mmoitems/api/interaction/weapon/untargeted/lute/WaveLuteAttack.java @@ -2,13 +2,13 @@ package net.Indyuce.mmoitems.api.interaction.weapon.untargeted.lute; import com.google.gson.JsonObject; import io.lumine.mythic.lib.MythicLib; +import io.lumine.mythic.lib.api.item.NBTItem; +import io.lumine.mythic.lib.damage.DamageMetadata; +import io.lumine.mythic.lib.damage.DamageType; import net.Indyuce.mmoitems.MMOItems; import net.Indyuce.mmoitems.MMOUtils; -import net.Indyuce.mmoitems.api.ItemAttackResult; -import net.Indyuce.mmoitems.api.player.PlayerStats.CachedStats; +import net.Indyuce.mmoitems.api.ItemAttackMetadata; import net.Indyuce.mmoitems.api.util.SoundReader; -import io.lumine.mythic.lib.api.DamageType; -import io.lumine.mythic.lib.api.item.NBTItem; import net.Indyuce.mmoitems.stat.data.ProjectileParticlesData; import org.bukkit.Location; import org.bukkit.Particle; @@ -22,10 +22,10 @@ import java.util.List; public class WaveLuteAttack implements LuteAttackHandler { @Override - public void handle(CachedStats stats, NBTItem nbt, double attackDamage, double range, Vector weight, SoundReader sound) { + public void handle(ItemAttackMetadata attack, NBTItem nbt, double attackDamage, double range, Vector weight, SoundReader sound) { new BukkitRunnable() { - final Vector vec = stats.getPlayer().getEyeLocation().getDirection().multiply(.4); - final Location loc = stats.getPlayer().getEyeLocation(); + final Vector vec = attack.getDamager().getEyeLocation().getDirection().multiply(.4); + final Location loc = attack.getDamager().getEyeLocation(); int ti = 0; public void run() { @@ -49,12 +49,12 @@ public class WaveLuteAttack implements LuteAttackHandler { double red = Double.parseDouble(String.valueOf(obj.get("Red"))); double green = Double.parseDouble(String.valueOf(obj.get("Green"))); double blue = Double.parseDouble(String.valueOf(obj.get("Blue"))); - ProjectileParticlesData.shootParticle(stats.getPlayer(), particle, loc.clone().add(vec.multiply(Math.sin((double) ti / 2))), red, green, blue); - ProjectileParticlesData.shootParticle(stats.getPlayer(), particle, loc.clone().add(vec.multiply(-1)), red, green, blue); + ProjectileParticlesData.shootParticle(attack.getDamager(), particle, loc.clone().add(vec.multiply(Math.sin((double) ti / 2))), red, green, blue); + ProjectileParticlesData.shootParticle(attack.getDamager(), particle, loc.clone().add(vec.multiply(-1)), red, green, blue); // If it's not colored, just shoot the particle } else { - ProjectileParticlesData.shootParticle(stats.getPlayer(), particle, loc.clone().add(vec.multiply(Math.sin((double) ti / 2))), 0, 0, 0); - ProjectileParticlesData.shootParticle(stats.getPlayer(), particle, loc.clone().add(vec.multiply(-1)), 0, 0, 0); + ProjectileParticlesData.shootParticle(attack.getDamager(), particle, loc.clone().add(vec.multiply(Math.sin((double) ti / 2))), 0, 0, 0); + ProjectileParticlesData.shootParticle(attack.getDamager(), particle, loc.clone().add(vec.multiply(-1)), 0, 0, 0); } // If no particle has been provided via projectile particle attribute, default to this particle } else { @@ -65,8 +65,8 @@ public class WaveLuteAttack implements LuteAttackHandler { if (j == 0) sound.play(loc, 2, (float) (.5 + (double) ti / range)); for (Entity target : entities) - if (MMOUtils.canDamage(stats.getPlayer(), loc, target)) { - new ItemAttackResult(attackDamage, DamageType.WEAPON, DamageType.PROJECTILE).applyEffectsAndDamage(stats, nbt, (LivingEntity) target); + if (MMOUtils.canDamage(attack.getDamager(), loc, target)) { + new ItemAttackMetadata(new DamageMetadata(attackDamage, DamageType.WEAPON, DamageType.PROJECTILE), attack.getStats()).applyEffectsAndDamage(nbt, (LivingEntity) target); cancel(); return; } diff --git a/src/main/java/net/Indyuce/mmoitems/api/interaction/weapon/untargeted/staff/LightningSpirit.java b/src/main/java/net/Indyuce/mmoitems/api/interaction/weapon/untargeted/staff/LightningSpirit.java index d89a79c6..9180d180 100644 --- a/src/main/java/net/Indyuce/mmoitems/api/interaction/weapon/untargeted/staff/LightningSpirit.java +++ b/src/main/java/net/Indyuce/mmoitems/api/interaction/weapon/untargeted/staff/LightningSpirit.java @@ -1,28 +1,26 @@ package net.Indyuce.mmoitems.api.interaction.weapon.untargeted.staff; import io.lumine.mythic.lib.MythicLib; -import io.lumine.mythic.lib.api.DamageType; import io.lumine.mythic.lib.api.MMORayTraceResult; import io.lumine.mythic.lib.api.item.NBTItem; import io.lumine.mythic.lib.version.VersionSound; import net.Indyuce.mmoitems.MMOUtils; -import net.Indyuce.mmoitems.api.ItemAttackResult; -import net.Indyuce.mmoitems.api.player.PlayerStats.CachedStats; +import net.Indyuce.mmoitems.api.ItemAttackMetadata; import org.bukkit.Location; import org.bukkit.Particle; public class LightningSpirit implements StaffAttackHandler { @Override - public void handle(CachedStats stats, NBTItem nbt, double attackDamage, double range) { - stats.getPlayer().getWorld().playSound(stats.getPlayer().getLocation(), VersionSound.ENTITY_FIREWORK_ROCKET_BLAST.toSound(), 2, 2); + public void handle(ItemAttackMetadata attackMeta, NBTItem nbt, double attackDamage, double range) { + attackMeta.getDamager().getWorld().playSound(attackMeta.getDamager().getLocation(), VersionSound.ENTITY_FIREWORK_ROCKET_BLAST.toSound(), 2, 2); - Location loc = stats.getPlayer().getEyeLocation(); - MMORayTraceResult trace = MythicLib.plugin.getVersion().getWrapper().rayTrace(stats.getPlayer(), range, - entity -> MMOUtils.canDamage(stats.getPlayer(), entity)); + Location loc = attackMeta.getDamager().getEyeLocation(); + MMORayTraceResult trace = MythicLib.plugin.getVersion().getWrapper().rayTrace(attackMeta.getDamager(), range, + entity -> MMOUtils.canDamage(attackMeta.getDamager(), entity)); if (trace.hasHit()) - new ItemAttackResult(attackDamage, DamageType.WEAPON, DamageType.MAGIC).applyEffectsAndDamage(stats, nbt, trace.getHit()); - trace.draw(loc, stats.getPlayer().getEyeLocation().getDirection(), 2, + attackMeta.applyEffects(nbt, trace.getHit()); + trace.draw(loc, attackMeta.getDamager().getEyeLocation().getDirection(), 2, loc1 -> loc1.getWorld().spawnParticle(Particle.FIREWORKS_SPARK, loc1, 0)); } } diff --git a/src/main/java/net/Indyuce/mmoitems/api/interaction/weapon/untargeted/staff/ManaSpirit.java b/src/main/java/net/Indyuce/mmoitems/api/interaction/weapon/untargeted/staff/ManaSpirit.java index 439da478..d434e8c8 100644 --- a/src/main/java/net/Indyuce/mmoitems/api/interaction/weapon/untargeted/staff/ManaSpirit.java +++ b/src/main/java/net/Indyuce/mmoitems/api/interaction/weapon/untargeted/staff/ManaSpirit.java @@ -1,7 +1,9 @@ package net.Indyuce.mmoitems.api.interaction.weapon.untargeted.staff; -import java.util.List; - +import io.lumine.mythic.lib.api.item.NBTItem; +import net.Indyuce.mmoitems.MMOItems; +import net.Indyuce.mmoitems.MMOUtils; +import net.Indyuce.mmoitems.api.ItemAttackMetadata; import org.bukkit.Color; import org.bukkit.Location; import org.bukkit.Particle; @@ -11,20 +13,15 @@ import org.bukkit.entity.LivingEntity; import org.bukkit.scheduler.BukkitRunnable; import org.bukkit.util.Vector; -import net.Indyuce.mmoitems.MMOItems; -import net.Indyuce.mmoitems.MMOUtils; -import net.Indyuce.mmoitems.api.ItemAttackResult; -import net.Indyuce.mmoitems.api.player.PlayerStats.CachedStats; -import io.lumine.mythic.lib.api.DamageType; -import io.lumine.mythic.lib.api.item.NBTItem; +import java.util.List; public class ManaSpirit implements StaffAttackHandler { @Override - public void handle(CachedStats stats, NBTItem nbt, double attackDamage, double range) { + public void handle(ItemAttackMetadata attackMeta, NBTItem nbt, double attackDamage, double range) { new BukkitRunnable() { - final Vector vec = stats.getPlayer().getEyeLocation().getDirection().multiply(.4); - final Location loc = stats.getPlayer().getEyeLocation(); + final Vector vec = attackMeta.getDamager().getEyeLocation().getDirection().multiply(.4); + final Location loc = attackMeta.getDamager().getEyeLocation(); int ti = 0; final double r = .2; @@ -48,9 +45,8 @@ public class ManaSpirit implements StaffAttackHandler { loc.getWorld().spawnParticle(Particle.REDSTONE, loc.clone().add(vec), 1, new Particle.DustOptions(Color.AQUA, 1)); } for (Entity target : targets) - if (MMOUtils.canDamage(stats.getPlayer(), loc, target)) { - new ItemAttackResult(attackDamage, DamageType.WEAPON, DamageType.MAGIC).applyEffectsAndDamage(stats, nbt, - (LivingEntity) target); + if (MMOUtils.canDamage(attackMeta.getDamager(), loc, target)) { + attackMeta.applyEffects(nbt, (LivingEntity) target); loc.getWorld().spawnParticle(Particle.EXPLOSION_LARGE, loc, 0); cancel(); return; diff --git a/src/main/java/net/Indyuce/mmoitems/api/interaction/weapon/untargeted/staff/NetherSpirit.java b/src/main/java/net/Indyuce/mmoitems/api/interaction/weapon/untargeted/staff/NetherSpirit.java index d261d64b..96fa7758 100644 --- a/src/main/java/net/Indyuce/mmoitems/api/interaction/weapon/untargeted/staff/NetherSpirit.java +++ b/src/main/java/net/Indyuce/mmoitems/api/interaction/weapon/untargeted/staff/NetherSpirit.java @@ -1,7 +1,9 @@ package net.Indyuce.mmoitems.api.interaction.weapon.untargeted.staff; -import java.util.List; - +import io.lumine.mythic.lib.api.item.NBTItem; +import net.Indyuce.mmoitems.MMOItems; +import net.Indyuce.mmoitems.MMOUtils; +import net.Indyuce.mmoitems.api.ItemAttackMetadata; import org.bukkit.Location; import org.bukkit.Particle; import org.bukkit.Sound; @@ -10,20 +12,15 @@ import org.bukkit.entity.LivingEntity; import org.bukkit.scheduler.BukkitRunnable; import org.bukkit.util.Vector; -import net.Indyuce.mmoitems.MMOItems; -import net.Indyuce.mmoitems.MMOUtils; -import net.Indyuce.mmoitems.api.ItemAttackResult; -import net.Indyuce.mmoitems.api.player.PlayerStats.CachedStats; -import io.lumine.mythic.lib.api.DamageType; -import io.lumine.mythic.lib.api.item.NBTItem; +import java.util.List; public class NetherSpirit implements StaffAttackHandler { @Override - public void handle(CachedStats stats, NBTItem nbt, double attackDamage, double range) { + public void handle(ItemAttackMetadata attackMeta, NBTItem nbt, double attackDamage, double range) { new BukkitRunnable() { - final Vector vec = stats.getPlayer().getEyeLocation().getDirection().multiply(.3); - final Location loc = stats.getPlayer().getEyeLocation(); + final Vector vec = attackMeta.getDamager().getEyeLocation().getDirection().multiply(.3); + final Location loc = attackMeta.getDamager().getEyeLocation(); int ti = 0; public void run() { @@ -40,8 +37,8 @@ public class NetherSpirit implements StaffAttackHandler { loc.getWorld().spawnParticle(Particle.FLAME, loc, 2, .07, .07, .07, 0); loc.getWorld().spawnParticle(Particle.SMOKE_NORMAL, loc, 0); for (Entity target : targets) - if (MMOUtils.canDamage(stats.getPlayer(), loc, target)) { - new ItemAttackResult(attackDamage, DamageType.WEAPON, DamageType.MAGIC).applyEffectsAndDamage(stats, nbt, (LivingEntity) target); + if (MMOUtils.canDamage(attackMeta.getDamager(), loc, target)) { + attackMeta.applyEffects(nbt, (LivingEntity) target); loc.getWorld().spawnParticle(Particle.EXPLOSION_LARGE, loc, 0); cancel(); return; diff --git a/src/main/java/net/Indyuce/mmoitems/api/interaction/weapon/untargeted/staff/StaffAttackHandler.java b/src/main/java/net/Indyuce/mmoitems/api/interaction/weapon/untargeted/staff/StaffAttackHandler.java index 5b60a073..05414cf1 100644 --- a/src/main/java/net/Indyuce/mmoitems/api/interaction/weapon/untargeted/staff/StaffAttackHandler.java +++ b/src/main/java/net/Indyuce/mmoitems/api/interaction/weapon/untargeted/staff/StaffAttackHandler.java @@ -1,16 +1,15 @@ package net.Indyuce.mmoitems.api.interaction.weapon.untargeted.staff; +import io.lumine.mythic.lib.api.item.NBTItem; +import net.Indyuce.mmoitems.api.ItemAttackMetadata; +import org.bukkit.Location; + import java.util.Random; -import org.bukkit.Location; - -import net.Indyuce.mmoitems.api.player.PlayerStats.CachedStats; -import io.lumine.mythic.lib.api.item.NBTItem; - public interface StaffAttackHandler { - void handle(CachedStats stats, NBTItem nbt, double attackDamage, double range); + static final Random random = new Random(); - Random random = new Random(); + void handle(ItemAttackMetadata attackMeta, NBTItem nbt, double attackDamage, double range); default Location getGround(Location loc) { for (int j = 0; j < 20; j++) { diff --git a/src/main/java/net/Indyuce/mmoitems/api/interaction/weapon/untargeted/staff/SunfireSpirit.java b/src/main/java/net/Indyuce/mmoitems/api/interaction/weapon/untargeted/staff/SunfireSpirit.java index 520bd3ed..3e337612 100644 --- a/src/main/java/net/Indyuce/mmoitems/api/interaction/weapon/untargeted/staff/SunfireSpirit.java +++ b/src/main/java/net/Indyuce/mmoitems/api/interaction/weapon/untargeted/staff/SunfireSpirit.java @@ -1,5 +1,10 @@ package net.Indyuce.mmoitems.api.interaction.weapon.untargeted.staff; +import io.lumine.mythic.lib.api.item.NBTItem; +import io.lumine.mythic.lib.version.VersionSound; +import net.Indyuce.mmoitems.MMOItems; +import net.Indyuce.mmoitems.MMOUtils; +import net.Indyuce.mmoitems.api.ItemAttackMetadata; import org.bukkit.Location; import org.bukkit.Particle; import org.bukkit.Sound; @@ -8,21 +13,13 @@ import org.bukkit.entity.LivingEntity; import org.bukkit.scheduler.BukkitRunnable; import org.bukkit.util.Vector; -import net.Indyuce.mmoitems.MMOItems; -import net.Indyuce.mmoitems.MMOUtils; -import net.Indyuce.mmoitems.api.ItemAttackResult; -import net.Indyuce.mmoitems.api.player.PlayerStats.CachedStats; -import io.lumine.mythic.lib.api.DamageType; -import io.lumine.mythic.lib.api.item.NBTItem; -import io.lumine.mythic.lib.version.VersionSound; - public class SunfireSpirit implements StaffAttackHandler { @Override - public void handle(CachedStats stats, NBTItem nbt, double attackDamage, double range) { - stats.getPlayer().getWorld().playSound(stats.getPlayer().getLocation(), Sound.ENTITY_WITHER_SHOOT, 2, 2); + public void handle(ItemAttackMetadata attackMeta, NBTItem nbt, double attackDamage, double range) { + attackMeta.getDamager().getWorld().playSound(attackMeta.getDamager().getLocation(), Sound.ENTITY_WITHER_SHOOT, 2, 2); new BukkitRunnable() { - final Location target = getGround(stats.getPlayer().getTargetBlock(null, (int) range * 2).getLocation()).add(0, 1.2, 0); + final Location target = getGround(attackMeta.getDamager().getTargetBlock(null, (int) range * 2).getLocation()).add(0, 1.2, 0); final double a = random.nextDouble() * Math.PI * 2; final Location loc = target.clone().add(Math.cos(a) * 4, 10, Math.sin(a) * 4); final Vector vec = target.toVector().subtract(loc.toVector()).multiply(.015); @@ -40,8 +37,8 @@ public class SunfireSpirit implements StaffAttackHandler { loc.getWorld().spawnParticle(Particle.EXPLOSION_LARGE, loc, 0); loc.getWorld().playSound(loc, VersionSound.ENTITY_FIREWORK_ROCKET_BLAST.toSound(), 2, 2); for (Entity target : MMOUtils.getNearbyChunkEntities(loc)) - if (MMOUtils.canDamage(stats.getPlayer(), target) && target.getLocation().distanceSquared(loc) <= 9) - new ItemAttackResult(attackDamage, DamageType.WEAPON, DamageType.MAGIC).applyEffectsAndDamage(stats, nbt, (LivingEntity) target); + if (MMOUtils.canDamage(attackMeta.getDamager(), target) && target.getLocation().distanceSquared(loc) <= 9) + attackMeta.applyEffectsAndDamage(nbt, (LivingEntity) target); cancel(); break; } diff --git a/src/main/java/net/Indyuce/mmoitems/api/interaction/weapon/untargeted/staff/ThunderSpirit.java b/src/main/java/net/Indyuce/mmoitems/api/interaction/weapon/untargeted/staff/ThunderSpirit.java index c7cf5229..fafe168c 100644 --- a/src/main/java/net/Indyuce/mmoitems/api/interaction/weapon/untargeted/staff/ThunderSpirit.java +++ b/src/main/java/net/Indyuce/mmoitems/api/interaction/weapon/untargeted/staff/ThunderSpirit.java @@ -1,5 +1,10 @@ package net.Indyuce.mmoitems.api.interaction.weapon.untargeted.staff; +import io.lumine.mythic.lib.api.item.NBTItem; +import io.lumine.mythic.lib.version.VersionSound; +import net.Indyuce.mmoitems.MMOItems; +import net.Indyuce.mmoitems.MMOUtils; +import net.Indyuce.mmoitems.api.ItemAttackMetadata; import org.bukkit.Location; import org.bukkit.Particle; import org.bukkit.Sound; @@ -8,21 +13,13 @@ import org.bukkit.entity.LivingEntity; import org.bukkit.scheduler.BukkitRunnable; import org.bukkit.util.Vector; -import net.Indyuce.mmoitems.MMOItems; -import net.Indyuce.mmoitems.MMOUtils; -import net.Indyuce.mmoitems.api.ItemAttackResult; -import net.Indyuce.mmoitems.api.player.PlayerStats.CachedStats; -import io.lumine.mythic.lib.api.DamageType; -import io.lumine.mythic.lib.api.item.NBTItem; -import io.lumine.mythic.lib.version.VersionSound; - public class ThunderSpirit implements StaffAttackHandler { @Override - public void handle(CachedStats stats, NBTItem nbt, double attackDamage, double range) { - stats.getPlayer().getWorld().playSound(stats.getPlayer().getLocation(), Sound.ENTITY_WITHER_SHOOT, 2, 2); + public void handle(ItemAttackMetadata attackMeta, NBTItem nbt, double attackDamage, double range) { + attackMeta.getDamager().getWorld().playSound(attackMeta.getDamager().getLocation(), Sound.ENTITY_WITHER_SHOOT, 2, 2); new BukkitRunnable() { - final Location target = getGround(stats.getPlayer().getTargetBlock(null, (int) range * 2).getLocation()).add(0, 1.2, 0); + final Location target = getGround(attackMeta.getDamager().getTargetBlock(null, (int) range * 2).getLocation()).add(0, 1.2, 0); final double a = random.nextDouble() * Math.PI * 2; final Location loc = target.clone().add(Math.cos(a) * 4, 10, Math.sin(a) * 4); final Vector vec = target.toVector().subtract(loc.toVector()).multiply(.015); @@ -38,8 +35,8 @@ public class ThunderSpirit implements StaffAttackHandler { loc.getWorld().spawnParticle(Particle.FIREWORKS_SPARK, loc, 24, 0, 0, 0, .12); loc.getWorld().playSound(loc, VersionSound.ENTITY_FIREWORK_ROCKET_BLAST.toSound(), 2, 2); for (Entity target : MMOUtils.getNearbyChunkEntities(loc)) - if (MMOUtils.canDamage(stats.getPlayer(), target) && target.getLocation().distanceSquared(loc) <= 9) - new ItemAttackResult(attackDamage, DamageType.WEAPON, DamageType.MAGIC).applyEffectsAndDamage(stats, nbt, (LivingEntity) target); + if (MMOUtils.canDamage(attackMeta.getDamager(), target) && target.getLocation().distanceSquared(loc) <= 9) + attackMeta.applyEffectsAndDamage(nbt, (LivingEntity) target); cancel(); } } diff --git a/src/main/java/net/Indyuce/mmoitems/api/interaction/weapon/untargeted/staff/VoidSpirit.java b/src/main/java/net/Indyuce/mmoitems/api/interaction/weapon/untargeted/staff/VoidSpirit.java index aa108175..2be78082 100644 --- a/src/main/java/net/Indyuce/mmoitems/api/interaction/weapon/untargeted/staff/VoidSpirit.java +++ b/src/main/java/net/Indyuce/mmoitems/api/interaction/weapon/untargeted/staff/VoidSpirit.java @@ -1,11 +1,9 @@ package net.Indyuce.mmoitems.api.interaction.weapon.untargeted.staff; -import io.lumine.mythic.lib.api.DamageType; import io.lumine.mythic.lib.api.item.NBTItem; import net.Indyuce.mmoitems.MMOItems; -import net.Indyuce.mmoitems.ability.Shulker_Missile; -import net.Indyuce.mmoitems.api.ItemAttackResult; -import net.Indyuce.mmoitems.api.player.PlayerStats.CachedStats; +import net.Indyuce.mmoitems.ability.list.vector.Shulker_Missile; +import net.Indyuce.mmoitems.api.ItemAttackMetadata; import org.bukkit.Sound; import org.bukkit.entity.EntityType; import org.bukkit.entity.ShulkerBullet; @@ -15,11 +13,11 @@ import org.bukkit.util.Vector; public class VoidSpirit implements StaffAttackHandler { @Override - public void handle(CachedStats stats, NBTItem nbt, double attackDamage, double range) { - Vector vec = stats.getPlayer().getEyeLocation().getDirection(); - stats.getPlayer().getWorld().playSound(stats.getPlayer().getLocation(), Sound.ENTITY_WITHER_SHOOT, 2, 2); - ShulkerBullet shulkerBullet = (ShulkerBullet) stats.getPlayer().getWorld().spawnEntity(stats.getPlayer().getLocation().add(0, 1, 0), EntityType.valueOf("SHULKER_BULLET")); - shulkerBullet.setShooter(stats.getPlayer()); + public void handle(ItemAttackMetadata attackMeta, NBTItem nbt, double attackDamage, double range) { + Vector vec = attackMeta.getDamager().getEyeLocation().getDirection(); + attackMeta.getDamager().getWorld().playSound(attackMeta.getDamager().getLocation(), Sound.ENTITY_WITHER_SHOOT, 2, 2); + ShulkerBullet shulkerBullet = (ShulkerBullet) attackMeta.getDamager().getWorld().spawnEntity(attackMeta.getDamager().getLocation().add(0, 1, 0), EntityType.valueOf("SHULKER_BULLET")); + shulkerBullet.setShooter(attackMeta.getDamager()); new BukkitRunnable() { double ti = 0; @@ -32,6 +30,6 @@ public class VoidSpirit implements StaffAttackHandler { shulkerBullet.setVelocity(vec); } }.runTaskTimer(MMOItems.plugin, 0, 1); - MMOItems.plugin.getEntities().registerCustomEntity(shulkerBullet, new Shulker_Missile.ShulkerMissileEntityData(new ItemAttackResult(attackDamage, DamageType.WEAPON, DamageType.MAGIC), stats, nbt)); + MMOItems.plugin.getEntities().registerCustomEntity(shulkerBullet, new Shulker_Missile.ShulkerMissileEntityData(attackMeta, nbt)); } } diff --git a/src/main/java/net/Indyuce/mmoitems/api/interaction/weapon/untargeted/staff/XRaySpirit.java b/src/main/java/net/Indyuce/mmoitems/api/interaction/weapon/untargeted/staff/XRaySpirit.java index 5255ba7e..17597a96 100644 --- a/src/main/java/net/Indyuce/mmoitems/api/interaction/weapon/untargeted/staff/XRaySpirit.java +++ b/src/main/java/net/Indyuce/mmoitems/api/interaction/weapon/untargeted/staff/XRaySpirit.java @@ -1,31 +1,28 @@ package net.Indyuce.mmoitems.api.interaction.weapon.untargeted.staff; +import io.lumine.mythic.lib.MythicLib; +import io.lumine.mythic.lib.api.MMORayTraceResult; +import io.lumine.mythic.lib.api.item.NBTItem; +import net.Indyuce.mmoitems.MMOUtils; +import net.Indyuce.mmoitems.api.ItemAttackMetadata; import org.bukkit.Color; import org.bukkit.Location; import org.bukkit.Sound; import org.bukkit.util.Vector; -import net.Indyuce.mmoitems.MMOUtils; -import net.Indyuce.mmoitems.api.ItemAttackResult; -import net.Indyuce.mmoitems.api.player.PlayerStats.CachedStats; -import io.lumine.mythic.lib.MythicLib; -import io.lumine.mythic.lib.api.DamageType; -import io.lumine.mythic.lib.api.MMORayTraceResult; -import io.lumine.mythic.lib.api.item.NBTItem; - public class XRaySpirit implements StaffAttackHandler { @Override - public void handle(CachedStats stats, NBTItem nbt, double attackDamage, double range) { - stats.getPlayer().getWorld().playSound(stats.getPlayer().getLocation(), Sound.BLOCK_FIRE_EXTINGUISH, 2, 2); + public void handle(ItemAttackMetadata attackMeta, NBTItem nbt, double attackDamage, double range) { + attackMeta.getDamager().getWorld().playSound(attackMeta.getDamager().getLocation(), Sound.BLOCK_FIRE_EXTINGUISH, 2, 2); - double a = Math.toRadians(stats.getPlayer().getEyeLocation().getYaw() + 160); - Location loc = stats.getPlayer().getEyeLocation().add(new Vector(Math.cos(a), 0, Math.sin(a)).multiply(.5)); + double a = Math.toRadians(attackMeta.getDamager().getEyeLocation().getYaw() + 160); + Location loc = attackMeta.getDamager().getEyeLocation().add(new Vector(Math.cos(a), 0, Math.sin(a)).multiply(.5)); - MMORayTraceResult trace = MythicLib.plugin.getVersion().getWrapper().rayTrace(stats.getPlayer(), range, entity -> MMOUtils.canDamage(stats.getPlayer(), entity)); + MMORayTraceResult trace = MythicLib.plugin.getVersion().getWrapper().rayTrace(attackMeta.getDamager(), range, entity -> MMOUtils.canDamage(attackMeta.getDamager(), entity)); if (trace.hasHit()) - new ItemAttackResult(attackDamage, DamageType.WEAPON, DamageType.MAGIC).applyEffectsAndDamage(stats, nbt, trace.getHit()); - trace.draw(loc, stats.getPlayer().getEyeLocation().getDirection(), 2, Color.BLACK); - stats.getPlayer().getWorld().playSound(stats.getPlayer().getLocation(), Sound.ENTITY_ZOMBIE_ATTACK_IRON_DOOR, 0.40f, 2); + attackMeta.applyEffectsAndDamage(nbt, trace.getHit()); + trace.draw(loc, attackMeta.getDamager().getEyeLocation().getDirection(), 2, Color.BLACK); + attackMeta.getDamager().getWorld().playSound(attackMeta.getDamager().getLocation(), Sound.ENTITY_ZOMBIE_ATTACK_IRON_DOOR, 0.40f, 2); } } diff --git a/src/main/java/net/Indyuce/mmoitems/api/player/PlayerAbilityData.java b/src/main/java/net/Indyuce/mmoitems/api/player/PlayerAbilityData.java deleted file mode 100644 index 44659484..00000000 --- a/src/main/java/net/Indyuce/mmoitems/api/player/PlayerAbilityData.java +++ /dev/null @@ -1,53 +0,0 @@ -package net.Indyuce.mmoitems.api.player; - -import java.util.HashMap; -import java.util.Map; - -import net.Indyuce.mmoitems.comp.mythicmobs.MythicMobsAbility; -import net.Indyuce.mmoitems.stat.data.AbilityData; - -public class PlayerAbilityData { - - /* - * MythicMobs skill damage is handled via math formula which can retrieve - * PAPI placeholders. when a skill is cast, all skill modifiers are cached - * into that map: 1- for easier and faster access 2- it removes interference - * for example when stats are calculating not when the spell is cast but - * rather when the spell hits - */ - private final Map cache = new HashMap<>(); - - public double getCachedModifier(String name) { - return cache.containsKey(name) ? cache.get(name).getValue() : 0; - } - - public void cacheModifiers(MythicMobsAbility ability, AbilityData data) { - for (String modifier : data.getModifiers()) - cacheModifier(ability, modifier, data.getModifier(modifier)); - } - - public void cacheModifier(MythicMobsAbility ability, String name, double value) { - cache.put(ability.getInternalName() + "." + name, new CachedModifier(value)); - } - - public void refresh() { - cache.values().removeIf(CachedModifier::isTimedOut); - } - - public static class CachedModifier { - private final long date = System.currentTimeMillis(); - private final double value; - - public CachedModifier(double value) { - this.value = value; - } - - public boolean isTimedOut() { - return date + 1000 * 60 < System.currentTimeMillis(); - } - - public double getValue() { - return value; - } - } -} diff --git a/src/main/java/net/Indyuce/mmoitems/api/player/PlayerData.java b/src/main/java/net/Indyuce/mmoitems/api/player/PlayerData.java index bd5f79a2..0cb62b4e 100644 --- a/src/main/java/net/Indyuce/mmoitems/api/player/PlayerData.java +++ b/src/main/java/net/Indyuce/mmoitems/api/player/PlayerData.java @@ -4,22 +4,22 @@ import io.lumine.mythic.lib.MythicLib; import io.lumine.mythic.lib.api.item.NBTItem; import io.lumine.mythic.lib.api.player.EquipmentSlot; import io.lumine.mythic.lib.api.player.MMOPlayerData; +import io.lumine.mythic.lib.damage.DamageMetadata; import net.Indyuce.mmoitems.ItemStats; import net.Indyuce.mmoitems.MMOItems; import net.Indyuce.mmoitems.MMOUtils; import net.Indyuce.mmoitems.api.ConfigFile; -import net.Indyuce.mmoitems.api.ItemAttackResult; +import net.Indyuce.mmoitems.api.ItemAttackMetadata; import net.Indyuce.mmoitems.api.ItemSet; import net.Indyuce.mmoitems.api.ItemSet.SetBonuses; import net.Indyuce.mmoitems.api.Type; -import net.Indyuce.mmoitems.api.ability.Ability; -import net.Indyuce.mmoitems.api.ability.Ability.CastingMode; -import net.Indyuce.mmoitems.api.ability.AbilityResult; +import net.Indyuce.mmoitems.ability.Ability; +import net.Indyuce.mmoitems.ability.Ability.CastingMode; +import net.Indyuce.mmoitems.ability.AbilityMetadata; import net.Indyuce.mmoitems.api.crafting.CraftingStatus; import net.Indyuce.mmoitems.api.event.AbilityUseEvent; import net.Indyuce.mmoitems.api.event.RefreshInventoryEvent; import net.Indyuce.mmoitems.api.item.mmoitem.VolatileMMOItem; -import net.Indyuce.mmoitems.api.player.PlayerStats.CachedStats; import net.Indyuce.mmoitems.api.player.inventory.EquippedItem; import net.Indyuce.mmoitems.api.player.inventory.EquippedPlayerItem; import net.Indyuce.mmoitems.api.player.inventory.InventoryUpdateHandler; @@ -53,7 +53,6 @@ public class PlayerData { private final InventoryUpdateHandler inventory = new InventoryUpdateHandler(this); private final CraftingStatus craftingStatus = new CraftingStatus(); - private final PlayerAbilityData playerAbilityData = new PlayerAbilityData(); private final Map abilityCooldowns = new HashMap<>(); private final Map itemCooldowns = new HashMap<>(); private final Map extraCooldowns = new HashMap<>(); @@ -344,10 +343,6 @@ public class PlayerData { return craftingStatus; } - public PlayerAbilityData getAbilityData() { - return playerAbilityData; - } - public int getPermanentPotionEffectAmplifier(PotionEffectType type) { return permanentEffects.containsKey(type) ? permanentEffects.get(type).getAmplifier() : -1; } @@ -374,63 +369,57 @@ public class PlayerData { /** * Casts all the abilities of a player under a specific casting mode onto a certain enemy *

- * Used internally by MMOItems to avoid caching the player stats (which costs - * a lot of calculations) before checking if the player can cast any ability. - *

- * Mainly due to random player clicks with no or few MMOItems being equipped - * still caching a lot of player stats. + * This is NOT used within MMOItems and is purely an API method. This has the effect + * of generating a ItemMetadata if necessary, which caches the player stats. * - * @param target The ability target, can be null. - * @param result The current attack, cannot be null. + * @param target Ability target which can be null * @param castMode The action the player performed to cast the ability + * @return Null if no ability was cast, or the attack metadata if any was cast. */ - @SuppressWarnings("UnusedReturnValue") - public ItemAttackResult castAbilities(@Nullable LivingEntity target, @NotNull ItemAttackResult result, @NotNull CastingMode castMode) { + @Nullable + public ItemAttackMetadata castAbilities(@Nullable LivingEntity target, @NotNull CastingMode castMode) { if (!hasAbility(castMode)) - return result; + return null; - return castAbilities(getStats().newTemporary(EquipmentSlot.OTHER), target, result, castMode); + ItemAttackMetadata meta = new ItemAttackMetadata(new DamageMetadata(), mmoData.getStatMap().cache(EquipmentSlot.OTHER)); + return castAbilities(meta, target, castMode); } /** * Casts all the abilities of a player under a specific casting mode onto a certain enemy * - * @param stats The player stats - * @param target The ability target, can be null. - * @param result The current attack, cannot be null. - * @param castMode The action the player performed to cast the ability + * @param attack Current attack meta + * @param target Ability target, can be null + * @param castMode Action the player performed to cast the ability */ - public ItemAttackResult castAbilities(CachedStats stats, LivingEntity target, ItemAttackResult result, CastingMode castMode) { - if (!mmoData.isOnline()) - return result; + public ItemAttackMetadata castAbilities(ItemAttackMetadata attack, LivingEntity target, CastingMode castMode) { /* - * if ability has target, check for ability flag at location of target - * and make sure player can attack target. if ability has no target, + * If the ability has target, check for ability flag at location of target + * and make sure player can attack target. If ability has no target, * check for WG flag at the caster location */ if (target == null ? !MMOItems.plugin.getFlags().isFlagAllowed(getPlayer(), CustomFlag.MI_ABILITIES) : !MMOItems.plugin.getFlags().isFlagAllowed(target.getLocation(), CustomFlag.MI_ABILITIES) || !MMOUtils.canDamage(getPlayer(), target)) - return result.setSuccessful(false); + return attack.setSuccessful(false); for (AbilityData ability : itemAbilities) if (ability.getCastingMode() == castMode) - cast(stats, target, result, ability); + cast(attack, target, ability); - return result; + return attack; } /** * Makes the player cast an ability. Checks for cooldown and mana cost before casting it. * Also calls a Bukkit event right before casting it. * - * @param stats The player stats - * @param target The ability target, can be null. - * @param attack The current attack, cannot be null. + * @param attack Current attack + * @param target Ability target, can be null * @param ability Ability to cast */ - public void cast(CachedStats stats, LivingEntity target, ItemAttackResult attack, AbilityData ability) { + public void cast(ItemAttackMetadata attack, LivingEntity target, AbilityData ability) { /* * Apply simple conditions including mana and stamina cost, permission @@ -443,8 +432,8 @@ public class PlayerData { * Apply extra conditions which depend on the ability the player is * casting */ - AbilityResult abilityResult = ability.getAbility().whenRan(stats, target, ability, attack); - if (!abilityResult.isSuccessful()) + AbilityMetadata abilityMetadata = ability.getAbility().canBeCast(attack, target, ability); + if (!abilityMetadata.isSuccessful()) return; AbilityUseEvent event = new AbilityUseEvent(this, ability, target); @@ -457,11 +446,11 @@ public class PlayerData { * target, removes resources needed from the player */ if (ability.hasModifier("mana")) - rpgPlayer.giveMana(-abilityResult.getModifier("mana")); + rpgPlayer.giveMana(-abilityMetadata.getModifier("mana")); if (ability.hasModifier("stamina")) - rpgPlayer.giveStamina(-abilityResult.getModifier("stamina")); + rpgPlayer.giveStamina(-abilityMetadata.getModifier("stamina")); - double cooldown = abilityResult.getModifier("cooldown") * (1 - Math.min(.8, stats.getStat(ItemStats.COOLDOWN_REDUCTION) / 100)); + double cooldown = abilityMetadata.getModifier("cooldown") * (1 - Math.min(.8, stats.getStat(ItemStats.COOLDOWN_REDUCTION) / 100)); if (cooldown > 0) applyAbilityCooldown(ability.getAbility(), cooldown); @@ -470,7 +459,7 @@ public class PlayerData { * the ability is cast otherwise instantaneously damaging abilities like * Sparkle can trigger deadly crash loops */ - ability.getAbility().whenCast(stats, abilityResult, attack); + ability.getAbility().whenCast(attack, abilityMetadata); } public boolean isOnCooldown(CooldownType type) { diff --git a/src/main/java/net/Indyuce/mmoitems/api/player/PlayerStats.java b/src/main/java/net/Indyuce/mmoitems/api/player/PlayerStats.java index bf028ac6..68619c80 100644 --- a/src/main/java/net/Indyuce/mmoitems/api/player/PlayerStats.java +++ b/src/main/java/net/Indyuce/mmoitems/api/player/PlayerStats.java @@ -11,10 +11,6 @@ import net.Indyuce.mmoitems.api.Type; import net.Indyuce.mmoitems.api.player.inventory.EquippedPlayerItem; import net.Indyuce.mmoitems.stat.type.AttributeStat; import net.Indyuce.mmoitems.stat.type.ItemStat; -import org.bukkit.entity.Player; - -import java.util.HashMap; -import java.util.Map; public class PlayerStats { private final PlayerData playerData; @@ -46,9 +42,10 @@ public class PlayerStats { * * @param castSlot Every stat modifier with the opposite modifier * source will NOT be taken into account for stat calculation + * @return */ - public CachedStats newTemporary(EquipmentSlot castSlot) { - return new CachedStats(castSlot); + public StatMap.CachedStatMap newTemporary(EquipmentSlot castSlot) { + return playerData.getMMOPlayerData().getStatMap().cache(castSlot); } public void updateStats() { @@ -89,56 +86,4 @@ public class PlayerStats { packet.runUpdate(); } } - - public class CachedStats { - private final Player player; - private final Map stats = new HashMap<>(); - - /** - * Used to cache stats when a player casts a skill so that if the player - * swaps items or changes any of his stat value before the end of the - * spell duration, the stat value is not updated - * - * @castSlot The equipment slot of the item the player is casting - * a skill/attacking with. Helps determine what stats modifiers needs to be - * applied and what modifiers must be filtered - */ - public CachedStats(EquipmentSlot castSlot) { - player = playerData.getPlayer(); - - if (castSlot.isHand()) { - - /* - * When casting a skill or an attack with a certain hand, stats - * from the other hand shouldn't be taken into account - */ - EquipmentSlot ignored = castSlot.getOppositeHand(); - for (StatInstance ins : getMap().getInstances()) - this.stats.put(ins.getStat(), ins.getFilteredTotal(mod -> mod.getSlot() != ignored)); - } else - - /* - * Not casting the attack with a specific - * hand so take everything into account - */ - for (StatInstance ins : getMap().getInstances()) - this.stats.put(ins.getStat(), ins.getTotal()); - } - - public PlayerData getData() { - return playerData; - } - - public Player getPlayer() { - return player; - } - - public double getStat(ItemStat stat) { - return stats.containsKey(stat.getId()) ? stats.get(stat.getId()) : 0; - } - - public void setStat(ItemStat stat, double value) { - stats.put(stat.getId(), value); - } - } } diff --git a/src/main/java/net/Indyuce/mmoitems/api/util/TemporaryListener.java b/src/main/java/net/Indyuce/mmoitems/api/util/TemporaryListener.java index d57bac63..f68f0af4 100644 --- a/src/main/java/net/Indyuce/mmoitems/api/util/TemporaryListener.java +++ b/src/main/java/net/Indyuce/mmoitems/api/util/TemporaryListener.java @@ -1,21 +1,20 @@ package net.Indyuce.mmoitems.api.util; +import net.Indyuce.mmoitems.MMOItems; import org.bukkit.Bukkit; import org.bukkit.event.HandlerList; import org.bukkit.event.Listener; -import net.Indyuce.mmoitems.MMOItems; - public abstract class TemporaryListener implements Listener { - /* - * handler lists which must be called when the temporary listener is closed - * so that the listener is entirely unregistered. + /** + * Handler lists which must be called when the temporary listener is + * closed so that the listener is entirely unregistered. */ private final HandlerList[] lists; - /* - * sometimes the close method is called twice because of a safe delayed task + /** + * Sometimes the close method is called twice because of a safe delayed task * not being cancelled when the listener is closed. */ private boolean closed; @@ -25,8 +24,8 @@ public abstract class TemporaryListener implements Listener { Bukkit.getPluginManager().registerEvents(this, MMOItems.plugin); } - /* - * used to close the temporary listener after some delay + /** + * Closes the temporary listener after some delay */ public void close(long duration) { Bukkit.getScheduler().runTaskLater(MMOItems.plugin, (Runnable) this::close, duration); diff --git a/src/main/java/net/Indyuce/mmoitems/command/mmoitems/AbilityCommandTreeNode.java b/src/main/java/net/Indyuce/mmoitems/command/mmoitems/AbilityCommandTreeNode.java index 65fb56cb..37549cae 100644 --- a/src/main/java/net/Indyuce/mmoitems/command/mmoitems/AbilityCommandTreeNode.java +++ b/src/main/java/net/Indyuce/mmoitems/command/mmoitems/AbilityCommandTreeNode.java @@ -1,12 +1,13 @@ package net.Indyuce.mmoitems.command.mmoitems; import io.lumine.mythic.lib.api.player.EquipmentSlot; +import io.lumine.mythic.lib.damage.DamageMetadata; import io.lumine.mythic.lib.mmolibcommands.api.CommandTreeNode; import io.lumine.mythic.lib.mmolibcommands.api.Parameter; import net.Indyuce.mmoitems.MMOItems; -import net.Indyuce.mmoitems.api.ItemAttackResult; -import net.Indyuce.mmoitems.api.ability.Ability; -import net.Indyuce.mmoitems.api.ability.Ability.CastingMode; +import net.Indyuce.mmoitems.ability.Ability; +import net.Indyuce.mmoitems.ability.Ability.CastingMode; +import net.Indyuce.mmoitems.api.ItemAttackMetadata; import net.Indyuce.mmoitems.api.player.PlayerData; import net.Indyuce.mmoitems.stat.data.AbilityData; import org.bukkit.Bukkit; @@ -74,7 +75,7 @@ public class AbilityCommandTreeNode extends CommandTreeNode { } PlayerData data = PlayerData.get(target); - data.cast(data.getStats().newTemporary(EquipmentSlot.MAIN_HAND), null, new ItemAttackResult(0), ability); + data.cast(new ItemAttackMetadata(new DamageMetadata(), data.getMMOPlayerData().getStatMap().cache(EquipmentSlot.MAIN_HAND)), null, ability); return CommandResult.SUCCESS; } } diff --git a/src/main/java/net/Indyuce/mmoitems/command/mmoitems/list/AbilityCommandTreeNode.java b/src/main/java/net/Indyuce/mmoitems/command/mmoitems/list/AbilityCommandTreeNode.java index ad1827e3..f28a7999 100644 --- a/src/main/java/net/Indyuce/mmoitems/command/mmoitems/list/AbilityCommandTreeNode.java +++ b/src/main/java/net/Indyuce/mmoitems/command/mmoitems/list/AbilityCommandTreeNode.java @@ -4,7 +4,7 @@ import org.bukkit.ChatColor; import org.bukkit.command.CommandSender; import net.Indyuce.mmoitems.MMOItems; -import net.Indyuce.mmoitems.api.ability.Ability; +import net.Indyuce.mmoitems.ability.Ability; import io.lumine.mythic.lib.mmolibcommands.api.CommandTreeNode; public class AbilityCommandTreeNode extends CommandTreeNode { diff --git a/src/main/java/net/Indyuce/mmoitems/comp/RealDualWieldHook.java b/src/main/java/net/Indyuce/mmoitems/comp/RealDualWieldHook.java index af1e95dd..f36cbd93 100644 --- a/src/main/java/net/Indyuce/mmoitems/comp/RealDualWieldHook.java +++ b/src/main/java/net/Indyuce/mmoitems/comp/RealDualWieldHook.java @@ -2,10 +2,11 @@ package net.Indyuce.mmoitems.comp; import com.evill4mer.RealDualWield.Api.PlayerDamageEntityWithOffhandEvent; import io.lumine.mythic.lib.MythicLib; -import io.lumine.mythic.lib.api.DamageType; import io.lumine.mythic.lib.api.item.NBTItem; import io.lumine.mythic.lib.api.player.EquipmentSlot; -import net.Indyuce.mmoitems.api.ItemAttackResult; +import io.lumine.mythic.lib.damage.DamageMetadata; +import io.lumine.mythic.lib.damage.DamageType; +import net.Indyuce.mmoitems.api.ItemAttackMetadata; import net.Indyuce.mmoitems.api.TypeSet; import net.Indyuce.mmoitems.api.interaction.weapon.Weapon; import net.Indyuce.mmoitems.api.player.PlayerData; @@ -19,26 +20,22 @@ public class RealDualWieldHook implements Listener { @EventHandler(priority = EventPriority.HIGH, ignoreCancelled = true) public void a(PlayerDamageEntityWithOffhandEvent event) { - /* - * Citizens and Sentinels NPC support; damage = 0 check to ignore safety - * checks; check for entity attack - */ + // Citizens NPC support; also check if it's not a useless event if (event.getDamage() == 0 || !(event.getEntity() instanceof LivingEntity) || event.getEntity().hasMetadata("NPC")) return; - // custom damage check + // Custom damage check LivingEntity target = (LivingEntity) event.getEntity(); if (MythicLib.plugin.getDamage().findInfo(target) != null) return; /* - * must apply attack conditions before apply any effects. the event must - * be cancelled before anything is applied + * Must apply attack conditions before apply any effects. + * The event must be cancelled before anything is applied */ Player player = event.getPlayer(); PlayerData playerData = PlayerData.get(player); NBTItem offhandItem = MythicLib.plugin.getVersion().getWrapper().getNBTItem(player.getInventory().getItemInOffHand()); - ItemAttackResult result = new ItemAttackResult(event.getDamage(), DamageType.WEAPON, DamageType.PHYSICAL); if (offhandItem.hasType()) { Weapon weapon = new Weapon(playerData, offhandItem); @@ -54,10 +51,9 @@ public class RealDualWieldHook implements Listener { } } - /* - * cast on-hit abilities and add the extra damage to the damage event - */ - result.applyEffects(playerData.getStats().newTemporary(EquipmentSlot.OFF_HAND), offhandItem, target); - event.setDamage(result.getDamage()); + // Cast on-hit abilities and add extra damage to the Bukkit event + ItemAttackMetadata attack = new ItemAttackMetadata(new DamageMetadata(event.getDamage(), DamageType.WEAPON, DamageType.PHYSICAL), playerData.getMMOPlayerData().getStatMap().cache(EquipmentSlot.OFF_HAND)); + attack.applyEffects(offhandItem, target); + event.setDamage(attack.getDamage().getDamage()); } } diff --git a/src/main/java/net/Indyuce/mmoitems/comp/mythicmobs/MythicMobsAbility.java b/src/main/java/net/Indyuce/mmoitems/comp/mythicmobs/MythicMobsAbility.java deleted file mode 100644 index 2da36a71..00000000 --- a/src/main/java/net/Indyuce/mmoitems/comp/mythicmobs/MythicMobsAbility.java +++ /dev/null @@ -1,88 +0,0 @@ -package net.Indyuce.mmoitems.comp.mythicmobs; - -import java.util.ArrayList; -import java.util.List; -import java.util.Optional; - -import org.apache.commons.lang.Validate; -import org.bukkit.configuration.file.FileConfiguration; -import org.bukkit.entity.Entity; -import org.bukkit.entity.LivingEntity; - -import io.lumine.xikage.mythicmobs.MythicMobs; -import io.lumine.xikage.mythicmobs.skills.Skill; -import net.Indyuce.mmoitems.api.ItemAttackResult; -import net.Indyuce.mmoitems.api.ability.Ability; -import net.Indyuce.mmoitems.api.ability.AbilityResult; -import net.Indyuce.mmoitems.api.player.PlayerStats.CachedStats; -import net.Indyuce.mmoitems.stat.data.AbilityData; - -public class MythicMobsAbility extends Ability { - private final Skill skill; - private final boolean selfOnly; - - public MythicMobsAbility(String id, FileConfiguration config) { - super(id, config.getString("name"), CastingMode.ON_HIT, CastingMode.WHEN_HIT, CastingMode.LEFT_CLICK, CastingMode.RIGHT_CLICK, CastingMode.SHIFT_LEFT_CLICK, CastingMode.SHIFT_RIGHT_CLICK); - - String skillName = config.getString("mythicmobs-skill-id"); - Validate.notNull(skillName, "Could not find MM skill name"); - - Optional opt = MythicMobs.inst().getSkillManager().getSkill(skillName); - Validate.isTrue(opt.isPresent(), "Could not find MM skill " + skillName); - skill = opt.get(); - - selfOnly = config.getBoolean("self-only"); - - addModifier("cooldown", 10); - addModifier("mana", 0); - addModifier("stamina", 0); - - for (String mod : config.getKeys(false)) - if (!mod.equals("name") && !mod.equals("mythicmobs-skill-id") && !mod.equals("self-only")) - addModifier(mod.toLowerCase().replace("_", "-").replace(" ", "-"), config.getInt(mod)); - } - - public String getInternalName() { - return skill.getInternalName(); - } - - @Override - public void whenCast(CachedStats stats, AbilityResult ability, ItemAttackResult result) { - LivingEntity target = ((MythicMobsAbilityResult) ability).getTarget(); - List targets = new ArrayList<>(); - targets.add(target == null || selfOnly ? stats.getPlayer() : target); - - /* - * cache placeholders so they can be retrieved later by MythicMobs math - * formulas - */ - stats.getData().getAbilityData().cacheModifiers(this, ability.getAbility()); - - if (!MythicMobs.inst().getAPIHelper().castSkill(stats.getPlayer(), skill.getInternalName(), stats.getPlayer(), stats.getPlayer().getEyeLocation(), targets, null, 1)) - result.setSuccessful(false); - } - - @Override - public AbilityResult whenRan(CachedStats playerStats, LivingEntity target, AbilityData data, ItemAttackResult result) { - return new MythicMobsAbilityResult(data, target); - } - - public static class MythicMobsAbilityResult extends AbilityResult { - private final LivingEntity target; - - public MythicMobsAbilityResult(AbilityData ability, LivingEntity target) { - super(ability); - - this.target = target; - } - - public LivingEntity getTarget() { - return target; - } - - @Override - public boolean isSuccessful() { - return true; - } - } -} diff --git a/src/main/java/net/Indyuce/mmoitems/comp/mythicmobs/MythicMobsHook.java b/src/main/java/net/Indyuce/mmoitems/comp/mythicmobs/MythicMobsHook.java index 54646b64..70f86392 100644 --- a/src/main/java/net/Indyuce/mmoitems/comp/mythicmobs/MythicMobsHook.java +++ b/src/main/java/net/Indyuce/mmoitems/comp/mythicmobs/MythicMobsHook.java @@ -1,28 +1,27 @@ package net.Indyuce.mmoitems.comp.mythicmobs; -import java.util.logging.Level; - -import org.apache.commons.lang.Validate; -import org.bukkit.Bukkit; -import org.bukkit.event.EventHandler; -import org.bukkit.event.Listener; - import io.lumine.xikage.mythicmobs.MythicMobs; import io.lumine.xikage.mythicmobs.adapters.bukkit.BukkitItemStack; import io.lumine.xikage.mythicmobs.api.bukkit.events.MythicDropLoadEvent; -import io.lumine.xikage.mythicmobs.api.bukkit.events.MythicReloadedEvent; import io.lumine.xikage.mythicmobs.drops.Drop; import io.lumine.xikage.mythicmobs.drops.DropMetadata; import io.lumine.xikage.mythicmobs.drops.IMultiDrop; import io.lumine.xikage.mythicmobs.drops.LootBag; import io.lumine.xikage.mythicmobs.drops.droppables.ItemDrop; import io.lumine.xikage.mythicmobs.io.MythicLineConfig; +import io.lumine.xikage.mythicmobs.skills.SkillMetadata; import io.lumine.xikage.mythicmobs.skills.placeholders.Placeholder; import net.Indyuce.mmoitems.MMOItems; import net.Indyuce.mmoitems.api.Type; import net.Indyuce.mmoitems.api.droptable.item.DropItem; import net.Indyuce.mmoitems.api.droptable.item.MMOItemDropItem; import net.Indyuce.mmoitems.api.player.PlayerData; +import org.apache.commons.lang.Validate; +import org.bukkit.Bukkit; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; + +import java.util.logging.Level; public class MythicMobsHook implements Listener { @@ -36,9 +35,9 @@ public class MythicMobsHook implements Listener { * need to change something in MM compatibility and sent it back to MM devs */ public MythicMobsHook() { - MythicMobs.inst().getPlaceholderManager().register("mmoitems.skill", + /*MythicMobs.inst().getPlaceholderManager().register("mmoitems.skill", Placeholder.meta((metadata, arg) -> String.valueOf(PlayerData - .get(metadata.getCaster().getEntity().getUniqueId()).getAbilityData().getCachedModifier(arg)))); + .get(metadata.getCaster().getEntity().getUniqueId()).getAbilityData().getCachedModifier(arg))));*/ Bukkit.getPluginManager().registerEvents(this, MMOItems.plugin); // MMOItems.plugin.getCrafting().registerIngredient("mythicitem", config -> new MythicItemIngredient(config), // new ConditionalDisplay("&8" + AltChar.check + " &7#amount# #item#", "&c" + AltChar.cross + " &7#amount# #item#"), @@ -58,11 +57,29 @@ public class MythicMobsHook implements Listener { * register placeholders when MM is reloaded. the skill placeholder let players * retrieve cached ability values. */ - @EventHandler + /*@EventHandler public void b(MythicReloadedEvent event) { MythicMobs.inst().getPlaceholderManager().register("mmoitems.skill", Placeholder.meta((metadata, arg) -> String.valueOf(PlayerData .get(metadata.getCaster().getEntity().getUniqueId()).getAbilityData().getCachedModifier(arg)))); + }*/ + + private void registerSkillPlaceholders() { + + Placeholder.meta((meta, arg) -> { + + SkillMetadata skillMeta = (SkillMetadata) meta; + skillMeta.getVariables().get("MMOStats"); + + + + + } ); + + MythicMobs.inst().getPlaceholderManager().register("modifier", + Placeholder.meta((metadata, arg) -> String.valueOf(PlayerData + .get(metadata.getCaster().getEntity().getUniqueId()).getAbilityData().getCachedModifier(arg)))); + } public static class MMOItemsDrop extends Drop implements IMultiDrop { diff --git a/src/main/java/net/Indyuce/mmoitems/comp/mythicmobs/skill/MythicMobsAbility.java b/src/main/java/net/Indyuce/mmoitems/comp/mythicmobs/skill/MythicMobsAbility.java new file mode 100644 index 00000000..926e1d6b --- /dev/null +++ b/src/main/java/net/Indyuce/mmoitems/comp/mythicmobs/skill/MythicMobsAbility.java @@ -0,0 +1,76 @@ +package net.Indyuce.mmoitems.comp.mythicmobs.skill; + +import io.lumine.xikage.mythicmobs.MythicMobs; +import io.lumine.xikage.mythicmobs.adapters.AbstractEntity; +import io.lumine.xikage.mythicmobs.adapters.AbstractLocation; +import io.lumine.xikage.mythicmobs.adapters.bukkit.BukkitAdapter; +import io.lumine.xikage.mythicmobs.mobs.GenericCaster; +import io.lumine.xikage.mythicmobs.skills.Skill; +import io.lumine.xikage.mythicmobs.skills.SkillCaster; +import io.lumine.xikage.mythicmobs.skills.SkillMetadata; +import io.lumine.xikage.mythicmobs.skills.SkillTrigger; +import net.Indyuce.mmoitems.ability.Ability; +import net.Indyuce.mmoitems.api.ItemAttackMetadata; +import net.Indyuce.mmoitems.stat.data.AbilityData; +import org.apache.commons.lang.Validate; +import org.bukkit.configuration.file.FileConfiguration; +import org.bukkit.entity.LivingEntity; + +import java.util.HashSet; +import java.util.Optional; + +public class MythicMobsAbility extends Ability { + private final Skill skill; + + public MythicMobsAbility(String id, FileConfiguration config) { + super(id, config.getString("name"), CastingMode.ON_HIT, CastingMode.WHEN_HIT, CastingMode.LEFT_CLICK, CastingMode.RIGHT_CLICK, CastingMode.SHIFT_LEFT_CLICK, CastingMode.SHIFT_RIGHT_CLICK); + + String skillName = config.getString("mythicmobs-skill-id"); + Validate.notNull(skillName, "Could not find MM skill name"); + + Optional opt = MythicMobs.inst().getSkillManager().getSkill(skillName); + Validate.isTrue(opt.isPresent(), "Could not find MM skill " + skillName); + skill = opt.get(); + + addModifier("cooldown", 10); + addModifier("mana", 0); + addModifier("stamina", 0); + + for (String mod : config.getKeys(false)) + if (!mod.equals("name") && !mod.equals("mythicmobs-skill-id") && !mod.equals("self-only")) + addModifier(mod.toLowerCase().replace("_", "-").replace(" ", "-"), config.getInt(mod)); + } + + public String getInternalName() { + return skill.getInternalName(); + } + + @Override + public void whenCast(ItemAttackMetadata attackMeta, MythicMobsAbilityMetadata ability) { + LivingEntity target = ability.getTarget(); + + // TODO what's the difference between trigger and caster. + AbstractEntity trigger = BukkitAdapter.adapt(attackMeta.getDamager()); + SkillCaster caster = new GenericCaster(trigger); + + HashSet targetEntities = new HashSet<>(); + HashSet targetLocations = new HashSet<>(); + + targetEntities.add(BukkitAdapter.adapt(target)); + + SkillMetadata data = new SkillMetadata(SkillTrigger.API, caster, trigger, BukkitAdapter.adapt(attackMeta.getDamager().getEyeLocation()), targetEntities, targetLocations, 1); + + // Stats are cached inside a variable. + /*data.getVariables().putObject();*/ + + if (skill.usable(data, SkillTrigger.API)) + skill.execute(data); + else + attackMeta.setSuccessful(false); + } + + @Override + public MythicMobsAbilityMetadata canBeCast(ItemAttackMetadata attackMeta, LivingEntity target, AbilityData data) { + return new MythicMobsAbilityMetadata(data, target); + } +} diff --git a/src/main/java/net/Indyuce/mmoitems/comp/mythicmobs/skill/MythicMobsAbilityMetadata.java b/src/main/java/net/Indyuce/mmoitems/comp/mythicmobs/skill/MythicMobsAbilityMetadata.java new file mode 100644 index 00000000..e6c1b84a --- /dev/null +++ b/src/main/java/net/Indyuce/mmoitems/comp/mythicmobs/skill/MythicMobsAbilityMetadata.java @@ -0,0 +1,24 @@ +package net.Indyuce.mmoitems.comp.mythicmobs.skill; + +import net.Indyuce.mmoitems.ability.AbilityMetadata; +import net.Indyuce.mmoitems.stat.data.AbilityData; +import org.bukkit.entity.LivingEntity; + +public class MythicMobsAbilityMetadata extends AbilityMetadata { + private final LivingEntity target; + + public MythicMobsAbilityMetadata(AbilityData ability, LivingEntity target) { + super(ability); + + this.target = target; + } + + public LivingEntity getTarget() { + return target; + } + + @Override + public boolean isSuccessful() { + return true; + } +} \ No newline at end of file diff --git a/src/main/java/net/Indyuce/mmoitems/comp/rpg/HeroesHook.java b/src/main/java/net/Indyuce/mmoitems/comp/rpg/HeroesHook.java index 39693255..366b354d 100644 --- a/src/main/java/net/Indyuce/mmoitems/comp/rpg/HeroesHook.java +++ b/src/main/java/net/Indyuce/mmoitems/comp/rpg/HeroesHook.java @@ -7,22 +7,26 @@ import com.herocraftonline.heroes.api.events.HeroChangeLevelEvent; import com.herocraftonline.heroes.characters.Hero; import com.herocraftonline.heroes.characters.skill.SkillType; import io.lumine.mythic.lib.MythicLib; -import io.lumine.mythic.lib.api.AttackResult; -import io.lumine.mythic.lib.api.DamageHandler; -import io.lumine.mythic.lib.api.DamageType; -import io.lumine.mythic.lib.api.RegisteredAttack; +import io.lumine.mythic.lib.api.player.EquipmentSlot; +import io.lumine.mythic.lib.api.player.MMOPlayerData; +import io.lumine.mythic.lib.damage.AttackHandler; +import io.lumine.mythic.lib.damage.AttackMetadata; +import io.lumine.mythic.lib.damage.DamageMetadata; +import io.lumine.mythic.lib.damage.DamageType; import net.Indyuce.mmoitems.ItemStats; import net.Indyuce.mmoitems.api.player.PlayerData; import net.Indyuce.mmoitems.api.player.RPGPlayer; import org.bukkit.entity.Entity; +import org.bukkit.entity.Player; import org.bukkit.event.EventHandler; import org.bukkit.event.Listener; import java.util.HashMap; import java.util.Map; +import java.util.Set; import java.util.stream.Collectors; -public class HeroesHook implements RPGHandler, Listener, DamageHandler { +public class HeroesHook implements RPGHandler, Listener, AttackHandler { private final Map damages = new HashMap<>(); public HeroesHook() { @@ -34,15 +38,18 @@ public class HeroesHook implements RPGHandler, Listener, DamageHandler { } @Override - public boolean hasDamage(Entity entity) { - return Heroes.getInstance().getDamageManager().isSpellTarget(entity); + public boolean isAttacked(Entity entity) { + SkillUseInfo info = Heroes.getInstance().getDamageManager().getSpellTargetInfo(entity); + return info != null && info.getCharacter().getEntity() instanceof Player; } @Override - public RegisteredAttack getDamage(Entity entity) { + public AttackMetadata getAttack(Entity entity) { SkillUseInfo info = Heroes.getInstance().getDamageManager().getSpellTargetInfo(entity); - return new RegisteredAttack(new AttackResult(true, 0, info.getSkill().getTypes().stream().filter(damages::containsKey) - .map(damages::get).collect(Collectors.toSet())), info.getCharacter().getEntity()); + Player player = (Player) info.getCharacter().getEntity(); + Set types = info.getSkill().getTypes().stream().filter(damages::containsKey).map(damages::get).collect(Collectors.toSet()); + DamageMetadata damageMeta = new DamageMetadata(0, types.toArray(new DamageType[0])); + return new AttackMetadata(damageMeta, MMOPlayerData.get(player).getStatMap().cache(EquipmentSlot.MAIN_HAND)); } @Override diff --git a/src/main/java/net/Indyuce/mmoitems/comp/rpg/SkillAPIHook.java b/src/main/java/net/Indyuce/mmoitems/comp/rpg/SkillAPIHook.java index 6742f7e7..171c8080 100644 --- a/src/main/java/net/Indyuce/mmoitems/comp/rpg/SkillAPIHook.java +++ b/src/main/java/net/Indyuce/mmoitems/comp/rpg/SkillAPIHook.java @@ -5,12 +5,15 @@ import com.sucy.skill.api.event.PlayerLevelUpEvent; import com.sucy.skill.api.event.SkillDamageEvent; import com.sucy.skill.api.player.PlayerData; import io.lumine.mythic.lib.MythicLib; -import io.lumine.mythic.lib.api.AttackResult; -import io.lumine.mythic.lib.api.DamageHandler; -import io.lumine.mythic.lib.api.DamageType; -import io.lumine.mythic.lib.api.RegisteredAttack; +import io.lumine.mythic.lib.api.player.EquipmentSlot; +import io.lumine.mythic.lib.api.player.MMOPlayerData; +import io.lumine.mythic.lib.damage.AttackHandler; +import io.lumine.mythic.lib.damage.AttackMetadata; +import io.lumine.mythic.lib.damage.DamageMetadata; +import io.lumine.mythic.lib.damage.DamageType; import net.Indyuce.mmoitems.api.player.RPGPlayer; import org.bukkit.entity.Entity; +import org.bukkit.entity.Player; import org.bukkit.event.EventHandler; import org.bukkit.event.EventPriority; import org.bukkit.event.Listener; @@ -19,8 +22,8 @@ import org.bukkit.event.entity.EntityDamageByEntityEvent; import java.util.HashMap; import java.util.Map; -public class SkillAPIHook implements RPGHandler, Listener, DamageHandler { - private final Map damageInfo = new HashMap<>(); +public class SkillAPIHook implements RPGHandler, Listener, AttackHandler { + private final Map damageInfo = new HashMap<>(); public SkillAPIHook() { MythicLib.plugin.getDamage().registerHandler(this); @@ -32,18 +35,23 @@ public class SkillAPIHook implements RPGHandler, Listener, DamageHandler { } @Override - public RegisteredAttack getDamage(Entity entity) { - return damageInfo.get(entity.getEntityId()); + public boolean isAttacked(Entity entity) { + return damageInfo.containsKey(entity.getEntityId()); } @Override - public boolean hasDamage(Entity entity) { - return damageInfo.containsKey(entity.getEntityId()); + public AttackMetadata getAttack(Entity entity) { + return damageInfo.get(entity.getEntityId()); } @EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true) public void a(SkillDamageEvent event) { - damageInfo.put(event.getTarget().getEntityId(), new RegisteredAttack(new AttackResult(event.getDamage(), DamageType.SKILL), event.getDamager())); + if (!(event.getDamager() instanceof Player)) + return; + + DamageMetadata damageMeta = new DamageMetadata(event.getDamage(), DamageType.SKILL); + AttackMetadata attackMeta = new AttackMetadata(damageMeta, MMOPlayerData.get(event.getDamager().getUniqueId()).getStatMap().cache(EquipmentSlot.OTHER)); + damageInfo.put(event.getTarget().getEntityId(), attackMeta); } @EventHandler(priority = EventPriority.MONITOR) diff --git a/src/main/java/net/Indyuce/mmoitems/gui/edition/AbilityEdition.java b/src/main/java/net/Indyuce/mmoitems/gui/edition/AbilityEdition.java index d1bb4338..cde3e456 100644 --- a/src/main/java/net/Indyuce/mmoitems/gui/edition/AbilityEdition.java +++ b/src/main/java/net/Indyuce/mmoitems/gui/edition/AbilityEdition.java @@ -3,8 +3,8 @@ package net.Indyuce.mmoitems.gui.edition; import net.Indyuce.mmoitems.ItemStats; import net.Indyuce.mmoitems.MMOItems; import net.Indyuce.mmoitems.MMOUtils; -import net.Indyuce.mmoitems.api.ability.Ability; -import net.Indyuce.mmoitems.api.ability.Ability.CastingMode; +import net.Indyuce.mmoitems.ability.Ability; +import net.Indyuce.mmoitems.ability.Ability.CastingMode; import net.Indyuce.mmoitems.api.edition.StatEdition; import net.Indyuce.mmoitems.api.item.template.MMOItemTemplate; import net.Indyuce.mmoitems.api.util.NumericStatFormula; diff --git a/src/main/java/net/Indyuce/mmoitems/gui/edition/AbilityListEdition.java b/src/main/java/net/Indyuce/mmoitems/gui/edition/AbilityListEdition.java index 07e4f109..bacb7e73 100644 --- a/src/main/java/net/Indyuce/mmoitems/gui/edition/AbilityListEdition.java +++ b/src/main/java/net/Indyuce/mmoitems/gui/edition/AbilityListEdition.java @@ -15,8 +15,8 @@ import org.bukkit.inventory.meta.ItemMeta; import net.Indyuce.mmoitems.MMOItems; import net.Indyuce.mmoitems.MMOUtils; -import net.Indyuce.mmoitems.api.ability.Ability; -import net.Indyuce.mmoitems.api.ability.Ability.CastingMode; +import net.Indyuce.mmoitems.ability.Ability; +import net.Indyuce.mmoitems.ability.Ability.CastingMode; import net.Indyuce.mmoitems.api.item.template.MMOItemTemplate; import net.Indyuce.mmoitems.api.util.NumericStatFormula; import io.lumine.mythic.lib.MythicLib; diff --git a/src/main/java/net/Indyuce/mmoitems/listener/ElementListener.java b/src/main/java/net/Indyuce/mmoitems/listener/ElementListener.java index 7485621f..b7cd8af0 100644 --- a/src/main/java/net/Indyuce/mmoitems/listener/ElementListener.java +++ b/src/main/java/net/Indyuce/mmoitems/listener/ElementListener.java @@ -10,6 +10,7 @@ import org.bukkit.event.EventPriority; import org.bukkit.event.Listener; import org.bukkit.event.entity.EntityDamageByEntityEvent; +// TODO refactor this shit public class ElementListener implements Listener { private static final Map WATER_WEAKNESS = new HashMap<>(); diff --git a/src/main/java/net/Indyuce/mmoitems/listener/ItemUse.java b/src/main/java/net/Indyuce/mmoitems/listener/ItemUse.java index 495e94fc..9e34324f 100644 --- a/src/main/java/net/Indyuce/mmoitems/listener/ItemUse.java +++ b/src/main/java/net/Indyuce/mmoitems/listener/ItemUse.java @@ -1,12 +1,14 @@ package net.Indyuce.mmoitems.listener; import io.lumine.mythic.lib.MythicLib; -import io.lumine.mythic.lib.api.DamageType; import io.lumine.mythic.lib.api.item.NBTItem; import io.lumine.mythic.lib.api.player.EquipmentSlot; +import io.lumine.mythic.lib.api.stat.StatMap; +import io.lumine.mythic.lib.damage.DamageMetadata; +import io.lumine.mythic.lib.damage.DamageType; import net.Indyuce.mmoitems.MMOItems; import net.Indyuce.mmoitems.MMOUtils; -import net.Indyuce.mmoitems.api.ItemAttackResult; +import net.Indyuce.mmoitems.api.ItemAttackMetadata; import net.Indyuce.mmoitems.api.Type; import net.Indyuce.mmoitems.api.TypeSet; import net.Indyuce.mmoitems.api.interaction.*; @@ -16,7 +18,6 @@ import net.Indyuce.mmoitems.api.interaction.weapon.untargeted.Staff; import net.Indyuce.mmoitems.api.interaction.weapon.untargeted.UntargetedWeapon; import net.Indyuce.mmoitems.api.interaction.weapon.untargeted.UntargetedWeapon.WeaponType; import net.Indyuce.mmoitems.api.player.PlayerData; -import net.Indyuce.mmoitems.api.player.PlayerStats.CachedStats; import net.Indyuce.mmoitems.api.util.message.Message; import org.bukkit.ChatColor; import org.bukkit.GameMode; @@ -118,7 +119,6 @@ public class ItemUse implements Listener { return; Player player = (Player) event.getDamager(); - CachedStats stats = null; /* * Must apply attack conditions before apply any effects. the event must @@ -126,7 +126,7 @@ public class ItemUse implements Listener { */ PlayerData playerData = PlayerData.get(player); NBTItem item = MythicLib.plugin.getVersion().getWrapper().getNBTItem(player.getInventory().getItemInMainHand()); - ItemAttackResult result = new ItemAttackResult(event.getDamage(), DamageType.WEAPON, DamageType.PHYSICAL); + ItemAttackMetadata attackMeta = null; if (item.hasType() && Type.get(item.getType()) != Type.BLOCK) { Weapon weapon = new Weapon(playerData, item); @@ -141,16 +141,19 @@ public class ItemUse implements Listener { return; } - weapon.handleTargetedAttack(stats = playerData.getStats().newTemporary(EquipmentSlot.MAIN_HAND), target, result); - if (!result.isSuccessful()) { + StatMap.CachedStatMap cachedStatMap = playerData.getMMOPlayerData().getStatMap().cache(EquipmentSlot.MAIN_HAND); + attackMeta = new ItemAttackMetadata(new DamageMetadata(event.getDamage(), DamageType.WEAPON, DamageType.PHYSICAL), cachedStatMap); + if (!weapon.handleTargetedAttack(attackMeta, target).isSuccessful()) { event.setCancelled(true); return; } } // Cast on-hit abilities and add the extra damage to the damage event - result.applyEffects(stats == null ? playerData.getStats().newTemporary(EquipmentSlot.MAIN_HAND) : stats, item, target); - event.setDamage(result.getDamage()); + attackMeta.applyEffects(item, target); + + // Finally update Bukkit event + event.setDamage(attackMeta.getDamage().getDamage()); } /* diff --git a/src/main/java/net/Indyuce/mmoitems/listener/PlayerListener.java b/src/main/java/net/Indyuce/mmoitems/listener/PlayerListener.java index c634bd3d..925b9323 100644 --- a/src/main/java/net/Indyuce/mmoitems/listener/PlayerListener.java +++ b/src/main/java/net/Indyuce/mmoitems/listener/PlayerListener.java @@ -1,17 +1,15 @@ package net.Indyuce.mmoitems.listener; import io.lumine.mythic.lib.MythicLib; -import io.lumine.mythic.lib.api.DamageType; import io.lumine.mythic.lib.api.item.NBTItem; import io.lumine.mythic.lib.api.player.EquipmentSlot; import io.lumine.mythic.utils.Schedulers; import io.lumine.mythic.utils.events.extra.ArmorEquipEvent; import net.Indyuce.mmoitems.MMOItems; import net.Indyuce.mmoitems.MMOUtils; -import net.Indyuce.mmoitems.api.ItemAttackResult; +import net.Indyuce.mmoitems.ability.Ability.CastingMode; import net.Indyuce.mmoitems.api.SoulboundInfo; import net.Indyuce.mmoitems.api.Type; -import net.Indyuce.mmoitems.api.ability.Ability.CastingMode; import net.Indyuce.mmoitems.api.interaction.util.InteractItem; import net.Indyuce.mmoitems.api.interaction.weapon.Weapon; import net.Indyuce.mmoitems.api.player.PlayerData; @@ -62,7 +60,7 @@ public class PlayerListener implements Listener { return; Player player = (Player) event.getEntity(); - PlayerData.get(player).castAbilities(damager, new ItemAttackResult(event.getDamage(), DamageType.SKILL), CastingMode.WHEN_HIT); + PlayerData.get(player).castAbilities(damager, CastingMode.WHEN_HIT); } @EventHandler(priority = EventPriority.LOW) @@ -72,9 +70,8 @@ public class PlayerListener implements Listener { Player player = event.getPlayer(); boolean left = event.getAction() == Action.LEFT_CLICK_AIR || event.getAction() == Action.LEFT_CLICK_BLOCK; - PlayerData.get(player).castAbilities(null, new ItemAttackResult(true, DamageType.SKILL), - player.isSneaking() ? (left ? CastingMode.SHIFT_LEFT_CLICK : CastingMode.SHIFT_RIGHT_CLICK) - : (left ? CastingMode.LEFT_CLICK : CastingMode.RIGHT_CLICK)); + CastingMode castMode = player.isSneaking() ? (left ? CastingMode.SHIFT_LEFT_CLICK : CastingMode.SHIFT_RIGHT_CLICK) : (left ? CastingMode.LEFT_CLICK : CastingMode.RIGHT_CLICK); + PlayerData.get(player).castAbilities(null, castMode); } /* diff --git a/src/main/java/net/Indyuce/mmoitems/manager/AbilityManager.java b/src/main/java/net/Indyuce/mmoitems/manager/AbilityManager.java index c8b77a50..31e154e2 100644 --- a/src/main/java/net/Indyuce/mmoitems/manager/AbilityManager.java +++ b/src/main/java/net/Indyuce/mmoitems/manager/AbilityManager.java @@ -1,8 +1,8 @@ package net.Indyuce.mmoitems.manager; import net.Indyuce.mmoitems.MMOItems; -import net.Indyuce.mmoitems.api.ability.Ability; -import net.Indyuce.mmoitems.comp.mythicmobs.MythicMobsAbility; +import net.Indyuce.mmoitems.ability.Ability; +import net.Indyuce.mmoitems.comp.mythicmobs.skill.MythicMobsAbility; import org.apache.commons.lang.Validate; import org.bukkit.Bukkit; import org.bukkit.configuration.file.YamlConfiguration; diff --git a/src/main/java/net/Indyuce/mmoitems/manager/ConfigManager.java b/src/main/java/net/Indyuce/mmoitems/manager/ConfigManager.java index f1a15566..3e1a780c 100644 --- a/src/main/java/net/Indyuce/mmoitems/manager/ConfigManager.java +++ b/src/main/java/net/Indyuce/mmoitems/manager/ConfigManager.java @@ -6,8 +6,8 @@ import net.Indyuce.mmoitems.MMOItems; import net.Indyuce.mmoitems.MMOUtils; import net.Indyuce.mmoitems.api.ConfigFile; import net.Indyuce.mmoitems.api.ReforgeOptions; -import net.Indyuce.mmoitems.api.ability.Ability; -import net.Indyuce.mmoitems.api.ability.Ability.CastingMode; +import net.Indyuce.mmoitems.ability.Ability; +import net.Indyuce.mmoitems.ability.Ability.CastingMode; import net.Indyuce.mmoitems.api.item.util.ConfigItem; import net.Indyuce.mmoitems.api.item.util.ConfigItems; import net.Indyuce.mmoitems.api.util.NumericStatFormula; diff --git a/src/main/java/net/Indyuce/mmoitems/manager/EntityManager.java b/src/main/java/net/Indyuce/mmoitems/manager/EntityManager.java index 25149d84..149f1935 100644 --- a/src/main/java/net/Indyuce/mmoitems/manager/EntityManager.java +++ b/src/main/java/net/Indyuce/mmoitems/manager/EntityManager.java @@ -1,14 +1,14 @@ package net.Indyuce.mmoitems.manager; -import io.lumine.mythic.lib.api.DamageType; import io.lumine.mythic.lib.api.item.NBTItem; -import net.Indyuce.mmoitems.ItemStats; +import io.lumine.mythic.lib.api.stat.StatMap; +import io.lumine.mythic.lib.damage.DamageMetadata; +import io.lumine.mythic.lib.damage.DamageType; import net.Indyuce.mmoitems.MMOItems; -import net.Indyuce.mmoitems.api.ItemAttackResult; +import net.Indyuce.mmoitems.api.ItemAttackMetadata; import net.Indyuce.mmoitems.api.interaction.projectile.ArrowParticles; import net.Indyuce.mmoitems.api.interaction.projectile.EntityData; import net.Indyuce.mmoitems.api.interaction.projectile.ProjectileData; -import net.Indyuce.mmoitems.api.player.PlayerStats.CachedStats; import org.bukkit.Bukkit; import org.bukkit.enchantments.Enchantment; import org.bukkit.entity.Arrow; @@ -36,7 +36,7 @@ public class EntityManager implements Listener { private final WeakHashMap projectiles = new WeakHashMap<>(); - public void registerCustomProjectile(NBTItem sourceItem, CachedStats stats, Entity entity, boolean customWeapon) { + public void registerCustomProjectile(NBTItem sourceItem, StatMap.CachedStatMap stats, Entity entity, boolean customWeapon) { registerCustomProjectile(sourceItem, stats, entity, customWeapon, 1); } @@ -45,11 +45,12 @@ public class EntityManager implements Listener { * * @param sourceItem Item used to shoot the projectile * @param stats Cached stats of the player shooting the projectile - * @param entity - * @param customWeapon - * @param damageCoefficient + * @param entity The custom entity + * @param customWeapon Is the source weapon is a custom item + * @param damageCoefficient The damage coefficient. For bows, this is basically the pull force. + * For tridents or anything else this is always set to 1 */ - public void registerCustomProjectile(NBTItem sourceItem, CachedStats stats, Entity entity, boolean customWeapon, double damageCoefficient) { + public void registerCustomProjectile(NBTItem sourceItem, StatMap.CachedStatMap stats, Entity entity, boolean customWeapon, double damageCoefficient) { /* * By default damage is set to minecraft's default 7. It is then @@ -58,8 +59,10 @@ public class EntityManager implements Listener { * * For tridents or crossbows, damage coefficient is always 1 */ - double damage = stats.getStat(ItemStats.ATTACK_DAMAGE); - stats.setStat(ItemStats.ATTACK_DAMAGE, (damage == 0 ? 7 : damage) * damageCoefficient); + double damage = stats.getStat("ATTACK_DAMAGE"); + damage = damage == 0 ? 7 : damage * damageCoefficient; + ItemAttackMetadata attackMeta = new ItemAttackMetadata(new DamageMetadata(damage, DamageType.WEAPON, DamageType.PHYSICAL, DamageType.PROJECTILE), stats); + stats.setStat("ATTACK_DAMAGE", damage); /* * Load arrow particles if the entity is an arrow and if the item has @@ -69,7 +72,7 @@ public class EntityManager implements Listener { if (entity instanceof Arrow && sourceItem.hasTag("MMOITEMS_ARROW_PARTICLES")) new ArrowParticles((Arrow) entity, sourceItem); - projectiles.put(entity.getEntityId(), new ProjectileData(sourceItem, stats, customWeapon)); + projectiles.put(entity.getEntityId(), new ProjectileData(sourceItem, attackMeta, customWeapon)); } public void registerCustomEntity(Entity entity, EntityData data) { @@ -109,14 +112,14 @@ public class EntityManager implements Listener { * Projectile Damage and Effects * * TODO when throwing a trident, on hit abilities dont cast half - * of the time because you don't hold the item anymore, therefore - * the ability does not register. - * To fix that, not only cache the player statistics using CachedStats - * but also the player abilities as well as elemental stats. in fact - * a lot of extra stats need to be cached when a ranged attack is delivered. + * of the time because you don't hold the item anymore, therefore + * the ability does not register. + * To fix that, not only cache the player statistics using CachedStats + * but also the player abilities as well as elemental stats. In fact + * a lot of extra stats need to be cached when a ranged attack is delivered. * * TODO This bug could also be exploited using a bow, by holding another item - * after shooting an arrow!! + * after shooting an arrow!! */ @EventHandler(ignoreCancelled = true) public void b(EntityDamageByEntityEvent event) { @@ -129,23 +132,22 @@ public class EntityManager implements Listener { ProjectileData data = getProjectileData(projectile); LivingEntity target = (LivingEntity) event.getEntity(); - CachedStats stats = data.getPlayerStats(); - ItemAttackResult result = new ItemAttackResult(data.isCustomWeapon() ? stats.getStat(ItemStats.ATTACK_DAMAGE) : event.getDamage(), - DamageType.WEAPON, DamageType.PROJECTILE, DamageType.PHYSICAL).applyOnHitEffects(stats, target); + // Apply on hit effects + data.getAttackMetadata().applyOnHitEffects(target); // Apply power vanilla enchant if (projectile instanceof Arrow && data.getSourceItem().getItem().hasItemMeta() && data.getSourceItem().getItem().getItemMeta().getEnchants().containsKey(Enchantment.ARROW_DAMAGE)) - result.multiplyDamage(1.25 + (.25 * data.getSourceItem().getItem().getItemMeta().getEnchantLevel(Enchantment.ARROW_DAMAGE))); + data.getAttackMetadata().getDamage().multiply(1.25 + (.25 * data.getSourceItem().getItem().getItemMeta().getEnchantLevel(Enchantment.ARROW_DAMAGE)), DamageType.WEAPON); // Apply MMOItems specific modifications if (data.isCustomWeapon()) { data.applyPotionEffects(target); - result.applyElementalEffects(stats, data.getSourceItem(), target); + data.getAttackMetadata().applyElementalEffects(data.getSourceItem(), target); } - event.setDamage(result.getDamage()); + event.setDamage(data.getAttackMetadata().getDamage().getDamage()); unregisterCustomProjectile(projectile); } } \ No newline at end of file diff --git a/src/main/java/net/Indyuce/mmoitems/stat/Abilities.java b/src/main/java/net/Indyuce/mmoitems/stat/Abilities.java index 3a51a5bc..fb0cd2d0 100644 --- a/src/main/java/net/Indyuce/mmoitems/stat/Abilities.java +++ b/src/main/java/net/Indyuce/mmoitems/stat/Abilities.java @@ -13,11 +13,10 @@ import org.bukkit.Material; import org.bukkit.configuration.ConfigurationSection; import org.bukkit.event.inventory.InventoryClickEvent; -import net.Indyuce.mmoitems.ItemStats; import net.Indyuce.mmoitems.MMOItems; import net.Indyuce.mmoitems.MMOUtils; -import net.Indyuce.mmoitems.api.ability.Ability; -import net.Indyuce.mmoitems.api.ability.Ability.CastingMode; +import net.Indyuce.mmoitems.ability.Ability; +import net.Indyuce.mmoitems.ability.Ability.CastingMode; import net.Indyuce.mmoitems.api.item.build.ItemStackBuilder; import net.Indyuce.mmoitems.api.item.mmoitem.ReadMMOItem; import net.Indyuce.mmoitems.api.util.NumericStatFormula; diff --git a/src/main/java/net/Indyuce/mmoitems/stat/data/AbilityData.java b/src/main/java/net/Indyuce/mmoitems/stat/data/AbilityData.java index 56835329..3dd08928 100644 --- a/src/main/java/net/Indyuce/mmoitems/stat/data/AbilityData.java +++ b/src/main/java/net/Indyuce/mmoitems/stat/data/AbilityData.java @@ -10,8 +10,8 @@ import org.bukkit.configuration.ConfigurationSection; import com.google.gson.JsonObject; import net.Indyuce.mmoitems.MMOItems; -import net.Indyuce.mmoitems.api.ability.Ability; -import net.Indyuce.mmoitems.api.ability.Ability.CastingMode; +import net.Indyuce.mmoitems.ability.Ability; +import net.Indyuce.mmoitems.ability.Ability.CastingMode; public class AbilityData { private final Ability ability; diff --git a/src/main/java/net/Indyuce/mmoitems/stat/data/random/RandomAbilityData.java b/src/main/java/net/Indyuce/mmoitems/stat/data/random/RandomAbilityData.java index 4a37c949..cc65bfb5 100644 --- a/src/main/java/net/Indyuce/mmoitems/stat/data/random/RandomAbilityData.java +++ b/src/main/java/net/Indyuce/mmoitems/stat/data/random/RandomAbilityData.java @@ -8,8 +8,8 @@ import org.apache.commons.lang.Validate; import org.bukkit.configuration.ConfigurationSection; import net.Indyuce.mmoitems.MMOItems; -import net.Indyuce.mmoitems.api.ability.Ability; -import net.Indyuce.mmoitems.api.ability.Ability.CastingMode; +import net.Indyuce.mmoitems.ability.Ability; +import net.Indyuce.mmoitems.ability.Ability.CastingMode; import net.Indyuce.mmoitems.api.item.build.MMOItemBuilder; import net.Indyuce.mmoitems.api.util.NumericStatFormula; import net.Indyuce.mmoitems.stat.data.AbilityData;