fix DIVE: allow creative, feedback messages, segment hit sampling; tune GRENADE faster flight + 10t cd
This commit is contained in:
@@ -37,8 +37,14 @@ public class SkyDiveAttack implements Listener {
|
||||
private static final Map<UUID, Boolean> diving = new ConcurrentHashMap<>();
|
||||
|
||||
public static boolean tryUse(Player p, TensionManager tension) {
|
||||
if (SwoonHandler.isSwooned(p)) return false;
|
||||
if (p.getGameMode() == GameMode.CREATIVE || p.getGameMode() == GameMode.SPECTATOR) return false;
|
||||
if (SwoonHandler.isSwooned(p)) {
|
||||
p.sendActionBar(Component.text("SWOONED - can't use DIVE").color(NamedTextColor.RED));
|
||||
return false;
|
||||
}
|
||||
if (p.getGameMode() == GameMode.SPECTATOR) {
|
||||
p.sendActionBar(Component.text("Spectators can't use DIVE").color(NamedTextColor.RED));
|
||||
return false;
|
||||
}
|
||||
if (Boolean.TRUE.equals(diving.get(p.getUniqueId()))) {
|
||||
p.sendActionBar(Component.text("Already diving!").color(NamedTextColor.RED));
|
||||
return false;
|
||||
@@ -60,6 +66,7 @@ public class SkyDiveAttack implements Listener {
|
||||
diving.put(p.getUniqueId(), true);
|
||||
p.getWorld().playSound(p.getLocation(), Sound.ENTITY_FIREWORK_ROCKET_LAUNCH, 1f, 0.8f);
|
||||
p.getWorld().spawnParticle(Particle.CLOUD, p.getLocation(), 10, 0.3, 0.2, 0.3, 0.05);
|
||||
p.sendActionBar(Component.text("SkyDive!").color(NamedTextColor.AQUA));
|
||||
|
||||
new BukkitRunnable() {
|
||||
final double startY = p.getLocation().getY();
|
||||
@@ -88,6 +95,7 @@ public class SkyDiveAttack implements Listener {
|
||||
p.setFallDistance(0);
|
||||
frozen.put(p.getUniqueId(), top);
|
||||
p.getWorld().playSound(top, Sound.BLOCK_BEACON_ACTIVATE, 0.8f, 1.4f);
|
||||
p.sendActionBar(Component.text("Aim with your camera!").color(NamedTextColor.AQUA));
|
||||
|
||||
new BukkitRunnable() {
|
||||
long left = FREEZE_TICKS;
|
||||
@@ -125,10 +133,12 @@ public class SkyDiveAttack implements Listener {
|
||||
p.setFallDistance(0);
|
||||
immuneUntil.put(p.getUniqueId(), System.currentTimeMillis() + FALL_IMMUNE_MS);
|
||||
p.getWorld().playSound(p.getLocation(), Sound.ENTITY_ENDER_DRAGON_FLAP, 1f, 1.2f);
|
||||
p.sendActionBar(Component.text("DIVE!").color(NamedTextColor.DARK_RED));
|
||||
|
||||
new BukkitRunnable() {
|
||||
int ticks = 0;
|
||||
boolean hit = false;
|
||||
Location prev = p.getLocation().add(0, 1, 0).clone();
|
||||
|
||||
@Override public void run() {
|
||||
if (!p.isOnline() || p.isDead()) { cleanup(p); cancel(); return; }
|
||||
@@ -139,19 +149,27 @@ public class SkyDiveAttack implements Listener {
|
||||
new Particle.DustOptions(Color.fromRGB(80, 160, 255), 1.4f));
|
||||
cur.getWorld().spawnParticle(Particle.CLOUD, cur, 1, 0.1, 0.1, 0.1, 0.02);
|
||||
|
||||
for (LivingEntity le : cur.getWorld().getNearbyLivingEntities(cur, 1.2)) {
|
||||
if (le == p) continue;
|
||||
if (!DamageUtil.canHurt(p, le)) continue;
|
||||
DamageUtil.apply(p, le, DAMAGE);
|
||||
Vector kb = dir.clone().multiply(1.2);
|
||||
kb.setY(kb.getY() + 0.4);
|
||||
le.setVelocity(kb);
|
||||
le.getWorld().spawnParticle(Particle.CRIT, le.getLocation().add(0, 1, 0), 12, 0.4, 0.4, 0.4, 0.1);
|
||||
le.getWorld().playSound(le.getLocation(), Sound.ENTITY_PLAYER_ATTACK_CRIT, 1f, 0.8f);
|
||||
plugin.getTension().startBattle(p, le);
|
||||
hit = true;
|
||||
break;
|
||||
// Семплируем весь пройденный за тик отрезок, иначе на скорости 2.8 цель проскакивает между тиками
|
||||
Vector seg = cur.clone().subtract(prev).toVector();
|
||||
double len = seg.length();
|
||||
int steps = Math.max(1, (int) Math.ceil(len / 0.5));
|
||||
for (int s = 0; s <= steps && !hit; s++) {
|
||||
Location check = prev.clone().add(seg.clone().multiply((double) s / steps));
|
||||
for (LivingEntity le : check.getWorld().getNearbyLivingEntities(check, 1.2)) {
|
||||
if (le == p) continue;
|
||||
if (!DamageUtil.canHurt(p, le)) continue;
|
||||
DamageUtil.apply(p, le, DAMAGE);
|
||||
Vector kb = dir.clone().multiply(1.2);
|
||||
kb.setY(kb.getY() + 0.4);
|
||||
le.setVelocity(kb);
|
||||
le.getWorld().spawnParticle(Particle.CRIT, le.getLocation().add(0, 1, 0), 12, 0.4, 0.4, 0.4, 0.1);
|
||||
le.getWorld().playSound(le.getLocation(), Sound.ENTITY_PLAYER_ATTACK_CRIT, 1f, 0.8f);
|
||||
plugin.getTension().startBattle(p, le);
|
||||
hit = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
prev = cur.clone();
|
||||
if (hit) { finish(); return; }
|
||||
Location ahead = p.getEyeLocation().add(dir.clone().multiply(1.0));
|
||||
if (ahead.getBlock().isSolid()) { finish(); return; }
|
||||
|
||||
Reference in New Issue
Block a user