!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; 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.Color;
import org.bukkit.Location; import org.bukkit.Location;
import org.bukkit.Particle; import org.bukkit.Particle;
@ -15,17 +27,7 @@ import org.bukkit.potion.PotionEffectType;
import org.bukkit.scheduler.BukkitRunnable; import org.bukkit.scheduler.BukkitRunnable;
import org.bukkit.util.Vector; import org.bukkit.util.Vector;
import net.Indyuce.mmoitems.MMOItems; import javax.annotation.Nullable;
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;
public class Shulker_Missile extends Ability implements Listener { public class Shulker_Missile extends Ability implements Listener {
public Shulker_Missile() { public Shulker_Missile() {
@ -63,18 +65,17 @@ public class Shulker_Missile extends Ability implements Listener {
ShulkerBullet shulkerBullet = (ShulkerBullet) stats.getPlayer().getWorld().spawnEntity(stats.getPlayer().getLocation().add(0, 1, 0), ShulkerBullet shulkerBullet = (ShulkerBullet) stats.getPlayer().getWorld().spawnEntity(stats.getPlayer().getLocation().add(0, 1, 0),
EntityType.SHULKER_BULLET); EntityType.SHULKER_BULLET);
shulkerBullet.setShooter(stats.getPlayer()); 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), new AttackResult(ability.getModifier("damage"), DamageType.SKILL, DamageType.MAGIC, DamageType.PROJECTILE),
ability.getModifier("effect-duration")); ability.getModifier("effect-duration")));
new BukkitRunnable() { new BukkitRunnable() {
double ti = 0; double ti = 0;
public void run() { public void run() {
ti++; if (shulkerBullet.isDead() || ti++ >= duration * 20) {
if (shulkerBullet.isDead() || ti >= duration * 20) {
shulkerBullet.remove(); shulkerBullet.remove();
cancel(); cancel();
} } else
shulkerBullet.setVelocity(vec); shulkerBullet.setVelocity(vec);
} }
}.runTaskTimer(MMOItems.plugin, 0, 1); }.runTaskTimer(MMOItems.plugin, 0, 1);
@ -89,31 +90,30 @@ public class Shulker_Missile extends Ability implements Listener {
LivingEntity entity = (LivingEntity) event.getEntity(); LivingEntity entity = (LivingEntity) event.getEntity();
if (!MMOItems.plugin.getEntities().isCustomEntity(damager)) if (!MMOItems.plugin.getEntities().isCustomEntity(damager))
return; return;
if (!MMOUtils.canDamage(entity)) { if (!MMOUtils.canDamage(entity)) {
event.setCancelled(true); event.setCancelled(true);
return; return;
} }
Object[] data = MMOItems.plugin.getEntities().getEntityData(damager); ShulkerMissileEntityData data = (ShulkerMissileEntityData) MMOItems.plugin.getEntities().getEntityData(damager);
AttackResult result = (AttackResult) data[0];
double duration = (double) data[1] * 20;
// void spirit // Void spirit
if (data.length > 2) if (data.isWeaponAttack())
((ItemAttackResult) result).applyEffects((CachedStats) data[2], (NBTItem) data[3], entity); ((ItemAttackResult) data.result).applyEffects(data.stats, data.weapon, entity);
event.setDamage(result.getDamage()); event.setDamage(data.result.getDamage());
new BukkitRunnable() { new BukkitRunnable() {
final Location loc = entity.getLocation(); final Location loc = entity.getLocation();
double y = 0; double y = 0;
public void run() { 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) { if (y == 0) {
entity.removePotionEffect(PotionEffectType.LEVITATION); 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++) { for (int j1 = 0; j1 < 3; j1++) {
@ -130,4 +130,46 @@ public class Shulker_Missile extends Ability implements Listener {
}.runTaskTimer(MMOItems.plugin, 0, 1); }.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 * @param stats Player doing the attack
* Player doing the attack * @param item The item being used
* @param item * @param target The entity target
* The item being used
* @param target
* The entity target
* @return The unedited attack result * @return The unedited attack result
*/ */
@SuppressWarnings("UnusedReturnValue") @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.JsonObject;
import com.google.gson.JsonParser; 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.entity.LivingEntity;
import org.bukkit.potion.PotionEffectType; import org.bukkit.potion.PotionEffectType;

View File

@ -1,17 +1,17 @@
package net.Indyuce.mmoitems.api.interaction.weapon.untargeted.staff; 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.Sound;
import org.bukkit.entity.EntityType; import org.bukkit.entity.EntityType;
import org.bukkit.entity.ShulkerBullet; import org.bukkit.entity.ShulkerBullet;
import org.bukkit.scheduler.BukkitRunnable; import org.bukkit.scheduler.BukkitRunnable;
import org.bukkit.util.Vector; 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 { public class VoidSpirit implements StaffAttackHandler {
@Override @Override
@ -32,6 +32,6 @@ public class VoidSpirit implements StaffAttackHandler {
shulkerBullet.setVelocity(vec); shulkerBullet.setVelocity(vec);
} }
}.runTaskTimer(MMOItems.plugin, 0, 1); }.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 io.lumine.mythic.lib.api.item.NBTItem;
import net.Indyuce.mmoitems.ItemStats; import net.Indyuce.mmoitems.ItemStats;
import net.Indyuce.mmoitems.MMOItems; import net.Indyuce.mmoitems.MMOItems;
import net.Indyuce.mmoitems.api.ArrowParticles;
import net.Indyuce.mmoitems.api.ItemAttackResult; 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 net.Indyuce.mmoitems.api.player.PlayerStats.CachedStats;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
import org.bukkit.enchantments.Enchantment; import org.bukkit.enchantments.Enchantment;
@ -26,12 +27,12 @@ import java.util.WeakHashMap;
public class EntityManager implements Listener { public class EntityManager implements Listener {
/* /**
* entity data used by abilities or staff attacks that utilize entities like * Entity data used by abilities or staff attacks that utilize entities like
* evoker fangs or shulker missiles. it can correspond to the damage the * evoker fangs or shulker missiles. It can correspond to the damage the
* entity is supposed to deal, etc * 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<>(); private final WeakHashMap<Integer, ProjectileData> projectiles = new WeakHashMap<>();
@ -39,19 +40,30 @@ public class EntityManager implements Listener {
registerCustomProjectile(sourceItem, stats, entity, customWeapon, 1); 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) { 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. * By default damage is set to minecraft's default 7. It is then
* it's then multiplied by the damage coefficient which corresponds for * multiplied by the coefficient proportionnal to the pull force.
* bows to the pull force just like vanilla. it does not work with * 1 corresponds to a fully pulled bow just like in vanilla MC.
* tridents *
* For tridents or crossbows, damage coefficient is always 1
*/ */
double damage = stats.getStat(ItemStats.ATTACK_DAMAGE); double damage = stats.getStat(ItemStats.ATTACK_DAMAGE);
stats.setStat(ItemStats.ATTACK_DAMAGE, (damage == 0 ? 7 : damage) * damageCoefficient); stats.setStat(ItemStats.ATTACK_DAMAGE, (damage == 0 ? 7 : damage) * damageCoefficient);
/* /*
* load arrow particles if the entity is an arrow and if the item has * 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 * arrow particles. Currently projectiles are only arrows so there is no
* problem with other projectiles like snowballs etc. * problem with other projectiles like snowballs etc.
*/ */
if (entity instanceof Arrow && sourceItem.hasTag("MMOITEMS_ARROW_PARTICLES")) 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)); 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); entities.put(entity.getEntityId(), data);
} }
@ -76,7 +88,7 @@ public class EntityManager implements Listener {
return projectiles.get(projectile.getEntityId()); return projectiles.get(projectile.getEntityId());
} }
public Object[] getEntityData(Entity entity) { public EntityData getEntityData(Entity entity) {
return entities.get(entity.getEntityId()); return entities.get(entity.getEntityId());
} }
@ -95,6 +107,16 @@ public class EntityManager implements Listener {
/* /*
* Projectile Damage and Effects * 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) @EventHandler(ignoreCancelled = true)
public void b(EntityDamageByEntityEvent event) { 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(), ItemAttackResult result = new ItemAttackResult(data.isCustomWeapon() ? stats.getStat(ItemStats.ATTACK_DAMAGE) : event.getDamage(),
DamageType.WEAPON, DamageType.PROJECTILE, DamageType.PHYSICAL).applyOnHitEffects(stats, target); DamageType.WEAPON, DamageType.PROJECTILE, DamageType.PHYSICAL).applyOnHitEffects(stats, target);
/* // Apply power vanilla enchant
* only modify the damage when the bow used is a custom weapon.
*/
if (data.isCustomWeapon()) {
data.applyPotionEffects(target);
result.applyElementalEffects(stats, data.getSourceItem(), target);
if (projectile instanceof Arrow && data.getSourceItem().getItem().hasItemMeta() if (projectile instanceof Arrow && data.getSourceItem().getItem().hasItemMeta()
&& data.getSourceItem().getItem().getItemMeta().getEnchants().containsKey(Enchantment.ARROW_DAMAGE)) && data.getSourceItem().getItem().getItemMeta().getEnchants().containsKey(Enchantment.ARROW_DAMAGE))
result.multiplyDamage(1.25 + (.25 * data.getSourceItem().getItem().getItemMeta().getEnchantLevel(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);
} }
event.setDamage(result.getDamage()); event.setDamage(result.getDamage());