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.ChestManager;
|
||||||
import dev.loki.chest.ChestOpening;
|
import dev.loki.chest.ChestOpening;
|
||||||
import dev.loki.core.GameSession;
|
import dev.loki.core.GameSession;
|
||||||
|
import dev.loki.damage.AttackListener;
|
||||||
|
import dev.loki.damage.DamageHandler;
|
||||||
import dev.loki.gate.ExitGate;
|
import dev.loki.gate.ExitGate;
|
||||||
import dev.loki.gate.GateManager;
|
import dev.loki.gate.GateManager;
|
||||||
import dev.loki.hook.Hook;
|
import dev.loki.hook.Hook;
|
||||||
|
|
@ -10,6 +12,7 @@ import dev.loki.hook.HookManager;
|
||||||
import dev.loki.hook.HookRescue;
|
import dev.loki.hook.HookRescue;
|
||||||
import dev.loki.hook.HookSacrifice;
|
import dev.loki.hook.HookSacrifice;
|
||||||
import dev.loki.hook.HookStage;
|
import dev.loki.hook.HookStage;
|
||||||
|
import dev.loki.killer.KillerController;
|
||||||
import dev.loki.listener.PlayerInteractListener;
|
import dev.loki.listener.PlayerInteractListener;
|
||||||
import dev.loki.listener.PlayerMoveListener;
|
import dev.loki.listener.PlayerMoveListener;
|
||||||
import dev.loki.mdbd;
|
import dev.loki.mdbd;
|
||||||
|
|
@ -21,14 +24,21 @@ import dev.loki.pallet.PalletManager;
|
||||||
import dev.loki.pallet.PalletStun;
|
import dev.loki.pallet.PalletStun;
|
||||||
import dev.loki.player.BasePlayer;
|
import dev.loki.player.BasePlayer;
|
||||||
import dev.loki.player.Killer;
|
import dev.loki.player.Killer;
|
||||||
|
import dev.loki.player.PlayerManager;
|
||||||
import dev.loki.player.PlayerState;
|
import dev.loki.player.PlayerState;
|
||||||
import dev.loki.player.Survivor;
|
import dev.loki.player.Survivor;
|
||||||
|
import dev.loki.state.StateMachine;
|
||||||
import dev.loki.ui.ActionBar;
|
import dev.loki.ui.ActionBar;
|
||||||
import net.kyori.adventure.text.Component;
|
import net.kyori.adventure.text.Component;
|
||||||
import net.kyori.adventure.text.format.NamedTextColor;
|
import net.kyori.adventure.text.format.NamedTextColor;
|
||||||
import org.bukkit.Bukkit;
|
import org.bukkit.Bukkit;
|
||||||
import org.bukkit.Sound;
|
import org.bukkit.Sound;
|
||||||
import org.bukkit.entity.Player;
|
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 {
|
public class GameplayPhase implements Phase {
|
||||||
|
|
||||||
|
|
@ -49,6 +59,14 @@ public class GameplayPhase implements Phase {
|
||||||
private ChestManager chestManager;
|
private ChestManager chestManager;
|
||||||
private ChestOpening chestOpening;
|
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
|
// Listener references grabbed from plugin
|
||||||
private PlayerMoveListener moveListener;
|
private PlayerMoveListener moveListener;
|
||||||
private PlayerInteractListener interactListener;
|
private PlayerInteractListener interactListener;
|
||||||
|
|
@ -87,6 +105,56 @@ public class GameplayPhase implements Phase {
|
||||||
session.setHookManager(hookManager);
|
session.setHookManager(hookManager);
|
||||||
session.setGateManager(gateManager);
|
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 ---
|
// --- Wire listeners ---
|
||||||
moveListener = plugin.getMoveListener();
|
moveListener = plugin.getMoveListener();
|
||||||
interactListener = plugin.getInteractListener();
|
interactListener = plugin.getInteractListener();
|
||||||
|
|
@ -136,6 +204,28 @@ public class GameplayPhase implements Phase {
|
||||||
chestOpening.cancelAll();
|
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));
|
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