Merge branch 'fancier-stats' into 'master'

Make use of the next/previous arrows in the interface used for `::stats`,...

See merge request 2009scape/2009scape!309
This commit is contained in:
Ceikry 2021-10-19 21:13:54 +00:00
commit fb3931fbf4
11 changed files with 344 additions and 60 deletions

View file

@ -40578,6 +40578,7 @@
"grand_exchange_price": "29900",
"stand_anim": "1662",
"tradeable": "true",
"rare_item": "true",
"run_anim": "1664",
"archery_ticket_price": "0",
"id": "4153",
@ -45819,6 +45820,7 @@
"grand_exchange_price": "94300",
"name": "Ahrim's hood",
"tradeable": "true",
"rare_item": "true",
"archery_ticket_price": "0",
"id": "4708",
"bonuses": "0,0,0,6,-2,15,13,16,6,0,15,0,0,0,0"
@ -45849,6 +45851,7 @@
"grand_exchange_price": "69500",
"stand_anim": "813",
"tradeable": "true",
"rare_item": "true",
"run_anim": "1210",
"archery_ticket_price": "0",
"id": "4710",
@ -45887,6 +45890,7 @@
"grand_exchange_price": "1000000",
"name": "Ahrim's robetop",
"tradeable": "true",
"rare_item": "true",
"archery_ticket_price": "0",
"id": "4712",
"bonuses": "0,0,0,30,-10,52,37,63,30,0,60,0,0,0,0"
@ -45914,6 +45918,7 @@
"grand_exchange_price": "1700000",
"name": "Ahrim's robeskirt",
"tradeable": "true",
"rare_item": "true",
"archery_ticket_price": "0",
"id": "4714",
"bonuses": "0,0,0,22,-7,33,30,36,22,0,30,0,0,0,0"
@ -45942,6 +45947,7 @@
"grand_exchange_price": "1300000",
"name": "Dharok's helm",
"tradeable": "true",
"rare_item": "true",
"archery_ticket_price": "0",
"id": "4716",
"bonuses": "0,0,0,-3,-1,45,48,44,-1,51,15,0,0,0,0"
@ -45972,6 +45978,7 @@
"grand_exchange_price": "516900",
"stand_anim": "2065",
"tradeable": "true",
"rare_item": "true",
"run_anim": "824",
"archery_ticket_price": "0",
"id": "4718",
@ -46009,6 +46016,7 @@
"grand_exchange_price": "511400",
"name": "Dharok's platebody",
"tradeable": "true",
"rare_item": "true",
"archery_ticket_price": "0",
"id": "4720",
"bonuses": "0,0,0,-30,-10,122,120,107,-6,132,60,0,0,0,0"
@ -46036,6 +46044,7 @@
"grand_exchange_price": "748800",
"name": "Dharok's platelegs",
"tradeable": "true",
"rare_item": "true",
"archery_ticket_price": "0",
"id": "4722",
"bonuses": "0,0,0,-21,-7,85,82,83,-4,92,30,0,0,0,0"
@ -46065,6 +46074,7 @@
"grand_exchange_price": "396300",
"name": "Guthan's helm",
"tradeable": "true",
"rare_item": "true",
"archery_ticket_price": "0",
"id": "4724",
"bonuses": "0,0,0,-6,-2,55,58,54,-1,62,15,0,0,0,0"
@ -46095,6 +46105,7 @@
"grand_exchange_price": "588400",
"stand_anim": "813",
"tradeable": "true",
"rare_item": "true",
"run_anim": "1210",
"archery_ticket_price": "0",
"id": "4726",
@ -46132,6 +46143,7 @@
"grand_exchange_price": "316800",
"name": "Guthan's platebody",
"tradeable": "true",
"rare_item": "true",
"archery_ticket_price": "0",
"id": "4728",
"bonuses": "0,0,0,-30,-10,122,120,107,-6,132,60,0,0,0,0"
@ -46159,6 +46171,7 @@
"grand_exchange_price": "315600",
"name": "Guthan's chainskirt",
"tradeable": "true",
"rare_item": "true",
"archery_ticket_price": "0",
"id": "4730",
"bonuses": "0,0,0,-14,-7,75,72,73,-4,82,30,0,0,0,0"
@ -46187,6 +46200,7 @@
"grand_exchange_price": "38900",
"name": "Karil's coif",
"tradeable": "true",
"rare_item": "true",
"archery_ticket_price": "0",
"id": "4732",
"bonuses": "0,0,0,-1,3,6,9,12,6,10,15,0,0,0,0"
@ -46217,6 +46231,7 @@
"grand_exchange_price": "188000",
"stand_anim": "2074",
"tradeable": "true",
"rare_item": "true",
"run_anim": "2077",
"archery_ticket_price": "0",
"id": "4734",
@ -46255,6 +46270,7 @@
"grand_exchange_price": "1800000",
"name": "Karil's leathertop",
"tradeable": "true",
"rare_item": "true",
"archery_ticket_price": "0",
"id": "4736",
"bonuses": "0,0,0,-15,30,47,42,50,65,57,60,0,0,0,0"
@ -46282,6 +46298,7 @@
"grand_exchange_price": "217000",
"name": "Karil's leatherskirt",
"tradeable": "true",
"rare_item": "true",
"archery_ticket_price": "0",
"id": "4738",
"bonuses": "0,0,0,-10,17,26,20,28,35,33,30,0,0,0,0"
@ -46327,6 +46344,7 @@
"grand_exchange_price": "139000",
"name": "Torag's helm",
"tradeable": "true",
"rare_item": "true",
"archery_ticket_price": "0",
"id": "4745",
"bonuses": "0,0,0,-6,-2,55,58,54,-1,62,15,0,0,0,0"
@ -46359,6 +46377,7 @@
"attack_audios": "1332,0,0,0",
"name": "Torag's hammers",
"tradeable": "true",
"rare_item": "true",
"archery_ticket_price": "0",
"id": "4747",
"bonuses": "-4,-4,85,-4,0,0,0,0,0,0,0,72,0,0,0"
@ -46387,6 +46406,7 @@
"grand_exchange_price": "346200",
"name": "Torag's platebody",
"tradeable": "true",
"rare_item": "true",
"archery_ticket_price": "0",
"id": "4749",
"bonuses": "0,0,0,-30,-10,122,120,107,-6,132,60,0,0,0,0"
@ -46414,6 +46434,7 @@
"grand_exchange_price": "427200",
"name": "Torag's platelegs",
"tradeable": "true",
"rare_item": "true",
"archery_ticket_price": "0",
"id": "4751",
"bonuses": "0,0,0,-21,-7,85,82,83,-4,92,30,0,0,0,0"
@ -46443,6 +46464,7 @@
"grand_exchange_price": "687200",
"name": "Verac's helm",
"tradeable": "true",
"rare_item": "true",
"archery_ticket_price": "0",
"id": "4753",
"bonuses": "0,0,0,-6,-2,55,58,54,0,56,15,0,3,0,0"
@ -46473,6 +46495,7 @@
"grand_exchange_price": "135500",
"stand_anim": "1832",
"tradeable": "true",
"rare_item": "true",
"run_anim": "1831",
"archery_ticket_price": "0",
"id": "4755",
@ -46511,6 +46534,7 @@
"grand_exchange_price": "270000",
"name": "Verac's brassard",
"tradeable": "true",
"rare_item": "true",
"archery_ticket_price": "0",
"id": "4757",
"bonuses": "0,0,0,-6,-2,81,95,85,0,81,60,0,5,0,0"
@ -46538,6 +46562,7 @@
"grand_exchange_price": "411400",
"name": "Verac's plateskirt",
"tradeable": "true",
"rare_item": "true",
"archery_ticket_price": "0",
"id": "4759",
"bonuses": "0,0,0,-21,-7,85,82,83,0,84,30,0,4,0,0"
@ -106101,6 +106126,7 @@
"grand_exchange_price": "95400",
"name": "Dragon boots",
"tradeable": "true",
"rare_item": "true",
"archery_ticket_price": "0",
"id": "11732",
"bonuses": "0,0,0,-3,-1,16,17,18,0,0,15,4,0,0,0"
@ -121161,6 +121187,7 @@
"grand_exchange_price": "43082",
"stand_anim": "813",
"tradeable": "true",
"rare_item": "true",
"run_anim": "824",
"archery_ticket_price": "0",
"id": "13290",
@ -139539,4 +139566,4 @@
"attack_audios": "2555,0,0,0",
"name": "Staff of the raven"
}
]
]

View file

@ -31,6 +31,7 @@ import core.game.world.update.flag.npc.NPCFaceLocation;
import core.game.world.update.flag.npc.NPCForceChat;
import core.game.world.update.flag.npc.NPCSwitchId;
import core.tools.RandomFunction;
import rs09.game.content.global.GlobalKillCounter;
import rs09.game.content.jobs.JobManager;
import rs09.game.node.entity.combat.CombatSwingHandler;
import rs09.game.system.config.NPCConfigParser;
@ -534,6 +535,7 @@ public class NPC extends Entity {
Player p = !(killer instanceof Player) ? null : (Player) killer;
if (p != null) {
p.incrementAttribute("/save:" + STATS_BASE + ":" + STATS_ENEMIES_KILLED);
GlobalKillCounter.incrementKills(p, originalId);
}
handleDrops(p, killer);
if (!isRespawn()) {

View file

@ -1,5 +1,6 @@
package core.game.node.entity.npc.drop;
import api.ContentAPI;
import core.cache.def.impl.NPCDefinition;
import core.game.content.global.Bones;
import core.game.ge.GrandExchangeDatabase;
@ -17,6 +18,7 @@ import core.tools.StringUtils;
import rs09.game.ai.AIPlayer;
import rs09.game.ai.AIRepository;
import rs09.game.ai.general.GeneralBotCreator;
import rs09.game.content.global.GlobalKillCounter;
import rs09.game.content.global.NPCDropTable;
import rs09.game.ge.OfferManager;
import rs09.game.system.config.ItemConfigParser;
@ -111,9 +113,7 @@ public final class NPCDropTables {
}
return;
}
if (item.getDefinition().getConfiguration(ItemConfigParser.RARE_ITEM, false)) {
Repository.sendNews(player.getUsername() + " has just received: " + item.getAmount() + " x " + item.getName() + ".");
}
ContentAPI.announceIfRare(player, item);
if(item.getId() == 6199 && player instanceof Player){
player.sendMessage("<col=990000>A mystery box has fallen on the ground.</col>");
}
@ -239,4 +239,4 @@ public final class NPCDropTables {
this.modRate = modRate;
}
}
}

View file

@ -1,16 +1,18 @@
package core.game.node.entity.skill.runecrafting;
import core.game.container.impl.EquipmentContainer;
import core.game.node.entity.skill.SkillPulse;
import core.game.node.entity.skill.Skills;
import core.game.node.entity.impl.Animator.Priority;
import core.game.node.entity.player.Player;
import core.game.node.entity.player.link.diary.DiaryType;
import core.game.node.entity.skill.SkillPulse;
import core.game.node.entity.skill.Skills;
import core.game.node.item.Item;
import rs09.game.world.GameWorld;
import core.game.world.update.flag.context.Animation;
import core.game.world.update.flag.context.Graphics;
import core.tools.RandomFunction;
import static rs09.game.node.entity.player.info.stats.StatAttributeKeysKt.STATS_BASE;
import static rs09.game.node.entity.player.info.stats.StatAttributeKeysKt.STATS_RC;
import rs09.game.world.GameWorld;
import java.util.ArrayList;
import java.util.Arrays;
@ -176,6 +178,7 @@ public final class RuneCraftPulse extends SkillPulse<Item> {
if (player.getInventory().remove(item) && player.getInventory().hasSpaceFor(i)) {
player.getInventory().add(i);
player.incrementAttribute("/save:" + STATS_BASE + ":" + STATS_RC, amount);
player.getSkills().addExperience(Skills.RUNECRAFTING, rune.getExperience() * amount, true);
// Achievement Diary handling
@ -195,6 +198,7 @@ public final class RuneCraftPulse extends SkillPulse<Item> {
}
} else {
if (player.getInventory().remove(item)) {
player.incrementAttribute("/save:" + STATS_BASE + ":" + STATS_RC, amount);
for (int i = 0; i < amount; i++) {
Rune rune = null;
while (rune == null) {

View file

@ -7,6 +7,7 @@ import core.game.node.entity.player.info.login.PlayerParser;
import rs09.Server;
import rs09.ServerConstants;
import rs09.ServerStore;
import rs09.game.content.global.GlobalKillCounter;
import rs09.game.ge.OfferManager;
import rs09.game.system.SystemLogger;
import rs09.game.world.repository.Repository;
@ -91,6 +92,7 @@ public final class SystemTermination {
} catch (Exception ignored) {}
}
Repository.getDisconnectionQueue().update();
GlobalKillCounter.save();
GrandExchangeDatabase.save();
OfferManager.save();
SystemLogger.flushLogs();
@ -102,4 +104,4 @@ public final class SystemTermination {
// ServerStore.dump(directory + "store/");
SystemLogger.logInfo("[SystemTerminator] Saved player accounts!");
}
}
}

View file

@ -35,7 +35,9 @@ import core.game.world.update.flag.chunk.AnimateObjectUpdateFlag
import core.game.world.update.flag.context.Animation
import core.game.world.update.flag.context.Graphics
import rs09.game.content.dialogue.DialogueFile
import rs09.game.content.global.GlobalKillCounter;
import rs09.game.system.SystemLogger
import rs09.game.system.config.ItemConfigParser;
import rs09.game.world.GameWorld
import rs09.game.world.GameWorld.Pulser
import rs09.game.world.repository.Repository
@ -1254,4 +1256,12 @@ object ContentAPI {
is Graphics -> Graphics.send(gfx, location)
}
}
@JvmStatic
fun announceIfRare(player: Player, item: Item) {
if (item.definition.getConfiguration(ItemConfigParser.RARE_ITEM, false)) {
ContentAPI.sendNews("${player.username} has just received: ${item.amount} x ${item.name}.");
GlobalKillCounter.incrementRareDrop(player, item);
}
}
}

View file

@ -10,6 +10,7 @@ import core.tools.TimeStamp
import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
import rs09.game.content.global.GlobalKillCounter;
import rs09.game.ge.GEAutoStock
import rs09.game.system.SystemLogger
import rs09.game.system.config.ServerConfigParser
@ -74,6 +75,7 @@ object Server {
startTime = System.currentTimeMillis()
val t = TimeStamp()
SystemLogger.logInfo("Initializing Server Store...")
GlobalKillCounter.init()
ServerStore.init()
SystemLogger.logInfo("Initialized ${ServerStore.counter} store files.")
GameWorld.prompt(true)

View file

@ -1,5 +1,6 @@
package rs09.game.content.activity.barrows
import api.ContentAPI
import core.game.component.Component
import core.game.container.access.InterfaceContainer
import core.game.content.global.BossKillCounter
@ -93,9 +94,10 @@ object RewardChest {
player.interfaceManager.open(Component(Components.TRAIL_REWARD_364))
BossKillCounter.addtoBarrowsCount(player)
for(item in rewards){
ContentAPI.announceIfRare(player, item);
if(!player.inventory.add(item)){
GroundItemManager.create(item,player)
}
}
}
}
}

View file

@ -0,0 +1,107 @@
package rs09.game.content.global
import core.game.node.entity.player.Player
import rs09.game.system.SystemLogger
import java.io.File
import java.io.FileReader
import java.io.FileWriter
import org.json.simple.JSONArray
import org.json.simple.JSONObject
import org.json.simple.parser.JSONParser
import rs09.ServerConstants
import core.game.node.item.Item
object GlobalKillCounter {
val kills: HashMap<String, HashMap<Long, Long>> = HashMap()
val rare_drops: HashMap<String, HashMap<Long, Long>> = HashMap()
fun init() {
val file = File(ServerConstants.DATA_PATH + File.separator + "global_kill_stats.json")
if(!file.exists()) {
return
}
val reader = FileReader(file)
val parser = JSONParser()
try {
val data = parser.parse(reader) as JSONObject
val tmp_kills = data.get("kills")
populate(kills, tmp_kills)
val tmp_rare_drops = data.get("rare_drops")
populate(rare_drops, tmp_rare_drops)
} catch (e: Exception){
SystemLogger.logErr("Failed parsing ${file.name} - stack trace below.")
e.printStackTrace()
}
}
@JvmStatic
fun populate(field: HashMap<String, HashMap<Long, Long>>, obj: Any?) {
if(obj != null && obj is JSONObject) {
for((player, tmp_kc) in obj.asIterable()) {
if(player is String) {
val kc: HashMap<Long, Long> = HashMap()
for((npc_id, count) in (tmp_kc as JSONObject).asIterable()) {
kc.put(java.lang.Long.parseLong(npc_id as String), count as Long)
}
field.put(player, kc)
}
}
}
}
@JvmStatic
fun saveField(field: HashMap<String, HashMap<Long, Long>>): JSONObject {
val tmp_kills = JSONObject()
for((player, kc) in field.asIterable()) {
val tmp_kc = JSONObject()
for((id, count) in kc.asIterable()) {
tmp_kc.put(id, count)
}
tmp_kills.put(player, tmp_kc)
}
return tmp_kills
}
@JvmStatic
fun save() {
val data = JSONObject()
data.put("kills", saveField(kills))
data.put("rare_drops", saveField(rare_drops))
val file = File(ServerConstants.DATA_PATH + File.separator + "global_kill_stats.json")
FileWriter(file).use { it.write(data.toJSONString()); it.flush(); it.close() }
}
@JvmStatic
fun incrementKills(player: Player, npc_id: Int) {
val player_kills = kills.getOrPut(player.username, { HashMap() })
val old_amount = player_kills.getOrElse(npc_id.toLong(), { 0 })
player_kills.put(npc_id.toLong(), 1 + old_amount)
}
@JvmStatic
fun incrementRareDrop(player: Player, item: Item) {
val player_drops = rare_drops.getOrPut(player.username, { HashMap() })
val old_amount = player_drops.getOrElse(item.id.toLong(), { 0 })
player_drops.put(item.id.toLong(), item.amount + old_amount)
}
@JvmStatic
fun getKills(player: Player, npc_id: Int): Long {
return kills.getOrElse(player.username, { HashMap() }).getOrElse(npc_id.toLong(), { 0 })
}
@JvmStatic
fun getKills(player: Player, npc_ids: IntArray): Long {
var sum: Long = 0
for(npc_id in npc_ids) {
sum += getKills(player, npc_id)
}
return sum
}
@JvmStatic
fun getRareDrops(player: Player, item_id: Int): Long {
return rare_drops.getOrElse(player.username, { HashMap() }).getOrElse(item_id.toLong(), { 0 })
}
}

View file

@ -6,6 +6,7 @@ const val STATS_DEATHS = "deaths"
const val STATS_LOGS = "logs_chopped"
const val STATS_FISH = "fish_caught"
const val STATS_ROCKS = "rocks_mined"
const val STATS_RC = "essence_crafted"
const val STATS_ALKHARID_GATE = "alkharid_gate"
const val FISHING_TRAWLER_GAMES_WON = "fishing-trawler-games"
const val FISHING_TRAWLER_LEAKS_PATCHED = "fishing-trawler-leaks-patched"

View file

@ -4,10 +4,168 @@ import core.game.component.Component
import core.game.content.global.BossKillCounter
import core.game.node.entity.player.Player
import core.plugin.Initializable
import org.rs09.consts.Items;
import org.rs09.consts.NPCs;
import rs09.game.content.global.GlobalKillCounter;
import rs09.game.interaction.InterfaceListener
import rs09.game.system.command.Command
import rs09.game.system.command.sets.CommandSet
import rs09.game.world.repository.Repository
val TUROTH_IDS = intArrayOf(NPCs.TUROTH_1622, NPCs.TUROTH_1623, NPCs.TUROTH_1626, NPCs.TUROTH_1627, NPCs.TUROTH_1628, NPCs.TUROTH_1629, NPCs.TUROTH_1630)
val KURASK_IDS = intArrayOf(NPCs.KURASK_1608, NPCs.KURASK_1609, NPCs.KURASK_4229, NPCs.KURASK_7811)
val GARGOYLE_IDS = intArrayOf(NPCs.GARGOYLE_1610, NPCs.GARGOYLE_1827, NPCs.GARGOYLE_6389)
val SPIRITUAL_MAGE_IDS = intArrayOf(NPCs.SPIRITUAL_MAGE_6221, NPCs.SPIRITUAL_MAGE_6231, NPCs.SPIRITUAL_MAGE_6257, NPCs.SPIRITUAL_MAGE_6278)
val GREEN_DRAGON_IDS = intArrayOf(NPCs.GREEN_DRAGON_941, NPCs.GREEN_DRAGON_4677, NPCs.GREEN_DRAGON_4678, NPCs.GREEN_DRAGON_4679, NPCs.GREEN_DRAGON_4680, NPCs.BRUTAL_GREEN_DRAGON_5362)
val BLUE_DRAGON_IDS = intArrayOf(NPCs.BLUE_DRAGON_55, NPCs.BLUE_DRAGON_4681, NPCs.BLUE_DRAGON_4682, NPCs.BLUE_DRAGON_4683, NPCs.BLUE_DRAGON_4684, NPCs.BLUE_DRAGON_5178)
val RED_DRAGON_IDS = intArrayOf(NPCs.RED_DRAGON_53, NPCs.RED_DRAGON_4669, NPCs.RED_DRAGON_4670, NPCs.RED_DRAGON_4671, NPCs.RED_DRAGON_4672)
val BLACK_DRAGON_IDS = intArrayOf(NPCs.BLACK_DRAGON_54, NPCs.BLACK_DRAGON_4673, NPCs.BLACK_DRAGON_4674, NPCs.BLACK_DRAGON_4675, NPCs.BLACK_DRAGON_4676)
val BRONZE_DRAGON_IDS = intArrayOf(NPCs.BRONZE_DRAGON_1590)
val IRON_DRAGON_IDS = intArrayOf(NPCs.IRON_DRAGON_1591)
val STEEL_DRAGON_IDS = intArrayOf(NPCs.STEEL_DRAGON_1592, NPCs.STEEL_DRAGON_3590)
val MITHRIL_DRAGON_IDS = intArrayOf(NPCs.MITHRIL_DRAGON_5363, NPCs.MITHRIL_DRAGON_8424)
val SKELETAL_WYVERN_IDS = intArrayOf(NPCs.SKELETAL_WYVERN_3068, NPCs.SKELETAL_WYVERN_3069, NPCs.SKELETAL_WYVERN_3070, NPCs.SKELETAL_WYVERN_3071)
val SPACER = "<str> </str>";
val NUM_PAGES = 3
fun sendStats(player: Player, other: Player, page: Int){
prepareInterface(player, other, page)
val globalData = other.savedData.globalData
for(i in (68..97)) {
when(page) {
0 -> {
when(i) {
//Various stats
97 -> sendLine(player,"Easy Clues: ${other.treasureTrailManager.completedClues[0]}",i)
68 -> sendLine(player,"Medium Clues: ${other.treasureTrailManager.completedClues[1]}",i)
69 -> sendLine(player,"Hard Clues: ${other.treasureTrailManager.completedClues[2]}",i)
70 -> sendLine(player,SPACER,i)
71 -> sendLine(player,"Slayer Tasks: ${other.slayer.totalTasks}",i)
72 -> sendLine(player,"Quest Points: ${other.questRepository.points}",i)
73 -> sendLine(player,"Ironman Mode: ${other.ironmanManager.mode.name.toLowerCase()}",i)
74 -> sendLine(player,"Deaths: ${other.getAttribute("$STATS_BASE:$STATS_DEATHS",0)}",i)
75 -> sendLine(player,SPACER,i)
76 -> sendLine(player,"Logs Chopped: ${other.getAttribute("$STATS_BASE:$STATS_LOGS",0)}",i)
77 -> sendLine(player,"Rocks Mined: ${other.getAttribute("$STATS_BASE:$STATS_ROCKS",0)}",i)
78 -> sendLine(player,"Fish Caught: ${other.getAttribute("$STATS_BASE:$STATS_FISH",0)}",i)
79 -> sendLine(player, "Essence Crafted: ${other.getAttribute("$STATS_BASE:$STATS_RC",0)}", i)
//Boss KC
82 -> sendLine(player, "KBD KC: ${globalData.bossCounters.get(BossKillCounter.KING_BLACK_DRAGON.ordinal)}",i)
83 -> sendLine(player, "TDs KC: ${globalData.bossCounters.get(BossKillCounter.TORMENTED_DEMONS.ordinal)}",i)
84 -> sendLine(player, "Supreme KC: ${globalData.bossCounters.get(BossKillCounter.DAGANNOTH_SUPREME.ordinal)}",i)
85 -> sendLine(player, "Rex KC: ${globalData.bossCounters.get(BossKillCounter.DAGANNOTH_REX.ordinal)}",i)
86 -> sendLine(player, "Prime KC: ${globalData.bossCounters.get(BossKillCounter.DAGANNOTH_PRIME.ordinal)}",i)
87 -> sendLine(player, "Barrows KC: ${globalData.barrowsLoots}",i)
88 -> sendLine(player, "Chaos Ele: ${globalData.bossCounters.get(BossKillCounter.CHAOS_ELEMENTAL.ordinal)}",i)
89 -> sendLine(player, "Mole KC: ${globalData.bossCounters.get(BossKillCounter.GIANT_MOLE.ordinal)}",i)
90 -> sendLine(player, "Sara KC: ${globalData.bossCounters.get(BossKillCounter.SARADOMIN.ordinal)}",i)
91 -> sendLine(player, "Zammy KC: ${globalData.bossCounters.get(BossKillCounter.ZAMORAK.ordinal)}",i)
92 -> sendLine(player, "Bandos KC: ${globalData.bossCounters.get(BossKillCounter.BANDOS.ordinal)}",i)
93 -> sendLine(player, "Arma KC: ${globalData.bossCounters.get(BossKillCounter.ARMADYL.ordinal)}",i)
94 -> sendLine(player, "Jad KC: ${globalData.bossCounters.get(BossKillCounter.JAD.ordinal)}",i)
95 -> sendLine(player, "KQ KC: ${globalData.bossCounters.get(BossKillCounter.KALPHITE_QUEEN.ordinal)}",i)
96 -> sendLine(player, "Corp KC: ${globalData.bossCounters.get(BossKillCounter.CORPOREAL_BEAST.ordinal)}",i)
else -> sendLine(player,"",i)
}
}
1 -> {
when(i) {
97 -> sendLine(player, "Turoths: ${GlobalKillCounter.getKills(other, TUROTH_IDS)}", i)
68 -> sendLine(player, "Kurasks: ${GlobalKillCounter.getKills(other, KURASK_IDS)}", i)
69 -> sendLine(player, "Leaf-bladed swords: ${GlobalKillCounter.getRareDrops(other, Items.LEAF_BLADED_SPEAR_4158)}", i)
70 -> sendLine(player,SPACER,i)
71 -> sendLine(player, "Gargoyles: ${GlobalKillCounter.getKills(other, GARGOYLE_IDS)}", i)
72 -> sendLine(player, "Granite mauls: ${GlobalKillCounter.getRareDrops(other, Items.GRANITE_MAUL_4153)}", i)
73 -> sendLine(player,SPACER,i)
74 -> sendLine(player, "Spiritual mages: ${GlobalKillCounter.getKills(other, SPIRITUAL_MAGE_IDS)}", i)
75 -> sendLine(player, "Dragon boots: ${GlobalKillCounter.getRareDrops(other, Items.DRAGON_BOOTS_11732)}", i)
76 -> sendLine(player,SPACER,i)
77 -> sendLine(player, "Abyssal demons: ${GlobalKillCounter.getKills(other, NPCs.ABYSSAL_DEMON_1615)}", i)
78 -> sendLine(player, "Abyssal whips: ${GlobalKillCounter.getRareDrops(other, Items.ABYSSAL_WHIP_4151)}", i)
79 -> sendLine(player,SPACER,i)
80 -> sendLine(player, "Dark beasts: ${GlobalKillCounter.getKills(other, NPCs.DARK_BEAST_2783)}", i)
81 -> sendLine(player, "Dark bows: ${GlobalKillCounter.getRareDrops(other, Items.DARK_BOW_11235)}", i)
82 -> sendLine(player, "Green Dragons: ${GlobalKillCounter.getKills(other, GREEN_DRAGON_IDS)}", i)
83 -> sendLine(player, "Blue Dragons: ${GlobalKillCounter.getKills(other, BLUE_DRAGON_IDS)}", i)
84 -> sendLine(player, "Red Dragons: ${GlobalKillCounter.getKills(other, RED_DRAGON_IDS)}", i)
85 -> sendLine(player, "Black Dragons: ${GlobalKillCounter.getKills(other, BLACK_DRAGON_IDS)}", i)
86 -> sendLine(player,SPACER,i)
87 -> sendLine(player, "Bronze Dragons: ${GlobalKillCounter.getKills(other, BRONZE_DRAGON_IDS)}", i)
88 -> sendLine(player, "Iron Dragons: ${GlobalKillCounter.getKills(other, IRON_DRAGON_IDS)}", i)
89 -> sendLine(player, "Steel Dragons: ${GlobalKillCounter.getKills(other, STEEL_DRAGON_IDS)}", i)
90 -> sendLine(player, "Mithril Dragons: ${GlobalKillCounter.getKills(other, MITHRIL_DRAGON_IDS)}", i)
91 -> sendLine(player, "Skeletal Wyverns: ${GlobalKillCounter.getKills(other, SKELETAL_WYVERN_IDS)}", i)
92 -> sendLine(player,SPACER,i)
93 -> sendLine(player, "Draconic visages: ${GlobalKillCounter.getRareDrops(other, Items.DRACONIC_VISAGE_11286)}", i)
else -> sendLine(player,"",i)
}
}
2 -> {
when(i) {
97 -> sendLine(player, "Ahrim's hood: ${GlobalKillCounter.getRareDrops(other, Items.AHRIMS_HOOD_4708)}", i)
68 -> sendLine(player, "Ahrim's staff: ${GlobalKillCounter.getRareDrops(other, Items.AHRIMS_STAFF_4710)}", i)
69 -> sendLine(player, "Ahrim's robetop: ${GlobalKillCounter.getRareDrops(other, Items.AHRIMS_ROBETOP_4712)}", i)
70 -> sendLine(player, "Ahrim's robeskirt: ${GlobalKillCounter.getRareDrops(other, Items.AHRIMS_ROBESKIRT_4714)}", i)
71 -> sendLine(player,SPACER,i)
72 -> sendLine(player, "Dharok's helm: ${GlobalKillCounter.getRareDrops(other, Items.DHAROKS_HELM_4716)}", i)
73 -> sendLine(player, "Dharok's greataxe: ${GlobalKillCounter.getRareDrops(other, Items.DHAROKS_GREATAXE_4718)}", i)
74 -> sendLine(player, "Dharok's platebody: ${GlobalKillCounter.getRareDrops(other, Items.DHAROKS_PLATEBODY_4720)}", i)
75 -> sendLine(player, "Dharok's platelegs: ${GlobalKillCounter.getRareDrops(other, Items.DHAROKS_PLATELEGS_4722)}", i)
76 -> sendLine(player,SPACER,i)
77 -> sendLine(player, "Guthan's helm: ${GlobalKillCounter.getRareDrops(other, Items.GUTHANS_HELM_4724)}", i)
78 -> sendLine(player, "Guthan's warspear: ${GlobalKillCounter.getRareDrops(other, Items.GUTHANS_WARSPEAR_4726)}", i)
79 -> sendLine(player, "Guthan's platebody: ${GlobalKillCounter.getRareDrops(other, Items.GUTHANS_PLATEBODY_4728)}", i)
80 -> sendLine(player, "Guthan's chainskirt: ${GlobalKillCounter.getRareDrops(other, Items.GUTHANS_CHAINSKIRT_4730)}", i)
82 -> sendLine(player, "Karil's coif: ${GlobalKillCounter.getRareDrops(other, Items.KARILS_COIF_4732)}", i)
83 -> sendLine(player, "Karil's crossbow: ${GlobalKillCounter.getRareDrops(other, Items.KARILS_CROSSBOW_4734)}", i)
84 -> sendLine(player, "Karil's leathertop: ${GlobalKillCounter.getRareDrops(other, Items.KARILS_LEATHERTOP_4736)}", i)
85 -> sendLine(player, "Karil's leatherskirt: ${GlobalKillCounter.getRareDrops(other, Items.KARILS_LEATHERSKIRT_4738)}", i)
86 -> sendLine(player,SPACER,i)
87 -> sendLine(player, "Torag's helm: ${GlobalKillCounter.getRareDrops(other, Items.TORAGS_HELM_4745)}", i)
88 -> sendLine(player, "Torag's hammers: ${GlobalKillCounter.getRareDrops(other, Items.TORAGS_HAMMERS_4747)}", i)
89 -> sendLine(player, "Torag's platebody: ${GlobalKillCounter.getRareDrops(other, Items.TORAGS_PLATEBODY_4749)}", i)
90 -> sendLine(player, "Torag's platelegs: ${GlobalKillCounter.getRareDrops(other, Items.TORAGS_PLATELEGS_4751)}", i)
91 -> sendLine(player,SPACER,i)
92 -> sendLine(player, "Verac's helm: ${GlobalKillCounter.getRareDrops(other, Items.VERACS_HELM_4753)}", i)
93 -> sendLine(player, "Verac's flail: ${GlobalKillCounter.getRareDrops(other, Items.VERACS_FLAIL_4755)}", i)
94 -> sendLine(player, "Verac's brassard: ${GlobalKillCounter.getRareDrops(other, Items.VERACS_BRASSARD_4757)}", i)
95 -> sendLine(player, "Verac's plateskirt: ${GlobalKillCounter.getRareDrops(other, Items.VERACS_PLATESKIRT_4759)}", i)
else -> sendLine(player,"",i)
}
}
}
}
player.interfaceManager.open(Component(26))
}
fun sendLine(player: Player, line: String, child: Int) {
player.packetDispatch.sendString(line,26,child)
}
fun prepareInterface(player: Player,other: Player, page: Int){
player.setAttribute("stats-page-info", StatsPageInfo(other, page))
if(page == 0) {
player.packetDispatch.sendInterfaceConfig(26,62,true)
player.packetDispatch.sendInterfaceConfig(26,65,true)
} else {
sendLine(player, "Previous", 65)
}
if(page == NUM_PAGES - 1) {
player.packetDispatch.sendInterfaceConfig(26,64,true)
player.packetDispatch.sendInterfaceConfig(26,66,true)
} else {
sendLine(player, "Next", 66)
}
player.packetDispatch.sendString(other.username + "'s Stats - Page ${page + 1}",26,101)
}
data class StatsPageInfo(val other: Player, val page: Int) {}
@Initializable
class StatsCommandSet : CommandSet(Command.Privilege.STANDARD) {
override fun defineCommands() {
@ -28,64 +186,33 @@ class StatsCommandSet : CommandSet(Command.Privilege.STANDARD) {
return@define
}
sendStats(player,other)
sendStats(player,other, 0)
}
}
fun sendStats(player: Player){
sendStats(player,player)
sendStats(player,player, 0)
}
fun sendStats(player: Player, other: Player){
prepareInterface(player,other)
val globalData = other.savedData.globalData
for(i in (67..96)){
when(i){
//Various stats
67 -> sendLine(player,"Easy Clues: ${other.treasureTrailManager.completedClues[0]}",97)
68 -> sendLine(player,"Medium Clues: ${other.treasureTrailManager.completedClues[1]}",i)
69 -> sendLine(player,"Hard Clues: ${other.treasureTrailManager.completedClues[2]}",i)
70 -> sendLine(player,"<str> </str>",i)
71 -> sendLine(player,"Slayer Tasks: ${other.slayer.totalTasks}",i)
72 -> sendLine(player,"Quest Points: ${other.questRepository.points}",i)
73 -> sendLine(player,"Ironman Mode: ${other.ironmanManager.mode.name.toLowerCase()}",i)
74 -> sendLine(player,"Deaths: ${other.getAttribute("$STATS_BASE:$STATS_DEATHS",0)}",i)
75 -> sendLine(player,"<str> </str>",i)
76 -> sendLine(player,"Logs Chopped: ${other.getAttribute("$STATS_BASE:$STATS_LOGS",0)}",i)
77 -> sendLine(player,"Rocks Mined: ${other.getAttribute("$STATS_BASE:$STATS_ROCKS",0)}",i)
78 -> sendLine(player,"Fish Caught: ${other.getAttribute("$STATS_BASE:$STATS_FISH",0)}",i)
}
//Boss KC
82 -> sendLine(player, "KBD KC: ${globalData.bossCounters.get(BossKillCounter.KING_BLACK_DRAGON.ordinal)}",i)
83 -> sendLine(player, "TDs KC: ${globalData.bossCounters.get(BossKillCounter.TORMENTED_DEMONS.ordinal)}",i)
84 -> sendLine(player, "Supreme KC: ${globalData.bossCounters.get(BossKillCounter.DAGANNOTH_SUPREME.ordinal)}",i)
85 -> sendLine(player, "Rex KC: ${globalData.bossCounters.get(BossKillCounter.DAGANNOTH_REX.ordinal)}",i)
86 -> sendLine(player, "Prime KC: ${globalData.bossCounters.get(BossKillCounter.DAGANNOTH_PRIME.ordinal)}",i)
87 -> sendLine(player, "Barrows KC: ${globalData.barrowsLoots}",i)
88 -> sendLine(player, "Chaos Ele: ${globalData.bossCounters.get(BossKillCounter.CHAOS_ELEMENTAL.ordinal)}",i)
89 -> sendLine(player, "Mole KC: ${globalData.bossCounters.get(BossKillCounter.GIANT_MOLE.ordinal)}",i)
90 -> sendLine(player, "Sara KC: ${globalData.bossCounters.get(BossKillCounter.SARADOMIN.ordinal)}",i)
91 -> sendLine(player, "Zammy KC: ${globalData.bossCounters.get(BossKillCounter.ZAMORAK.ordinal)}",i)
92 -> sendLine(player, "Bandos KC: ${globalData.bossCounters.get(BossKillCounter.BANDOS.ordinal)}",i)
93 -> sendLine(player, "Arma KC: ${globalData.bossCounters.get(BossKillCounter.ARMADYL.ordinal)}",i)
94 -> sendLine(player, "Jad KC: ${globalData.bossCounters.get(BossKillCounter.JAD.ordinal)}",i)
95 -> sendLine(player, "KQ KC: ${globalData.bossCounters.get(BossKillCounter.KALPHITE_QUEEN.ordinal)}",i)
96 -> sendLine(player, "Corp KC: ${globalData.bossCounters.get(BossKillCounter.CORPOREAL_BEAST.ordinal)}",i)
else -> sendLine(player,"",i)
class StatsInterface : InterfaceListener() {
val COMPONENT_ID = 26
override fun defineListeners() {
on(COMPONENT_ID, 61) { player, _, _, _, _, _ ->
val info: StatsPageInfo? = player.getAttribute("stats-page-info", null)
if(info != null) {
sendStats(player, info.other, info.page-1)
}
return@on true
}
on(COMPONENT_ID, 63) { player, _, _, _, _, _ ->
val info: StatsPageInfo? = player.getAttribute("stats-page-info", null)
if(info != null) {
sendStats(player, info.other, info.page+1)
}
return@on true
}
player.interfaceManager.open(Component(26))
}
fun sendLine(player: Player, line: String, child: Int){
player.packetDispatch.sendString(line,26,child)
}
fun prepareInterface(player: Player,other: Player){
player.packetDispatch.sendInterfaceConfig(26,64,true)
player.packetDispatch.sendInterfaceConfig(26,62,true)
player.packetDispatch.sendInterfaceConfig(26,65,true)
player.packetDispatch.sendInterfaceConfig(26,66,true)
player.packetDispatch.sendString(other.username + "'s Stats",26,101)
}
}