feat: disable invuln for plugin damage + DamageUtil + DiamondTri/Barrage/Overhead nerf
This commit is contained in:
@@ -25,7 +25,7 @@ public class BlackKnifeListener implements Listener {
|
|||||||
private final java.util.Map<java.util.UUID, BukkitRunnable> previewTasks = new java.util.HashMap<>();
|
private final java.util.Map<java.util.UUID, BukkitRunnable> previewTasks = new java.util.HashMap<>();
|
||||||
private final java.util.Map<java.util.UUID, BukkitRunnable> lungeHighlightTasks = new java.util.HashMap<>();
|
private final java.util.Map<java.util.UUID, BukkitRunnable> lungeHighlightTasks = new java.util.HashMap<>();
|
||||||
private final java.util.Map<java.util.UUID, Integer> swordCombo = new java.util.HashMap<>();
|
private final java.util.Map<java.util.UUID, Integer> swordCombo = new java.util.HashMap<>();
|
||||||
private static final String[] MODES = {"STARS", "SWORD", "DIAMOND", "LUNGE", "SNIPE", "TRI", "OVERHEAD"};
|
private static final String[] MODES = {"STARS", "SWORD", "DIAMOND", "DIAMOND_TRI", "BARRAGE", "LUNGE", "SNIPE", "TRI", "OVERHEAD"};
|
||||||
|
|
||||||
public BlackKnifeListener(BlackKnifePlugin plugin) { this.plugin = plugin; }
|
public BlackKnifeListener(BlackKnifePlugin plugin) { this.plugin = plugin; }
|
||||||
|
|
||||||
@@ -119,6 +119,14 @@ public class BlackKnifeListener implements Listener {
|
|||||||
p.setCooldown(item.getType(), 15);
|
p.setCooldown(item.getType(), 15);
|
||||||
p.getWorld().playSound(p.getLocation(), Sound.BLOCK_AMETHYST_BLOCK_PLACE, 1f, 0.9f);
|
p.getWorld().playSound(p.getLocation(), Sound.BLOCK_AMETHYST_BLOCK_PLACE, 1f, 0.9f);
|
||||||
}
|
}
|
||||||
|
} else if (m.equals("DIAMOND_TRI")) {
|
||||||
|
if (DiamondTripleAttack.tryUse(p, tm)) {
|
||||||
|
p.setCooldown(item.getType(), 40);
|
||||||
|
}
|
||||||
|
} else if (m.equals("BARRAGE")) {
|
||||||
|
if (PhantomBarrageAttack.tryUse(p, tm)) {
|
||||||
|
p.setCooldown(item.getType(), 50);
|
||||||
|
}
|
||||||
} else if (m.equals("LUNGE")) {
|
} else if (m.equals("LUNGE")) {
|
||||||
LivingEntity target = getLungeTarget(p);
|
LivingEntity target = getLungeTarget(p);
|
||||||
if (LungeAttack.tryUse(p, tm, target)) {
|
if (LungeAttack.tryUse(p, tm, target)) {
|
||||||
@@ -138,7 +146,7 @@ public class BlackKnifeListener implements Listener {
|
|||||||
} else if (m.equals("OVERHEAD")) {
|
} else if (m.equals("OVERHEAD")) {
|
||||||
Location gaze = getGazePoint(p);
|
Location gaze = getGazePoint(p);
|
||||||
if (LungeAttack.tryOverhead(p, tm, gaze)) {
|
if (LungeAttack.tryOverhead(p, tm, gaze)) {
|
||||||
p.setCooldown(item.getType(), 30);
|
p.setCooldown(item.getType(), 50);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
e.setCancelled(true);
|
e.setCancelled(true);
|
||||||
@@ -229,7 +237,7 @@ public class BlackKnifeListener implements Listener {
|
|||||||
Location gp = getGazePoint(p);
|
Location gp = getGazePoint(p);
|
||||||
for (int i = 0; i < 16; i++) {
|
for (int i = 0; i < 16; i++) {
|
||||||
double a = (double) i / 16 * Math.PI * 2;
|
double a = (double) i / 16 * Math.PI * 2;
|
||||||
Location ring = gp.clone().add(Math.cos(a) * 2, 0.1, Math.sin(a) * 2);
|
Location ring = gp.clone().add(Math.cos(a) * 1.8, 0.1, Math.sin(a) * 1.8);
|
||||||
p.spawnParticle(Particle.DUST, ring, 1, 0, 0, 0, 0, new Particle.DustOptions(Color.fromRGB(20, 20, 20), 1.2f));
|
p.spawnParticle(Particle.DUST, ring, 1, 0, 0, 0, 0, new Particle.DustOptions(Color.fromRGB(20, 20, 20), 1.2f));
|
||||||
p.spawnParticle(Particle.ASH, ring, 1, 0, 0, 0, 0);
|
p.spawnParticle(Particle.ASH, ring, 1, 0, 0, 0, 0);
|
||||||
}
|
}
|
||||||
@@ -243,6 +251,30 @@ public class BlackKnifeListener implements Listener {
|
|||||||
};
|
};
|
||||||
r.runTaskTimer(plugin, 1L, 4L);
|
r.runTaskTimer(plugin, 1L, 4L);
|
||||||
lungeHighlightTasks.put(p.getUniqueId(), r);
|
lungeHighlightTasks.put(p.getUniqueId(), r);
|
||||||
|
} else if (m.equals("DIAMOND_TRI")) {
|
||||||
|
BukkitRunnable r = new BukkitRunnable() {
|
||||||
|
@Override public void run() {
|
||||||
|
if (!p.isOnline() || !getMode(p).equals("DIAMOND_TRI")) { cancel(); return; }
|
||||||
|
if (p.hasCooldown(Material.NETHERITE_SWORD)) return;
|
||||||
|
if (!BlackKnifeItem.is(p.getInventory().getItemInMainHand()) && !BlackKnifeItem.is(p.getInventory().getItemInOffHand())) return;
|
||||||
|
Location base = p.getEyeLocation().add(p.getEyeLocation().getDirection().normalize().multiply(1.5));
|
||||||
|
for (int i=0;i<3;i++){ double a=(double)i/3*Math.PI*2; Location pp=base.clone().add(Math.cos(a)*0.5, Math.sin(a)*0.3, Math.sin(a)*0.5); p.spawnParticle(Particle.DUST,pp,1,0,0,0,0,new Particle.DustOptions(Color.fromRGB(180,0,255),1f)); p.spawnParticle(Particle.END_ROD,pp,1,0.02,0.02,0.02,0); }
|
||||||
|
}
|
||||||
|
};
|
||||||
|
r.runTaskTimer(plugin, 1L, 5L);
|
||||||
|
lungeHighlightTasks.put(p.getUniqueId(), r);
|
||||||
|
} else if (m.equals("BARRAGE")) {
|
||||||
|
BukkitRunnable r = new BukkitRunnable() {
|
||||||
|
@Override public void run() {
|
||||||
|
if (!p.isOnline() || !getMode(p).equals("BARRAGE")) { cancel(); return; }
|
||||||
|
if (p.hasCooldown(Material.NETHERITE_SWORD)) return;
|
||||||
|
if (!BlackKnifeItem.is(p.getInventory().getItemInMainHand()) && !BlackKnifeItem.is(p.getInventory().getItemInOffHand())) return;
|
||||||
|
Location c = p.getLocation().add(0,1,0);
|
||||||
|
for(int i=0;i<5;i++){ double a=(double)i/5*Math.PI*2 + System.currentTimeMillis()*0.002; Location orb=c.clone().add(Math.cos(a)*1.5, Math.sin(a*2)*0.3, Math.sin(a)*1.5); p.spawnParticle(Particle.SCULK_SOUL,orb,1,0.02,0.02,0.02,0); p.spawnParticle(Particle.ASH,orb,1,0,0,0,0); }
|
||||||
|
}
|
||||||
|
};
|
||||||
|
r.runTaskTimer(plugin, 1L, 4L);
|
||||||
|
lungeHighlightTasks.put(p.getUniqueId(), r);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -298,8 +330,7 @@ public class BlackKnifeListener implements Listener {
|
|||||||
for (var ent : n2.getWorld().getNearbyEntities(n2, 0.7, 0.7, 0.7)) {
|
for (var ent : n2.getWorld().getNearbyEntities(n2, 0.7, 0.7, 0.7)) {
|
||||||
if (ent instanceof Player pl && pl != p) continue;
|
if (ent instanceof Player pl && pl != p) continue;
|
||||||
if (ent instanceof org.bukkit.entity.LivingEntity le && le != p) {
|
if (ent instanceof org.bukkit.entity.LivingEntity le && le != p) {
|
||||||
le.getPersistentDataContainer().set(SwoonHandler.MAGIC_DAMAGE, PersistentDataType.BYTE, (byte) 1);
|
DamageUtil.apply(p, le, 3.0);
|
||||||
le.damage(3.0, p);
|
|
||||||
shard.remove();
|
shard.remove();
|
||||||
cancel();
|
cancel();
|
||||||
break;
|
break;
|
||||||
|
|||||||
@@ -0,0 +1,23 @@
|
|||||||
|
package me.sashegdev.blackknife;
|
||||||
|
|
||||||
|
import org.bukkit.entity.LivingEntity;
|
||||||
|
import org.bukkit.entity.Player;
|
||||||
|
import org.bukkit.persistence.PersistentDataType;
|
||||||
|
|
||||||
|
public class DamageUtil {
|
||||||
|
public static void apply(Player attacker, LivingEntity victim, double amount) {
|
||||||
|
victim.getPersistentDataContainer().set(SwoonHandler.MAGIC_DAMAGE, PersistentDataType.BYTE, (byte) 1);
|
||||||
|
victim.damage(amount, attacker);
|
||||||
|
victim.getPersistentDataContainer().remove(SwoonHandler.MAGIC_DAMAGE);
|
||||||
|
victim.setNoDamageTicks(0);
|
||||||
|
victim.setMaximumNoDamageTicks(10);
|
||||||
|
BlackKnifePlugin.getInstance().getServer().getScheduler().runTaskLater(BlackKnifePlugin.getInstance(), () -> {
|
||||||
|
if (victim.isValid() && victim.getMaximumNoDamageTicks() == 0) victim.setMaximumNoDamageTicks(10);
|
||||||
|
}, 1L);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void applyRaw(Player attacker, LivingEntity victim, double amount) {
|
||||||
|
if (victim instanceof Player pl && pl.isBlocking()) amount /= 2.5;
|
||||||
|
apply(attacker, victim, amount);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -67,8 +67,7 @@ public class DiamondAttack {
|
|||||||
n2.getWorld().spawnParticle(Particle.CRIT, n2, 1, 0.05, 0.05, 0.05, 0);
|
n2.getWorld().spawnParticle(Particle.CRIT, n2, 1, 0.05, 0.05, 0.05, 0);
|
||||||
for (var ent : n2.getWorld().getNearbyEntities(n2, 0.7, 0.7, 0.7, e -> e instanceof LivingEntity && e != p)) {
|
for (var ent : n2.getWorld().getNearbyEntities(n2, 0.7, 0.7, 0.7, e -> e instanceof LivingEntity && e != p)) {
|
||||||
LivingEntity le = (LivingEntity) ent;
|
LivingEntity le = (LivingEntity) ent;
|
||||||
le.getPersistentDataContainer().set(SwoonHandler.MAGIC_DAMAGE, PersistentDataType.BYTE, (byte) 1);
|
DamageUtil.apply(p, le, 2.0);
|
||||||
le.damage(2.0, p);
|
|
||||||
shard.remove();
|
shard.remove();
|
||||||
cancel();
|
cancel();
|
||||||
break;
|
break;
|
||||||
@@ -93,8 +92,7 @@ public class DiamondAttack {
|
|||||||
boolean hit = false;
|
boolean hit = false;
|
||||||
for (var ent : nl.getWorld().getNearbyEntities(nl, 0.7, 0.7, 0.7, e -> e instanceof LivingEntity && e != p)) {
|
for (var ent : nl.getWorld().getNearbyEntities(nl, 0.7, 0.7, 0.7, e -> e instanceof LivingEntity && e != p)) {
|
||||||
LivingEntity le = (LivingEntity) ent;
|
LivingEntity le = (LivingEntity) ent;
|
||||||
le.getPersistentDataContainer().set(SwoonHandler.MAGIC_DAMAGE, PersistentDataType.BYTE, (byte) 1);
|
DamageUtil.apply(p, le, 5.0);
|
||||||
le.damage(5.0, p);
|
|
||||||
hit = true;
|
hit = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -136,8 +134,7 @@ public class DiamondAttack {
|
|||||||
shard.getWorld().spawnParticle(Particle.CRIT, n2, 1, 0.05, 0.05, 0.05, 0);
|
shard.getWorld().spawnParticle(Particle.CRIT, n2, 1, 0.05, 0.05, 0.05, 0);
|
||||||
for (var ent : n2.getWorld().getNearbyEntities(n2, 0.7, 0.7, 0.7, e -> e instanceof LivingEntity && e != p)) {
|
for (var ent : n2.getWorld().getNearbyEntities(n2, 0.7, 0.7, 0.7, e -> e instanceof LivingEntity && e != p)) {
|
||||||
LivingEntity le = (LivingEntity) ent;
|
LivingEntity le = (LivingEntity) ent;
|
||||||
le.getPersistentDataContainer().set(SwoonHandler.MAGIC_DAMAGE, PersistentDataType.BYTE, (byte) 1);
|
DamageUtil.apply(p, le, 2.0); shard.remove(); cancel(); break;
|
||||||
le.damage(2.0, p); shard.remove(); cancel(); break;
|
|
||||||
}
|
}
|
||||||
for (Player pl : n2.getWorld().getNearbyPlayers(n2, 0.9)) {
|
for (Player pl : n2.getWorld().getNearbyPlayers(n2, 0.9)) {
|
||||||
if (pl == p) continue;
|
if (pl == p) continue;
|
||||||
|
|||||||
@@ -0,0 +1,85 @@
|
|||||||
|
package me.sashegdev.blackknife;
|
||||||
|
|
||||||
|
import net.kyori.adventure.text.Component;
|
||||||
|
import net.kyori.adventure.text.format.NamedTextColor;
|
||||||
|
import org.bukkit.Color;
|
||||||
|
import org.bukkit.Location;
|
||||||
|
import org.bukkit.Material;
|
||||||
|
import org.bukkit.Particle;
|
||||||
|
import org.bukkit.Sound;
|
||||||
|
import org.bukkit.entity.BlockDisplay;
|
||||||
|
import org.bukkit.entity.Display;
|
||||||
|
import org.bukkit.entity.LivingEntity;
|
||||||
|
import org.bukkit.entity.Player;
|
||||||
|
import org.bukkit.persistence.PersistentDataType;
|
||||||
|
import org.bukkit.scheduler.BukkitRunnable;
|
||||||
|
import org.bukkit.util.Vector;
|
||||||
|
|
||||||
|
public class DiamondTripleAttack {
|
||||||
|
public static boolean tryUse(Player p, TensionManager tension) {
|
||||||
|
if (tension.getTP(p) < 87.5f) { p.sendActionBar(Component.text("Need 35% TP").color(NamedTextColor.RED)); return false; }
|
||||||
|
tension.setTP(p, tension.getTP(p) - 87.5f);
|
||||||
|
Location target = getGazeTarget(p);
|
||||||
|
if (target == null) target = p.getEyeLocation().add(p.getEyeLocation().getDirection().normalize().multiply(20));
|
||||||
|
double baseAngle = p.getEyeLocation().getYaw();
|
||||||
|
for (int i = 0; i < 3; i++) {
|
||||||
|
double angle = (baseAngle + i * 120) % 360;
|
||||||
|
Vector dir = Vector.getRandom().normalize();
|
||||||
|
double yawRad = Math.toRadians(angle);
|
||||||
|
Vector offset = new Vector(Math.cos(yawRad), 0, Math.sin(yawRad)).multiply(0.7);
|
||||||
|
Location spawn = p.getEyeLocation().clone().add(offset).add(p.getEyeLocation().getDirection().normalize().multiply(1.5));
|
||||||
|
launch(p, target.clone(), spawn);
|
||||||
|
}
|
||||||
|
p.getWorld().playSound(p.getLocation(), Sound.BLOCK_AMETHYST_BLOCK_PLACE, 1f, 1.1f);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static Location getGazeTarget(Player p) {
|
||||||
|
var ray = p.getWorld().rayTraceBlocks(p.getEyeLocation(), p.getEyeLocation().getDirection(), 40);
|
||||||
|
if (ray != null && ray.getHitPosition() != null) return new Location(p.getWorld(), ray.getHitPosition().getX(), ray.getHitPosition().getY(), ray.getHitPosition().getZ());
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void launch(Player p, Location target, Location spawn) {
|
||||||
|
BlockDisplay shard = p.getWorld().spawn(spawn, BlockDisplay.class, d -> {
|
||||||
|
d.setBlock(Material.AMETHYST_BLOCK.createBlockData());
|
||||||
|
d.setBrightness(new Display.Brightness(15, 15));
|
||||||
|
d.setViewRange(64);
|
||||||
|
d.setTransformation(new org.bukkit.util.Transformation(new org.joml.Vector3f(-0.45f, -0.45f, -0.45f), new org.joml.AxisAngle4f(), new org.joml.Vector3f(0.9f, 0.9f, 0.9f), new org.joml.AxisAngle4f()));
|
||||||
|
});
|
||||||
|
EntityTracker.mark(shard);
|
||||||
|
BlackKnifePlugin plugin = BlackKnifePlugin.getPlugin(BlackKnifePlugin.class);
|
||||||
|
Vector initDir = target.clone().subtract(spawn).toVector().normalize().multiply(1.4);
|
||||||
|
new BukkitRunnable() {
|
||||||
|
Vector vel = initDir.clone();
|
||||||
|
@Override public void run() {
|
||||||
|
if (!shard.isValid() || shard.isDead()) { cancel(); return; }
|
||||||
|
Location cur = shard.getLocation();
|
||||||
|
Vector toTarget = target.clone().subtract(cur).toVector().normalize().multiply(1.4);
|
||||||
|
vel = vel.multiply(0.88).add(toTarget.multiply(0.12)).normalize().multiply(1.4);
|
||||||
|
Location nl = cur.clone().add(vel);
|
||||||
|
int steps = Math.max(1, (int)Math.ceil(vel.length()/0.5));
|
||||||
|
for (int s=0;s<=steps;s++) {
|
||||||
|
Location check = cur.clone().add(vel.clone().multiply((double)s/steps));
|
||||||
|
if (check.getBlock().isSolid()) { shard.remove(); cancel(); return; }
|
||||||
|
}
|
||||||
|
shard.teleport(nl);
|
||||||
|
nl.getWorld().spawnParticle(Particle.DUST, nl,1,0,0,0,0,new Particle.DustOptions(Color.fromRGB(180,0,255),1f));
|
||||||
|
nl.getWorld().spawnParticle(Particle.END_ROD, nl,1,0.05,0.05,0.05,0);
|
||||||
|
for (LivingEntity le : nl.getWorld().getNearbyLivingEntities(nl,0.8)) {
|
||||||
|
if (le == p) continue;
|
||||||
|
DamageUtil.apply(p, le, 7.0);
|
||||||
|
le.addPotionEffect(new org.bukkit.potion.PotionEffect(org.bukkit.potion.PotionEffectType.SLOWNESS,20,0,false,false,true));
|
||||||
|
nl.getWorld().spawnParticle(Particle.CRIT, le.getLocation().add(0,1,0),8,0.3,0.3,0.3,0.1);
|
||||||
|
shard.remove(); cancel(); return;
|
||||||
|
}
|
||||||
|
for (Player pl : nl.getWorld().getNearbyPlayers(nl,0.9)) {
|
||||||
|
if (pl==p) continue;
|
||||||
|
double d2 = pl.getLocation().add(0,1,0).distanceSquared(nl);
|
||||||
|
if (d2>0.25 && d2<0.81) plugin.getTension().addTP(pl,2.5f,"DODGE +1%");
|
||||||
|
}
|
||||||
|
if (nl.distanceSquared(spawn) > 1600 || shard.getTicksLived() > 80) { shard.remove(); cancel(); }
|
||||||
|
}
|
||||||
|
}.runTaskTimer(plugin,1L,1L);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -196,11 +196,11 @@ public class LungeAttack {
|
|||||||
p.sendActionBar(Component.text("Look at ground within 120 blocks!").color(NamedTextColor.RED));
|
p.sendActionBar(Component.text("Look at ground within 120 blocks!").color(NamedTextColor.RED));
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (tension.getTP(p) < 50f) {
|
if (tension.getTP(p) < 62.5f) {
|
||||||
p.sendActionBar(Component.text("Need 20% TP").color(NamedTextColor.RED));
|
p.sendActionBar(Component.text("Need 25% TP").color(NamedTextColor.RED));
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
tension.setTP(p, tension.getTP(p) - 50f);
|
tension.setTP(p, tension.getTP(p) - 62.5f);
|
||||||
BlackKnifePlugin plugin = BlackKnifePlugin.getPlugin(BlackKnifePlugin.class);
|
BlackKnifePlugin plugin = BlackKnifePlugin.getPlugin(BlackKnifePlugin.class);
|
||||||
Location above = gazePoint.clone().add(0, 10, 0);
|
Location above = gazePoint.clone().add(0, 10, 0);
|
||||||
BlockDisplay sword = p.getWorld().spawn(above, BlockDisplay.class, d -> {
|
BlockDisplay sword = p.getWorld().spawn(above, BlockDisplay.class, d -> {
|
||||||
@@ -213,13 +213,22 @@ public class LungeAttack {
|
|||||||
new org.joml.Vector3f(1.5f, 1.5f, 1.5f),
|
new org.joml.Vector3f(1.5f, 1.5f, 1.5f),
|
||||||
new org.joml.AxisAngle4f()));
|
new org.joml.AxisAngle4f()));
|
||||||
});
|
});
|
||||||
|
EntityTracker.mark(sword);
|
||||||
p.getWorld().playSound(gazePoint, Sound.ENTITY_PLAYER_ATTACK_SWEEP, 1f, 0.5f);
|
p.getWorld().playSound(gazePoint, Sound.ENTITY_PLAYER_ATTACK_SWEEP, 1f, 0.5f);
|
||||||
p.getWorld().playSound(gazePoint, Sound.BLOCK_ANVIL_LAND, 0.6f, 1.4f);
|
p.getWorld().playSound(gazePoint, Sound.BLOCK_ANVIL_LAND, 0.6f, 1.4f);
|
||||||
Vector vel = new Vector(0, -1.8, 0);
|
Vector vel = new Vector(0, -1.2, 0);
|
||||||
new BukkitRunnable() {
|
new BukkitRunnable() {
|
||||||
|
int hold = 8;
|
||||||
@Override public void run() {
|
@Override public void run() {
|
||||||
if (!sword.isValid()) { cancel(); return; }
|
if (!sword.isValid()) { cancel(); return; }
|
||||||
Location cur = sword.getLocation();
|
Location cur = sword.getLocation();
|
||||||
|
if (hold > 0) {
|
||||||
|
hold--;
|
||||||
|
cur.getWorld().spawnParticle(Particle.SMOKE, cur, 2, 0.15, 0.15, 0.15, 0);
|
||||||
|
cur.getWorld().spawnParticle(Particle.SCULK_SOUL, cur, 1, 0.05, 0.05, 0.05, 0);
|
||||||
|
cur.getWorld().spawnParticle(Particle.ASH, cur, 1, 0, 0, 0, 0);
|
||||||
|
return;
|
||||||
|
}
|
||||||
Location nl = cur.clone().add(vel);
|
Location nl = cur.clone().add(vel);
|
||||||
sword.teleport(nl);
|
sword.teleport(nl);
|
||||||
nl.getWorld().spawnParticle(Particle.DUST, nl, 2, 0.15, 0.15, 0.15, 0, new Particle.DustOptions(Color.fromRGB(0, 0, 0), 1.5f));
|
nl.getWorld().spawnParticle(Particle.DUST, nl, 2, 0.15, 0.15, 0.15, 0, new Particle.DustOptions(Color.fromRGB(0, 0, 0), 1.5f));
|
||||||
@@ -265,6 +274,7 @@ public class LungeAttack {
|
|||||||
if (ent instanceof Player pl && pl.isBlocking()) amount /= 2.5;
|
if (ent instanceof Player pl && pl.isBlocking()) amount /= 2.5;
|
||||||
ent.getPersistentDataContainer().set(SwoonHandler.MAGIC_DAMAGE, PersistentDataType.BYTE, (byte) 1);
|
ent.getPersistentDataContainer().set(SwoonHandler.MAGIC_DAMAGE, PersistentDataType.BYTE, (byte) 1);
|
||||||
ent.damage(amount, attacker);
|
ent.damage(amount, attacker);
|
||||||
|
ent.setNoDamageTicks(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void startPhase1(Player p, Location epicenter, LivingEntity target, BlackKnifePlugin plugin) {
|
private static void startPhase1(Player p, Location epicenter, LivingEntity target, BlackKnifePlugin plugin) {
|
||||||
|
|||||||
@@ -166,8 +166,7 @@ public class MagicListener implements Listener {
|
|||||||
marker.teleport(nl);
|
marker.teleport(nl);
|
||||||
for(var ent: nl.getWorld().getNearbyEntities(nl,0.7,0.7,0.7, en->en instanceof LivingEntity && en!=p)) {
|
for(var ent: nl.getWorld().getNearbyEntities(nl,0.7,0.7,0.7, en->en instanceof LivingEntity && en!=p)) {
|
||||||
LivingEntity le=(LivingEntity)ent;
|
LivingEntity le=(LivingEntity)ent;
|
||||||
le.getPersistentDataContainer().set(SwoonHandler.MAGIC_DAMAGE,PersistentDataType.BYTE,(byte)1);
|
DamageUtil.apply(p, le, 15.0);
|
||||||
le.damage(15.0,p);
|
|
||||||
Location hit=le.getLocation().add(0,1,0);
|
Location hit=le.getLocation().add(0,1,0);
|
||||||
for(int k=0;k<12;k++){ double a=(double)k/12*Math.PI*2; for(int h=-1;h<=1;h++){ Location s=hit.clone().add(Math.cos(a)*0.5,h*0.25,Math.sin(a)*0.5); s.getWorld().spawnParticle(Particle.DUST,s,1,0,0,0,0,new Particle.DustOptions(Color.fromRGB(200,40,40),0.9f)); } } hit.getWorld().spawnParticle(Particle.CRIT,hit,10,0.3,0.3,0.3,0.1); hit.getWorld().playSound(hit,Sound.ENTITY_PLAYER_ATTACK_CRIT,1f,0.9f);
|
for(int k=0;k<12;k++){ double a=(double)k/12*Math.PI*2; for(int h=-1;h<=1;h++){ Location s=hit.clone().add(Math.cos(a)*0.5,h*0.25,Math.sin(a)*0.5); s.getWorld().spawnParticle(Particle.DUST,s,1,0,0,0,0,new Particle.DustOptions(Color.fromRGB(200,40,40),0.9f)); } } hit.getWorld().spawnParticle(Particle.CRIT,hit,10,0.3,0.3,0.3,0.1); hit.getWorld().playSound(hit,Sound.ENTITY_PLAYER_ATTACK_CRIT,1f,0.9f);
|
||||||
le.addPotionEffect(new org.bukkit.potion.PotionEffect(org.bukkit.potion.PotionEffectType.SLOWNESS,40,1,false,false,true));
|
le.addPotionEffect(new org.bukkit.potion.PotionEffect(org.bukkit.potion.PotionEffectType.SLOWNESS,40,1,false,false,true));
|
||||||
@@ -205,8 +204,7 @@ public class MagicListener implements Listener {
|
|||||||
marker.teleport(nl);
|
marker.teleport(nl);
|
||||||
for(var ent: nl.getWorld().getNearbyEntities(nl,0.7,0.7,0.7, en->en instanceof LivingEntity && en!=p)) {
|
for(var ent: nl.getWorld().getNearbyEntities(nl,0.7,0.7,0.7, en->en instanceof LivingEntity && en!=p)) {
|
||||||
LivingEntity le=(LivingEntity)ent;
|
LivingEntity le=(LivingEntity)ent;
|
||||||
le.getPersistentDataContainer().set(SwoonHandler.MAGIC_DAMAGE,PersistentDataType.BYTE,(byte)1);
|
DamageUtil.apply(p, le, 8.0);
|
||||||
le.damage(8.0,p);
|
|
||||||
Location hit=le.getLocation().add(0,1,0);
|
Location hit=le.getLocation().add(0,1,0);
|
||||||
for(int k=0;k<12;k++){ double a=(double)k/12*Math.PI*2; for(int h=-1;h<=1;h++){ Location s=hit.clone().add(Math.cos(a)*0.5,h*0.25,Math.sin(a)*0.5); s.getWorld().spawnParticle(Particle.SNOWFLAKE,s,1,0.02,0.02,0.02,0); } } hit.getWorld().spawnParticle(Particle.SNOWFLAKE,hit,8,0.3,0.3,0.3,0.1); hit.getWorld().playSound(hit,Sound.BLOCK_GLASS_BREAK,1f,0.7f);
|
for(int k=0;k<12;k++){ double a=(double)k/12*Math.PI*2; for(int h=-1;h<=1;h++){ Location s=hit.clone().add(Math.cos(a)*0.5,h*0.25,Math.sin(a)*0.5); s.getWorld().spawnParticle(Particle.SNOWFLAKE,s,1,0.02,0.02,0.02,0); } } hit.getWorld().spawnParticle(Particle.SNOWFLAKE,hit,8,0.3,0.3,0.3,0.1); hit.getWorld().playSound(hit,Sound.BLOCK_GLASS_BREAK,1f,0.7f);
|
||||||
le.addPotionEffect(new org.bukkit.potion.PotionEffect(org.bukkit.potion.PotionEffectType.SLOWNESS,40,1,false,false,true));
|
le.addPotionEffect(new org.bukkit.potion.PotionEffect(org.bukkit.potion.PotionEffectType.SLOWNESS,40,1,false,false,true));
|
||||||
|
|||||||
@@ -0,0 +1,80 @@
|
|||||||
|
package me.sashegdev.blackknife;
|
||||||
|
|
||||||
|
import net.kyori.adventure.text.Component;
|
||||||
|
import net.kyori.adventure.text.format.NamedTextColor;
|
||||||
|
import org.bukkit.Color;
|
||||||
|
import org.bukkit.Location;
|
||||||
|
import org.bukkit.Material;
|
||||||
|
import org.bukkit.Particle;
|
||||||
|
import org.bukkit.Sound;
|
||||||
|
import org.bukkit.entity.BlockDisplay;
|
||||||
|
import org.bukkit.entity.Display;
|
||||||
|
import org.bukkit.entity.LivingEntity;
|
||||||
|
import org.bukkit.entity.Player;
|
||||||
|
import org.bukkit.persistence.PersistentDataType;
|
||||||
|
import org.bukkit.scheduler.BukkitRunnable;
|
||||||
|
import org.bukkit.util.Vector;
|
||||||
|
|
||||||
|
public class PhantomBarrageAttack {
|
||||||
|
public static boolean tryUse(Player p, TensionManager tension) {
|
||||||
|
if (tension.getTP(p) < 100f) { p.sendActionBar(Component.text("Need 40% TP").color(NamedTextColor.RED)); return false; }
|
||||||
|
tension.setTP(p, tension.getTP(p) - 100f);
|
||||||
|
Location center = p.getLocation().add(0,1,0);
|
||||||
|
BlackKnifePlugin plugin = BlackKnifePlugin.getPlugin(BlackKnifePlugin.class);
|
||||||
|
p.getWorld().playSound(center, Sound.ENTITY_PHANTOM_AMBIENT, 1f, 0.6f);
|
||||||
|
p.getWorld().playSound(center, Sound.BLOCK_BEACON_ACTIVATE, 1f, 1.4f);
|
||||||
|
for (int i=0;i<5;i++) {
|
||||||
|
double angle = (double)i/5 * Math.PI*2;
|
||||||
|
final double fa = angle;
|
||||||
|
Location spawn = center.clone().add(Math.cos(angle)*2, Math.sin(angle*2)*0.5, Math.sin(angle)*2);
|
||||||
|
BlockDisplay orb = p.getWorld().spawn(spawn, BlockDisplay.class, d -> {
|
||||||
|
d.setBlock(Material.SCULK_CATALYST.createBlockData());
|
||||||
|
d.setBrightness(new Display.Brightness(15,15));
|
||||||
|
d.setViewRange(64);
|
||||||
|
d.setTransformation(new org.bukkit.util.Transformation(new org.joml.Vector3f(-0.35f,-0.35f,-0.35f),new org.joml.AxisAngle4f(),new org.joml.Vector3f(0.7f,0.7f,0.7f),new org.joml.AxisAngle4f()));
|
||||||
|
});
|
||||||
|
EntityTracker.mark(orb);
|
||||||
|
new BukkitRunnable() {
|
||||||
|
int ticks = 0;
|
||||||
|
Location cur = spawn.clone();
|
||||||
|
Vector dir = new Vector(-Math.sin(fa), 0, Math.cos(fa)).normalize().multiply(0.35);
|
||||||
|
@Override public void run() {
|
||||||
|
if (!orb.isValid() || orb.isDead()) { cancel(); return; }
|
||||||
|
if (ticks < 30) {
|
||||||
|
cur = cur.clone().add(dir);
|
||||||
|
dir = new Vector(-Math.sin(fa + ticks*0.15), 0, Math.cos(fa + ticks*0.15)).normalize().multiply(0.35);
|
||||||
|
orb.teleport(cur);
|
||||||
|
cur.getWorld().spawnParticle(Particle.SCULK_SOUL, cur,1,0.05,0.05,0.05,0);
|
||||||
|
cur.getWorld().spawnParticle(Particle.ASH, cur,1,0,0,0,0);
|
||||||
|
ticks++;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (ticks == 30) {
|
||||||
|
cur.getWorld().playSound(cur, Sound.ENTITY_PHANTOM_FLAP, 1f, 1.2f);
|
||||||
|
}
|
||||||
|
Location target = getGazeTarget(p);
|
||||||
|
if (target == null) target = p.getEyeLocation().add(p.getEyeLocation().getDirection().normalize().multiply(25));
|
||||||
|
Vector toTarget = target.clone().subtract(cur).toVector().normalize().multiply(1.6);
|
||||||
|
Location nl = cur.clone().add(toTarget);
|
||||||
|
int steps = Math.max(1,(int)Math.ceil(toTarget.length()/0.5));
|
||||||
|
for(int s=0;s<=steps;s++){ Location check=cur.clone().add(toTarget.clone().multiply((double)s/steps)); if(check.getBlock().isSolid()){orb.remove();cancel();return;} }
|
||||||
|
orb.teleport(nl);
|
||||||
|
cur = nl;
|
||||||
|
nl.getWorld().spawnParticle(Particle.DUST, nl,1,0,0,0,0,new Particle.DustOptions(Color.fromRGB(30,10,50),1.2f));
|
||||||
|
nl.getWorld().spawnParticle(Particle.SCULK_SOUL, nl,1,0.05,0.05,0.05,0);
|
||||||
|
for(LivingEntity le: nl.getWorld().getNearbyLivingEntities(nl,0.9)){ if(le==p) continue; DamageUtil.apply(p, le, 6.0); le.getWorld().spawnParticle(Particle.CRIT, le.getLocation().add(0,1,0),8,0.3,0.3,0.3,0.1); orb.remove(); cancel(); return; }
|
||||||
|
for(Player pl: nl.getWorld().getNearbyPlayers(nl,0.9)){ if(pl==p) continue; double d2=pl.getLocation().add(0,1,0).distanceSquared(nl); if(d2>0.25 && d2<0.81) plugin.getTension().addTP(pl,2.5f,"DODGE +1%"); }
|
||||||
|
if(cur.distanceSquared(target) < 1 || orb.getTicksLived() > 100){ orb.remove(); cancel(); }
|
||||||
|
ticks++;
|
||||||
|
}
|
||||||
|
}.runTaskTimer(plugin,1L,1L);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static Location getGazeTarget(Player p){
|
||||||
|
var ray = p.getWorld().rayTraceBlocks(p.getEyeLocation(), p.getEyeLocation().getDirection(), 40);
|
||||||
|
if(ray!=null && ray.getHitPosition()!=null) return new Location(p.getWorld(), ray.getHitPosition().getX(), ray.getHitPosition().getY(), ray.getHitPosition().getZ());
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -70,8 +70,7 @@ public class SwordAttack {
|
|||||||
marker.teleport(nl);
|
marker.teleport(nl);
|
||||||
for (var ent : nl.getWorld().getNearbyEntities(nl, 0.7, 0.7, 0.7, e -> e instanceof LivingEntity && e != p)) {
|
for (var ent : nl.getWorld().getNearbyEntities(nl, 0.7, 0.7, 0.7, e -> e instanceof LivingEntity && e != p)) {
|
||||||
LivingEntity le = (LivingEntity) ent;
|
LivingEntity le = (LivingEntity) ent;
|
||||||
le.getPersistentDataContainer().set(SwoonHandler.MAGIC_DAMAGE, PersistentDataType.BYTE, (byte) 1);
|
DamageUtil.apply(p, le, 15.0);
|
||||||
le.damage(15.0, p);
|
|
||||||
Location hit = le.getLocation().add(0, 1, 0);
|
Location hit = le.getLocation().add(0, 1, 0);
|
||||||
for (int k = 0; k < 12; k++) {
|
for (int k = 0; k < 12; k++) {
|
||||||
double a = (double) k / 12 * Math.PI * 2;
|
double a = (double) k / 12 * Math.PI * 2;
|
||||||
|
|||||||
Reference in New Issue
Block a user