Jump to content
Existing user? Sign In

Sign In



Sign Up

[Ruse] Global Skilling Boss Triggered By Global XP


Flub

Recommended Posts

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

Link to comment
Share on other sites

  • 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

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Contact

[email protected]

astra.security

What is a RSPS?

A RSPS, also known as RuneScape private server, is an online game based on RuneScape, and controlled by independent individuals.

Popular RSPS Servers

Runewild Ikov RedemptionRSPS

Disclaimer

Runesuite is not affiliated with runescape, jagex in any way & exists solely for educational purposes.

×
×
  • Create New...