Converted some content to the new event hooks and listeners systems in order to clean up code a bit

Added interfaces for standardizing the saving/loading process for data, and allowing it to be declared independently of an entry in PlayerSaver/PlayerSaveParser
This commit is contained in:
Ceikry
2022-04-04 07:12:54 +00:00
committed by Ryan
parent abfddaca43
commit 24b28d84fd
78 changed files with 771 additions and 753 deletions
+3 -2
View File
@@ -18,6 +18,7 @@ import org.rs09.consts.Components
import rs09.ServerConstants
import rs09.game.Event
import rs09.game.camerautils.PlayerCamera
import rs09.game.content.ame.RandomEventManager
import rs09.game.system.SystemLogger
import rs09.game.world.GameWorld
@@ -231,7 +232,7 @@ abstract class Cutscene(val player: Player) {
player.lock()
player.hook(Event.SelfDeath, CUTSCENE_DEATH_HOOK)
player.logoutListeners["cutscene"] = {player -> player.location = exitLocation; player.getCutscene()?.end() }
player.antiMacroHandler.enabled = false
RandomEventManager.getInstance(player)!!.enabled = false
}
/**
@@ -260,7 +261,7 @@ abstract class Cutscene(val player: Player) {
clearNPCs()
player.unhook(CUTSCENE_DEATH_HOOK)
player.logoutListeners.remove("cutscene")
player.antiMacroHandler.enabled = true
RandomEventManager.getInstance(player)!!.enabled = false
return true
}
}
@@ -0,0 +1,19 @@
package api
import core.game.node.entity.player.Player
import org.json.simple.JSONObject
interface PersistPlayer {
/**
* NOTE: This should NOT reference nonstatic class-local variables.
* You need to fetch a player's specific instance of the data and save from that.
* For reference, see [rs09.game.node.entity.skill.slayer.SlayerManager]
*/
fun savePlayer(player: Player, save: JSONObject)
/**
* NOTE: This should NOT reference nonstatic class-local variables.
* You need to fetch a player's specific instance of the data and parse to that.
* For reference, see [rs09.game.node.entity.skill.slayer.SlayerManager]
*/
fun parsePlayer(player: Player, data: JSONObject)
}
@@ -0,0 +1,6 @@
package api
interface PersistWorld {
fun saveWorld()
fun parseWorld()
}
+2 -1
View File
@@ -12,4 +12,5 @@ data class LitFireEvent(val logId: Int) : Event
data class InteractionEvent(val target: Node, val option: String) : Event
data class ButtonClickedEvent(val iface: Int, val buttonId: Int) : Event
data class UsedWithEvent(val used: Int, val with: Int) : Event
data class SelfDeath(val killer: Entity) : Event
data class SelfDeath(val killer: Entity) : Event
data class TickEvent(val source: Entity) : Event
+9 -8
View File
@@ -3,12 +3,13 @@ package rs09.game
import api.events.*
object Event {
val ResourceProduced = ResourceProducedEvent::class.java
val NPCKilled = NPCKillEvent::class.java
val Teleport = TeleportEvent::class.java
val FireLit = LitFireEvent::class.java
val Interaction = InteractionEvent::class.java
val ButtonClicked = ButtonClickedEvent::class.java
val UsedWith = UsedWithEvent::class.java
val SelfDeath = SelfDeath::class.java
@JvmStatic val ResourceProduced = ResourceProducedEvent::class.java
@JvmStatic val NPCKilled = NPCKillEvent::class.java
@JvmStatic val Teleport = TeleportEvent::class.java
@JvmStatic val FireLit = LitFireEvent::class.java
@JvmStatic val Interaction = InteractionEvent::class.java
@JvmStatic val ButtonClicked = ButtonClickedEvent::class.java
@JvmStatic val UsedWith = UsedWithEvent::class.java
@JvmStatic val SelfDeath = SelfDeath::class.java
@JvmStatic val Tick = TickEvent::class.java
}
@@ -1,9 +1,15 @@
package rs09.game.content.ame
import api.LoginListener
import api.events.EventHook
import api.events.TickEvent
import api.getAttribute
import api.setAttribute
import core.game.node.entity.Entity
import core.game.node.entity.player.Player
import core.game.world.map.zone.ZoneRestriction
import core.tools.RandomFunction
import rs09.game.Event
import rs09.game.system.SystemLogger
import rs09.game.world.GameWorld
import kotlin.random.Random
@@ -11,15 +17,23 @@ import kotlin.random.Random
private const val AVG_DELAY_TICKS = 6000 // 60 minutes
private const val MIN_DELAY_TICKS = AVG_DELAY_TICKS / 2
private const val MAX_DELAY_TICKS = MIN_DELAY_TICKS + AVG_DELAY_TICKS // window of 60 min centered on 60 min (30 to 90 min)
class RandomEventManager(val player: Player) {
class RandomEventManager(val player: Player? = null) : LoginListener, EventHook<TickEvent> {
var event: RandomEventNPC? = null
var enabled: Boolean = false
var nextSpawn = 0
val skills = arrayOf("WoodcuttingSkillPulse","FishingPulse","MiningSkillPulse","BoneBuryingOptionPlugin")
fun tick() {
if (player.isArtificial) return
if (GameWorld.ticks > nextSpawn && getAttribute(player, "tutorial:complete", false)) fireEvent()
override fun login(player: Player) {
if(player.isArtificial) return
val instance = RandomEventManager(player)
player.hook(Event.Tick, instance)
setAttribute(player, "random-manager", instance)
instance.rollNextSpawn()
SystemLogger.logRE("Initialized REManager for ${player.username}.")
}
override fun process(entity: Entity, event: TickEvent) {
if (GameWorld.ticks > nextSpawn && getAttribute(player!!, "tutorial:complete", false)) fireEvent()
}
fun fireEvent() {
@@ -27,29 +41,21 @@ class RandomEventManager(val player: Player) {
rollNextSpawn()
return
}
if (player.zoneMonitor.isRestricted(ZoneRestriction.RANDOM_EVENTS)) {
if (player!!.zoneMonitor.isRestricted(ZoneRestriction.RANDOM_EVENTS)) {
nextSpawn = GameWorld.ticks + 3000
return
}
val currentAction = player.pulseManager.current.toString()
var ame = RandomEvents.values().random()
if(currentAction.contains("WoodcuttingSkillPulse") && Random.nextBoolean()){
ame = RandomEvents.TREE_SPIRIT
}
else if(currentAction.contains("FishingPulse") && Random.nextBoolean()){
ame = RandomEvents.RIVER_TROLL
}
else if(currentAction.contains("MiningSkillPulse") && Random.nextBoolean()){
ame = RandomEvents.ROCK_GOLEM
}
else if(currentAction.contains("BoneBuryingOptionPlugin") && Random.nextBoolean()){
ame = RandomEvents.SHADE
}
else {
ame = RandomEvents.values().random()
while(ame.type == "skill"){
ame = RandomEvents.values().random()
}
val ame: RandomEvents = if(currentAction.contains("WoodcuttingSkillPulse") && Random.nextBoolean()){
RandomEvents.TREE_SPIRIT
} else if(currentAction.contains("FishingPulse") && Random.nextBoolean()){
RandomEvents.RIVER_TROLL
} else if(currentAction.contains("MiningSkillPulse") && Random.nextBoolean()){
RandomEvents.ROCK_GOLEM
} else if(currentAction.contains("BoneBuryingOptionPlugin") && Random.nextBoolean()){
RandomEvents.SHADE
} else {
RandomEvents.values().filter { it.type != "skill" }.random()
}
event = ame.npc.create(player,ame.loot,ame.type)
if (event!!.spawnLocation == null) {
@@ -61,14 +67,14 @@ class RandomEventManager(val player: Player) {
SystemLogger.logRE("Fired ${event!!.name} for ${player.username}")
}
fun init() {
if (player.isArtificial) return
rollNextSpawn()
SystemLogger.logRE("Initialized REManager for ${player.username}")
enabled = true
}
private fun rollNextSpawn() {
nextSpawn = GameWorld.ticks + RandomFunction.random(MIN_DELAY_TICKS, MAX_DELAY_TICKS)
}
companion object {
@JvmStatic fun getInstance(player: Player): RandomEventManager?
{
return getAttribute(player, "random-manager", null)
}
}
}
@@ -37,7 +37,7 @@ abstract class RandomEventNPC(id: Int) : NPC(id) {
open fun terminate() {
finalized = true
pulseManager.clear("amemovement")
player.antiMacroHandler.event = null
RandomEventManager.getInstance(player)!!.event = null
if (initialized) {
poofClear(this)
}
@@ -1,6 +1,7 @@
package rs09.game.content.ame.events
import core.game.node.entity.player.Player
import rs09.game.content.ame.RandomEventManager
import rs09.game.content.ame.events.supriseexam.SurpriseExamUtils
import rs09.game.content.dialogue.DialogueFile
@@ -22,11 +23,11 @@ class MysteriousOldManDialogue(val type: String) : DialogueFile() {
1 -> {
end()
teleport(player!!,type)
player!!.antiMacroHandler.event?.terminate()
RandomEventManager.getInstance(player!!)?.event?.terminate()
}
2 -> {
end()
player!!.antiMacroHandler.event?.terminate()
RandomEventManager.getInstance(player!!)?.event?.terminate()
}
}
}
@@ -3,6 +3,7 @@ package rs09.game.content.ame.events.certer
import api.addItemOrDrop
import core.game.component.Component
import core.game.node.entity.player.link.emote.Emotes
import rs09.game.content.ame.RandomEventManager
import rs09.game.content.dialogue.DialogueFile
import rs09.tools.END_DIALOGUE
@@ -29,13 +30,13 @@ class CerterDialogue(val initial: Boolean) : DialogueFile() {
npc("Sorry, I don't think so.").also {
player!!.setAttribute("certer:reward", true)
stage = END_DIALOGUE
player!!.antiMacroHandler.event?.terminate()
RandomEventManager.getInstance(player!!)?.event?.terminate()
}
} else {
npc("Thank you, I hope you like your present. I must be", "leaving now though.").also {
player!!.setAttribute("certer:reward", true)
stage = END_DIALOGUE
player!!.antiMacroHandler.event?.loot!!.roll().forEach { addItemOrDrop(player!!, it.id, it.amount) }
RandomEventManager.getInstance(player!!)!!.event!!.loot!!.roll().forEach { addItemOrDrop(player!!, it.id, it.amount) }
}
}
}
@@ -50,7 +51,7 @@ class CerterDialogue(val initial: Boolean) : DialogueFile() {
// Wave goodbye
npc!!.animate(Emotes.WAVE.animation)
// Terminate the event
player!!.antiMacroHandler.event?.terminate()
RandomEventManager.getInstance(player!!)?.event?.terminate()
} else {
player!!.setAttribute("random:pause", false)
}
@@ -3,6 +3,7 @@ package rs09.game.content.ame.events.certer
import core.game.node.entity.player.Player
import core.game.node.item.Item
import org.rs09.consts.Items
import rs09.game.content.ame.RandomEventManager
import rs09.game.interaction.InterfaceListener
class CerterEventInterface : InterfaceListener() {
@@ -36,7 +37,7 @@ class CerterEventInterface : InterfaceListener() {
val correctAnswer = player.getAttribute("certer:correctIndex", 0)
player.setAttribute("certer:correct", correctAnswer == answer)
player.interfaceManager.close()
player.dialogueInterpreter.open(CerterDialogue(false), player.antiMacroHandler.event?.asNpc())
player.dialogueInterpreter.open(CerterDialogue(false), RandomEventManager.getInstance(player)!!.event?.asNpc())
return@on true
}
@@ -2,6 +2,7 @@ package rs09.game.content.ame.events.drilldemon
import core.game.content.dialogue.FacialExpression
import core.game.system.task.Pulse
import rs09.game.content.ame.RandomEventManager
import rs09.game.content.dialogue.DialogueFile
import rs09.tools.END_DIALOGUE
import rs09.tools.START_DIALOGUE
@@ -9,7 +10,7 @@ import rs09.tools.START_DIALOGUE
class SeargentDamienDialogue(val isCorrect: Boolean = false) : DialogueFile() {
override fun handle(componentID: Int, buttonID: Int) {
var correctAmt = player!!.getAttribute(DrillDemonUtils.DD_CORRECT_COUNTER,0)
if(correctAmt == 4 && player!!.antiMacroHandler.event == null) {
if(correctAmt == 4 && RandomEventManager.getInstance(player!!)!!.event == null) {
when(stage){
0 -> npc(FacialExpression.OLD_NORMAL,"My god you actually did it, you limp","wristed worm-bodied MAGGOT! Take this","and get out of my sight.").also { stage++ }
1 -> {
@@ -24,7 +25,7 @@ class SeargentDamienDialogue(val isCorrect: Boolean = false) : DialogueFile() {
})
}
}
} else if(player!!.antiMacroHandler.event == null){
} else if(RandomEventManager.getInstance(player!!)!!.event == null){
when(stage){
START_DIALOGUE -> if(isCorrect) npc(FacialExpression.OLD_NORMAL,"Good! Now...").also { stage++ } else npc(FacialExpression.OLD_ANGRY1,"WRONG, MAGGOT!").also { stage++ }
1 -> {
@@ -40,12 +41,12 @@ class SeargentDamienDialogue(val isCorrect: Boolean = false) : DialogueFile() {
1 -> {
end()
DrillDemonUtils.teleport(player!!)
player!!.antiMacroHandler.event?.terminate()
RandomEventManager.getInstance(player!!)!!.event?.terminate()
stage = END_DIALOGUE
}
2 -> {
end()
player!!.antiMacroHandler.event?.terminate()
RandomEventManager.getInstance(player!!)!!.event?.terminate()
stage = END_DIALOGUE
}
}
@@ -7,6 +7,7 @@ import core.game.component.Component
import core.game.node.entity.combat.ImpactHandler
import core.game.node.item.GroundItemManager
import core.game.node.item.Item
import rs09.game.content.ame.RandomEventManager
import rs09.game.content.dialogue.DialogueFile
import rs09.tools.END_DIALOGUE
@@ -15,7 +16,7 @@ class GenieDialogue : DialogueFile() {
val assigned = player!!.getAttribute("genie:item",0)
npcl(FacialExpression.NEUTRAL, "Ah, so you are there, ${player!!.name.capitalize()}. I'm so glad you summoned me. Please take this lamp and make your wish.")
addItemOrDrop(player!!, assigned)
player!!.antiMacroHandler.event?.terminate()
RandomEventManager.getInstance(player!!)!!.event?.terminate()
stage = END_DIALOGUE
}
}
@@ -5,6 +5,7 @@ import core.game.component.Component
import core.game.node.entity.combat.ImpactHandler
import core.game.node.item.GroundItemManager
import core.game.node.item.Item
import rs09.game.content.ame.RandomEventManager
import rs09.game.content.dialogue.DialogueFile
import rs09.tools.END_DIALOGUE
@@ -26,13 +27,13 @@ class SandwichLadyDialogue(val isChoice: Boolean) : DialogueFile() {
0 -> if(choice != assigned){
npc!!.sendChat("That's not what I said you could have!")
player!!.impactHandler.manualHit(npc,3,ImpactHandler.HitsplatType.NORMAL)
player!!.antiMacroHandler.event?.terminate()
RandomEventManager.getInstance(player!!)!!.event?.terminate()
} else {
npc("Here you are, dear. I hope you enjoy it!")
if(!player!!.inventory.add(Item(assigned))){
GroundItemManager.create(Item(assigned),player)
}
player!!.antiMacroHandler.event?.terminate()
RandomEventManager.getInstance(player!!)!!.event?.terminate()
stage = END_DIALOGUE
}
}
@@ -2,6 +2,7 @@ package rs09.game.content.ame.events.sandwichlady
import core.game.node.item.Item
import org.rs09.consts.Items
import rs09.game.content.ame.RandomEventManager
import rs09.game.interaction.InterfaceListener
class SandwichLadyInterface : InterfaceListener(){
@@ -31,7 +32,7 @@ class SandwichLadyInterface : InterfaceListener(){
player.setAttribute("sandwich-lady:choice",item.id)
player.interfaceManager.close()
player.dialogueInterpreter.open(SandwichLadyDialogue(true),player.antiMacroHandler.event)
player.dialogueInterpreter.open(SandwichLadyDialogue(true), RandomEventManager.getInstance(player)!!.event)
return@on true
}
}
@@ -7,6 +7,7 @@ import core.game.node.entity.player.Player
import core.plugin.Initializable
import org.rs09.consts.Items
import org.rs09.consts.NPCs
import rs09.game.ge.GrandExchangeRecords
/**
* @author qmqz
@@ -37,7 +38,7 @@ class SirsalBankerDialogue(player: Player? = null) : DialoguePlugin(player){
1 -> when (buttonId) {
1 -> end().also { player.bank.open() }
2 -> end().also { player.bankPinManager.openSettings() }
3 -> end().also { player.exchangeRecords.openCollectionBox() }
3 -> end().also { GrandExchangeRecords.getInstance(player).openCollectionBox() }
4 -> player(FacialExpression.HALF_ASKING, "What is this place?").also { stage = 5 }
}
@@ -1,6 +1,7 @@
package rs09.game.content.global.action
import core.game.container.impl.EquipmentContainer
import core.game.interaction.item.brawling_gloves.BrawlingGlovesManager
import core.game.node.Node
import core.game.node.entity.combat.equipment.WeaponInterface
import core.game.node.entity.player.Player
@@ -62,7 +63,7 @@ class EquipHandler : InteractionListener() {
//check if a brawling glove is being equipped and register it
if (item.id in 13845..13857) {
player.debug("Registering gloves... ID: " + item.id)
player.brawlingGlovesManager.registerGlove(item.id)
BrawlingGlovesManager.getInstance(player).registerGlove(item.id)
}
if (item.id == Items.BLACK_CHAINBODY_1107 && player.getAttribute("diary:falador:black-chain-bought", false)
&& ZoneBorders(2969, 3310, 2975, 3314, 0).insideBorder(player)
@@ -17,7 +17,7 @@ class TutorialLoginCheck : LoginListener {
setAttribute(player, "/save:tutorial:complete", true)
return
}
GameWorld.Pulser.submit(object : Pulse() {
GameWorld.Pulser.submit(object : Pulse(2) {
override fun pulse(): Boolean {
TutorialStage.load(player, getAttribute(player, "tutorial:stage", 0), true)
return true
@@ -214,7 +214,7 @@ class GrandExchange : StartupListener {
offer.playerUID = player.details.uid
offer.offerState = OfferState.REGISTERED
//player.exchangeRecords.update(offer)
//GrandExchangeRecords.getInstance(player).update(offer)
if (offer.sell) {
Repository.sendNews(player.username + " just offered " + offer.amount + " " + getItemName(offer.itemID) + " on the GE.")
@@ -257,10 +257,10 @@ class GrandExchange : StartupListener {
seller.update()
val sellerPlayer = Repository.uid_map[seller.playerUID]
sellerPlayer?.exchangeRecords?.visualizeRecords()
GrandExchangeRecords.getInstance(sellerPlayer).visualizeRecords()
buyer.update()
val buyerPlayer = Repository.uid_map[buyer.playerUID]
buyerPlayer?.exchangeRecords?.visualizeRecords()
GrandExchangeRecords.getInstance(buyerPlayer).visualizeRecords()
}
fun getValidOffers(): List<GrandExchangeOffer>
@@ -41,15 +41,59 @@ import java.util.*
* @author Angle
*/
class GrandExchangeRecords(private val player: Player) {
class GrandExchangeRecords(private val player: Player? = null) : PersistPlayer, LoginListener {
var history = arrayOfNulls<GrandExchangeOffer>(5)
val offerRecords = arrayOfNulls<OfferRecord>(6)
override fun login(player: Player) {
val instance = GrandExchangeRecords(player)
instance.init()
player.setAttribute("ge-records", instance)
}
override fun parsePlayer(player: Player, data: JSONObject) {
/**
* Parse history from JSON
*/
val historyRaw = data["ge-history"]
if(historyRaw != null){
val history = historyRaw as JSONArray
for (i in history.indices) {
val offer = history[i] as JSONObject
val o = GrandExchangeOffer()
o.itemID = offer["itemId"].toString().toInt()
o.sell = offer["isSell"] as Boolean
o.totalCoinExchange = (offer["totalCoinExchange"].toString().toInt())
o.completedAmount = (offer["completedAmount"].toString().toInt())
getInstance(player).history[i] = o
}
}
}
override fun savePlayer(player: Player, save: JSONObject) {
/**
* Save history to JSON
*/
val history = JSONArray()
getInstance(player).history.map {
if(it != null){
val historyEntry = JSONObject()
historyEntry["isSell"] = it.sell
historyEntry["itemId"] = it.itemID.toString()
historyEntry["totalCoinExchange"] = it.totalCoinExchange.toString()
historyEntry["completedAmount"] = it.completedAmount.toString()
history.add(historyEntry)
SystemLogger.logInfo("Adding history entry for ${it.itemID}")
}
}
save["ge-history"] = history
}
/**
* Opens the collection box.
*/
fun openCollectionBox() {
if (!player.bankPinManager.isUnlocked) {
if (!player!!.bankPinManager.isUnlocked) {
player.bankPinManager.openType(3)
return
}
@@ -143,7 +187,7 @@ class GrandExchangeRecords(private val player: Player) {
*/
val conn = GEDB.connect()
val stmt = conn.createStatement()
val offer_records = stmt.executeQuery("SELECT * from player_offers where player_uid = ${player.details.uid} AND offer_state < 6")
val offer_records = stmt.executeQuery("SELECT * from player_offers where player_uid = ${player!!.details.uid} AND offer_state < 6")
val needsIndex = ArrayDeque<GrandExchangeOffer>()
@@ -175,23 +219,6 @@ class GrandExchangeRecords(private val player: Player) {
}
visualizeRecords()
/**
* Parse history from JSON
*/
val historyRaw = geData["history"]
if(historyRaw != null){
val history = historyRaw as JSONArray
for (i in history.indices) {
val offer = history[i] as JSONObject
var o = GrandExchangeOffer()
o.itemID = offer["itemId"].toString().toInt()
o.sell = offer["isSell"] as Boolean
o.totalCoinExchange = (offer["totalCoinExchange"].toString().toInt())
o.completedAmount = (offer["completedAmount"].toString().toInt())
history[i] = o
}
}
}
/**
@@ -210,7 +237,7 @@ class GrandExchangeRecords(private val player: Player) {
}
}
if (updated) {
sendMessage(player, "You have items from the Grand Exchange waiting in your collection box.")
sendMessage(player!!, "You have items from the Grand Exchange waiting in your collection box.")
}
}
@@ -242,4 +269,11 @@ class GrandExchangeRecords(private val player: Player) {
}
data class OfferRecord(val uid: Long, val slot: Int)
companion object {
@JvmStatic fun getInstance(player: Player? = null): GrandExchangeRecords
{
return player?.getAttribute("ge-records", GrandExchangeRecords()) ?: GrandExchangeRecords()
}
}
}
@@ -11,6 +11,7 @@ import core.game.world.update.flag.context.ChatMessage
import core.game.world.update.flag.player.ChatFlag
import core.net.amsc.MSPacketRepository
import core.net.amsc.WorldCommunicator
import rs09.game.node.entity.skill.slayer.SlayerManager
import rs09.game.world.GameWorld.Pulser
import rs09.net.packet.`in`.QCPacketType
import java.nio.ByteBuffer
@@ -114,8 +115,8 @@ object QCRepository {
//My current slayer assignment is
else if(qcString.contains("My current Slayer assignment is")){
val amount = player?.slayer?.amount
val taskName = NPCDefinition.forId(player?.slayer?.task?.ids?.get(0) ?: 0).name.toLowerCase()
val amount = SlayerManager.getInstance(player!!).amount
val taskName = NPCDefinition.forId(SlayerManager.getInstance(player!!).task?.ids?.get(0) ?: 0).name.toLowerCase()
if(amount ?: 0 > 0){
qcString = qcString.replace("complete", "$amount $taskName")
}
@@ -92,7 +92,7 @@ class StockMarket : InterfaceListener() {
on(Components.STOCKMARKET_105){player, _, op, button, _, _ ->
val tempOffer = getAttribute(player, "ge-temp", GrandExchangeOffer())
var openedIndex = getAttribute(player, "ge-index", -1)
var openedOffer = player.exchangeRecords.getOffer(openedIndex)
var openedOffer = GrandExchangeRecords.getInstance(player).getOffer(openedIndex)
when(button)
{
@@ -105,19 +105,19 @@ class StockMarket : InterfaceListener() {
203 -> abortOffer(player, openedOffer)
18,34,50,69,88,107 -> {
openedIndex = (button - 18) shr 4
openedOffer = player.exchangeRecords.getOffer(openedIndex)
openedOffer = GrandExchangeRecords.getInstance(player).getOffer(openedIndex)
if(op == 205) abortOffer(player, openedOffer)
else updateVarbits(player, openedOffer, openedIndex)
}
30,46,62,81,100,119 -> {
openedIndex = (button - 30) shr 4
openedOffer = player.exchangeRecords.getOffer(openedIndex)
openedOffer = GrandExchangeRecords.getInstance(player).getOffer(openedIndex)
updateVarbits(player, openedOffer, openedIndex)
player.interfaceManager.openChatbox(Components.OBJDIALOG_389)
}
31,47,63,82,101,120 -> {
openedIndex = (button - 31) shr 4
openedOffer = player.exchangeRecords.getOffer(openedIndex)
openedOffer = GrandExchangeRecords.getInstance(player).getOffer(openedIndex)
updateVarbits(player, openedOffer, openedIndex, true)
player.interfaceManager.openSingleTab(Component(Components.STOCKSIDE_107)).open(player)
player.packetDispatch.sendRunScript(
@@ -257,7 +257,7 @@ class StockMarket : InterfaceListener() {
}
if(GrandExchange.dispatch(player, offer))
{
player.exchangeRecords.offerRecords[offer.index] = GrandExchangeRecords.OfferRecord(offer.uid,offer.index)
GrandExchangeRecords.getInstance(player).offerRecords[offer.index] = GrandExchangeRecords.OfferRecord(offer.uid,offer.index)
player.removeAttribute("ge-temp")
}
else
@@ -276,7 +276,7 @@ class StockMarket : InterfaceListener() {
}
if(GrandExchange.dispatch(player, offer) && removeItem(player, Item(995, total)))
{
player.exchangeRecords.offerRecords[offer.index] = GrandExchangeRecords.OfferRecord(offer.uid, offer.index)
GrandExchangeRecords.getInstance(player).offerRecords[offer.index] = GrandExchangeRecords.OfferRecord(offer.uid, offer.index)
player.removeAttribute("ge-temp")
}
}
@@ -371,10 +371,10 @@ class StockMarket : InterfaceListener() {
{
val newHistory = arrayOfNulls<GrandExchangeOffer>(5)
newHistory[0] = offer
System.arraycopy(player.exchangeRecords.history, 0, newHistory, 1, 4)
player.exchangeRecords.history = newHistory
System.arraycopy(GrandExchangeRecords.getInstance(player).history, 0, newHistory, 1, 4)
GrandExchangeRecords.getInstance(player).history = newHistory
}
player.exchangeRecords.offerRecords[offer.index] = null
GrandExchangeRecords.getInstance(player).offerRecords[offer.index] = null
toMainInterface(player)
}
offer.update()
@@ -1,8 +1,10 @@
package rs09.game.interaction.npc
import core.game.content.quest.miniquest.barcrawl.BarcrawlManager
import core.game.content.quest.miniquest.barcrawl.BarcrawlType
import core.game.node.entity.npc.NPC
import rs09.game.content.activity.gnomecooking.*
import rs09.game.content.ame.RandomEventManager
import rs09.game.content.ame.RandomEvents
import rs09.game.interaction.InteractionListener
import rs09.game.system.SystemLogger
@@ -19,8 +21,8 @@ class NPCTalkListener : InteractionListener() {
on(barCrawlNPCs, NPC, "talk-to", "talk"){player, node ->
val type = BarcrawlType.forId(node.id)
if (player.barcrawlManager.isFinished || !player.barcrawlManager.isStarted || player.barcrawlManager.isCompleted(type!!.ordinal)) {
val instance = BarcrawlManager.getInstance(player)
if (instance.isFinished || !instance.isStarted || instance.isCompleted(type!!.ordinal)) {
player.dialogueInterpreter.open(node.id, node)
} else {
player.dialogueInterpreter.open("barcrawl dialogue", node.id, type)
@@ -31,10 +33,10 @@ class NPCTalkListener : InteractionListener() {
on(NPC,"talk-to","talk","talk to"){player,node ->
val npc = node.asNpc()
if(RandomEvents.randomIDs.contains(node.id)){
if(player.antiMacroHandler.event == null || player.antiMacroHandler.event!!.id != node.id){
if(RandomEventManager.getInstance(player)!!.event == null || RandomEventManager.getInstance(player)!!.event!!.id != node.id){
player.sendMessage("They aren't interested in talking to you.")
} else {
player.antiMacroHandler.event!!.talkTo(node.asNpc())
RandomEventManager.getInstance(player)!!.event!!.talkTo(node.asNpc())
}
return@on true
}
@@ -19,6 +19,7 @@ import core.game.world.map.path.Pathfinder
import core.tools.RandomFunction
import rs09.game.node.entity.combat.CombatSwingHandler
import rs09.game.node.entity.skill.skillcapeperks.SkillcapePerks
import rs09.game.node.entity.skill.slayer.SlayerManager
import kotlin.math.ceil
import kotlin.math.floor
@@ -146,7 +147,7 @@ open class MeleeSwingHandler
val amuletName = (if(entity is Player) getItemFromEquipment(entity, EquipmentSlot.AMULET)?.name ?: "null" else "null").toLowerCase()
val victimName = entity.properties.combatPulse.getVictim()?.name ?: "none"
if(entity is Player && entity.slayer.task?.ids?.contains((entity.properties.combatPulse?.getVictim()?.id ?: 0)) == true)
if(entity is Player && SlayerManager.getInstance(entity).task?.ids?.contains((entity.properties.combatPulse?.getVictim()?.id ?: 0)) == true)
effectiveAttackLevel *= SlayerEquipmentFlags.getDamAccBonus(entity) //Slayer Helm/ Black Mask/ Slayer cape
else if (entity is Player //Salve amulet
@@ -179,7 +180,7 @@ open class MeleeSwingHandler
cumulativeStr *= getSetMultiplier(entity, Skills.STRENGTH)
if(entity is Player && entity.slayer.task?.ids?.contains((entity.properties.combatPulse?.getVictim()?.id ?: 0)) == true)
if(entity is Player && SlayerManager.getInstance(entity).task?.ids?.contains((entity.properties.combatPulse?.getVictim()?.id ?: 0)) == true)
cumulativeStr *= SlayerEquipmentFlags.getDamAccBonus(entity) //Slayer helm/black mask/skillcape
/*val hit = (16 + cumulativeStr + bonus / 8 + cumulativeStr * bonus * 0.016865) * modifier
@@ -1,5 +1,6 @@
package rs09.game.node.entity.player.info.login
import api.LoginListener
import core.game.node.entity.player.Player
import core.game.node.entity.player.info.PlayerDetails
import core.game.node.entity.player.info.login.LoginConfiguration
@@ -14,10 +15,12 @@ import core.net.amsc.ManagementServerState
import core.net.amsc.WorldCommunicator
import rs09.game.system.SystemLogger
import rs09.game.world.GameWorld
import rs09.game.world.GameWorld.loginListeners
import rs09.game.world.repository.Repository
import java.util.concurrent.TimeUnit
import java.util.concurrent.locks.Lock
import java.util.concurrent.locks.ReentrantLock
import java.util.function.Consumer
/**
* Parses the login of a player.
@@ -105,14 +108,21 @@ class LoginParser(
reconnect(player, type)
return
}
if(!PlayerParser.parse(player)){
try {
val parser = PlayerParser.parse(player)
?: throw IllegalStateException("Failed parsing save for: " + player.username) //Parse core
loginListeners.forEach(Consumer { listener: LoginListener -> listener.login(player) }) //Run our login hooks
parser.runContentHooks() //Run our saved-content-parsing hooks
}
catch (e: Exception)
{
e.printStackTrace()
Repository.removePlayer(player)
Repository.LOGGED_IN_PLAYERS.remove(player.username)
Repository.lobbyPlayers.remove(player)
Repository.playerNames.remove(player.name)
MSPacketRepository.sendPlayerRemoval(player.name)
flag(Response.ERROR_LOADING_PROFILE)
return
}
//Repository.getPlayerNames().put(player.getName(), player);
GameWorld.Pulser.submit(object : Pulse(1) {
@@ -141,8 +151,12 @@ class LoginParser(
}
} catch (t: Throwable) {
t.printStackTrace()
Repository.removePlayer(player)
Repository.LOGGED_IN_PLAYERS.remove(player.username)
Repository.lobbyPlayers.remove(player)
Repository.playerNames.remove(player.name)
MSPacketRepository.sendPlayerRemoval(player.name)
flag(Response.ERROR_LOADING_PROFILE)
}
return true
}
@@ -1,5 +1,6 @@
package rs09.game.node.entity.player.info.login
import api.PersistPlayer
import core.game.interaction.item.brawling_gloves.BrawlingGloves
import core.game.node.entity.combat.CombatSpell
import core.game.node.entity.player.Player
@@ -18,6 +19,7 @@ import rs09.game.node.entity.skill.farming.CompostBins
import rs09.game.node.entity.skill.farming.FarmingPatch
import rs09.game.system.SystemLogger
import rs09.game.world.GameWorld
import java.io.File
import java.io.FileReader
import java.util.*
@@ -27,8 +29,11 @@ import java.util.*
* @param player: The player we are parsing.
*/
class PlayerSaveParser(val player: Player) {
companion object {
val contentHooks = ArrayList<PersistPlayer>()
}
var parser = JSONParser()
var reader: FileReader? = FileReader(ServerConstants.PLAYER_SAVE_PATH + player.name + ".json")
var reader: FileReader? = null
var saveFile: JSONObject? = null
var read = true
@@ -36,8 +41,12 @@ class PlayerSaveParser(val player: Player) {
val bin_varps = CompostBins.values().map { it.varpIndex }.toIntArray()
init {
reader
?: SystemLogger.logWarn("Couldn't find save file for ${player.name}, or save is corrupted.").also { read = false }
val JSON = File(ServerConstants.PLAYER_SAVE_PATH + player.name + ".json")
if(JSON.exists())
{
reader = FileReader(JSON)
}
reader ?: SystemLogger.logWarn("Couldn't find save file for ${player.name}, or save is corrupted.").also { read = false }
if (read) {
saveFile = parser.parse(reader) as JSONObject
}
@@ -45,48 +54,40 @@ class PlayerSaveParser(val player: Player) {
fun parse() = GlobalScope.launch {
if (read) {
launch {
parseCore()
parseAttributes()
parseSkills()
parseSettings()
parseSlayer()
parseQuests()
parseAppearance()
parseGrave()
parseVarps()
parseStates()
}
launch {
parseSpellbook()
parseGrandExchange()
parseSavedData()
parseAutocastSpell()
parseFarming()
parseConfigs()
parseMonitor()
}
launch {
parseMusic()
parseFamiliars()
parseBarCrawl()
parseAntiMacro()
parseTT()
parseBankPin()
}
launch {
parseHouse()
parseIronman()
parseEmoteManager()
parseStatistics()
parseBrawlingGloves()
parseAchievements()
parsePouches()
}
parseCore()
parseAttributes()
parseSkills()
parseSettings()
parseQuests()
parseAppearance()
parseGrave()
parseVarps()
parseStates()
parseSpellbook()
parseSavedData()
parseAutocastSpell()
parseFarming()
parseConfigs()
parseMonitor()
parseMusic()
parseFamiliars()
parseBankPin()
parseHouse()
parseIronman()
parseEmoteManager()
parseStatistics()
parseAchievements()
parsePouches()
parsePouches()
}
}
fun runContentHooks()
{
if(read)
contentHooks.forEach{it.parsePlayer(player, saveFile!!)}
}
fun parseVarps(){
if(saveFile!!.containsKey("varps"))
player.varpManager.parse(saveFile!!["varps"] as JSONArray)
@@ -127,16 +128,6 @@ class PlayerSaveParser(val player: Player) {
}
}
fun parseBrawlingGloves() {
if (saveFile!!.containsKey("brawlingGloves")) {
val bgData: JSONArray = saveFile!!["brawlingGloves"] as JSONArray
for (bg in bgData) {
val glove = bg as JSONObject
player.brawlingGlovesManager.registerGlove(BrawlingGloves.forIndicator(glove.get("gloveId").toString().toInt()).id, glove.get("charges").toString().toInt())
}
}
}
fun parseStatistics() {
if (saveFile!!.containsKey("statistics")) {
val stats: JSONArray = saveFile!!["statistics"] as JSONArray
@@ -186,14 +177,6 @@ class PlayerSaveParser(val player: Player) {
player.bankPinManager.parse(bpData)
}
fun parseTT() {
val ttData = saveFile!!["treasureTrails"] as JSONObject
player.treasureTrailManager.parse(ttData)
}
fun parseAntiMacro() {
}
fun parseStates() {
player.states.clear()
SystemLogger.logErr("Parsing states")
@@ -211,11 +194,6 @@ class PlayerSaveParser(val player: Player) {
}
}
fun parseBarCrawl() {
val barCrawlData = saveFile!!["barCrawl"] as JSONObject
player.barcrawlManager.parse(barCrawlData)
}
fun parseFamiliars() {
val familiarData = saveFile!!["familiarManager"] as JSONObject
player.familiarManager.parse(familiarData)
@@ -301,14 +279,6 @@ class PlayerSaveParser(val player: Player) {
player.savedData.globalData.parse(globalData)
}
fun parseGrandExchange() {
val geData: Any? = saveFile!!["grand_exchange"]
if (geData != null) {
player.exchangeRecords.parse(geData as JSONObject)
}
}
fun parseSpellbook() {
val spellbookData = (saveFile!!["spellbook"] as String).toInt()
player.spellBookManager.setSpellBook(SpellBookManager.SpellBook.forInterface(spellbookData))
@@ -332,12 +302,6 @@ class PlayerSaveParser(val player: Player) {
player.questRepository.parse(questData)
}
fun parseSlayer() {
saveFile ?: return
val slayerData = saveFile!!["slayer"] as JSONObject
player.slayer.parse(slayerData)
}
fun parseCore() {
saveFile ?: return
val coreData = saveFile!!["core_data"] as JSONObject
@@ -1,5 +1,6 @@
package rs09.game.node.entity.player.info.login
import api.PersistPlayer
import core.game.container.Container
import core.game.interaction.item.brawling_gloves.BrawlingGloves
import core.game.node.entity.player.Player
@@ -28,51 +29,36 @@ import javax.script.ScriptEngineManager
* @author Ceikry
*/
class PlayerSaver (val player: Player){
private fun populate(): JSONObject = runBlocking{
companion object {
val contentHooks = ArrayList<PersistPlayer>()
}
private fun populate(): JSONObject {
val saveFile = JSONObject()
val a = launch {
saveCoreData(saveFile)
saveSkills(saveFile)
saveSettings(saveFile)
saveSlayer(saveFile)
saveQuests(saveFile)
saveAppearance(saveFile)
saveSpellbook(saveFile)
saveVarps(saveFile)
}
val b = launch {
saveGraveType(saveFile)
saveGrandExchangeData(saveFile)
saveSavedData(saveFile)
saveAutocast(saveFile)
saveFarming(saveFile)
saveConfigs(saveFile)
savePlayerMonitor(saveFile)
}
val c = launch {
saveMusicPlayer(saveFile)
saveFamiliarManager(saveFile)
saveBarCrawl(saveFile)
saveStateManager(saveFile)
saveAntiMacroHandler(saveFile)
saveTreasureTrails(saveFile)
saveBankPinData(saveFile)
}
val d = launch {
saveHouseData(saveFile)
saveAchievementData(saveFile)
saveIronManData(saveFile)
saveEmoteData(saveFile)
saveStatManager(saveFile)
saveBrawlingGloves(saveFile)
saveAttributes(saveFile)
}
a.join()
b.join()
c.join()
d.join()
saveCoreData(saveFile)
saveSkills(saveFile)
saveSettings(saveFile)
saveQuests(saveFile)
saveAppearance(saveFile)
saveSpellbook(saveFile)
saveVarps(saveFile)
saveGraveType(saveFile)
saveSavedData(saveFile)
saveAutocast(saveFile)
saveConfigs(saveFile)
savePlayerMonitor(saveFile)
saveMusicPlayer(saveFile)
saveFamiliarManager(saveFile)
saveStateManager(saveFile)
saveBankPinData(saveFile)
saveHouseData(saveFile)
saveAchievementData(saveFile)
saveIronManData(saveFile)
saveEmoteData(saveFile)
saveStatManager(saveFile)
saveAttributes(saveFile)
savePouches(saveFile)
saveFile
contentHooks.forEach { it.savePlayer(player, saveFile) }
return saveFile
}
fun save() = runBlocking {
val manager = ScriptEngineManager()
@@ -138,19 +124,6 @@ class PlayerSaver (val player: Player){
}
}
fun saveBrawlingGloves(root: JSONObject){
if(player.brawlingGlovesManager.GloveCharges.isNotEmpty()){
val brawlingGloves = JSONArray()
player.brawlingGlovesManager.GloveCharges.map {
val brawlingGlove = JSONObject()
brawlingGlove.put("gloveId",BrawlingGloves.forId(it.key).indicator.toString())
brawlingGlove.put("charges",it.value.toString())
brawlingGloves.add(brawlingGlove)
}
root.put("brawlingGloves",brawlingGloves)
}
}
fun saveStatManager(root: JSONObject){
val statistics = JSONArray()
var index = 0
@@ -277,33 +250,6 @@ class PlayerSaver (val player: Player){
root.put("bankPinManager",bankPinManager)
}
fun saveTreasureTrails(root: JSONObject){
val treasureTrailManager = JSONObject()
if(player.treasureTrailManager.hasTrail()){
val trail = JSONObject()
trail.put("clueId",player.treasureTrailManager.clueId.toString())
trail.put("length",player.treasureTrailManager.trailLength.toString())
trail.put("stage",player.treasureTrailManager.trailStage.toString())
treasureTrailManager.put("trail",trail)
}
val completedClues = JSONArray()
player.treasureTrailManager.completedClues.map {
completedClues.add(it.toString())
}
treasureTrailManager.put("completedClues",completedClues)
root.put("treasureTrails",treasureTrailManager)
}
fun saveAntiMacroHandler(root: JSONObject){
/*if(player.antiMacroHandler.isSaveRequired){
val antiMacroEvent = JSONObject()
if(player.antiMacroHandler.hasEvent()){
antiMacroEvent.put("eventName",player.antiMacroHandler.event.name)
root.put("antiMacroEvent",antiMacroEvent)
}
}*/
}
fun saveStateManager(root: JSONObject){
val states = JSONArray()
player.states.forEach{key,clazz ->
@@ -317,17 +263,6 @@ class PlayerSaver (val player: Player){
root.put("states",states)
}
fun saveBarCrawl(root: JSONObject){
val barCrawl = JSONObject()
barCrawl.put("started",player.barcrawlManager.isStarted)
val barsVisited = JSONArray()
player.barcrawlManager.bars.map {
barsVisited.add(it)
}
barCrawl.put("bars",barsVisited)
root.put("barCrawl",barCrawl)
}
fun saveFamiliarManager(root: JSONObject){
val familiarManager = JSONObject()
val petDetails = JSONArray()
@@ -395,56 +330,6 @@ class PlayerSaver (val player: Player){
root.put("configs",configs)
}
fun saveFarming(root: JSONObject){
/*val farming = JSONObject()
if(player.farmingManager.equipment.container.itemCount() != 0) {
val equipment = saveContainer(player.farmingManager.equipment.container)
farming.put("equipment",equipment)
}
if(player.farmingManager.compostManager.bins.size != 0){
val bins = JSONArray()
player.farmingManager.compostManager.bins.map { compostBin ->
val bin = JSONObject()
bin.put("wrapperId",compostBin.wrapperId.toString())
if(compostBin.timeStamp != 0L){
bin.put("timeStamp",compostBin.timeStamp.toString())
}
if(compostBin.compostLevel > 0) {
bin.put("compostLevel",compostBin.compostLevel.toString())
}
if(compostBin.container.itemCount() > 0) {
val compostContainer = saveContainer(compostBin.container)
bin.put("compostContainer", compostContainer)
}
bins.add(bin)
}
farming.put("bins",bins)
player.farmingManager.seedlingManager.save(farming)
}
if(player.farmingManager.patches.size != 0){
val wrappers = JSONArray()
player.farmingManager.patches.map {
val wrapper = JSONObject()
wrapper.put("wrapperId",it.wrapperId.toString())
if(player.farmingManager.amuletBoundWrapper == player.farmingManager.getPatchWrapper(it.wrapperId))
farming.put("farmingAmuletWrapperID",it.wrapperId)
val cycle = JSONObject()
cycle.put("compostThreshold",it.cycle.compostThreshold.toString())
cycle.put("growthTime",it.cycle.growthTime.toString())
cycle.put("harvestAmount",it.cycle.harvestAmount.toString())
cycle.put("protection",it.cycle.isProtected)
wrapper.put("cycle",cycle)
if(it.node != null){
wrapper.put("nodeId",it.patch.getNodePosition(it.node).toString())
}
wrappers.add(wrapper)
}
farming.put("wrappers",wrappers)
}
root.put("farming",farming)*/
}
fun saveAutocast(root: JSONObject){
player.properties.autocastSpell ?: return
val spell = JSONObject()
@@ -631,36 +516,6 @@ class PlayerSaver (val player: Player){
root.put("activityData",activityData)
}
fun saveGrandExchangeData(root: JSONObject){
val grandExchange = JSONObject()
if(player.exchangeRecords.hasActiveOffer()){
val offers = JSONArray()
player.exchangeRecords.offerRecords.map {
if(it != null){
val offer = JSONObject()
offer["index"] = it.slot.toString()
offer["uid"] = it.uid.toString()
offers.add(offer)
}
}
grandExchange["offers"] = offers
}
val history = JSONArray()
player.exchangeRecords.history.map {
if(it != null){
val historyEntry = JSONObject()
historyEntry["isSell"] = it.sell
historyEntry["itemId"] = it.itemID.toString()
historyEntry["totalCoinExchange"] = it.totalCoinExchange.toString()
historyEntry["completedAmount"] = it.completedAmount.toString()
history.add(historyEntry)
}
}
grandExchange["history"] = history
root["grand_exchange"] = grandExchange
}
fun saveGraveType(root: JSONObject){
root.put("grave_type",player.graveManager.type.ordinal.toString())
}
@@ -697,24 +552,6 @@ class PlayerSaver (val player: Player){
root.put("quests",quests)
}
fun saveSlayer(root: JSONObject){
val slayer = JSONObject()
val slayerManager = player.slayer
if(slayerManager.removed.isNotEmpty()) {
val removedTasks = JSONArray()
slayerManager.removed.map {
removedTasks.add(it.ordinal.toString())
}
slayer.put("removedTasks",removedTasks)
}
slayer.put("taskStreak",slayerManager.flags.taskStreak.toString())
slayer.put("totalTasks",slayerManager.flags.completedTasks.toString())
slayer.put("equipmentFlags",slayerManager.flags.equipmentFlags)
slayer.put("taskFlags", slayerManager.flags.taskFlags)
slayer.put("rewardFlags", slayerManager.flags.rewardFlags)
root.put("slayer",slayer)
}
fun saveSettings(root: JSONObject){
val settings = JSONObject()
settings.put("brightness",player.settings.brightness.toString())
@@ -2,12 +2,14 @@ package rs09.game.node.entity.player.info.stats
import core.game.component.Component
import core.game.content.global.BossKillCounter
import core.game.content.ttrail.TreasureTrailManager
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.node.entity.skill.slayer.SlayerManager
import rs09.game.system.command.Command
import rs09.game.system.command.Privilege
import rs09.game.system.command.sets.CommandSet
@@ -38,11 +40,11 @@ fun sendStats(player: Player, other: Player, page: Int){
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)
97 -> sendLine(player,"Easy Clues: ${TreasureTrailManager.getInstance(other).completedClues[0]}",i)
68 -> sendLine(player,"Medium Clues: ${TreasureTrailManager.getInstance(other).completedClues[1]}",i)
69 -> sendLine(player,"Hard Clues: ${TreasureTrailManager.getInstance(other).completedClues[2]}",i)
70 -> sendLine(player,SPACER,i)
71 -> sendLine(player,"Slayer Tasks: ${other.slayer.flags.completedTasks}",i)
71 -> sendLine(player,"Slayer Tasks: ${SlayerManager.getInstance(other).flags.completedTasks}",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)
@@ -43,7 +43,7 @@ class BarbarianOutpostCourse
val id = node.id
getCourse(player)
when (id) {
2115, 2116 -> if (!player.barcrawlManager.isFinished || player.barcrawlManager.isStarted) {
2115, 2116 -> if (!BarcrawlManager.getInstance(player).isFinished || BarcrawlManager.getInstance(player).isStarted) {
player.dialogueInterpreter.open(384)
} else {
DoorActionHandler.handleAutowalkDoor(player, node as Scenery)
@@ -65,7 +65,7 @@ class BarbarianOutpostCourse
sendMessage(player, "You climb the low wall...")
AgilityHandler.forceWalk(player, flag, node.location.transform(-1, 0, 0), node.location.transform(1, 0, 0), Animation.create(839), 10, 13.5, null)
}
455 -> player.barcrawlManager.read()
455 -> BarcrawlManager.getInstance(player).read()
385 -> {
sendMessage(player, "The scorpion stings you!")
player.impactHandler.manualHit(player, 3, HitsplatType.NORMAL)
@@ -217,9 +217,9 @@ class BarbarianOutpostCourse
}
override fun open(vararg args: Any): Boolean {
if (!player.barcrawlManager.isStarted) {
if (!BarcrawlManager.getInstance(player).isStarted) {
npc("O, waddya want?")
} else if (player.barcrawlManager.isFinished && !player.barcrawlManager.isStarted) {
} else if (BarcrawlManager.getInstance(player).isFinished && !BarcrawlManager.getInstance(player).isStarted) {
npc("'Ello friend.")
stage = 50
} else {
@@ -250,7 +250,7 @@ class BarbarianOutpostCourse
stage++
}
4 -> end()
5 -> if (player.barcrawlManager.isFinished) {
5 -> if (BarcrawlManager.getInstance(player).isFinished) {
npc("You may pass if you like. You are a true", "barbarian now.")
stage = 4
} else {
@@ -280,8 +280,8 @@ class BarbarianOutpostCourse
stage++
}
10 -> {
player.barcrawlManager.reset()
player.barcrawlManager.isStarted = true
BarcrawlManager.getInstance(player).reset()
BarcrawlManager.getInstance(player).isStarted = true
player.inventory.add(BarcrawlManager.BARCRAWL_CARD, player)
interpreter.sendDialogue("The guard hands you a Barcrawl card.")
stage++
@@ -295,10 +295,10 @@ class BarbarianOutpostCourse
stage++
}
13 -> end()
20 -> if (!player.barcrawlManager.hasCard()) {
20 -> if (!BarcrawlManager.getInstance(player).hasCard()) {
player("I've lost my barcrawl card...")
stage = 23
} else if (player.barcrawlManager.isFinished) {
} else if (BarcrawlManager.getInstance(player).isFinished) {
player("I tink I jusht 'bout done dem all... but I losht count...")
stage = 24
} else {
@@ -318,7 +318,7 @@ class BarbarianOutpostCourse
if (!player.inventory.containsItem(BarcrawlManager.BARCRAWL_CARD)) {
end()
}
player.barcrawlManager.isStarted = false
BarcrawlManager.getInstance(player).isStarted = false
player.bank.remove(BarcrawlManager.BARCRAWL_CARD)
player.inventory.remove(BarcrawlManager.BARCRAWL_CARD)
interpreter.sendDialogue("You give the card to the barbarian.")
@@ -12,6 +12,7 @@ import core.game.node.entity.impl.ForceMovement
import core.game.node.entity.npc.AbstractNPC
import core.game.node.entity.player.Player
import core.game.node.entity.skill.Skills
import core.game.node.entity.skill.hunter.HunterManager
import core.game.node.item.Item
import core.game.node.scenery.Scenery
import core.game.system.task.Pulse
@@ -176,9 +177,9 @@ class PitfallListeners : InteractionListener() {
return@on true
}
val maxTraps = player.hunterManager.maximumTraps
val maxTraps = HunterManager.getInstance(player).maximumTraps
if(player.getAttribute("pitfall:count", 0) >= maxTraps) {
player.sendMessage("You can't set up more than ${maxTraps} pitfall traps at your hunter level.")
player.sendMessage("You can't set up more than $maxTraps pitfall traps at your hunter level.")
return@on true
}
player.incrementAttribute("pitfall:count", 1)
@@ -29,47 +29,47 @@ object SlayerEquipmentFlags {
if((getItemFromEquipment(player, EquipmentSlot.AMULET)?.id ?: 0) == Items.WITCHWOOD_ICON_8923) flags = flags or (1 shl 7)
if((getItemFromEquipment(player, EquipmentSlot.SHIELD)?.id ?: 0) == Items.MIRROR_SHIELD_4156) flags = flags or (1 shl 8)
player.slayer.flags.equipmentFlags = flags
SlayerManager.getInstance(player).flags.equipmentFlags = flags
}
@JvmStatic
fun hasNosePeg(player: Player): Boolean{
return player.slayer.flags.equipmentFlags and 1 == 1
return SlayerManager.getInstance(player).flags.equipmentFlags and 1 == 1
}
@JvmStatic
fun hasEarmuffs(player: Player): Boolean {
return (player.slayer.flags.equipmentFlags shr 1) and 1 == 1
return (SlayerManager.getInstance(player).flags.equipmentFlags shr 1) and 1 == 1
}
@JvmStatic
fun hasFaceMask(player: Player): Boolean {
return (player.slayer.flags.equipmentFlags shr 2) and 1 == 1
return (SlayerManager.getInstance(player).flags.equipmentFlags shr 2) and 1 == 1
}
@JvmStatic
fun hasBlackMask(player: Player): Boolean {
return (player.slayer.flags.equipmentFlags shr 3) and 1 == 1
return (SlayerManager.getInstance(player).flags.equipmentFlags shr 3) and 1 == 1
}
@JvmStatic
fun hasSpinyHelmet(player: Player): Boolean {
return (player.slayer.flags.equipmentFlags shr 4) and 1 == 1
return (SlayerManager.getInstance(player).flags.equipmentFlags shr 4) and 1 == 1
}
@JvmStatic
fun hasWitchwoodIcon(player: Player): Boolean {
return (player.slayer.flags.equipmentFlags shr 7) and 1 == 1
return (SlayerManager.getInstance(player).flags.equipmentFlags shr 7) and 1 == 1
}
@JvmStatic
fun hasMirrorShield(player: Player): Boolean {
return (player.slayer.flags.equipmentFlags shr 8) and 1 == 1
return (SlayerManager.getInstance(player).flags.equipmentFlags shr 8) and 1 == 1
}
@JvmStatic
fun getDamAccBonus(player: Player): Double {
val isCape = player.slayer.flags.equipmentFlags == 0x3F
val isCape = SlayerManager.getInstance(player).flags.equipmentFlags == 0x3F
val hasMask = hasBlackMask(player)
return if(isCape) 1.075
@@ -1,6 +1,5 @@
package rs09.game.node.entity.skill.slayer
import core.game.node.entity.player.Player
import core.game.node.entity.skill.slayer.Master
import core.game.node.entity.skill.slayer.Tasks
@@ -8,7 +7,7 @@ import core.game.node.entity.skill.slayer.Tasks
* Bitflag-based system for storing slayer-related data for a player and various helper functions.
* @author Ceikry
*/
class SlayerFlags(val player: Player) {
class SlayerFlags {
var taskFlags = 0
var rewardFlags = 0
var equipmentFlags = 0
@@ -1,47 +0,0 @@
package rs09.game.node.entity.skill.slayer
import api.events.EventHook
import api.events.NPCKillEvent
import api.rewardXP
import core.game.node.entity.Entity
import core.game.node.entity.player.Player
import core.game.node.entity.skill.Skills
import core.game.node.entity.skill.slayer.Master
object SlayerKillHook : EventHook<NPCKillEvent>
{
override fun process(entity: Entity, event: NPCKillEvent) {
val npc = event.npc
val player = entity as? Player ?: return
val slayer = player.slayer
val flags = slayer.flags
if (slayer.hasTask()) {
rewardXP(player, Skills.SLAYER, npc.skills.maximumLifepoints.toDouble())
slayer.decrementAmount(1)
if(slayer.hasTask()) return
flags.taskStreak = flags.taskStreak + 1
flags.completedTasks = flags.completedTasks + 1
if ((flags.completedTasks > 4 || flags.canEarnPoints()) && flags.getMaster() != Master.TURAEL && flags.getPoints() < 64000) {
var points = flags.getMaster().taskPoints[0]
if (flags.taskStreak % 50 == 0) {
points = flags.getMaster().taskPoints[2]
} else if (flags.taskStreak % 10 == 0) {
points = flags.getMaster().taskPoints[1]
}
flags.incrementPoints(points)
if (flags.getPoints() > 64000) {
flags.setPoints(64000)
}
player.sendMessages("You've completed " + flags.taskStreak + " tasks in a row and received " + points + " points, with a total of " + flags.getPoints(), "You have completed " + flags.completedTasks + " tasks in total. Return to a Slayer master.")
} else if (flags.completedTasks == 4) {
player.sendMessage("You've completed your task; you will start gaining points on your next task!")
flags.flagCanEarnPoints()
} else if (flags.getMaster() == Master.TURAEL) {
player.sendMessages("You've completed your task; Tasks from Turael do not award points.", "Return to a Slayer master.")
} else {
player.sendMessages("You've completed your task; Complete " + (4 - flags.completedTasks) + " more task(s) to start gaining points.", "Return to a Slayer master.")
}
}
}
}
@@ -1,7 +1,15 @@
package rs09.game.node.entity.skill.slayer
import api.LoginListener
import api.PersistPlayer
import api.events.EventHook
import api.events.NPCKillEvent
import api.getAttribute
import api.rewardXP
import core.cache.def.impl.NPCDefinition
import core.game.node.entity.Entity
import core.game.node.entity.player.Player
import core.game.node.entity.skill.Skills
import core.game.node.entity.skill.slayer.Master
import core.game.node.entity.skill.slayer.Tasks
import org.json.simple.JSONArray
@@ -10,23 +18,44 @@ import rs09.game.Event
import java.util.*
/**
* Manages the players slayer task.
* Manages the players slayer data.
* @author Ceikry
*/
class SlayerManager(val player: Player) {
init {
player.hook(Event.NPCKilled, SlayerKillHook)
class SlayerManager(val player: Player? = null) : LoginListener, PersistPlayer, EventHook<NPCKillEvent> {
override fun login(player: Player) {
val instance = SlayerManager(player)
player.hook(Event.NPCKilled, instance)
player.setAttribute("slayer-manager", instance)
}
/**
* The player's slayer flags
*/
@JvmField
val flags: SlayerFlags = SlayerFlags(player)
val flags: SlayerFlags = SlayerFlags()
fun parse(slayerData: JSONObject) {
override fun savePlayer(player: Player, save: JSONObject) {
val slayer = JSONObject()
val slayerManager = getInstance(player)
if(slayerManager.removed.isNotEmpty()) {
val removedTasks = JSONArray()
slayerManager.removed.map {
removedTasks.add(it.ordinal.toString())
}
slayer["removedTasks"] = removedTasks
}
slayer["taskStreak"] = slayerManager.flags.taskStreak.toString()
slayer["totalTasks"] = slayerManager.flags.completedTasks.toString()
slayer["equipmentFlags"] = slayerManager.flags.equipmentFlags
slayer["taskFlags"] = slayerManager.flags.taskFlags
slayer["rewardFlags"] = slayerManager.flags.rewardFlags
save["slayer"] = slayer
}
override fun parsePlayer(player: Player, data: JSONObject) {
val slayerData = data["slayer"] as JSONObject
val m = slayerData["master"]
val flags = getInstance(player).flags
if (m != null) {
flags.setMaster(Master.forId(m.toString().toInt()))
}
@@ -71,13 +100,48 @@ class SlayerManager(val player: Player) {
if (slayerData.containsKey("rewardFlags")) flags.rewardFlags = slayerData["rewardFlags"].toString().toInt()
}
override fun process(entity: Entity, event: NPCKillEvent) {
val npc = event.npc
val player = entity as? Player ?: return
val slayer = getInstance(player)
val flags = slayer.flags
if (slayer.hasTask() && npc.id in slayer.task!!.npcs) {
rewardXP(player, Skills.SLAYER, npc.skills.maximumLifepoints.toDouble())
slayer.decrementAmount(1)
if(slayer.hasTask()) return
flags.taskStreak = flags.taskStreak + 1
flags.completedTasks = flags.completedTasks + 1
if ((flags.completedTasks > 4 || flags.canEarnPoints()) && flags.getMaster() != Master.TURAEL && flags.getPoints() < 64000) {
var points = flags.getMaster().taskPoints[0]
if (flags.taskStreak % 50 == 0) {
points = flags.getMaster().taskPoints[2]
} else if (flags.taskStreak % 10 == 0) {
points = flags.getMaster().taskPoints[1]
}
flags.incrementPoints(points)
if (flags.getPoints() > 64000) {
flags.setPoints(64000)
}
player.sendMessages("You've completed " + flags.taskStreak + " tasks in a row and received " + points + " points, with a total of " + flags.getPoints(), "You have completed " + flags.completedTasks + " tasks in total. Return to a Slayer master.")
} else if (flags.completedTasks == 4) {
player.sendMessage("You've completed your task; you will start gaining points on your next task!")
flags.flagCanEarnPoints()
} else if (flags.getMaster() == Master.TURAEL) {
player.sendMessages("You've completed your task; Tasks from Turael do not award points.", "Return to a Slayer master.")
} else {
player.sendMessages("You've completed your task; Complete " + (4 - flags.completedTasks) + " more task(s) to start gaining points.", "Return to a Slayer master.")
}
}
}
/**
* Method used to assign a new task for a player.
* @param master the master to give the task.
*/
fun generate(master: Master) {
val task = SlayerUtils.generate(player, master) ?: return
SlayerUtils.assign(player, task, master)
val task = SlayerUtils.generate(player!!, master) ?: return
SlayerUtils.assign(player!!, task, master)
}
/**
@@ -137,7 +201,7 @@ class SlayerManager(val player: Player) {
fun decrementAmount(amount: Int) {
flags.decrementTaskAmount(amount)
player.varpManager.get(2502).setVarbit(0, flags.taskFlags shr 4).send(player)
player!!.varpManager.get(2502).setVarbit(0, flags.taskFlags shr 4).send(player)
}
/**
@@ -169,4 +233,11 @@ class SlayerManager(val player: Player) {
get() = flags.removed
val isCanEarnPoints: Boolean
get() = flags.canEarnPoints()
companion object {
@JvmStatic fun getInstance(player: Player) : SlayerManager
{
return getAttribute(player, "slayer-manager", SlayerManager())
}
}
}
@@ -31,20 +31,20 @@ object SlayerUtils {
fun canBeAssigned(player: Player, task: Tasks): Boolean
{
return player.getSkills().getLevel(Skills.SLAYER) >= task.levelReq && !player.slayer.flags.removed.contains(task)
return player.getSkills().getLevel(Skills.SLAYER) >= task.levelReq && !SlayerManager.getInstance(player).flags.removed.contains(task)
}
fun assign(player: Player, task: Tasks, master: Master)
{
player.slayer.master = master
player.slayer.task = task
player.slayer.amount = RandomFunction.random(master.assignment_range[0], master.assignment_range[1])
SlayerManager.getInstance(player).master = master
SlayerManager.getInstance(player).task = task
SlayerManager.getInstance(player).amount = RandomFunction.random(master.assignment_range[0], master.assignment_range[1])
if (master == Master.DURADEL) {
player.achievementDiaryManager.finishTask(player, DiaryType.KARAMJA, 2, 8)
} else if (master == Master.VANNAKA) {
player.achievementDiaryManager.finishTask(player, DiaryType.VARROCK, 1, 14)
}
player.varpManager.get(2502).setVarbit(0, player.slayer.flags.taskFlags shr 4).send(player)
player.varpManager.get(2502).setVarbit(0, SlayerManager.getInstance(player).flags.taskFlags shr 4).send(player)
}
@JvmStatic
@@ -28,6 +28,7 @@ import rs09.game.ai.pvp.PVPAIPBuilderUtils
import rs09.game.ai.resource.ResourceAIPActions
import rs09.game.ai.skillingbot.SkillingBotsBuilder
import rs09.game.ai.wilderness.PvPBotsBuilder
import rs09.game.node.entity.skill.slayer.SlayerManager
import java.util.*
/**
@@ -195,7 +196,7 @@ class AIPCommandPlugin : CommandPlugin() {
return true
}
"slayerpoints" -> {
player.slayer.slayerPoints = 50000
SlayerManager.getInstance(player).slayerPoints = 50000
return true
}
"dragonbot" -> {
@@ -265,11 +266,11 @@ class AIPCommandPlugin : CommandPlugin() {
}
"ranger" -> {
}
"removetask" -> return if (!player.slayer.hasTask()) {
"removetask" -> return if (!SlayerManager.getInstance(player).hasTask()) {
player.sendMessage("You don't have an active task right now.")
true
} else {
player.slayer.clear()
SlayerManager.getInstance(player).clear()
player.sendMessage("You have canceled your current task.")
true
}
@@ -22,6 +22,7 @@ import kotlinx.coroutines.launch
import org.rs09.consts.Components
import rs09.ServerConstants
import rs09.game.content.activity.fishingtrawler.TrawlerLoot
import rs09.game.content.ame.RandomEventManager
import rs09.game.content.ame.RandomEvents
import rs09.game.ge.GrandExchange
import rs09.game.node.entity.state.newsys.states.FarmingState
@@ -461,13 +462,13 @@ class MiscCommandSet : CommandSet(Privilege.ADMIN){
}
define("testlady", Privilege.ADMIN){ player, _ ->
player.antiMacroHandler.event = RandomEvents.RIVER_TROLL.npc.create(player)
player.antiMacroHandler.event!!.init()
RandomEventManager.getInstance(player)!!.event = RandomEvents.RIVER_TROLL.npc.create(player)
RandomEventManager.getInstance(player)!!.event!!.init()
}
define("revent", Privilege.ADMIN){ player, _ ->
println(player.pulseManager.current)
player.antiMacroHandler.fireEvent()
RandomEventManager.getInstance(player)!!.fireEvent()
}
define("addcredits", Privilege.ADMIN){ player, _ ->
@@ -2,6 +2,7 @@ package rs09.game.system.command.sets
import core.game.node.entity.npc.NPC
import core.plugin.Initializable
import rs09.game.node.entity.skill.slayer.SlayerManager
import rs09.game.system.command.Command
import rs09.game.system.command.Privilege
@@ -13,8 +14,8 @@ class SlayerCommandSet : CommandSet(Privilege.ADMIN){
*/
define("finishtask"){player,_ ->
notify(player, "Kill the npc that spawned to finish your task.")
player.slayer.amount = 1
val finisher = NPC(player.slayer.task?.npcs?.get(0) ?: 0, player.location)
SlayerManager.getInstance(player).amount = 1
val finisher = NPC(SlayerManager.getInstance(player).task?.npcs?.get(0) ?: 0, player.location)
finisher.isRespawn = false
finisher.init()
}
@@ -32,7 +33,7 @@ class SlayerCommandSet : CommandSet(Privilege.ADMIN){
reject(player,"Amount needs to be a valid integer!")
}
player.slayer.slayerPoints = amount!!
SlayerManager.getInstance(player).slayerPoints = amount!!
notify(player, "Set slayer points to $amount.")
}
}
@@ -15,8 +15,11 @@ import io.github.classgraph.ClassInfo
import rs09.game.ai.general.scriptrepository.PlayerScripts
import rs09.game.interaction.InteractionListener
import rs09.game.interaction.InterfaceListener
import rs09.game.node.entity.player.info.login.PlayerSaveParser
import rs09.game.node.entity.player.info.login.PlayerSaver
import rs09.game.node.entity.skill.magic.SpellListener
import rs09.game.system.SystemLogger
import rs09.game.system.command.Command
import rs09.game.world.GameWorld
import java.util.*
import java.util.function.Consumer
@@ -106,6 +109,15 @@ object ClassScanner {
val clazz = it.loadClass().newInstance() as TickListener
GameWorld.tickListeners.add(clazz)
}
result.getClassesImplementing("api.PersistPlayer").filter { !it.isAbstract }.forEach {
val clazz = it.loadClass().newInstance() as PersistPlayer
PlayerSaver.contentHooks.add(clazz)
PlayerSaveParser.contentHooks.add(clazz)
}
result.getClassesImplementing("api.PersistWorld").filter { !it.isAbstract }.forEach {
val clazz = it.loadClass().newInstance() as PersistPlayer
PlayerSaver.contentHooks.add(clazz)
}
}
/**