remove: key/toolbox/map items, keep only medkit and flashlight
This commit is contained in:
parent
f9847dbb73
commit
3d6204cc83
156 changed files with 583 additions and 517 deletions
|
|
@ -13,14 +13,12 @@ public class ChestLoot {
|
|||
this.random = ThreadLocalRandom.current();
|
||||
}
|
||||
|
||||
/** Roll a random item with weighted probabilities. */
|
||||
/** 55% медкит, 45% фонарик. Заряды чуть рандомные. */
|
||||
public ItemStack rollLoot() {
|
||||
int roll = random.nextInt(100);
|
||||
|
||||
if (roll < 30) return DBDItems.medkit(12 + random.nextInt(5)); // 30%
|
||||
if (roll < 55) return DBDItems.flashlight(6 + random.nextInt(4)); // 25%
|
||||
if (roll < 80) return DBDItems.toolbox(10 + random.nextInt(7)); // 25%
|
||||
if (roll < 92) return DBDItems.key(24 + random.nextInt(9)); // 12%
|
||||
return DBDItems.map(8 + random.nextInt(9)); // 8%
|
||||
if (random.nextInt(100) < 55) {
|
||||
return DBDItems.medkit(12 + random.nextInt(5));
|
||||
} else {
|
||||
return DBDItems.flashlight(6 + random.nextInt(3));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -10,8 +10,8 @@ import org.bukkit.persistence.PersistentDataType;
|
|||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Central factory for all DBD custom items.
|
||||
* Items are identified by a PersistentDataContainer tag "mdbd:item_type".
|
||||
* Central factory for DBD custom items: Medkit and Flashlight.
|
||||
* Items are identified by PersistentDataContainer tag "mdbd:item_type".
|
||||
* Charges are stored as "mdbd:charges".
|
||||
*/
|
||||
public final class DBDItems {
|
||||
|
|
@ -31,7 +31,7 @@ public final class DBDItems {
|
|||
charges, ItemType.MEDKIT.getDefaultCharges(),
|
||||
List.of(
|
||||
"<gray>Лечит одно состояние здоровья.",
|
||||
"<yellow>ПКМ <gray>— начать лечение"
|
||||
"<yellow>ПКМ <gray>— начать самолечение"
|
||||
),
|
||||
"MEDKIT"
|
||||
);
|
||||
|
|
@ -55,54 +55,6 @@ public final class DBDItems {
|
|||
|
||||
public static ItemStack flashlight() { return flashlight(ItemType.FLASHLIGHT.getDefaultCharges()); }
|
||||
|
||||
/** Ящик с инструментами — ускоряет ремонт генератора. */
|
||||
public static ItemStack toolbox(int charges) {
|
||||
return build(
|
||||
Material.CHEST,
|
||||
"<#00CED1>Ящик с инструментами",
|
||||
charges, ItemType.TOOLBOX.getDefaultCharges(),
|
||||
List.of(
|
||||
"<gray>Ускоряет ремонт генераторов.",
|
||||
"<yellow>Держите в руке <gray>во время ремонта"
|
||||
),
|
||||
"TOOLBOX"
|
||||
);
|
||||
}
|
||||
|
||||
public static ItemStack toolbox() { return toolbox(ItemType.TOOLBOX.getDefaultCharges()); }
|
||||
|
||||
/** Ключ — открывает люк (hatch). */
|
||||
public static ItemStack key(int charges) {
|
||||
return build(
|
||||
Material.TRIPWIRE_HOOK,
|
||||
"<#FFA500>Ключ",
|
||||
charges, ItemType.KEY.getDefaultCharges(),
|
||||
List.of(
|
||||
"<gray>Открывает люк немедленно.",
|
||||
"<yellow>ПКМ у люка <gray>— открыть"
|
||||
),
|
||||
"KEY"
|
||||
);
|
||||
}
|
||||
|
||||
public static ItemStack key() { return key(ItemType.KEY.getDefaultCharges()); }
|
||||
|
||||
/** Карта — показывает объекты на карте. */
|
||||
public static ItemStack map(int charges) {
|
||||
return build(
|
||||
Material.MAP,
|
||||
"<#87CEEB>Карта",
|
||||
charges, ItemType.MAP.getDefaultCharges(),
|
||||
List.of(
|
||||
"<gray>Раскрывает объекты поблизости.",
|
||||
"<yellow>ПКМ <gray>— активировать"
|
||||
),
|
||||
"MAP"
|
||||
);
|
||||
}
|
||||
|
||||
public static ItemStack map() { return map(ItemType.MAP.getDefaultCharges()); }
|
||||
|
||||
// ── Helpers ───────────────────────────────────────────────────────────────
|
||||
|
||||
private static ItemStack build(Material mat, String name, int charges, int maxCharges,
|
||||
|
|
@ -111,7 +63,6 @@ public final class DBDItems {
|
|||
item.editMeta(meta -> {
|
||||
meta.displayName(TextUtil.color(name));
|
||||
|
||||
// Build lore: description lines + charges bar
|
||||
var lore = new java.util.ArrayList<Component>();
|
||||
for (String line : loreLines) {
|
||||
lore.add(TextUtil.color(line));
|
||||
|
|
@ -148,51 +99,18 @@ public final class DBDItems {
|
|||
return c != null ? c : 0;
|
||||
}
|
||||
|
||||
/** Обновить заряды на существующем предмете и вернуть обновлённый стак. */
|
||||
public static ItemStack setCharges(ItemStack item, int newCharges) {
|
||||
if (item == null || !item.hasItemMeta()) return item;
|
||||
String type = getType(item);
|
||||
if (type == null) return item;
|
||||
int max = getMaxCharges(type);
|
||||
return build(item.getType(),
|
||||
getDisplayNameRaw(type), newCharges, max,
|
||||
getLoreRaw(type), type);
|
||||
return switch (type) {
|
||||
case "MEDKIT" -> medkit(newCharges);
|
||||
case "FLASHLIGHT" -> flashlight(newCharges);
|
||||
default -> item;
|
||||
};
|
||||
}
|
||||
|
||||
public static boolean isMedkit(ItemStack item) { return "MEDKIT".equals(getType(item)); }
|
||||
public static boolean isFlashlight(ItemStack item) { return "FLASHLIGHT".equals(getType(item)); }
|
||||
public static boolean isToolbox(ItemStack item) { return "TOOLBOX".equals(getType(item)); }
|
||||
public static boolean isKey(ItemStack item) { return "KEY".equals(getType(item)); }
|
||||
public static boolean isMap(ItemStack item) { return "MAP".equals(getType(item)); }
|
||||
public static boolean isDBDItem(ItemStack item) { return getType(item) != null; }
|
||||
|
||||
private static int getMaxCharges(String type) {
|
||||
return switch (type) {
|
||||
case "MEDKIT" -> ItemType.MEDKIT.getDefaultCharges();
|
||||
case "FLASHLIGHT" -> ItemType.FLASHLIGHT.getDefaultCharges();
|
||||
case "TOOLBOX" -> ItemType.TOOLBOX.getDefaultCharges();
|
||||
case "KEY" -> ItemType.KEY.getDefaultCharges();
|
||||
default -> ItemType.MAP.getDefaultCharges();
|
||||
};
|
||||
}
|
||||
|
||||
private static String getDisplayNameRaw(String type) {
|
||||
return switch (type) {
|
||||
case "MEDKIT" -> "<#00FF7F>Медкит";
|
||||
case "FLASHLIGHT" -> "<#FFD700>Фонарик";
|
||||
case "TOOLBOX" -> "<#00CED1>Ящик с инструментами";
|
||||
case "KEY" -> "<#FFA500>Ключ";
|
||||
default -> "<#87CEEB>Карта";
|
||||
};
|
||||
}
|
||||
|
||||
private static List<String> getLoreRaw(String type) {
|
||||
return switch (type) {
|
||||
case "MEDKIT" -> List.of("<gray>Лечит одно состояние здоровья.", "<yellow>ПКМ <gray>— начать лечение");
|
||||
case "FLASHLIGHT" -> List.of("<gray>Ослепляет киллера при попадании.", "<yellow>ПКМ <gray>— направить луч на киллера");
|
||||
case "TOOLBOX" -> List.of("<gray>Ускоряет ремонт генераторов.", "<yellow>Держите в руке <gray>во время ремонта");
|
||||
case "KEY" -> List.of("<gray>Открывает люк немедленно.", "<yellow>ПКМ у люка <gray>— открыть");
|
||||
default -> List.of("<gray>Раскрывает объекты поблизости.", "<yellow>ПКМ <gray>— активировать");
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,96 +0,0 @@
|
|||
package dev.loki.item;
|
||||
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.NamespacedKey;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.inventory.meta.ItemMeta;
|
||||
import org.bukkit.persistence.PersistentDataContainer;
|
||||
import org.bukkit.persistence.PersistentDataType;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
public class ItemKey implements BaseItem {
|
||||
|
||||
private static final NamespacedKey ITEM_KEY = new NamespacedKey("mdbd", "item_type");
|
||||
private static final NamespacedKey CHARGES_KEY = new NamespacedKey("mdbd", "charges");
|
||||
|
||||
private final int charges;
|
||||
|
||||
public ItemKey() {
|
||||
this(ItemType.KEY.getDefaultCharges());
|
||||
}
|
||||
|
||||
public ItemKey(int charges) {
|
||||
this.charges = charges;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemType getType() {
|
||||
return ItemType.KEY;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemStack createItemStack() {
|
||||
ItemStack item = new ItemStack(Material.TRIPWIRE_HOOK);
|
||||
ItemMeta meta = item.getItemMeta();
|
||||
if (meta != null) {
|
||||
meta.setDisplayName("§6" + getType().getDisplayName());
|
||||
meta.setLore(Arrays.asList(
|
||||
"§7" + getType().getDescription(),
|
||||
"§eCharges: §f" + charges + "/" + getType().getDefaultCharges(),
|
||||
"§7Opens the Hatch instantly"
|
||||
));
|
||||
|
||||
PersistentDataContainer pdc = meta.getPersistentDataContainer();
|
||||
pdc.set(ITEM_KEY, PersistentDataType.STRING, getItemId());
|
||||
pdc.set(CHARGES_KEY, PersistentDataType.INTEGER, charges);
|
||||
|
||||
item.setItemMeta(meta);
|
||||
}
|
||||
return item;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canUse(Player player) {
|
||||
return charges > 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onUse(Player player) {
|
||||
if (charges > 0) {
|
||||
player.sendMessage("§6You use the Key on the Hatch...");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDeplete(Player player) {
|
||||
player.getInventory().setItemInMainHand(null);
|
||||
player.sendMessage("§cYour key breaks!");
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getCharges() {
|
||||
return charges;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setCharges(int charges) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isDepleted() {
|
||||
return charges <= 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getItemId() {
|
||||
return "KEY";
|
||||
}
|
||||
|
||||
public static boolean isKey(ItemStack item) {
|
||||
if (item == null || !item.hasItemMeta()) return false;
|
||||
PersistentDataContainer pdc = item.getItemMeta().getPersistentDataContainer();
|
||||
return "KEY".equals(pdc.get(ITEM_KEY, PersistentDataType.STRING));
|
||||
}
|
||||
}
|
||||
|
|
@ -1,96 +0,0 @@
|
|||
package dev.loki.item;
|
||||
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.NamespacedKey;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.inventory.meta.ItemMeta;
|
||||
import org.bukkit.persistence.PersistentDataContainer;
|
||||
import org.bukkit.persistence.PersistentDataType;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
public class ItemMap implements BaseItem {
|
||||
|
||||
private static final NamespacedKey ITEM_KEY = new NamespacedKey("mdbd", "item_type");
|
||||
private static final NamespacedKey CHARGES_KEY = new NamespacedKey("mdbd", "charges");
|
||||
|
||||
private final int charges;
|
||||
|
||||
public ItemMap() {
|
||||
this(ItemType.MAP.getDefaultCharges());
|
||||
}
|
||||
|
||||
public ItemMap(int charges) {
|
||||
this.charges = charges;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemType getType() {
|
||||
return ItemType.MAP;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemStack createItemStack() {
|
||||
ItemStack item = new ItemStack(Material.MAP);
|
||||
ItemMeta meta = item.getItemMeta();
|
||||
if (meta != null) {
|
||||
meta.setDisplayName("§d" + getType().getDisplayName());
|
||||
meta.setLore(Arrays.asList(
|
||||
"§7" + getType().getDescription(),
|
||||
"§eCharges: §f" + charges + "/" + getType().getDefaultCharges(),
|
||||
"§7Right-click to reveal generators"
|
||||
));
|
||||
|
||||
PersistentDataContainer pdc = meta.getPersistentDataContainer();
|
||||
pdc.set(ITEM_KEY, PersistentDataType.STRING, getItemId());
|
||||
pdc.set(CHARGES_KEY, PersistentDataType.INTEGER, charges);
|
||||
|
||||
item.setItemMeta(meta);
|
||||
}
|
||||
return item;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canUse(Player player) {
|
||||
return charges > 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onUse(Player player) {
|
||||
if (charges > 0) {
|
||||
player.sendMessage("§dThe Map reveals nearby generators!");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDeplete(Player player) {
|
||||
player.getInventory().setItemInMainHand(null);
|
||||
player.sendMessage("§cYour map has faded!");
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getCharges() {
|
||||
return charges;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setCharges(int charges) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isDepleted() {
|
||||
return charges <= 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getItemId() {
|
||||
return "MAP";
|
||||
}
|
||||
|
||||
public static boolean isMap(ItemStack item) {
|
||||
if (item == null || !item.hasItemMeta()) return false;
|
||||
PersistentDataContainer pdc = item.getItemMeta().getPersistentDataContainer();
|
||||
return "MAP".equals(pdc.get(ITEM_KEY, PersistentDataType.STRING));
|
||||
}
|
||||
}
|
||||
|
|
@ -1,98 +0,0 @@
|
|||
package dev.loki.item;
|
||||
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.NamespacedKey;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.inventory.meta.ItemMeta;
|
||||
import org.bukkit.persistence.PersistentDataContainer;
|
||||
import org.bukkit.persistence.PersistentDataType;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
public class ItemToolbox implements BaseItem {
|
||||
|
||||
private static final NamespacedKey ITEM_KEY = new NamespacedKey("mdbd", "item_type");
|
||||
private static final NamespacedKey CHARGES_KEY = new NamespacedKey("mdbd", "charges");
|
||||
|
||||
private final int charges;
|
||||
|
||||
public ItemToolbox() {
|
||||
this(ItemType.TOOLBOX.getDefaultCharges());
|
||||
}
|
||||
|
||||
public ItemToolbox(int charges) {
|
||||
this.charges = charges;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemType getType() {
|
||||
return ItemType.TOOLBOX;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemStack createItemStack() {
|
||||
ItemStack item = new ItemStack(Material.CHEST);
|
||||
ItemMeta meta = item.getItemMeta();
|
||||
if (meta != null) {
|
||||
meta.setDisplayName("§b" + getType().getDisplayName());
|
||||
meta.setLore(Arrays.asList(
|
||||
"§7" + getType().getDescription(),
|
||||
"§eCharges: §f" + charges + "/" + getType().getDefaultCharges(),
|
||||
"§7Hold while repairing for bonus speed"
|
||||
));
|
||||
|
||||
PersistentDataContainer pdc = meta.getPersistentDataContainer();
|
||||
pdc.set(ITEM_KEY, PersistentDataType.STRING, getItemId());
|
||||
pdc.set(CHARGES_KEY, PersistentDataType.INTEGER, charges);
|
||||
|
||||
item.setItemMeta(meta);
|
||||
}
|
||||
return item;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canUse(Player player) {
|
||||
return charges > 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onUse(Player player) {
|
||||
player.sendMessage("§bYour toolbox speeds up the repair!");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDeplete(Player player) {
|
||||
player.getInventory().setItemInMainHand(null);
|
||||
player.sendMessage("§cYour toolbox is empty!");
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getCharges() {
|
||||
return charges;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setCharges(int charges) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isDepleted() {
|
||||
return charges <= 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getItemId() {
|
||||
return "TOOLBOX";
|
||||
}
|
||||
|
||||
public static boolean isToolbox(ItemStack item) {
|
||||
if (item == null || !item.hasItemMeta()) return false;
|
||||
PersistentDataContainer pdc = item.getItemMeta().getPersistentDataContainer();
|
||||
return "TOOLBOX".equals(pdc.get(ITEM_KEY, PersistentDataType.STRING));
|
||||
}
|
||||
|
||||
public static double getRepairBonus() {
|
||||
return 0.15;
|
||||
}
|
||||
}
|
||||
|
|
@ -2,10 +2,7 @@ package dev.loki.item;
|
|||
|
||||
public enum ItemType {
|
||||
MEDKIT("Medkit", "Heals one health state", 16),
|
||||
FLASHLIGHT("Flashlight", "Blinds the Killer", 8),
|
||||
TOOLBOX("Toolbox", "Speeds up repairs", 16),
|
||||
KEY("Key", "Opens the Hatch", 32),
|
||||
MAP("Map", "Reveals objectives", 16);
|
||||
FLASHLIGHT("Flashlight", "Blinds the Killer", 8);
|
||||
|
||||
private final String displayName;
|
||||
private final String description;
|
||||
|
|
@ -17,15 +14,7 @@ public enum ItemType {
|
|||
this.defaultCharges = defaultCharges;
|
||||
}
|
||||
|
||||
public String getDisplayName() {
|
||||
return displayName;
|
||||
}
|
||||
|
||||
public String getDescription() {
|
||||
return description;
|
||||
}
|
||||
|
||||
public int getDefaultCharges() {
|
||||
return defaultCharges;
|
||||
}
|
||||
public String getDisplayName() { return displayName; }
|
||||
public String getDescription() { return description; }
|
||||
public int getDefaultCharges() { return defaultCharges; }
|
||||
}
|
||||
|
|
|
|||
|
|
@ -27,14 +27,13 @@ import java.util.Map;
|
|||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
* Handles right-click usage of DBD custom items during gameplay.
|
||||
* Handles right-click usage of DBD custom items (Medkit, Flashlight) during gameplay.
|
||||
*/
|
||||
public class ItemUseListener implements Listener {
|
||||
|
||||
private final Plugin plugin;
|
||||
private final GameSession session;
|
||||
|
||||
// Medkit heal: survivor UUID → task
|
||||
private final Map<UUID, BukkitTask> activeHeals = new HashMap<>();
|
||||
private static final int MEDKIT_TICKS = 160; // 8 seconds
|
||||
|
||||
|
|
@ -68,33 +67,28 @@ public class ItemUseListener implements Listener {
|
|||
ItemStack hand = player.getInventory().getItemInMainHand();
|
||||
if (!DBDItems.isDBDItem(hand)) return;
|
||||
|
||||
event.setCancelled(true);
|
||||
|
||||
String type = DBDItems.getType(hand);
|
||||
if (type == null) return;
|
||||
|
||||
event.setCancelled(true); // prevent block interaction
|
||||
|
||||
switch (type) {
|
||||
case "MEDKIT" -> useMedkit(player, (Survivor) bp, hand);
|
||||
case "FLASHLIGHT" -> useFlashlight(player, hand);
|
||||
case "TOOLBOX" -> { /* passive — handled in repair */ }
|
||||
case "KEY" -> useKey(player, (Survivor) bp, hand);
|
||||
case "MAP" -> useMap(player, hand);
|
||||
if ("MEDKIT".equals(type)) {
|
||||
useMedkit(player, (Survivor) bp, hand);
|
||||
} else if ("FLASHLIGHT".equals(type)) {
|
||||
useFlashlight(player, hand);
|
||||
}
|
||||
}
|
||||
|
||||
// ── Medkit ───────────────────────────────────────────────────────────────
|
||||
// ── Медкит ────────────────────────────────────────────────────────────────
|
||||
|
||||
private void useMedkit(Player player, Survivor survivor, ItemStack item) {
|
||||
UUID uuid = player.getUniqueId();
|
||||
|
||||
// Toggle: if already healing, cancel
|
||||
// Повторный ПКМ — отмена лечения
|
||||
if (activeHeals.containsKey(uuid)) {
|
||||
cancelHeal(player);
|
||||
return;
|
||||
}
|
||||
|
||||
PlayerState state = survivor.getState();
|
||||
if (state != PlayerState.INJURED) {
|
||||
if (survivor.getState() != PlayerState.INJURED) {
|
||||
player.sendMessage(Component.text("Вы не ранены!", NamedTextColor.RED));
|
||||
return;
|
||||
}
|
||||
|
|
@ -106,11 +100,10 @@ public class ItemUseListener implements Listener {
|
|||
}
|
||||
|
||||
player.sendMessage(Component.text("Начинаете самолечение...", NamedTextColor.GREEN));
|
||||
player.sendActionBar(Component.text("⚕ Самолечение...", NamedTextColor.GREEN));
|
||||
|
||||
BukkitTask task = new BukkitRunnable() {
|
||||
int ticks = 0;
|
||||
int chargesLeft = charges;
|
||||
final int startCharges = charges;
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
|
|
@ -121,29 +114,40 @@ public class ItemUseListener implements Listener {
|
|||
}
|
||||
|
||||
ticks++;
|
||||
chargesLeft = Math.max(0, charges - ticks);
|
||||
|
||||
// Update action bar progress
|
||||
int filled = (int)(8.0 * ticks / MEDKIT_TICKS);
|
||||
// Прогресс в action bar
|
||||
int filled = (int) (8.0 * ticks / MEDKIT_TICKS);
|
||||
int empty = 8 - filled;
|
||||
int pct = (int) (100.0 * ticks / MEDKIT_TICKS);
|
||||
player.sendActionBar(Component.text(
|
||||
"⚕ " + "█".repeat(filled) + "░".repeat(empty) +
|
||||
" " + (int)(100.0 * ticks / MEDKIT_TICKS) + "%",
|
||||
"⚕ " + "█".repeat(filled) + "░".repeat(empty) + " " + pct + "%",
|
||||
NamedTextColor.GREEN));
|
||||
|
||||
// Use 1 charge per 10 ticks
|
||||
if (ticks % 10 == 0) {
|
||||
updateItemCharges(player, chargesLeft);
|
||||
player.playSound(player.getLocation(), Sound.ENTITY_PLAYER_HURT, 0.2f, 1.5f);
|
||||
// Звук каждые 20 тиков
|
||||
if (ticks % 20 == 0) {
|
||||
player.playSound(player.getLocation(), Sound.ENTITY_PLAYER_HURT, 0.15f, 1.8f);
|
||||
// Обновляем заряды на предмете
|
||||
int usedCharges = (int)(1.0 * ticks / MEDKIT_TICKS * startCharges);
|
||||
int remaining = Math.max(1, startCharges - usedCharges);
|
||||
player.getInventory().setItemInMainHand(DBDItems.setCharges(
|
||||
player.getInventory().getItemInMainHand(), remaining));
|
||||
}
|
||||
|
||||
if (ticks >= MEDKIT_TICKS) {
|
||||
// Heal done
|
||||
survivor.setState(PlayerState.HEALTHY);
|
||||
player.sendMessage(Component.text("✔ Вы вылечились!", NamedTextColor.GREEN));
|
||||
player.sendActionBar(Component.empty());
|
||||
player.playSound(player.getLocation(), Sound.ENTITY_PLAYER_LEVELUP, 0.5f, 1.5f);
|
||||
updateItemCharges(player, Math.max(0, charges - MEDKIT_TICKS / 10));
|
||||
player.playSound(player.getLocation(), Sound.ENTITY_PLAYER_LEVELUP, 0.6f, 1.5f);
|
||||
|
||||
// Тратим заряды
|
||||
int remaining = startCharges - 8;
|
||||
if (remaining <= 0) {
|
||||
player.getInventory().setItemInMainHand(null);
|
||||
player.sendMessage(Component.text("Медкит израсходован.", NamedTextColor.RED));
|
||||
} else {
|
||||
player.getInventory().setItemInMainHand(DBDItems.medkit(remaining));
|
||||
}
|
||||
|
||||
activeHeals.remove(uuid);
|
||||
cancel();
|
||||
}
|
||||
|
|
@ -162,7 +166,7 @@ public class ItemUseListener implements Listener {
|
|||
}
|
||||
}
|
||||
|
||||
// ── Flashlight ────────────────────────────────────────────────────────────
|
||||
// ── Фонарик ───────────────────────────────────────────────────────────────
|
||||
|
||||
private void useFlashlight(Player player, ItemStack item) {
|
||||
int charges = DBDItems.getCharges(item);
|
||||
|
|
@ -171,7 +175,7 @@ public class ItemUseListener implements Listener {
|
|||
return;
|
||||
}
|
||||
|
||||
// Ray-trace to find killer within 15 blocks
|
||||
// Луч 15 блоков
|
||||
var result = player.getWorld().rayTraceEntities(
|
||||
player.getEyeLocation(),
|
||||
player.getEyeLocation().getDirection(),
|
||||
|
|
@ -184,10 +188,10 @@ public class ItemUseListener implements Listener {
|
|||
BasePlayer bp = session.getPlayer(target.getUniqueId());
|
||||
if (bp != null && bp.isKiller()) {
|
||||
target.addPotionEffect(new PotionEffect(PotionEffectType.BLINDNESS, 60, 1, false, false));
|
||||
target.addPotionEffect(new PotionEffect(PotionEffectType.SLOWNESS, 60, 3, false, false));
|
||||
target.addPotionEffect(new PotionEffect(PotionEffectType.SLOWNESS, 50, 2, false, false));
|
||||
target.playSound(target.getLocation(), Sound.ENTITY_BLAZE_HURT, 1.0f, 0.5f);
|
||||
player.sendMessage(Component.text("✔ Ослепили киллера!", NamedTextColor.YELLOW));
|
||||
target.sendMessage(Component.text("☀ Вас ослепили фонариком!", NamedTextColor.YELLOW));
|
||||
player.sendMessage(Component.text("✔ Ослепили киллера!", NamedTextColor.YELLOW));
|
||||
hitKiller = true;
|
||||
}
|
||||
}
|
||||
|
|
@ -196,69 +200,15 @@ public class ItemUseListener implements Listener {
|
|||
player.sendMessage(Component.text("Мимо...", NamedTextColor.GRAY));
|
||||
}
|
||||
|
||||
// Spend 1 charge per use
|
||||
updateItemCharges(player, charges - 1);
|
||||
// 1 заряд за использование
|
||||
int remaining = charges - 1;
|
||||
if (remaining <= 0) {
|
||||
player.getInventory().setItemInMainHand(null);
|
||||
player.sendMessage(Component.text("Фонарик разрядился.", NamedTextColor.RED));
|
||||
} else {
|
||||
player.getInventory().setItemInMainHand(DBDItems.flashlight(remaining));
|
||||
}
|
||||
|
||||
player.playSound(player.getLocation(), Sound.BLOCK_REDSTONE_TORCH_BURNOUT, 0.3f, 1.5f);
|
||||
}
|
||||
|
||||
// ── Key ───────────────────────────────────────────────────────────────────
|
||||
|
||||
private void useKey(Player player, Survivor survivor, ItemStack item) {
|
||||
int charges = DBDItems.getCharges(item);
|
||||
if (charges <= 0) {
|
||||
player.sendMessage(Component.text("Ключ сломан!", NamedTextColor.RED));
|
||||
return;
|
||||
}
|
||||
// Actual hatch opening logic is handled by hatch system
|
||||
// This just plays the animation and spends a charge
|
||||
player.sendMessage(Component.text("Вы используете ключ...", NamedTextColor.GOLD));
|
||||
player.playSound(player.getLocation(), Sound.BLOCK_IRON_DOOR_OPEN, 1.0f, 0.8f);
|
||||
updateItemCharges(player, charges - 1);
|
||||
}
|
||||
|
||||
// ── Map ───────────────────────────────────────────────────────────────────
|
||||
|
||||
private void useMap(Player player, ItemStack item) {
|
||||
int charges = DBDItems.getCharges(item);
|
||||
if (charges <= 0) {
|
||||
player.sendMessage(Component.text("Карта использована!", NamedTextColor.RED));
|
||||
return;
|
||||
}
|
||||
|
||||
// Show nearby generators / hooks in chat
|
||||
player.sendMessage(Component.text("═══ Карта (ближайшие объекты) ═══", NamedTextColor.AQUA));
|
||||
|
||||
var genManager = session.getGeneratorManager();
|
||||
if (genManager != null) {
|
||||
genManager.getIncompleteGenerators().stream()
|
||||
.filter(g -> g.getLocation().getWorld().equals(player.getWorld()))
|
||||
.sorted((a, b) -> Double.compare(
|
||||
a.getLocation().distance(player.getLocation()),
|
||||
b.getLocation().distance(player.getLocation())))
|
||||
.limit(3)
|
||||
.forEach(g -> {
|
||||
int dist = (int) g.getLocation().distance(player.getLocation());
|
||||
player.sendMessage(Component.text(
|
||||
" ⚙ Генератор [" + (int)g.getProgress() + "%] — " + dist + " блоков",
|
||||
NamedTextColor.YELLOW));
|
||||
});
|
||||
}
|
||||
|
||||
updateItemCharges(player, charges - 1);
|
||||
player.playSound(player.getLocation(), Sound.ITEM_ARMOR_EQUIP_LEATHER, 0.5f, 1.0f);
|
||||
}
|
||||
|
||||
// ── Utils ─────────────────────────────────────────────────────────────────
|
||||
|
||||
private void updateItemCharges(Player player, int newCharges) {
|
||||
ItemStack item = player.getInventory().getItemInMainHand();
|
||||
if (!DBDItems.isDBDItem(item)) return;
|
||||
|
||||
if (newCharges <= 0) {
|
||||
player.getInventory().setItemInMainHand(null);
|
||||
player.sendMessage(Component.text("Предмет израсходован.", NamedTextColor.RED));
|
||||
} else {
|
||||
player.getInventory().setItemInMainHand(DBDItems.setCharges(item, newCharges));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue