fix multiplayer: remove KNOCKED, swoon softlock, combat checks, dodge TP gate, inv cache, killfeed, threads/leaks
This commit is contained in:
@@ -34,43 +34,31 @@ public class SwoonHandler implements Listener {
|
||||
|
||||
public SwoonHandler(BlackKnifePlugin plugin) { this.plugin = plugin; }
|
||||
|
||||
@EventHandler(priority = EventPriority.HIGHEST)
|
||||
@EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true)
|
||||
public void onHit(org.bukkit.event.entity.EntityDamageByEntityEvent e) {
|
||||
if (!(e.getDamager() instanceof Player p)) return;
|
||||
if (p.getGameMode() == org.bukkit.GameMode.SPECTATOR) return;
|
||||
if (!BlackKnifeItem.is(p.getInventory().getItemInMainHand()) && !BlackKnifeItem.is(p.getInventory().getItemInOffHand())) return;
|
||||
if (!(e.getEntity() instanceof LivingEntity target)) return;
|
||||
if (target.getPersistentDataContainer().has(MAGIC_DAMAGE, PersistentDataType.BYTE)) {
|
||||
target.getPersistentDataContainer().remove(MAGIC_DAMAGE);
|
||||
return;
|
||||
}
|
||||
if (target.getPersistentDataContainer().has(SWOONED, PersistentDataType.BYTE)) return;
|
||||
if (target instanceof Player vt) {
|
||||
if (vt.getGameMode() == org.bukkit.GameMode.CREATIVE || vt.getGameMode() == org.bukkit.GameMode.SPECTATOR) return;
|
||||
if (vt.isInvulnerable()) return;
|
||||
}
|
||||
if (p.hasCooldown(Material.NETHERITE_SWORD)) return;
|
||||
e.setCancelled(true);
|
||||
plugin.getTension().setTP(p, Math.max(0, plugin.getTension().getTP(p) - 125f));
|
||||
if (target instanceof Player tp) {
|
||||
double maxHp = tp.getAttribute(org.bukkit.attribute.Attribute.GENERIC_MAX_HEALTH).getValue();
|
||||
var attr = tp.getAttribute(org.bukkit.attribute.Attribute.GENERIC_MAX_HEALTH);
|
||||
double maxHp = attr != null ? attr.getValue() : 20.0;
|
||||
double vhpTmp = tp.getHealth() - 999;
|
||||
double vhp = Math.max(-2147483648.0, Math.min(maxHp, vhpTmp));
|
||||
final double finalVhp = vhp;
|
||||
tp.setHealth(1.0);
|
||||
tp.setWalkSpeed(0f);
|
||||
tp.getPersistentDataContainer().set(SWOONED, PersistentDataType.BYTE, (byte) 1);
|
||||
tp.getPersistentDataContainer().set(VHP, PersistentDataType.DOUBLE, vhp);
|
||||
tp.addPotionEffect(new PotionEffect(PotionEffectType.SLOWNESS, 100000, 10, false, false, true));
|
||||
tp.addPotionEffect(new PotionEffect(PotionEffectType.JUMP_BOOST, 100000, 128, false, false, true));
|
||||
tp.addPotionEffect(new PotionEffect(PotionEffectType.WEAKNESS, 100000, 10, false, false, true));
|
||||
tp.addPotionEffect(new PotionEffect(PotionEffectType.DARKNESS, 100000, 0, false, false, true));
|
||||
tp.addPotionEffect(new PotionEffect(PotionEffectType.BLINDNESS, 100, 0, false, false, true));
|
||||
TextDisplay td = tp.getWorld().spawn(tp.getLocation().add(0, 2.4, 0), TextDisplay.class, d -> {
|
||||
d.text(Component.text(String.format("%.0f HP", finalVhp)).color(NamedTextColor.DARK_RED));
|
||||
d.setBillboard(Display.Billboard.CENTER);
|
||||
d.setSeeThrough(true);
|
||||
d.setShadowed(true);
|
||||
d.setBackgroundColor(org.bukkit.Color.fromARGB(64, 40, 0, 0));
|
||||
d.setAlignment(TextDisplay.TextAlignment.CENTER);
|
||||
d.getPersistentDataContainer().set(SWOONED, PersistentDataType.BYTE, (byte)1);
|
||||
});
|
||||
EntityTracker.mark(td);
|
||||
displays.put(tp.getUniqueId(), td);
|
||||
applySwoon(tp, vhp);
|
||||
tp.getWorld().spawnParticle(org.bukkit.Particle.SOUL, tp.getLocation().add(0,1,0), 40, 0.5,0.5,0.5,0.05);
|
||||
tp.getWorld().spawnParticle(org.bukkit.Particle.SCULK_SOUL, tp.getLocation().add(0,1,0), 15, 0.5,0.5,0.5,0.02);
|
||||
tp.getWorld().spawnParticle(org.bukkit.Particle.ASH, tp.getLocation().add(0,1,0), 20, 0.5,0.5,0.5,0);
|
||||
@@ -80,14 +68,7 @@ public class SwoonHandler implements Listener {
|
||||
tp.getWorld().playSound(tp.getLocation(), Sound.ENTITY_WARDEN_SONIC_BOOM, 1f, 0.5f);
|
||||
tp.getWorld().playSound(tp.getLocation(), Sound.ENTITY_ELDER_GUARDIAN_CURSE, 1f, 0.7f);
|
||||
if (Math.random() < 0.1) tp.getWorld().dropItemNaturally(tp.getLocation(), BlackKnifeItem.create());
|
||||
plugin.getServer().getScheduler().runTaskTimer(plugin, task -> {
|
||||
TextDisplay d = displays.get(tp.getUniqueId());
|
||||
if (d == null || !tp.isOnline() || !tp.getPersistentDataContainer().has(SWOONED, PersistentDataType.BYTE)) { task.cancel(); return; }
|
||||
d.teleport(tp.getLocation().add(0, 2.4, 0));
|
||||
Double cur = tp.getPersistentDataContainer().get(VHP, PersistentDataType.DOUBLE);
|
||||
if (cur != null) d.text(Component.text(String.format("%.0f HP", cur)).color(cur < 0 ? NamedTextColor.DARK_RED : NamedTextColor.YELLOW));
|
||||
if (tp.isDead()) { d.remove(); task.cancel(); }
|
||||
}, 2L, 2L);
|
||||
startDisplayTask(tp);
|
||||
} else {
|
||||
target.getPersistentDataContainer().set(MAGIC_DAMAGE, PersistentDataType.BYTE, (byte) 1);
|
||||
target.damage(999.0, p);
|
||||
@@ -154,31 +135,120 @@ public class SwoonHandler implements Listener {
|
||||
Double vhp = p.getPersistentDataContainer().get(VHP, PersistentDataType.DOUBLE);
|
||||
if (vhp == null) vhp = -10.0;
|
||||
double newVhp = vhp + heal;
|
||||
double maxHp = p.getAttribute(org.bukkit.attribute.Attribute.GENERIC_MAX_HEALTH).getValue();
|
||||
var attr = p.getAttribute(org.bukkit.attribute.Attribute.GENERIC_MAX_HEALTH);
|
||||
double maxHp = attr != null ? attr.getValue() : 20.0;
|
||||
newVhp = Math.min(maxHp, newVhp);
|
||||
p.getPersistentDataContainer().set(VHP, PersistentDataType.DOUBLE, newVhp);
|
||||
TextDisplay td = displays.get(p.getUniqueId());
|
||||
if (td != null) td.text(Component.text(String.format("%.0f HP", newVhp)).color(newVhp < 0 ? NamedTextColor.DARK_RED : newVhp < 1 ? NamedTextColor.YELLOW : NamedTextColor.GREEN));
|
||||
if (td != null && td.isValid()) td.text(Component.text(String.format("%.0f HP", newVhp)).color(newVhp < 0 ? NamedTextColor.DARK_RED : newVhp < 1 ? NamedTextColor.YELLOW : NamedTextColor.GREEN));
|
||||
if (newVhp >= 1) {
|
||||
p.getPersistentDataContainer().remove(SWOONED);
|
||||
p.getPersistentDataContainer().remove(VHP);
|
||||
p.setHealth(Math.min(newVhp, maxHp));
|
||||
p.setWalkSpeed(0.2f);
|
||||
p.removePotionEffect(PotionEffectType.SLOWNESS);
|
||||
p.removePotionEffect(PotionEffectType.JUMP_BOOST);
|
||||
p.removePotionEffect(PotionEffectType.WEAKNESS);
|
||||
p.removePotionEffect(PotionEffectType.DARKNESS);
|
||||
if (td != null) { td.remove(); displays.remove(p.getUniqueId()); }
|
||||
p.sendActionBar(Component.text("Revived from SWOON!").color(NamedTextColor.GREEN));
|
||||
p.getWorld().playSound(p.getLocation(), Sound.BLOCK_BEACON_ACTIVATE, 1f, 1.2f);
|
||||
revive(p);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void applySwoon(Player tp, double vhp) {
|
||||
tp.setHealth(1.0);
|
||||
try { tp.setWalkSpeed(0f); } catch (Exception ignored) {}
|
||||
tp.getPersistentDataContainer().set(SWOONED, PersistentDataType.BYTE, (byte) 1);
|
||||
tp.getPersistentDataContainer().set(VHP, PersistentDataType.DOUBLE, vhp);
|
||||
tp.addPotionEffect(new PotionEffect(PotionEffectType.SLOWNESS, 100000, 10, false, false, true));
|
||||
tp.addPotionEffect(new PotionEffect(PotionEffectType.JUMP_BOOST, 100000, 128, false, false, true));
|
||||
tp.addPotionEffect(new PotionEffect(PotionEffectType.WEAKNESS, 100000, 10, false, false, true));
|
||||
tp.addPotionEffect(new PotionEffect(PotionEffectType.DARKNESS, 100000, 0, false, false, true));
|
||||
tp.addPotionEffect(new PotionEffect(PotionEffectType.BLINDNESS, 100, 0, false, false, true));
|
||||
TextDisplay old = displays.remove(tp.getUniqueId());
|
||||
if (old != null && old.isValid()) { EntityTracker.untrack(old); old.remove(); }
|
||||
TextDisplay td = tp.getWorld().spawn(tp.getLocation().add(0, 2.4, 0), TextDisplay.class, d -> {
|
||||
d.text(Component.text(String.format("%.0f HP", vhp)).color(NamedTextColor.DARK_RED));
|
||||
d.setBillboard(Display.Billboard.CENTER);
|
||||
d.setSeeThrough(true);
|
||||
d.setShadowed(true);
|
||||
d.setBackgroundColor(org.bukkit.Color.fromARGB(64, 40, 0, 0));
|
||||
d.setAlignment(TextDisplay.TextAlignment.CENTER);
|
||||
d.getPersistentDataContainer().set(SWOONED, PersistentDataType.BYTE, (byte) 1);
|
||||
});
|
||||
EntityTracker.mark(td);
|
||||
displays.put(tp.getUniqueId(), td);
|
||||
}
|
||||
|
||||
private void startDisplayTask(Player tp) {
|
||||
plugin.getServer().getScheduler().runTaskTimer(plugin, task -> {
|
||||
TextDisplay d = displays.get(tp.getUniqueId());
|
||||
if (d == null || !d.isValid() || !tp.isOnline() || !tp.getPersistentDataContainer().has(SWOONED, PersistentDataType.BYTE)) {
|
||||
if (d != null && !d.isValid()) displays.remove(tp.getUniqueId());
|
||||
task.cancel();
|
||||
return;
|
||||
}
|
||||
d.teleport(tp.getLocation().add(0, 2.4, 0));
|
||||
Double cur = tp.getPersistentDataContainer().get(VHP, PersistentDataType.DOUBLE);
|
||||
if (cur != null) d.text(Component.text(String.format("%.0f HP", cur)).color(cur < 0 ? NamedTextColor.DARK_RED : NamedTextColor.YELLOW));
|
||||
if (tp.isDead()) { EntityTracker.untrack(d); d.remove(); displays.remove(tp.getUniqueId()); task.cancel(); }
|
||||
}, 2L, 2L);
|
||||
}
|
||||
|
||||
public void revive(Player p) {
|
||||
Double stored = p.getPersistentDataContainer().get(VHP, PersistentDataType.DOUBLE);
|
||||
p.getPersistentDataContainer().remove(SWOONED);
|
||||
p.getPersistentDataContainer().remove(VHP);
|
||||
var attr = p.getAttribute(org.bukkit.attribute.Attribute.GENERIC_MAX_HEALTH);
|
||||
double maxHp = attr != null ? attr.getValue() : 20.0;
|
||||
double hp = stored != null ? Math.min(Math.max(stored, 1.0), maxHp) : 1.0;
|
||||
try { p.setHealth(hp); } catch (Exception ignored) {}
|
||||
try { p.setWalkSpeed(0.2f); } catch (Exception ignored) {}
|
||||
p.removePotionEffect(PotionEffectType.SLOWNESS);
|
||||
p.removePotionEffect(PotionEffectType.JUMP_BOOST);
|
||||
p.removePotionEffect(PotionEffectType.WEAKNESS);
|
||||
p.removePotionEffect(PotionEffectType.DARKNESS);
|
||||
p.removePotionEffect(PotionEffectType.BLINDNESS);
|
||||
TextDisplay td = displays.remove(p.getUniqueId());
|
||||
if (td != null && td.isValid()) { EntityTracker.untrack(td); td.remove(); }
|
||||
p.sendActionBar(Component.text("Revived from SWOON!").color(NamedTextColor.GREEN));
|
||||
p.getWorld().playSound(p.getLocation(), Sound.BLOCK_BEACON_ACTIVATE, 1f, 1.2f);
|
||||
}
|
||||
|
||||
public void cleanupOffline(Player p) {
|
||||
TextDisplay td = displays.remove(p.getUniqueId());
|
||||
if (td != null && td.isValid()) { EntityTracker.untrack(td); td.remove(); }
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void onQuit(org.bukkit.event.player.PlayerQuitEvent e) {
|
||||
cleanupOffline(e.getPlayer());
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void onJoin(org.bukkit.event.player.PlayerJoinEvent e) {
|
||||
Player p = e.getPlayer();
|
||||
if (!p.getPersistentDataContainer().has(SWOONED, PersistentDataType.BYTE)) return;
|
||||
Double vhp = p.getPersistentDataContainer().get(VHP, PersistentDataType.DOUBLE);
|
||||
if (vhp == null) { p.getPersistentDataContainer().remove(SWOONED); try { p.setWalkSpeed(0.2f); } catch (Exception ignored) {} return; }
|
||||
applySwoon(p, vhp);
|
||||
startDisplayTask(p);
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void onRespawn(org.bukkit.event.player.PlayerRespawnEvent e) {
|
||||
Player p = e.getPlayer();
|
||||
if (!p.getPersistentDataContainer().has(SWOONED, PersistentDataType.BYTE)) return;
|
||||
p.getPersistentDataContainer().remove(SWOONED);
|
||||
p.getPersistentDataContainer().remove(VHP);
|
||||
try { p.setWalkSpeed(0.2f); } catch (Exception ignored) {}
|
||||
p.removePotionEffect(PotionEffectType.SLOWNESS);
|
||||
p.removePotionEffect(PotionEffectType.JUMP_BOOST);
|
||||
p.removePotionEffect(PotionEffectType.WEAKNESS);
|
||||
p.removePotionEffect(PotionEffectType.DARKNESS);
|
||||
p.removePotionEffect(PotionEffectType.BLINDNESS);
|
||||
cleanupOffline(p);
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void onDeath(PlayerDeathEvent e) {
|
||||
displays.remove(e.getEntity().getUniqueId());
|
||||
e.getEntity().getPersistentDataContainer().remove(SWOONED);
|
||||
Player p = e.getEntity();
|
||||
TextDisplay td = displays.remove(p.getUniqueId());
|
||||
if (td != null && td.isValid()) { EntityTracker.untrack(td); td.remove(); }
|
||||
p.getPersistentDataContainer().remove(SWOONED);
|
||||
p.getPersistentDataContainer().remove(VHP);
|
||||
}
|
||||
|
||||
public static boolean isSwooned(LivingEntity e) {
|
||||
|
||||
Reference in New Issue
Block a user