mirror of
https://gitlab.com/2009scape/2009scape.git
synced 2025-12-21 09:02:07 -07:00
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:
commit
fb3931fbf4
11 changed files with 344 additions and 60 deletions
|
|
@ -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"
|
||||
}
|
||||
]
|
||||
]
|
||||
|
|
|
|||
|
|
@ -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()) {
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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) {
|
||||
|
|
|
|||
|
|
@ -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!");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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 })
|
||||
}
|
||||
}
|
||||
|
|
@ -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"
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue