Jump to content

Featured Replies

Posted
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 :D 

OuFYztU.png

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

  • 1 month later...
  • 3 weeks later...
  • 2 months later...
  • 2 weeks later...
  • 2 weeks later...
  • 1 month later...
  • 1 month later...
  • 8 months later...

Create an account or sign in to comment