diff --git a/src/main/java/pl/piecuu/killstreak/KillstreakCommand.java b/src/main/java/pl/piecuu/killstreak/KillstreakCommand.java index 65bc275..e876067 100644 --- a/src/main/java/pl/piecuu/killstreak/KillstreakCommand.java +++ b/src/main/java/pl/piecuu/killstreak/KillstreakCommand.java @@ -32,6 +32,14 @@ public class KillstreakCommand { .then(Commands.argument("profile", ArgumentTypes.playerProfiles()) .requires(s -> s.getSender().hasPermission("ks.admin.get")) .executes(KillstreakCommand::getOtherKillstreak) + .then(Commands.literal("best") + .requires(s -> s.getSender().hasPermission("ks.admin.get.best")) + .executes(KillstreakCommand::getOtherBestKillstreak) + ) + ) + .then(Commands.literal("best") + .requires(s -> s.getSender().hasPermission("ks.get.best")) + .executes(KillstreakCommand::getOwnBestKillstreak) ) ) .then(Commands.literal("set") @@ -42,7 +50,12 @@ public class KillstreakCommand { ) .then(Commands.literal("reset") .requires(s -> s.getSender().hasPermission("ks.admin.reset")) - .then(playerArgument.executes(KillstreakCommand::resetKillstreak)) + .then(playerArgument + .executes(KillstreakCommand::resetKillstreak) + .then(Commands.literal("best") + .executes(KillstreakCommand::resetBestKillstreak) + ) + ) ); return ks.build(); @@ -62,6 +75,27 @@ public class KillstreakCommand { return offlinePlayer; } + private static int getOwnBestKillstreak(CommandContext ctx) throws CommandSyntaxException { + final Entity entity = ctx.getSource().getExecutor(); + if(!(entity instanceof Player p)) return 0; + KillstreakManager km = KillstreakManager.getInstance(); + + final long killstreak = km.getBestKillstreak(p); + + ctx.getSource().getSender().sendMessage(km.getBestKillstreakComponent(killstreak)); + return 1; + } + + private static int getOtherBestKillstreak(CommandContext ctx) throws CommandSyntaxException { + final OfflinePlayer offlinePlayer = getOfflinePlayerFromCtx(ctx); + KillstreakManager km = KillstreakManager.getInstance(); + + final long killstreak = km.getBestKillstreak(offlinePlayer); + + ctx.getSource().getSender().sendMessage(km.getBestKillstreakComponent(killstreak)); + return 1; + } + private static int resetKillstreak(CommandContext ctx) throws CommandSyntaxException { final Player player = getFirstPlayerFromCtx(ctx); KillstreakManager km = KillstreakManager.getInstance(); @@ -72,6 +106,16 @@ public class KillstreakCommand { return 1; } + private static int resetBestKillstreak(CommandContext ctx) throws CommandSyntaxException { + final Player player = getFirstPlayerFromCtx(ctx); + KillstreakManager km = KillstreakManager.getInstance(); + + km.setBestKillstreak(player, 0L); + + ctx.getSource().getSender().sendMessage(km.getBestKillstreakComponent(0L)); + return 1; + } + private static int setKillstreak(CommandContext ctx) throws CommandSyntaxException { final Player player = getFirstPlayerFromCtx(ctx); final long killstreak = LongArgumentType.getLong(ctx, "killstreak"); diff --git a/src/main/java/pl/piecuu/killstreak/KillstreakExpansion.java b/src/main/java/pl/piecuu/killstreak/KillstreakExpansion.java index ded1c50..6a36eee 100644 --- a/src/main/java/pl/piecuu/killstreak/KillstreakExpansion.java +++ b/src/main/java/pl/piecuu/killstreak/KillstreakExpansion.java @@ -2,6 +2,9 @@ package pl.piecuu.killstreak; import me.clip.placeholderapi.expansion.PlaceholderExpansion; import net.kyori.adventure.text.Component; +import net.kyori.adventure.text.format.TextColor; +import net.kyori.adventure.text.format.TextDecoration; + import org.bukkit.entity.Player; import org.jetbrains.annotations.NotNull; @@ -45,8 +48,44 @@ public class KillstreakExpansion extends PlaceholderExpansion { final Component output = km.getKillstreakComponent(killstreak); return MiniMessage.miniMessage().serialize(output); + } else if(identifier.equalsIgnoreCase("killstreak_tab")) { + KillstreakManager km = KillstreakManager.getInstance(); + final long killstreak = km.getInvisKillstreak(p); + final long bestKillstreak = km.getBestKillstreak(p); + final Component bestComponent = km.getBestKillstreakComponent(bestKillstreak); + if(killstreak == 0 && bestKillstreak > 0) + return MiniMessage.miniMessage().serialize(bestComponent); + else if(killstreak == 0) return ""; + + Component output = km.getKillstreakComponent(killstreak); + + if(bestKillstreak > killstreak) { + output = output + .appendSpace() + .append(Component.text("|", TextColor.color( + KillstreakExpansion.mix( + output.children().getLast().color(), + bestComponent.children().getFirst().color(), + 0.6 + ) + )).decoration(TextDecoration.BOLD, true)) + .appendSpace() + .append(bestComponent); + } + return MiniMessage.miniMessage().serialize(output); } return null; } + + private static TextColor mix(TextColor c1, TextColor c2, double ratio) { + ratio = Math.max(0, Math.min(1, ratio)); + double inverse = 1.0 - ratio; + + int r = (int) (c1.red() * inverse + c2.red() * ratio); + int g = (int) (c1.green() * inverse + c2.green() * ratio); + int b = (int) (c1.blue() * inverse + c2.blue() * ratio); + + return TextColor.color(r, g, b); + } } \ No newline at end of file diff --git a/src/main/java/pl/piecuu/killstreak/KillstreakManager.java b/src/main/java/pl/piecuu/killstreak/KillstreakManager.java index e7a191d..64f298b 100644 --- a/src/main/java/pl/piecuu/killstreak/KillstreakManager.java +++ b/src/main/java/pl/piecuu/killstreak/KillstreakManager.java @@ -1,5 +1,7 @@ package pl.piecuu.killstreak; +import java.util.Map; + import org.bukkit.NamespacedKey; import org.bukkit.OfflinePlayer; import org.bukkit.entity.Player; @@ -8,6 +10,7 @@ import org.bukkit.persistence.PersistentDataType; import net.kyori.adventure.text.Component; import net.kyori.adventure.text.format.TextColor; import net.kyori.adventure.text.format.TextDecoration; +import net.kyori.adventure.text.format.TextDecoration.State; import pl.piecuu.invisninja.InvisNinja; public class KillstreakManager { @@ -16,6 +19,7 @@ public class KillstreakManager { return instance; } public NamespacedKey playerKillstreakKey; + public NamespacedKey playerBestKillstreakKey; public NamespacedKey playerInvisKSKey; @SuppressWarnings("unused") @@ -25,60 +29,95 @@ public class KillstreakManager { instance = this; this.playerKillstreakKey = new NamespacedKey(plugin, "playerKillstreakKey"); this.playerInvisKSKey = new NamespacedKey(plugin, "playerInvisKSKey"); + this.playerBestKillstreakKey = new NamespacedKey(plugin, "playerBestKillstreakKey"); + } + + public long getBestKillstreak(OfflinePlayer player) { + return this.getLongFromPDC(player, playerBestKillstreakKey); + } + + public void setBestKillstreak(Player player, long bestKillstreak) { + this.setLongFromPDC(player, playerBestKillstreakKey, bestKillstreak); + } + + public void normaliseBestKillstreak(Player player) { + long killstreak = this.getKillstreak(player); + this.setBestKillstreak(player, killstreak); } public void setKillstreak(Player player, long streak) { - if(streak < 0) return; - player.getPersistentDataContainer().set(playerKillstreakKey, PersistentDataType.LONG, streak); - if(Killstreak.getInvisNinja() == null || !InvisNinja.isPlayerInvisible(player)) { - setInvisKillstreak(player, streak); - } + this.setLongFromPDC(player, playerKillstreakKey, streak); } public void setInvisKillstreak(Player player, long streak) { - if(streak < 0) return; - player.getPersistentDataContainer().set(playerInvisKSKey, PersistentDataType.LONG, streak); + this.setLongFromPDC(player, playerInvisKSKey, streak); } public long getInvisKillstreak(Player player) { - if(Killstreak.getInvisNinja() == null || !InvisNinja.isPlayerInvisible(player)) return getKillstreak(player); - return player.getPersistentDataContainer().getOrDefault(playerInvisKSKey, PersistentDataType.LONG, 0L); + final long realKS = this.getLongFromPDC(player, playerInvisKSKey); + if(Killstreak.getInvisNinja() == null || !InvisNinja.isPlayerInvisible(player)) { + long ks = this.getKillstreak(player); + if(ks > this.getBestKillstreak(player)) this.normaliseBestKillstreak(player); + this.setInvisKillstreak(player, ks); + return ks; + } + return realKS; } public long getKillstreak(OfflinePlayer player) { - return player.getPersistentDataContainer().getOrDefault(playerKillstreakKey, PersistentDataType.LONG, 0L); + return this.getLongFromPDC(player, playerKillstreakKey); } - + public long increaseKillstreak(Player player, long amount) { long killstreak = this.getKillstreak(player); killstreak += amount; this.setKillstreak(player, killstreak); return killstreak; } - + public void resetKillstreak(Player player) { - setKillstreak(player, 0L); + this.setKillstreak(player, 0L); } + + + private long getLongFromPDC(OfflinePlayer player, NamespacedKey key) { + return player.getPersistentDataContainer().getOrDefault(key, PersistentDataType.LONG, 0L); + } + + private void setLongFromPDC(Player player, NamespacedKey key, long value) { + if(value < 0) return; + player.getPersistentDataContainer().set(key, PersistentDataType.LONG, value); + } + + + public boolean shouldAnnounceKillstreak(long killstreak, Player p) { if(Killstreak.getInvisNinja() != null && InvisNinja.isPlayerInvisible(p)) return false; - - return (killstreak >= 5 && killstreak % 5 == 0); + return killstreak >= 5 && killstreak % 5 == 0; } public int getColor(long killstreak) { if(killstreak == 0) return 0xffffff; else if(killstreak == 1) return 0xfbffa8; // washed out yellow - else if(killstreak < 5) return 0xfae92f; // yellow + else if(killstreak < 5) return 0xfae92f; // yellow else if(killstreak < 10) return 0xe6aa1e; // orange orange else if(killstreak < 15) return 0xe6711e; // darker orange else if(killstreak < 20) return 0xf54320; // intense red - else if(killstreak < 30) return 0xde5291; // some fuckass pink + else if(killstreak < 30) return 0xde5291; // some fuckass pink else return 0xde1ff0; // very intensive magenta } public Component getKillstreakComponent(long killstreak) { return Component.text("🔥", TextColor.color(0xff931f)) // 0xd18449 .append(Component.text(killstreak).color(TextColor.color(this.getColor(killstreak))).decoration(TextDecoration.BOLD, true)); - } + } + public Component getBestKillstreakComponent(long bestKillstreak) { + return Component.text("🔥", TextColor.color(0x9c9c9c)) + .append(Component.text(bestKillstreak).color(TextColor.color(0xababab))) + .decorations(Map.of( + TextDecoration.STRIKETHROUGH, State.TRUE, + TextDecoration.BOLD, State.TRUE + )); + } } diff --git a/src/main/resources/plugin.yml b/src/main/resources/plugin.yml index cf54e01..2bab57e 100644 --- a/src/main/resources/plugin.yml +++ b/src/main/resources/plugin.yml @@ -7,8 +7,12 @@ api-version: '1.21.11' permissions: ks.get: default: true + ks.get.best: + default: true ks.admin.get: default: op + ks.admin.get.best: + default: op ks.admin.set: default: op ks.admin.reset: