feat: custom damage system - cancel vanilla damage, state-based hits, killer/survivor HP always 20
This commit is contained in:
parent
d59b965407
commit
371384ca8a
1 changed files with 110 additions and 0 deletions
|
|
@ -3,6 +3,8 @@ package dev.loki.phase;
|
|||
import dev.loki.chest.ChestManager;
|
||||
import dev.loki.chest.ChestOpening;
|
||||
import dev.loki.core.GameSession;
|
||||
import dev.loki.damage.AttackListener;
|
||||
import dev.loki.damage.DamageHandler;
|
||||
import dev.loki.gate.ExitGate;
|
||||
import dev.loki.gate.GateManager;
|
||||
import dev.loki.hook.Hook;
|
||||
|
|
@ -10,6 +12,7 @@ import dev.loki.hook.HookManager;
|
|||
import dev.loki.hook.HookRescue;
|
||||
import dev.loki.hook.HookSacrifice;
|
||||
import dev.loki.hook.HookStage;
|
||||
import dev.loki.killer.KillerController;
|
||||
import dev.loki.listener.PlayerInteractListener;
|
||||
import dev.loki.listener.PlayerMoveListener;
|
||||
import dev.loki.mdbd;
|
||||
|
|
@ -21,14 +24,21 @@ import dev.loki.pallet.PalletManager;
|
|||
import dev.loki.pallet.PalletStun;
|
||||
import dev.loki.player.BasePlayer;
|
||||
import dev.loki.player.Killer;
|
||||
import dev.loki.player.PlayerManager;
|
||||
import dev.loki.player.PlayerState;
|
||||
import dev.loki.player.Survivor;
|
||||
import dev.loki.state.StateMachine;
|
||||
import dev.loki.ui.ActionBar;
|
||||
import net.kyori.adventure.text.Component;
|
||||
import net.kyori.adventure.text.format.NamedTextColor;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Sound;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.EventPriority;
|
||||
import org.bukkit.event.HandlerList;
|
||||
import org.bukkit.event.Listener;
|
||||
import org.bukkit.event.entity.EntityDamageEvent;
|
||||
|
||||
public class GameplayPhase implements Phase {
|
||||
|
||||
|
|
@ -49,6 +59,14 @@ public class GameplayPhase implements Phase {
|
|||
private ChestManager chestManager;
|
||||
private ChestOpening chestOpening;
|
||||
|
||||
// Damage system
|
||||
private PlayerManager playerManager;
|
||||
private StateMachine stateMachine;
|
||||
private DamageHandler damageHandler;
|
||||
private KillerController killerController;
|
||||
private AttackListener attackListener;
|
||||
private Listener vanillaDamageBlocker;
|
||||
|
||||
// Listener references grabbed from plugin
|
||||
private PlayerMoveListener moveListener;
|
||||
private PlayerInteractListener interactListener;
|
||||
|
|
@ -87,6 +105,56 @@ public class GameplayPhase implements Phase {
|
|||
session.setHookManager(hookManager);
|
||||
session.setGateManager(gateManager);
|
||||
|
||||
// --- Damage system ---
|
||||
// Build PlayerManager from current session players
|
||||
playerManager = new PlayerManager();
|
||||
for (BasePlayer bp : session.getPlayers().values()) {
|
||||
playerManager.register(bp);
|
||||
}
|
||||
|
||||
stateMachine = new StateMachine();
|
||||
damageHandler = new DamageHandler(stateMachine);
|
||||
|
||||
// When survivor is injured — show title + sound
|
||||
damageHandler.setOnSurvivorInjured(survivor -> {
|
||||
Player p = survivor.getPlayer();
|
||||
if (p != null && p.isOnline()) {
|
||||
p.showTitle(net.kyori.adventure.title.Title.title(
|
||||
Component.text("РАНЕН!", net.kyori.adventure.text.format.TextColor.color(0xFF8C00)),
|
||||
Component.text("Найдите аптечку или союзника", NamedTextColor.YELLOW)
|
||||
));
|
||||
p.playSound(p.getLocation(), Sound.ENTITY_PLAYER_HURT, 1.0f, 0.8f);
|
||||
// Keep HP at 20 always — damage is state-based not HP-based
|
||||
p.setHealth(20.0);
|
||||
}
|
||||
});
|
||||
|
||||
// When survivor is downed — show title + sound
|
||||
damageHandler.setOnSurvivorDowned(survivor -> {
|
||||
Player p = survivor.getPlayer();
|
||||
if (p != null && p.isOnline()) {
|
||||
p.showTitle(net.kyori.adventure.title.Title.title(
|
||||
Component.text("НОКДАУН!", net.kyori.adventure.text.format.TextColor.color(0xFF2222)),
|
||||
Component.text("Ждите помощи...", NamedTextColor.RED)
|
||||
));
|
||||
p.playSound(p.getLocation(), Sound.ENTITY_PLAYER_HURT, 1.0f, 0.5f);
|
||||
p.setHealth(20.0);
|
||||
}
|
||||
});
|
||||
|
||||
killerController = new KillerController(plugin, playerManager, damageHandler, session.getConfig());
|
||||
|
||||
// AttackListener — intercepts EntityDamageByEntityEvent, cancels vanilla damage, applies custom
|
||||
attackListener = new AttackListener(playerManager, damageHandler,
|
||||
(killer, survivor) -> killerController.tryAttack(killer, survivor));
|
||||
attackListener.register(plugin);
|
||||
|
||||
// Block ALL vanilla damage for players in this session (fall, fire, mobs, etc.)
|
||||
vanillaDamageBlocker = new VanillaDamageBlocker(session);
|
||||
Bukkit.getPluginManager().registerEvents(vanillaDamageBlocker, plugin);
|
||||
|
||||
killerController.initialize();
|
||||
|
||||
// --- Wire listeners ---
|
||||
moveListener = plugin.getMoveListener();
|
||||
interactListener = plugin.getInteractListener();
|
||||
|
|
@ -136,6 +204,28 @@ public class GameplayPhase implements Phase {
|
|||
chestOpening.cancelAll();
|
||||
}
|
||||
|
||||
// Unregister damage listeners
|
||||
if (attackListener != null) {
|
||||
attackListener.unregister();
|
||||
}
|
||||
if (vanillaDamageBlocker != null) {
|
||||
HandlerList.unregisterAll(vanillaDamageBlocker);
|
||||
vanillaDamageBlocker = null;
|
||||
}
|
||||
if (killerController != null) {
|
||||
killerController.shutdown();
|
||||
}
|
||||
if (playerManager != null) {
|
||||
playerManager.clear();
|
||||
}
|
||||
// Restore HP for all players
|
||||
for (BasePlayer bp : session.getPlayers().values()) {
|
||||
Player p = bp.getPlayer();
|
||||
if (p != null && p.isOnline()) {
|
||||
p.setHealth(20.0);
|
||||
}
|
||||
}
|
||||
|
||||
Bukkit.broadcast(Component.text("[DBD] Игровая фаза завершена!", NamedTextColor.GOLD));
|
||||
}
|
||||
|
||||
|
|
@ -381,4 +471,24 @@ public class GameplayPhase implements Phase {
|
|||
}
|
||||
});
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// Inner class: blocks all vanilla damage for players in the session
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
private static class VanillaDamageBlocker implements Listener {
|
||||
private final GameSession session;
|
||||
|
||||
VanillaDamageBlocker(GameSession session) {
|
||||
this.session = session;
|
||||
}
|
||||
|
||||
@EventHandler(priority = EventPriority.HIGHEST)
|
||||
public void onDamage(EntityDamageEvent event) {
|
||||
if (!(event.getEntity() instanceof Player p)) return;
|
||||
if (!session.getPlayers().containsKey(p.getUniqueId())) return;
|
||||
event.setCancelled(true);
|
||||
p.setHealth(20.0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue