Extended ::bury command to support hiding player name and adding message

Implemented ::buryitem <id> <true|false> [msg]
Implemented ::burymessage <msg>
This commit is contained in:
Kermit Frog
2026-04-01 14:37:51 +00:00
committed by Ryan
parent 2bad80f141
commit 23bc594469
@@ -3,11 +3,13 @@ package core.game.system.command.sets
import content.global.handlers.item.SpadeDigListener
import content.region.misc.tutisland.handlers.iface.CharacterDesign
import core.api.*
import core.ServerStore
import core.game.dialogue.DialogueFile
import core.game.node.entity.combat.ImpactHandler
import core.game.node.entity.npc.NPC
import core.game.node.entity.player.Player
import core.game.node.entity.player.info.login.PlayerSaver
import core.game.node.item.Item
import core.game.system.command.Privilege
import core.game.system.task.Pulse
import core.game.world.GameWorld
@@ -17,8 +19,9 @@ import core.game.world.repository.Repository.getPlayerByName
import core.game.world.update.flag.context.Animation
import core.game.world.update.flag.context.Graphics
import core.plugin.Initializable
import core.tools.END_DIALOGUE
import core.tools.RandomFunction
import core.tools.Log
import org.json.simple.JSONArray
import org.json.simple.JSONObject
import org.rs09.consts.Sounds
import java.awt.HeadlessException
@@ -30,6 +33,60 @@ import kotlin.streams.toList
class FunCommandSet : CommandSet(Privilege.ADMIN) {
var npcs: List<NPC> = ArrayList()
private val TREASURE_KEY = "fun_command_buried_treasures"
private val treasures = ArrayList<BuriedTreasure>()
init {
loadTreasures()
}
/**
* I hope ceikry doesn't punish me for this ~ used SkillcapePerks for a base idea tried to make it modular.
* Supports persistence across reboots for bury, buryitem, and burymessage supporting all command arguments.
*/
private fun loadTreasures() {
val archive = ServerStore.getArchive(TREASURE_KEY)
if (!archive.containsKey("data")) return
try {
val array = archive["data"] as JSONArray
for (obj in array) {
val json = obj as JSONObject
val x = (json["x"] as Long).toInt()
val y = (json["y"] as Long).toInt()
val z = (json["z"] as Long).toInt()
val loc = Location.create(x, y, z)
val type = TreasureType.valueOf(json["type"] as String)
val hiderName = json["hiderName"] as? String ?: "Unknown"
val hideName = json["hideName"] as? Boolean ?: false
val customMessage = json["customMessage"] as? String
val message = json["message"] as? String ?: ""
val items = ArrayList<Item>()
if (json.containsKey("items")) {
val itemsJson = json["items"] as JSONArray
for (i in itemsJson) {
val itemObj = i as JSONObject
val id = (itemObj["id"] as Long).toInt()
val amount = (itemObj["amount"] as Long).toInt()
items.add(Item(id, amount))
}
}
val treasure = BuriedTreasure(loc, type, items, message, hiderName, hideName, customMessage)
treasures.add(treasure)
registerTreasureListener(treasure)
}
log(FunCommandSet::class.java, Log.DEBUG, "Loaded ${treasures.size} buried treasures.")
} catch (e: Exception) {
log(FunCommandSet::class.java, Log.ERR, "Failed to load buried treasures: ${e.message}")
e.printStackTrace()
}
}
override fun defineCommands() {
@@ -175,19 +232,39 @@ class FunCommandSet : CommandSet(Privilege.ADMIN) {
/**
* Bury inventory at current location
*/
define("bury", description = "Buries your entire inventory at your current location."){player, _ ->
define("bury", description = "Buries your entire inventory at your current location for treasure hunters. Required true/false to hide players name and an optional custom message."){player, args ->
if(player.inventory.isEmpty){
reject(player, "You have no items to bury.")
}
if (args.size < 2) {
reject(player, "Usage: ::bury <lt>true | false<gt> [custom news message]")
return@define
}
val hideName = when(args[1].lowercase()) {
"true" -> true
"false" -> false
else -> {
reject(player, "Invalid argument. Usage: ::bury <lt>true | false<gt> [custom news message]")
return@define
}
}
val customMessage = if (args.size > 2) {
args.slice(2 until args.size).joinToString(" ")
} else {
null
}
player.dialogueInterpreter.open(object : DialogueFile(){
override fun handle(componentID: Int, buttonID: Int) {
when(stage){
0 -> dialogue("This will bury your whole inventory in this spot.","Are you sure?").also { stage++ }
0 -> dialogue("This will bury your whole inventory at this spot.","Are you sure?").also { stage++ }
1 -> options("Yes","No").also { stage++ }
2 -> when(buttonID){
1 -> bury(player).also { end() }
2 -> stage = END_DIALOGUE
1 -> bury(player, hideName, customMessage).also { end() }
2 -> end()
}
}
}
@@ -195,6 +272,78 @@ class FunCommandSet : CommandSet(Privilege.ADMIN) {
}
/**
* Bury a secret message at current location for a player to find.
*/
define("burymessage", description = "Buries a secret message at your current location."){ player, args ->
if (args.size < 2) {
reject(player, "Usage: ::burymessage [message]")
return@define
}
val message = args.slice(1 until args.size).joinToString(" ")
val loc = Location.create(player.location)
if(SpadeDigListener.listeners.containsKey(loc)){
reject(player, "There is already something buried here.")
return@define
}
val treasure = BuriedTreasure(loc, TreasureType.MESSAGE, emptyList(), message, player.username, false, null)
treasures.add(treasure)
saveTreasures()
registerTreasureListener(treasure)
notify(player, "You have buried the message '$message' at $loc")
log(FunCommandSet::class.java, Log.DEBUG, "Message buried by ${player.username} at $loc: \"$message\"")
}
/**
* Bury a specific item at current location
*/
define("buryitem", description = "Buries a specific item at your current location."){ player, args ->
if (args.size < 3) {
reject(player, "Usage: ::buryitem <lt>item id<gt> <lt>true | false<gt> [custom message]")
return@define
}
val itemId = args[1].toIntOrNull()
if (itemId == null) {
reject(player, "Invalid item ID.")
return@define
}
val hideName = when(args[2].lowercase()) {
"true" -> true
"false" -> false
else -> {
reject(player, "Invalid argument. Usage: ::buryitem <lt>item id<gt> <lt>true | false<gt> [custom message]")
return@define
}
}
val customMessage = if (args.size > 3) {
args.slice(3 until args.size).joinToString(" ")
} else {
null
}
player.dialogueInterpreter.open(object : DialogueFile(){
override fun handle(componentID: Int, buttonID: Int) {
when(stage){
0 -> dialogue("This will bury a ${Item(itemId).name} at this spot.","Are you sure?").also { stage++ }
1 -> options("Yes","No").also { stage++ }
2 -> when(buttonID){
1 -> buryItem(player, itemId, hideName, customMessage).also { end() }
2 -> end()
}
}
}
})
}
define("appearance", Privilege.ADMIN, "", "Allows you to change your appearance."){ player, _ ->
CharacterDesign.reopen(player)
}
@@ -249,19 +398,109 @@ class FunCommandSet : CommandSet(Privilege.ADMIN) {
}
fun bury(player: Player){
fun bury(player: Player, hideName: Boolean = false, customMessage: String? = null){
val loc = Location.create(player.location)
val inv = player.inventory.toArray().filterNotNull()
SpadeDigListener.registerListener(player.location){ p ->
for(item in inv){
if(SpadeDigListener.listeners.containsKey(loc)){
notify(player, "There is already something buried here.")
return
}
val inv = player.inventory.toArray().filterNotNull().toList()
if (inv.isEmpty()) {
notify(player, "You have nothing to bury.")
return
}
val treasure = BuriedTreasure(loc, TreasureType.ITEM, inv, "", player.username, hideName, customMessage)
treasures.add(treasure)
saveTreasures()
registerTreasureListener(treasure)
player.inventory.clear()
notify(player, "You have buried your loot at ${loc.toString()}")
log(FunCommandSet::class.java, Log.DEBUG, "Loot buried by ${player.username} at $loc. Masked: $hideName")
}
fun buryItem(player: Player, itemId: Int, hideName: Boolean, customMessage: String? = null) {
val loc = Location.create(player.location)
if(SpadeDigListener.listeners.containsKey(loc)){
notify(player, "There is already something buried here.")
return
}
val treasure = BuriedTreasure(loc, TreasureType.ITEM, listOf(Item(itemId, 1)), "", player.username, hideName, customMessage)
treasures.add(treasure)
saveTreasures()
registerTreasureListener(treasure)
notify(player, "You have buried item ${Item(itemId).name} at $loc")
log(FunCommandSet::class.java, Log.DEBUG, "Item $itemId buried by ${player.username} at $loc. Masked: $hideName")
}
private fun registerTreasureListener(t: BuriedTreasure) {
SpadeDigListener.registerListener(t.location) { p ->
log(FunCommandSet::class.java, Log.DEBUG, "SpadeDigListener triggered for ${p.username} at ${t.location}")
if (t.type == TreasureType.ITEM) {
for(item in t.items){
addItemOrDrop(p, item.id, item.amount)
sendMessage(p, "You dig and find ${if(item.amount > 1) "some" else "a"} ${item.name}")
}
sendNews("${player.username} has found the hidden treasure! Congratulations!!!")
SpadeDigListener.listeners.remove(loc)
}
player.inventory.clear()
notify(player, "You have buried your loot at ${loc.toString()}")
val finderName = if (t.hideName) "Someone" else p.username
val message = t.customMessage ?: "$finderName has found the hidden treasure! Congratulations!!!"
sendNews(message)
} else {
sendMessage(p, t.message)
}
SpadeDigListener.listeners.remove(t.location)
treasures.remove(t)
saveTreasures()
}
}
private fun saveTreasures() {
val array = JSONArray()
for (t in treasures) {
val json = JSONObject()
json["x"] = t.location.x
json["y"] = t.location.y
json["z"] = t.location.z
json["type"] = t.type.name
json["hiderName"] = t.hiderName
json["hideName"] = t.hideName
if (t.customMessage != null) json["customMessage"] = t.customMessage
json["message"] = t.message
val itemsArray = JSONArray()
for (i in t.items) {
val itemObj = JSONObject()
itemObj["id"] = i.id
itemObj["amount"] = i.amount
itemsArray.add(itemObj)
}
json["items"] = itemsArray
array.add(json)
}
val archive = ServerStore.getArchive(TREASURE_KEY)
archive["data"] = array
}
private data class BuriedTreasure(
val location: Location,
val type: TreasureType,
val items: List<Item>,
val message: String,
val hiderName: String,
val hideName: Boolean,
val customMessage: String?
)
private enum class TreasureType { ITEM, MESSAGE }
}