Posted October 6, 20213 yr comment_63124 Hey guys, this tut is for a system I created for the now leaked Platinum PS. It is a boss which is triggered when the server hits a global XP target. It then spawns in an instanced area, but the players can leaver / enter smoothly. Adapt as required, this wasn't ever intended to be a tutorial so it's more involved than others I've done. The rewards are currently XP in the chosen boss skill. Players are ranked based on damage caused to the boss. Positions 1-5 are rewarded. They are then shown a crappy interface, but it does the trick I made a new package in src.com.platinum.world.content.skillingboss Then there are two files: SkillBossConfig: package com.platinum.world.content.skillingboss; import com.platinum.model.Position; public class SkillBossConfig { // NPC ID Of the boss public static final int npcID = 6306; // The amount of time we add to the timer after it runs out public static final long timeDelay = 300000; // 5 minutes // How often will the server update players on the current XP count? public static long xpUpdateTimer = System.currentTimeMillis() + timeDelay; // 5 minutes // The spawn location of the boss public static final Position spawnPos = new Position(1861, 5222, 4); // The value that holds the global XP public static long serverXPCounter; // How much XP requred until the boss will spawn? public static long requiredServerXP = 1000000000; public static void resetTimer() { xpUpdateTimer = System.currentTimeMillis() + timeDelay; } } And SkillBossHandler package com.platinum.world.content.skillingboss; import com.platinum.model.Skill; import com.platinum.util.Misc; import com.platinum.world.World; import com.platinum.world.content.combat.CombatBuilder; import com.platinum.world.content.combat.CombatFactory; import com.platinum.world.content.discord.DiscordMessenger; import com.platinum.world.entity.impl.npc.NPC; import com.platinum.world.entity.impl.player.Player; import java.text.NumberFormat; import java.util.*; public class SkillBossHandler { private static Skill selectedSkill; public static NPC skillBoss = new NPC(SkillBossConfig.npcID, SkillBossConfig.spawnPos);; public static void handleServerXP(long XP) { if (World.getNpcs().contains(skillBoss)) { return; } if (System.currentTimeMillis() > SkillBossConfig.xpUpdateTimer && SkillBossConfig.serverXPCounter < SkillBossConfig.requiredServerXP) { SkillBossConfig.resetTimer(); long remainder = SkillBossConfig.requiredServerXP - SkillBossConfig.serverXPCounter; World.sendMessageDiscord("Global XP is currently: " + formatNumber(SkillBossConfig.serverXPCounter) + "! We need " + formatNumber(remainder) + " until the skilling boss spawns!"); } if (SkillBossConfig.serverXPCounter < SkillBossConfig.requiredServerXP) { SkillBossConfig.serverXPCounter += XP; } else { SkillBossConfig.serverXPCounter = 0; spawnSkillBoss(); } } public static String formatNumber(long number) { return NumberFormat.getInstance().format(number); } /** Spawns the Skilling Boss **/ private static void spawnSkillBoss() { selectedSkill = selectSkill(); World.register(skillBoss); World.sendMessageNonDiscord("@blu@The Skilling Boss has just spawned! Skill Selected: @red@" + selectedSkill.getFormatName() + "@blu@!"); DiscordMessenger.sendInGameMessage("The Skilling Boss has just spawned! Skill Selected: " + selectedSkill.getFormatName() + "!"); } /** Chooses a random Skill **/ private static Skill selectSkill() { return Skill.values()[Misc.exclusiveRandom(Skill.values().length)]; } /** After the NPC is killed, we calculate the damage **/ public static void calculateDamage(NPC npc) { if (npc.getCombatBuilder().getDamageMap().size() == 0) { return; } Map<Player, Integer> killers = new HashMap<>(); for (Map.Entry<Player, CombatBuilder.CombatDamageCache> entry : npc.getCombatBuilder().getDamageMap().entrySet()) { if (entry == null) { continue; } long timeout = entry.getValue().getStopwatch().elapsed(); if (timeout > CombatFactory.DAMAGE_CACHE_TIMEOUT) { continue; } Player player = entry.getKey(); if (player.getConstitution() <= 0 || !player.isRegistered()) { continue; } killers.put(player, entry.getValue().getDamage()); } npc.getCombatBuilder().getDamageMap().clear(); List<Map.Entry<Player, Integer>> result = sortEntries(killers); int count = 0; Player[] topFive = {null, null, null, null, null}; int[] topFiveDmg = {0, 0, 0, 0, 0}; int i = 0; for (Map.Entry<Player, Integer> entry : result) { Player killer = entry.getKey(); int damage = entry.getValue(); if (!Arrays.asList(topFive).equals(killer) && i <= 4) { topFive[i] = killer; topFiveDmg[i] = damage; System.out.println("Added " + killer.getUsername() + " who had dmg " + damage); } else { topFive[i] = null; topFiveDmg[i] = 0; } if (++count >= 20) { break; } i++; } String winners = ""; String fir = ""; String sec = ""; String thi = ""; String fou = ""; String fif = ""; int xpReward = 0; for (int t = 0; t <= 4; t++) { if (topFive[t] != null) { String username = topFive[t].getUsername(); String dmg = " dmg: " + Misc.formatAmount(topFiveDmg[t]); topFive[t].getPacketSender().sendInterface(297); topFive[t].getPacketSender().sendString(299, "@bla@Congratulations " + username + "!") .sendString(6158, selectedSkill.getFormatName() + " XP!") .sendString(303, "") .sendString(304, ""); switch (t) { case 0: fir = "1st: " + username + dmg; xpReward = topFiveDmg[t]; topFive[t].getPacketSender().sendString(301, "@bla@First Place!") .sendString(4444, "@gre@" + Misc.formatAmount(xpReward)); break; case 1: sec = "2nd: " + username + dmg; xpReward = topFiveDmg[t] / 2; topFive[t].getPacketSender().sendString(301, "@bla@Second Place!") .sendString(4444, "@gre@" + Misc.formatAmount(xpReward)); break; case 2: thi = "3rd: " + username + dmg; xpReward = topFiveDmg[t] / 3; topFive[t].getPacketSender().sendString(301, "@bla@Third Place!") .sendString(4444, "@gre@" + Misc.formatAmount(xpReward)); break; case 3: fou = "4th: " + username + dmg; xpReward = topFiveDmg[t] / 4; topFive[t].getPacketSender().sendString(301, "@bla@Fourth Place!") .sendString(4444, "@gre@" + Misc.formatAmount(xpReward)); break; case 4: fif = "5th: " + username + dmg; xpReward = topFiveDmg[t] / 5; topFive[t].getPacketSender().sendString(301, "@bla@Fifth Place!") .sendString(4444, "@gre@" + Misc.formatAmount(xpReward)); break; } reward(topFive[t], xpReward, selectedSkill); } winners = fir + sec + thi + fou + fif; } World.sendMessageDiscord("[Skill Boss] " + winners); World.deregister(skillBoss); } private static void reward(Player player, int xpReward, Skill skill) { if (player != null && skill != null) { player.getSkillManager().addExperience(skill, xpReward); player.getPacketSender().sendMessage("You have gained @blu@" + Misc.formatAmount(xpReward) + " @bla@" + selectedSkill.getFormatName() + " XP!"); } } static <K, V extends Comparable<? super V>> List<Map.Entry<K, V>> sortEntries(Map<K, V> map) { List<Map.Entry<K, V>> sortedEntries = new ArrayList<Map.Entry<K, V>>(map.entrySet()); Collections.sort(sortedEntries, new Comparator<Map.Entry<K, V>>() { @Override public int compare(Map.Entry<K, V> e1, Map.Entry<K, V> e2) { return e2.getValue().compareTo(e1.getValue()); } }); return sortedEntries; } } To count the global XP, add this into SkillManager.java (Inside the addExperience method) Ensure you add it after any multipliers / XP reductions so that 2x XP is included. SkillBossHandler.handleServerXP(experience); I used a location for our implementation since it's the cleanest way and keeps things organized (Locations.java) SKILLING_BOSS(new int[] { 1856, 1867 }, new int[] { 5214, 5229 }, true, true, true, false, true, true) { @Override public void logout(Player player) { if (player.getPosition().getZ() == 4) { player.moveTo(player.getPosition().getX(), player.getPosition().getY(), 0); } } @Override public void leave(Player player) { if (player.getPosition().getZ() == 4) { player.moveTo(player.getPosition().getX(), player.getPosition().getY(), 0); } } @Override public void enter(Player player) { if (World.getNpcs().contains(SkillBossHandler.skillBoss)) { player.moveTo(player.getPosition().getX(), player.getPosition().getY(), 4); } } @Override public boolean handleKilledNPC(Player killer, NPC npc) { if (npc == SkillBossHandler.skillBoss) { SkillBossHandler.calculateDamage(SkillBossHandler.skillBoss); return true; } return false; } }, Thanks bois
Create an account or sign in to comment