!insignificant api change

This commit is contained in:
Indyuce 2021-08-10 00:35:23 +02:00
parent 37cbccde05
commit 295368ad06
7 changed files with 129 additions and 65 deletions

View File

@ -1,5 +1,17 @@
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;
@ -15,17 +27,7 @@ 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.api.item.NBTItem;
import javax.annotation.Nullable;
public class Shulker_Missile extends Ability implements Listener {
public Shulker_Missile() {
@ -63,19 +65,18 @@ public class Shulker_Missile extends Ability implements Listener {
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,
MMOItems.plugin.getEntities().registerCustomEntity(shulkerBullet, new ShulkerMissileEntityData(
new AttackResult(ability.getModifier("damage"), DamageType.SKILL, DamageType.MAGIC, DamageType.PROJECTILE),
ability.getModifier("effect-duration"));
ability.getModifier("effect-duration")));
new BukkitRunnable() {
double ti = 0;
public void run() {
ti++;
if (shulkerBullet.isDead() || ti >= duration * 20) {
if (shulkerBullet.isDead() || ti++ >= duration * 20) {
shulkerBullet.remove();
cancel();
}
shulkerBullet.setVelocity(vec);
} else
shulkerBullet.setVelocity(vec);
}
}.runTaskTimer(MMOItems.plugin, 0, 1);
}
@ -89,31 +90,30 @@ public class Shulker_Missile extends Ability implements Listener {
LivingEntity entity = (LivingEntity) event.getEntity();
if (!MMOItems.plugin.getEntities().isCustomEntity(damager))
return;
if (!MMOUtils.canDamage(entity)) {
event.setCancelled(true);
return;
}
Object[] data = MMOItems.plugin.getEntities().getEntityData(damager);
AttackResult result = (AttackResult) data[0];
double duration = (double) data[1] * 20;
ShulkerMissileEntityData data = (ShulkerMissileEntityData) MMOItems.plugin.getEntities().getEntityData(damager);
// void spirit
if (data.length > 2)
((ItemAttackResult) result).applyEffects((CachedStats) data[2], (NBTItem) data[3], entity);
// Void spirit
if (data.isWeaponAttack())
((ItemAttackResult) data.result).applyEffects(data.stats, data.weapon, entity);
event.setDamage(result.getDamage());
event.setDamage(data.result.getDamage());
new BukkitRunnable() {
final Location loc = entity.getLocation();
double y = 0;
public void run() {
// potion effect applies after the damage...
// must have a "nanodelay"
// 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) duration, 0));
entity.addPotionEffect(new PotionEffect(PotionEffectType.LEVITATION, (int) (data.duration * 20), 0));
}
for (int j1 = 0; j1 < 3; j1++) {
@ -130,4 +130,46 @@ public class Shulker_Missile extends Ability implements Listener {
}.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;
}
}
}

View File

@ -71,14 +71,11 @@ public class ItemAttackResult extends AttackResult {
}
/**
* Applies weapon specific on-hit effects like elemental damage.
* 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
* @param stats Player doing the attack
* @param item The item being used
* @param target The entity target
* @return The unedited attack result
*/
@SuppressWarnings("UnusedReturnValue")

View File

@ -1,4 +1,4 @@
package net.Indyuce.mmoitems.api;
package net.Indyuce.mmoitems.api.interaction.projectile;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;

View File

@ -0,0 +1,4 @@
package net.Indyuce.mmoitems.api.interaction.projectile;
public interface EntityData {
}

View File

@ -1,4 +1,4 @@
package net.Indyuce.mmoitems.api;
package net.Indyuce.mmoitems.api.interaction.projectile;
import org.bukkit.entity.LivingEntity;
import org.bukkit.potion.PotionEffectType;

View File

@ -1,17 +1,17 @@
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 org.bukkit.Sound;
import org.bukkit.entity.EntityType;
import org.bukkit.entity.ShulkerBullet;
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.player.PlayerStats.CachedStats;
import io.lumine.mythic.lib.api.DamageType;
import io.lumine.mythic.lib.api.item.NBTItem;
public class VoidSpirit implements StaffAttackHandler {
@Override
@ -32,6 +32,6 @@ public class VoidSpirit implements StaffAttackHandler {
shulkerBullet.setVelocity(vec);
}
}.runTaskTimer(MMOItems.plugin, 0, 1);
MMOItems.plugin.getEntities().registerCustomEntity(shulkerBullet, new ItemAttackResult(attackDamage, DamageType.WEAPON, DamageType.MAGIC), 0., stats, nbt);
MMOItems.plugin.getEntities().registerCustomEntity(shulkerBullet, new Shulker_Missile.ShulkerMissileEntityData(new ItemAttackResult(attackDamage, DamageType.WEAPON, DamageType.MAGIC), stats, nbt));
}
}

View File

@ -4,9 +4,10 @@ import io.lumine.mythic.lib.api.DamageType;
import io.lumine.mythic.lib.api.item.NBTItem;
import net.Indyuce.mmoitems.ItemStats;
import net.Indyuce.mmoitems.MMOItems;
import net.Indyuce.mmoitems.api.ArrowParticles;
import net.Indyuce.mmoitems.api.ItemAttackResult;
import net.Indyuce.mmoitems.api.ProjectileData;
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;
@ -26,12 +27,12 @@ import java.util.WeakHashMap;
public class EntityManager implements Listener {
/*
* entity data used by abilities or staff attacks that utilize entities like
* evoker fangs or shulker missiles. it can correspond to the damage the
/**
* Entity data used by abilities or staff attacks that utilize entities like
* evoker fangs or shulker missiles. It can correspond to the damage the
* entity is supposed to deal, etc
*/
private final Map<Integer, Object[]> entities = new HashMap<>();
private final Map<Integer, EntityData> entities = new HashMap<>();
private final WeakHashMap<Integer, ProjectileData> projectiles = new WeakHashMap<>();
@ -39,19 +40,30 @@ public class EntityManager implements Listener {
registerCustomProjectile(sourceItem, stats, entity, customWeapon, 1);
}
/**
* Registers a custom projectile
*
* @param sourceItem Item used to shoot the projectile
* @param stats Cached stats of the player shooting the projectile
* @param entity
* @param customWeapon
* @param damageCoefficient
*/
public void registerCustomProjectile(NBTItem sourceItem, CachedStats stats, Entity entity, boolean customWeapon, double damageCoefficient) {
/*
* if damage is null, then it uses the default minecraft bow damage.
* it's then multiplied by the damage coefficient which corresponds for
* bows to the pull force just like vanilla. it does not work with
* tridents
* By default damage is set to minecraft's default 7. It is then
* multiplied by the coefficient proportionnal to the pull force.
* 1 corresponds to a fully pulled bow just like in vanilla MC.
*
* 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);
/*
* load arrow particles if the entity is an arrow and if the item has
* arrow particles. currently projectiles are only arrows so there is no
* Load arrow particles if the entity is an arrow and if the item has
* arrow particles. Currently projectiles are only arrows so there is no
* problem with other projectiles like snowballs etc.
*/
if (entity instanceof Arrow && sourceItem.hasTag("MMOITEMS_ARROW_PARTICLES"))
@ -60,7 +72,7 @@ public class EntityManager implements Listener {
projectiles.put(entity.getEntityId(), new ProjectileData(sourceItem, stats, customWeapon));
}
public void registerCustomEntity(Entity entity, Object... data) {
public void registerCustomEntity(Entity entity, EntityData data) {
entities.put(entity.getEntityId(), data);
}
@ -76,7 +88,7 @@ public class EntityManager implements Listener {
return projectiles.get(projectile.getEntityId());
}
public Object[] getEntityData(Entity entity) {
public EntityData getEntityData(Entity entity) {
return entities.get(entity.getEntityId());
}
@ -95,6 +107,16 @@ 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.
*
* TODO This bug could also be exploited using a bow, by holding another item
* after shooting an arrow!!
*/
@EventHandler(ignoreCancelled = true)
public void b(EntityDamageByEntityEvent event) {
@ -112,16 +134,15 @@ public class EntityManager implements Listener {
ItemAttackResult result = new ItemAttackResult(data.isCustomWeapon() ? stats.getStat(ItemStats.ATTACK_DAMAGE) : event.getDamage(),
DamageType.WEAPON, DamageType.PROJECTILE, DamageType.PHYSICAL).applyOnHitEffects(stats, target);
/*
* only modify the damage when the bow used is a custom weapon.
*/
// 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)));
// Apply MMOItems specific modifications
if (data.isCustomWeapon()) {
data.applyPotionEffects(target);
result.applyElementalEffects(stats, data.getSourceItem(), target);
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)));
}
event.setDamage(result.getDamage());