diff --git a/Server/src/main/java/core/game/node/entity/skill/Skills.java b/Server/src/main/java/core/game/node/entity/skill/Skills.java index 5666d5458..2bcb34c5c 100644 --- a/Server/src/main/java/core/game/node/entity/skill/Skills.java +++ b/Server/src/main/java/core/game/node/entity/skill/Skills.java @@ -1,6 +1,7 @@ package core.game.node.entity.skill; import api.events.DynamicSkillLevelChangeEvent; +import api.events.XPGainEvent; import core.game.interaction.item.brawling_gloves.BrawlingGloves; import core.game.interaction.item.brawling_gloves.BrawlingGlovesManager; import core.game.node.entity.Entity; @@ -275,6 +276,7 @@ public final class Skills { } if (entity instanceof Player) { PacketRepository.send(SkillLevel.class, new SkillContext((Player) entity, slot)); + entity.dispatch(new XPGainEvent(slot, experienceAdd)); } } diff --git a/Server/src/main/kotlin/api/events/Events.kt b/Server/src/main/kotlin/api/events/Events.kt index 911ef7f99..a0681ef92 100644 --- a/Server/src/main/kotlin/api/events/Events.kt +++ b/Server/src/main/kotlin/api/events/Events.kt @@ -41,4 +41,5 @@ data class FairyRingDialEvent(val fairyRing: FairyRing) : Event data class VarbitUpdateEvent(val offset: Int, val value: Int) : Event data class DynamicSkillLevelChangeEvent(val skillId: Int, val oldValue: Int, val newValue: Int): Event data class SummoningPointsRechargeEvent(val obelisk: Node) : Event -data class PrayerPointsRechargeEvent(val altar: Node) : Event \ No newline at end of file +data class PrayerPointsRechargeEvent(val altar: Node) : Event +data class XPGainEvent(val skillId: Int, val amount: Double) : Event \ No newline at end of file diff --git a/Server/src/main/kotlin/rs09/game/Event.kt b/Server/src/main/kotlin/rs09/game/Event.kt index 08d15db21..6f85c77b6 100644 --- a/Server/src/main/kotlin/rs09/game/Event.kt +++ b/Server/src/main/kotlin/rs09/game/Event.kt @@ -32,4 +32,5 @@ object Event { @JvmStatic val DynamicSkillLevelChanged = DynamicSkillLevelChangeEvent::class.java @JvmStatic val SummoningPointsRecharged = SummoningPointsRechargeEvent::class.java @JvmStatic val PrayerPointsRecharged = PrayerPointsRechargeEvent::class.java + @JvmStatic val XpGained = XPGainEvent::class.java } \ No newline at end of file diff --git a/Server/src/main/kotlin/rs09/game/content/global/worldevents/WorldEvent.kt b/Server/src/main/kotlin/rs09/game/content/global/worldevents/WorldEvent.kt index fd76cb29d..e4e90a8ca 100644 --- a/Server/src/main/kotlin/rs09/game/content/global/worldevents/WorldEvent.kt +++ b/Server/src/main/kotlin/rs09/game/content/global/worldevents/WorldEvent.kt @@ -2,6 +2,8 @@ package rs09.game.content.global.worldevents import rs09.game.system.SystemLogger import core.plugin.Plugin +import org.json.simple.JSONObject +import rs09.ServerStore import rs09.plugin.ClassScanner import java.util.* @@ -77,4 +79,8 @@ object WorldEvents { fun get(name: String): WorldEvent?{ return events.get(name.toLowerCase()) } + + fun getArchive() : JSONObject { + return ServerStore.getArchive("world-event-status") + } } \ No newline at end of file diff --git a/Server/src/main/kotlin/rs09/game/content/global/worldevents/holiday/christmas/GiftRollPlugin.kt b/Server/src/main/kotlin/rs09/game/content/global/worldevents/holiday/christmas/GiftRollPlugin.kt deleted file mode 100644 index adfa22bd0..000000000 --- a/Server/src/main/kotlin/rs09/game/content/global/worldevents/holiday/christmas/GiftRollPlugin.kt +++ /dev/null @@ -1,108 +0,0 @@ -package rs09.game.content.global.worldevents.holiday.christmas - -import api.Container -import api.* -import core.game.node.entity.player.Player -import core.game.node.entity.skill.Skills -import core.plugin.Initializable -import core.tools.RandomFunction -import org.rs09.consts.Items -import rs09.ServerStore -import rs09.ServerStore.Companion.getInt -import rs09.game.content.global.WeightBasedTable -import rs09.game.content.global.WeightedItem -import rs09.game.interaction.InteractionListener -import rs09.game.interaction.IntType -import rs09.game.system.SystemLogger -import rs09.plugin.CorePluginTypes.XPGainPlugin -import rs09.tools.stringtools.colorize -import java.time.Month -import java.util.* - -class GiftRollPlugin : XPGainPlugin() { - override fun run(player: Player, skill: Int, amount: Double) { - val numDaily = getDailyGifts(player) - - val cooldown = player.getAttribute("christmas-cooldown", 0L) - if(System.currentTimeMillis() < cooldown) return - player.setAttribute("/save:christmas-cooldown", System.currentTimeMillis() + 5000L) - - if(System.currentTimeMillis() > cooldown && numDaily < 10 && RandomFunction.roll(15).also { player.debug("Rolling gift: $it") } && amount > 20) { - incrementDailyGifts(player) - - addItemOrDrop(player, Items.MYSTERY_BOX_6199) - sendMessage(player, colorize("%RMerry Christmas! %GYou randomly receive a mystery box while training ${Skills.SKILL_NAME[skill]}!")) - } - } - - private fun getDailyGifts(player: Player) : Int { - return ServerStore.getArchive("daily-xmas-gifts").getInt(player.name) - } - - fun incrementDailyGifts(player: Player) { - val start = getDailyGifts(player) - ServerStore.getArchive("daily-xmas-gifts")[player.name] = start + 1 - } - - override fun fireEvent(identifier: String?, vararg args: Any?): Any { - return Unit - } -} - -class XMASMboxHandler : InteractionListener { - val MBOX = Items.MYSTERY_BOX_6199 - - override fun defineListeners() { - //disable if it's not december. - //Calendar.MONTH is 0-indexed, Month is 1-indexed. I know. It's dumb. Thanks oracle. - if(Calendar.getInstance().get(Calendar.MONTH) + 1 != Month.DECEMBER.value){ - return - } - - on(MBOX, IntType.ITEM, "open"){player, used -> - val item = MBOX_LOOT.roll().first() - - if(removeItem(player, used, Container.INVENTORY)) { - sendDialogue(player, "You open the gift and find ${item.amount} ${item.name}!") - addItemOrDrop(player, item.id, item.amount) - } - return@on true - } - } - - val MBOX_LOOT = WeightBasedTable.create( - WeightedItem(Items.TOY_HORSEY_2520, 1, 1, 0.025), - WeightedItem(Items.TOY_HORSEY_2522, 1, 1, 0.025), - WeightedItem(Items.TOY_HORSEY_2524, 1, 1, 0.025), - WeightedItem(Items.TOY_HORSEY_2526, 1, 1, 0.025), - WeightedItem(Items.TOY_KITE_12844, 1, 1, 0.025), - WeightedItem(Items.COAL_453, 1, 1, 0.025), - WeightedItem(Items.MOLTEN_GLASS_1776, 25, 100, 0.25), - WeightedItem(Items.FLAX_1780, 15, 70, 0.25), - WeightedItem(Items.UNCUT_SAPPHIRE_1624, 1, 5, 0.15), - WeightedItem(Items.UNCUT_EMERALD_1622, 1, 5, 0.15), - WeightedItem(Items.UNCUT_RUBY_1620, 1, 5, 0.15), - WeightedItem(Items.UNCUT_DIAMOND_1618, 1, 5, 0.15), - WeightedItem(Items.UNCUT_SAPPHIRE_1624, 100, 100, 0.0015), - WeightedItem(Items.UNCUT_EMERALD_1622, 100, 100, 0.0015), - WeightedItem(Items.UNCUT_RUBY_1620, 100, 100, 0.0015), - WeightedItem(Items.UNCUT_DIAMOND_1618, 100, 100, 0.0015), - WeightedItem(Items.PURE_ESSENCE_7937, 1, 50, 0.15), - WeightedItem(Items.PURE_ESSENCE_7937, 1000, 1000, 0.0015), - WeightedItem(Items.RANARR_SEED_5295, 1, 3, 0.065), - WeightedItem(Items.SNAPDRAGON_SEED_5300, 1, 3, 0.065), - WeightedItem(Items.GOLD_CHARM_12158, 1, 15, 0.15), - WeightedItem(Items.CRIMSON_CHARM_12160, 1, 15, 0.15), - WeightedItem(Items.BLUE_CHARM_12163, 1, 15, 0.15), - WeightedItem(Items.GREEN_CHARM_12159, 1, 15, 0.15), - WeightedItem(Items.SPIRIT_SHARDS_12183, 1, 100, 0.15), - WeightedItem(Items.PURPLE_SWEETS_10476, 1, 15, 0.25), - WeightedItem(Items.COINS_995, 100, 1000, 0.15), - WeightedItem(Items.COINS_995, 50000, 100000, 0.0015), - WeightedItem(Items.COINS_995, 1000000, 1000000, 0.0005), - WeightedItem(Items.NATURE_RUNE_561, 1, 10, 0.15), - WeightedItem(Items.ABYSSAL_WHIP_4151, 1, 1, 0.00005), - WeightedItem(Items.SANTA_HAT_1050, 1, 1, 0.00005), - - ).insertEasyClue(0.075).insertMediumClue(0.05).insertHardClue(0.025).insertRDTRoll(0.015) -} \ No newline at end of file diff --git a/Server/src/main/kotlin/rs09/game/content/global/worldevents/holiday/christmas/Giftmas.kt b/Server/src/main/kotlin/rs09/game/content/global/worldevents/holiday/christmas/Giftmas.kt new file mode 100644 index 000000000..5af3bdb4e --- /dev/null +++ b/Server/src/main/kotlin/rs09/game/content/global/worldevents/holiday/christmas/Giftmas.kt @@ -0,0 +1,162 @@ +package rs09.game.content.global.worldevents.holiday.christmas + +import api.* +import api.events.EventHook +import api.events.XPGainEvent +import core.game.node.entity.Entity +import core.game.node.entity.player.Player +import core.tools.RandomFunction +import org.json.simple.JSONObject +import org.rs09.consts.Items +import rs09.ServerStore +import rs09.ServerStore.Companion.getBoolean +import rs09.ServerStore.Companion.getInt +import rs09.game.Event +import rs09.game.content.global.WeightBasedTable +import rs09.game.content.global.WeightedItem +import rs09.game.content.global.worldevents.WorldEvents +import rs09.game.interaction.IntType +import rs09.game.interaction.InteractionListener +import rs09.game.system.command.Privilege +import rs09.game.world.repository.Repository +import rs09.tools.stringtools.colorize + +class Giftmas : Commands, StartupListener, LoginListener, InteractionListener { + override fun startup() { + if (checkActive()) + init() + } + + fun checkActive(): Boolean { + val archive = getArchive() + return archive.getBoolean("active") + } + + override fun login(player: Player) { + if (!checkActive()) return + player.hook(Event.XpGained, XpGainHook) + } + + fun init() { + try { + on(Items.MYSTERY_BOX_6199, IntType.ITEM, "open") { player, node -> + val loot = MBOX_LOOT.roll().first() + + if (!removeItem(player, node.asItem())) return@on true + + sendDialogue(player, "You open the mystery box and find ${loot.amount}x ${loot.name.lowercase()}!") + addItem(player, loot.id, loot.amount) + return@on true + } + } catch (ignored: Exception) {} + + for (player in Repository.players) + player.hook(Event.XpGained, XpGainHook) + } + + fun cleanup() { + for (player in Repository.players) + player.unhook(XpGainHook) + } + + override fun defineCommands() { + define("toggle-giftmas", Privilege.ADMIN, "", "Toggles the giftmas christmas event.") {player, args -> + val enabled = checkActive() + getArchive()["active"] = !enabled + notify(player, "Giftmas is now ${if (enabled) "DISABLED" else "ENABLED"}.") + if (!enabled) { + init() + } else { + cleanup() + } + } + } + + object XpGainHook : EventHook { + override fun process(entity: Entity, event: XPGainEvent) { + val wasCombat = event.skillId in 0..6 + val daily = getDailyGifts(entity.asPlayer(), wasCombat) + val player = entity.asPlayer() + val cooldown = entity.getAttribute("christmas-cooldown", 0L) + + if (event.amount < 25.0) return + if (!RandomFunction.roll(15)) return + if (daily >= if (wasCombat) DAILY_LIMIT_COMBAT else DAILY_LIMIT_SKILLING) return + if (System.currentTimeMillis() < cooldown) return + if (!addItem(player, Items.MYSTERY_BOX_6199)) return + + player.setAttribute("/save:christmas-cooldown", System.currentTimeMillis() + 5000L) + incrementDailyGifts(player, wasCombat) + sendMessage(player, MESSAGE_PRESENT_GRANTED) + + if (wasCombat && daily == DAILY_LIMIT_COMBAT - 1) + sendMessage(player, MESSAGE_DAILYXP_REACHED_COMBAT) + if (!wasCombat && daily == DAILY_LIMIT_SKILLING - 1) + sendMessage(player, MESSAGE_DAILYXP_REACHED_SKILLING) + } + + private fun getDailyGifts(player: Player, wasCombat: Boolean) : Int { + val archive = if (wasCombat) "daily-xmas-gifts-combat" else "daily-xmas-gifts-skilling" + return ServerStore.getArchive(archive).getInt(player.name) + } + + fun incrementDailyGifts(player: Player, wasCombat: Boolean) { + val start = getDailyGifts(player, wasCombat) + val archive = if (wasCombat) "daily-xmas-gifts-combat" else "daily-xmas-gifts-skilling" + ServerStore.getArchive(archive)[player.name] = start + 1 + } + } + + override fun defineListeners() {} + + companion object { + private val DAILY_LIMIT_SKILLING = 15 + private val DAILY_LIMIT_COMBAT = 5 + + private fun getArchive() : JSONObject { + val mainArchive = WorldEvents.getArchive() + if (!mainArchive.containsKey("giftmas")) + mainArchive["giftmas"] = JSONObject() + return mainArchive["giftmas"] as JSONObject + } + + private val MESSAGE_DAILYXP_REACHED_SKILLING = colorize("%RYou have reached your daily limit of presents from skilling!") + private val MESSAGE_DAILYXP_REACHED_COMBAT = colorize("%RYou have reached your daily limit of presents from combat!") + private val MESSAGE_PRESENT_GRANTED = colorize("%GYou find a present while training!") + private val MBOX_LOOT = WeightBasedTable.create( + WeightedItem(Items.TOY_HORSEY_2520, 1, 1, 0.025), + WeightedItem(Items.TOY_HORSEY_2522, 1, 1, 0.025), + WeightedItem(Items.TOY_HORSEY_2524, 1, 1, 0.025), + WeightedItem(Items.TOY_HORSEY_2526, 1, 1, 0.025), + WeightedItem(Items.TOY_KITE_12844, 1, 1, 0.025), + WeightedItem(Items.COAL_453, 1, 1, 0.025), + WeightedItem(Items.MOLTEN_GLASS_1776, 25, 50, 0.25), + WeightedItem(Items.FLAX_1780, 15, 70, 0.25), + WeightedItem(Items.BOW_STRING_1778, 10, 50, 0.15), + WeightedItem(Items.UNCUT_SAPPHIRE_1624, 1, 5, 0.15), + WeightedItem(Items.UNCUT_EMERALD_1622, 1, 5, 0.15), + WeightedItem(Items.UNCUT_RUBY_1620, 1, 5, 0.15), + WeightedItem(Items.UNCUT_DIAMOND_1618, 1, 5, 0.15), + WeightedItem(Items.UNCUT_SAPPHIRE_1624, 100, 100, 0.0015), + WeightedItem(Items.UNCUT_EMERALD_1622, 100, 100, 0.0015), + WeightedItem(Items.UNCUT_RUBY_1620, 100, 100, 0.0015), + WeightedItem(Items.UNCUT_DIAMOND_1618, 100, 100, 0.0015), + WeightedItem(Items.PURE_ESSENCE_7937, 1, 50, 0.15), + WeightedItem(Items.PURE_ESSENCE_7937, 1000, 1000, 0.0015), + WeightedItem(Items.RANARR_SEED_5295, 1, 3, 0.065), + WeightedItem(Items.SNAPDRAGON_SEED_5300, 1, 3, 0.065), + WeightedItem(Items.GOLD_CHARM_12158, 1, 15, 0.15), + WeightedItem(Items.CRIMSON_CHARM_12160, 1, 15, 0.15), + WeightedItem(Items.BLUE_CHARM_12163, 1, 15, 0.15), + WeightedItem(Items.GREEN_CHARM_12159, 1, 15, 0.15), + WeightedItem(Items.PURPLE_SWEETS_10476, 1, 15, 0.25), + WeightedItem(Items.COINS_995, 100, 1000, 0.15), + WeightedItem(Items.COINS_995, 50000, 100000, 0.0015), + WeightedItem(Items.COINS_995, 1000000, 1000000, 0.0005), + WeightedItem(Items.NATURE_RUNE_561, 1, 10, 0.15), + WeightedItem(Items.ABYSSAL_WHIP_4151, 1, 1, 0.00005), + WeightedItem(Items.SANTA_HAT_1050, 1, 1, 0.00005), + + ).insertEasyClue(0.015).insertMediumClue(0.010).insertHardClue(0.005).insertRDTRoll(0.015) + } +} \ No newline at end of file diff --git a/Server/src/main/kotlin/rs09/net/packet/PacketProcessor.kt b/Server/src/main/kotlin/rs09/net/packet/PacketProcessor.kt index e5658ea49..8a3e81f94 100644 --- a/Server/src/main/kotlin/rs09/net/packet/PacketProcessor.kt +++ b/Server/src/main/kotlin/rs09/net/packet/PacketProcessor.kt @@ -144,7 +144,7 @@ object PacketProcessor { } is Packet.QuickChat -> QCRepository.sendQC(pkt.player, pkt.multiplier, pkt.offset, pkt.type, pkt.indexA, pkt.indexB, pkt.forClan) is Packet.InputPromptResponse -> { - val script: ((Any) -> Boolean) = pkt.player.getAttribute("runscript", null) ?: return + val script: ((Any) -> Boolean) = pkt.player.getAttribute<((Any) -> Boolean)?>("runscript", null) ?: return if (pkt.player.locks.isInteractionLocked) return try {