feat: DeltaCraft awakening - TP only with magic/knife + soulbound MagicOrb + all physical triggers + Lang config

This commit is contained in:
SashegDev
2026-08-28 04:08:41 +03:00
parent 4ce654b838
commit a8ce2375c0
8 changed files with 230 additions and 11 deletions
@@ -0,0 +1,98 @@
package me.sashegdev.blackknife;
import org.bukkit.entity.LivingEntity;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.Listener;
import org.bukkit.event.entity.EntityDamageEvent;
import org.bukkit.event.entity.EntityDamageByEntityEvent;
import org.bukkit.event.entity.PlayerDeathEvent;
import org.bukkit.event.player.PlayerMoveEvent;
import java.util.HashMap;
import java.util.Map;
public class AwakeningManager implements Listener {
private final BlackKnifePlugin plugin;
private final MagicManager mgr;
private final Map<String, Double> chances = new HashMap<>();
public AwakeningManager(BlackKnifePlugin plugin, MagicManager mgr) {
this.plugin = plugin; this.mgr = mgr;
reloadChances();
}
public void reloadChances() {
chances.clear();
var cfg = plugin.getConfig();
chances.put("mob", cfg.getDouble("awakening.chances.mob", 0.05));
chances.put("kill", cfg.getDouble("awakening.chances.kill", 0.08));
chances.put("fall", cfg.getDouble("awakening.chances.fall", 0.03));
chances.put("lava", cfg.getDouble("awakening.chances.lava", 0.04));
chances.put("void", cfg.getDouble("awakening.chances.void", 0.10));
chances.put("generic", cfg.getDouble("awakening.chances.generic", 0.01));
}
private boolean tryAwaken(Player p, String cause) {
if (mgr.hasAwakened(p.getUniqueId())) return false;
if (BlackKnifeItem.is(p.getInventory().getItemInMainHand()) || BlackKnifeItem.is(p.getInventory().getItemInOffHand())) return false;
for (var it : p.getInventory().getContents()) if (BlackKnifeItem.is(it)) return false;
double chance = chances.getOrDefault(cause, chances.getOrDefault("generic", 0.01));
if (Math.random() >= chance) return false;
MagicProfile prof = mgr.awaken(p, cause);
p.getInventory().addItem(MagicItem.create(prof));
p.sendTitle("§dПробуждение!", "§7Магия пробудилась: " + cause, 10, 60, 10);
p.getWorld().playSound(p.getLocation(), org.bukkit.Sound.BLOCK_BEACON_ACTIVATE, 1f, 1.2f);
p.sendMessage("§d[Пробуждение] §7Твоя магия пробудилась! Причина: " + cause);
plugin.getLogger().info("Awakened " + p.getName() + " via " + cause);
return true;
}
@EventHandler(priority = EventPriority.MONITOR)
public void onDamage(EntityDamageEvent e) {
if (!(e.getEntity() instanceof Player p)) return;
if (e.isCancelled()) return;
String cause = e.getCause().name().toLowerCase();
if (cause.equals("fall")) {
int minFall = plugin.getConfig().getInt("awakening.fall_min", 15);
if (p.getFallDistance() >= minFall) tryAwaken(p, "fall");
else tryAwaken(p, "generic");
} else if (cause.equals("lava") || cause.equals("fire") || cause.equals("fire_tick")) tryAwaken(p, "lava");
else if (cause.equals("void")) tryAwaken(p, "void");
else tryAwaken(p, "generic");
}
@EventHandler(priority = EventPriority.MONITOR)
public void onDamageByEntity(EntityDamageByEntityEvent e) {
if (e.getEntity() instanceof Player victim) {
if (e.getDamager() instanceof LivingEntity le && !(le instanceof Player)) tryAwaken(victim, "mob");
}
if (e.getDamager() instanceof Player killer && e.getEntity() instanceof Player) {
tryAwaken(killer, "kill");
}
}
@EventHandler(priority = EventPriority.MONITOR)
public void onDeath(PlayerDeathEvent e) {
Player victim = e.getEntity();
Player killer = victim.getKiller();
if (killer != null && killer != victim) tryAwaken(killer, "kill");
var last = victim.getLastDamageCause();
if (last != null && last.getCause() != null) {
String cause = last.getCause().name().toLowerCase();
if (last instanceof EntityDamageByEntityEvent ev && ev.getDamager() instanceof LivingEntity le && !(le instanceof Player)) tryAwaken(victim, "mob");
else if (cause.equals("fall")) {
int minFall = plugin.getConfig().getInt("awakening.fall_min", 15);
if (victim.getFallDistance() >= minFall) tryAwaken(victim, "fall");
}
}
}
@EventHandler(priority = EventPriority.MONITOR)
public void onMove(PlayerMoveEvent e) {
Player p = e.getPlayer();
if (e.getFrom().getY() - e.getTo().getY() > 3) {
if (p.getFallDistance() > 10) tryAwaken(p, "fall");
}
}
}
@@ -28,6 +28,7 @@ public class BlackKnifeCommand implements CommandExecutor {
if (args.length >= 1 && args[0].equalsIgnoreCase("reload")) { if (args.length >= 1 && args[0].equalsIgnoreCase("reload")) {
if (chatConfig != null) chatConfig.load(); if (chatConfig != null) chatConfig.load();
plugin.reloadConfig(); plugin.reloadConfig();
plugin.reloadLang();
sender.sendMessage(Component.text("Chat+config reloaded lang=" + plugin.getLang()).color(NamedTextColor.GREEN)); sender.sendMessage(Component.text("Chat+config reloaded lang=" + plugin.getLang()).color(NamedTextColor.GREEN));
return true; return true;
} }
@@ -3,15 +3,18 @@ package me.sashegdev.blackknife;
import org.bukkit.plugin.java.JavaPlugin; import org.bukkit.plugin.java.JavaPlugin;
public class BlackKnifePlugin extends JavaPlugin { public class BlackKnifePlugin extends JavaPlugin {
private static BlackKnifePlugin instance;
private TensionManager tension; private TensionManager tension;
private MagicManager magicManager; private MagicManager magicManager;
private MagicListener magicListener; private MagicListener magicListener;
private ChatConfig chatConfig; private ChatConfig chatConfig;
private ChatHandler chatHandler; private ChatHandler chatHandler;
private AwakeningManager awakeningManager;
private String lang = "ru"; private String lang = "ru";
@Override @Override
public void onEnable() { public void onEnable() {
instance = this;
saveDefaultConfig(); saveDefaultConfig();
lang = getConfig().getString("lang", "ru"); lang = getConfig().getString("lang", "ru");
tension = new TensionManager(); tension = new TensionManager();
@@ -19,6 +22,7 @@ public class BlackKnifePlugin extends JavaPlugin {
magicListener = new MagicListener(this, magicManager); magicListener = new MagicListener(this, magicManager);
chatConfig = new ChatConfig(this); chatConfig = new ChatConfig(this);
chatHandler = new ChatHandler(this, chatConfig); chatHandler = new ChatHandler(this, chatConfig);
awakeningManager = new AwakeningManager(this, magicManager);
getServer().getPluginManager().registerEvents(tension, this); getServer().getPluginManager().registerEvents(tension, this);
getServer().getPluginManager().registerEvents(new BlackKnifeListener(this), this); getServer().getPluginManager().registerEvents(new BlackKnifeListener(this), this);
getServer().getPluginManager().registerEvents(new SwoonHandler(this), this); getServer().getPluginManager().registerEvents(new SwoonHandler(this), this);
@@ -27,6 +31,7 @@ public class BlackKnifePlugin extends JavaPlugin {
getServer().getPluginManager().registerEvents(new ParryHandler(this), this); getServer().getPluginManager().registerEvents(new ParryHandler(this), this);
getServer().getPluginManager().registerEvents(magicListener, this); getServer().getPluginManager().registerEvents(magicListener, this);
getServer().getPluginManager().registerEvents(chatHandler, this); getServer().getPluginManager().registerEvents(chatHandler, this);
getServer().getPluginManager().registerEvents(awakeningManager, this);
getServer().getPluginManager().registerEvents(new KillMessageHandler(this), this); getServer().getPluginManager().registerEvents(new KillMessageHandler(this), this);
getCommand("blackknife").setExecutor(new BlackKnifeCommand(this, chatConfig, chatHandler)); getCommand("blackknife").setExecutor(new BlackKnifeCommand(this, chatConfig, chatHandler));
getCommand("magic").setExecutor(new MagicCommand(magicManager, this)); getCommand("magic").setExecutor(new MagicCommand(magicManager, this));
@@ -34,10 +39,12 @@ public class BlackKnifePlugin extends JavaPlugin {
getLogger().info("BlackKnife 1.0.0 enabled - Paper 1.21.1 lang=" + lang); getLogger().info("BlackKnife 1.0.0 enabled - Paper 1.21.1 lang=" + lang);
} }
public static BlackKnifePlugin getInstance() { return instance; }
public TensionManager getTension() { return tension; } public TensionManager getTension() { return tension; }
public MagicManager getMagicManager() { return magicManager; } public MagicManager getMagicManager() { return magicManager; }
public MagicListener getMagicListener() { return magicListener; } public MagicListener getMagicListener() { return magicListener; }
public String getLang() { return lang; } public String getLang() { return lang; }
public void reloadLang() { lang = getConfig().getString("lang", "ru"); if (awakeningManager != null) awakeningManager.reloadChances(); }
@Override @Override
public void onDisable() { public void onDisable() {
@@ -34,11 +34,75 @@ public class MagicListener implements Listener {
@EventHandler @EventHandler
public void onJoin(PlayerJoinEvent e) { public void onJoin(PlayerJoinEvent e) {
Player p = e.getPlayer(); Player p = e.getPlayer();
if (BlackKnifeItem.is(p.getInventory().getItemInMainHand()) || BlackKnifeItem.is(p.getInventory().getItemInOffHand())) return; if (hasAnyBlackKnife(p)) return;
MagicProfile prof = mgr.getOrCreate(p); MagicProfile prof = mgr.getOrCreate(p);
if (!prof.awakened) return;
boolean hasMagic = false; boolean hasMagic = false;
for (ItemStack it : p.getInventory().getContents()) if (MagicItem.is(it)) { hasMagic = true; break; } for (ItemStack it : p.getInventory().getContents()) if (MagicItem.is(it)) { hasMagic = true; break; }
if (!hasMagic) p.getInventory().addItem(MagicItem.create(prof)); if (!hasMagic) {
p.getInventory().addItem(MagicItem.create(prof));
p.sendMessage("§d[Магия] §7Твой Magic Orb вернулся!");
}
}
private boolean hasAnyBlackKnife(Player p) {
for (ItemStack it : p.getInventory().getContents()) if (BlackKnifeItem.is(it)) return true;
return BlackKnifeItem.is(p.getInventory().getItemInMainHand()) || BlackKnifeItem.is(p.getInventory().getItemInOffHand());
}
@EventHandler
public void onDrop(org.bukkit.event.player.PlayerDropItemEvent e) {
if (!MagicItem.is(e.getItemDrop().getItemStack())) return;
}
@EventHandler
public void onPickup(org.bukkit.event.entity.EntityPickupItemEvent e) {
if (!(e.getEntity() instanceof Player picker)) return;
ItemStack item = e.getItem().getItemStack();
if (!MagicItem.is(item)) return;
String ownerStr = item.getItemMeta().getPersistentDataContainer().get(MagicItem.OWNER, PersistentDataType.STRING);
if (ownerStr == null) return;
if (ownerStr.equals(picker.getUniqueId().toString())) return;
e.setCancelled(true);
Player owner = plugin.getServer().getPlayer(UUID.fromString(ownerStr));
if (owner != null && owner.isOnline()) {
owner.getInventory().addItem(MagicItem.create(mgr.getOrCreate(owner)));
owner.sendMessage("§d[Магия] §7Твой Orb пытались подобрать, он вернулся!");
picker.sendMessage("§cЧужой Magic Orb вернулся владельцу!");
} else {
e.getItem().remove();
picker.sendMessage("§cЧужой Magic Orb исчез (владелец оффлайн)!");
}
}
@EventHandler
public void onDespawn(org.bukkit.event.entity.ItemDespawnEvent e) {
ItemStack item = e.getEntity().getItemStack();
if (!MagicItem.is(item)) return;
String ownerStr = item.getItemMeta().getPersistentDataContainer().get(MagicItem.OWNER, PersistentDataType.STRING);
if (ownerStr == null) return;
try {
UUID ownerId = UUID.fromString(ownerStr);
MagicProfile prof = mgr.get(ownerId);
if (prof != null && prof.awakened) {
Player owner = plugin.getServer().getPlayer(ownerId);
if (owner != null && owner.isOnline()) {
plugin.getServer().getScheduler().runTask(plugin, () -> owner.getInventory().addItem(MagicItem.create(prof)));
}
}
} catch (Exception ignored) {}
}
@EventHandler
public void onInventoryClick(org.bukkit.event.inventory.InventoryClickEvent e) {
if (!(e.getWhoClicked() instanceof Player p)) return;
ItemStack item = e.getCurrentItem();
if (!MagicItem.is(item)) return;
String ownerStr = item.getItemMeta().getPersistentDataContainer().get(MagicItem.OWNER, PersistentDataType.STRING);
if (ownerStr != null && !ownerStr.equals(p.getUniqueId().toString())) {
e.setCancelled(true);
p.sendMessage("§cЧужой Magic Orb нельзя трогать!");
}
} }
@EventHandler @EventHandler
@@ -38,23 +38,43 @@ public class MagicManager {
p.rare = y.getStringList("pack.rare"); p.rare = y.getStringList("pack.rare");
p.story = y.getStringList("pack.story"); p.story = y.getStringList("pack.story");
p.rareRolled = y.getBoolean("flags.rareRolled", false); p.rareRolled = y.getBoolean("flags.rareRolled", false);
p.awakened = y.getBoolean("flags.awakened", false);
p.awakeningCause = y.getString("flags.cause", null);
p.awakenedAt = y.getLong("flags.at", 0);
map.put(uuid, p); map.put(uuid, p);
} catch (Exception e) { plugin.getLogger().warning("Failed load magic " + f.getName() + ": " + e.getMessage()); } } catch (Exception e) { plugin.getLogger().warning("Failed load magic " + f.getName() + ": " + e.getMessage()); }
} }
} }
public boolean hasAwakened(UUID uuid) {
MagicProfile p = map.get(uuid);
return p != null && p.awakened;
}
public MagicProfile awaken(Player p, String cause) {
MagicProfile prof = map.get(p.getUniqueId());
if (prof == null) prof = new MagicProfile(p.getName(), p.getUniqueId());
prof.nick = p.getName();
prof.awakened = true;
prof.awakeningCause = cause;
prof.awakenedAt = System.currentTimeMillis();
if (!prof.rareRolled) {
prof.rareRolled = true;
if (Math.random() < 0.05) {
String[] pool = {"DETERMORE","FROSHE","PRAYER","SHIELDO"};
String pick = pool[(int)(Math.random()*pool.length)];
if (!prof.common.contains(pick)) prof.rare.add(pick);
}
}
map.put(p.getUniqueId(), prof);
save(prof);
return prof;
}
public MagicProfile getOrCreate(Player p) { public MagicProfile getOrCreate(Player p) {
MagicProfile prof = map.get(p.getUniqueId()); MagicProfile prof = map.get(p.getUniqueId());
if (prof == null) { if (prof == null) {
prof = new MagicProfile(p.getName(), p.getUniqueId()); prof = new MagicProfile(p.getName(), p.getUniqueId());
if (!prof.rareRolled) {
prof.rareRolled = true;
if (Math.random() < 0.05) {
String[] pool = {"DETERMORE","FROSHE","PRAYER","SHIELDO"};
String pick = pool[(int)(Math.random()*pool.length)];
if (!prof.common.contains(pick)) prof.rare.add(pick);
}
}
map.put(p.getUniqueId(), prof); map.put(p.getUniqueId(), prof);
save(prof); save(prof);
} else if (!prof.nick.equals(p.getName())) { } else if (!prof.nick.equals(p.getName())) {
@@ -81,6 +101,9 @@ public class MagicManager {
y.set("pack.story", prof.story); y.set("pack.story", prof.story);
y.set("pack.selected", prof.selectedIdx); y.set("pack.selected", prof.selectedIdx);
y.set("flags.rareRolled", prof.rareRolled); y.set("flags.rareRolled", prof.rareRolled);
y.set("flags.awakened", prof.awakened);
y.set("flags.cause", prof.awakeningCause);
y.set("flags.at", prof.awakenedAt);
y.save(f); y.save(f);
} catch (Exception e) { plugin.getLogger().warning("Failed save magic " + prof.uuid + ": " + e.getMessage()); } } catch (Exception e) { plugin.getLogger().warning("Failed save magic " + prof.uuid + ": " + e.getMessage()); }
} }
@@ -16,6 +16,9 @@ public class MagicProfile {
public List<String> rare = new ArrayList<>(); public List<String> rare = new ArrayList<>();
public List<String> story = new ArrayList<>(); public List<String> story = new ArrayList<>();
public boolean rareRolled; public boolean rareRolled;
public boolean awakened;
public String awakeningCause;
public long awakenedAt;
public MagicProfile(String nick, UUID uuid) { public MagicProfile(String nick, UUID uuid) {
this.nick = nick; this.uuid = uuid; this.firstSeen = System.currentTimeMillis(); this.nick = nick; this.uuid = uuid; this.firstSeen = System.currentTimeMillis();
@@ -30,6 +30,7 @@ public class TensionManager implements Listener {
} }
public void addTP(Player p, float amount, String reason) { public void addTP(Player p, float amount, String reason) {
if (!hasMagic(p)) return;
float cur = Math.min(250, getTP(p) + amount); float cur = Math.min(250, getTP(p) + amount);
tp.put(p.getUniqueId(), cur); tp.put(p.getUniqueId(), cur);
lastCombat.put(p.getUniqueId(), System.currentTimeMillis()); lastCombat.put(p.getUniqueId(), System.currentTimeMillis());
@@ -38,7 +39,18 @@ public class TensionManager implements Listener {
} }
public boolean isOwner(Player p) { public boolean isOwner(Player p) {
return BlackKnifeItem.is(p.getInventory().getItemInMainHand()) || BlackKnifeItem.is(p.getInventory().getItemInOffHand()); return BlackKnifeItem.is(p.getInventory().getItemInMainHand()) || BlackKnifeItem.is(p.getInventory().getItemInOffHand()) || hasAnyBlackKnife(p);
}
private boolean hasAnyBlackKnife(Player p) {
for (var it : p.getInventory().getContents()) if (BlackKnifeItem.is(it)) return true;
return false;
}
public boolean hasMagic(Player p) {
if (hasAnyBlackKnife(p)) return true;
var mgr = BlackKnifePlugin.getInstance() != null ? BlackKnifePlugin.getInstance().getMagicManager() : null;
return mgr != null && mgr.hasAwakened(p.getUniqueId());
} }
private void updateBar(Player p, float tpVal) { private void updateBar(Player p, float tpVal) {
+11
View File
@@ -1 +1,12 @@
lang: ru lang: ru
awakening:
enabled: true
tp_requires_magic: true
fall_min: 15
chances:
mob: 0.05
kill: 0.08
fall: 0.03
lava: 0.04
void: 0.10
generic: 0.01