Rewrote All Fired Up

This commit is contained in:
Player Name
2026-04-01 12:51:34 +00:00
committed by Ryan
parent df80d077ce
commit 45c3c2488f
6 changed files with 197 additions and 239 deletions
@@ -2,36 +2,35 @@ package content.minigame.allfiredup
import core.api.* import core.api.*
import core.game.node.entity.player.Player import core.game.node.entity.player.Player
import core.tools.SystemLogger
import core.game.world.map.Location import core.game.world.map.Location
import core.tools.Log import core.tools.Log
/** /**
* Various data for beacons, such as varp and offset, required FM level, etc * Various data for beacons, such as varp and offset, required FM level, etc
* @author Ceikry * @author Ceikry, Player Name
*/ */
enum class AFUBeacon(val title: String, val fmLevel: Int, val varbit: Int, val location: Location, val experience: Double, val keeper: Int = 0) { enum class AFUBeacon(val title: String, val fmLevel: Int, val varbit: Int, val location: Location, val experience: Double, val keeper: Int = 0) {
RIVER_SALVE("",43,5146,Location.create(3396, 3464, 0),216.2,8065), RIVER_SALVE("near the River Salve", 43, 5146, Location.create(3396, 3464, 0), 216.2, 8065),
RAG_AND_BONE("",43,5147,Location.create(3343, 3510, 0),235.8,8066), RAG_AND_BONE("near the Rag and Bone Man", 43, 5147, Location.create(3343, 3510, 0), 235.8, 8066),
JOLLY_BOAR("",48,5148,Location.create(3278, 3525, 0), 193.8,8067), JOLLY_BOAR("north of the Jolly Boar", 48, 5148, Location.create(3278, 3525, 0), 193.8, 8067),
NORTH_VARROCK_CASTLE("",53,5149,Location.create(3236, 3527, 0),178.5,8068), NORTH_VARROCK_CASTLE("north of Varrock Palace", 53, 5149, Location.create(3236, 3527, 0), 178.5, 8068),
GRAND_EXCHANGE("",59,5150,Location.create(3170, 3536, 0),194.3,8069), GRAND_EXCHANGE("north of the Grand Exchange", 59, 5150, Location.create(3170, 3536, 0), 194.3, 8069),
EDGEVILLE("",62,5151,Location.create(3087, 3516, 0),86.7,8070), EDGEVILLE("near Edgeville", 62, 5151, Location.create(3087, 3516, 0), 86.7, 8070),
MONASTERY("",68,5152,Location.create(3034, 3518, 0),224.4,8071), MONASTERY("near the Black Knights' Fortress", 68, 5152, Location.create(3034, 3518, 0), 224.4, 8071),
GOBLIN_VILLAGE("",72,5153,Location.create(2968, 3516, 0),194.8,8072), GOBLIN_VILLAGE("near Goblin Village", 72, 5153, Location.create(2968, 3516, 0), 194.8, 8072),
BURTHORPE("",76,5154,Location.create(2940, 3565, 0),195.3,8073), BURTHORPE("near Burthorpe", 76, 5154, Location.create(2940, 3565, 0), 195.3, 8073),
DEATH_PLATEAU("",79,5155,Location.create(2944, 3622, 0),249.9,8074), DEATH_PLATEAU("east of Death Plateau", 79, 5155, Location.create(2944, 3622, 0), 249.9, 8074),
TROLLHEIM("",83,5156,Location.create(2939, 3680, 0),201.0,8075), TROLLHEIM("east of Trollheim", 83, 5156, Location.create(2939, 3680, 0), 201.0, 8075),
GWD("",87,5157,Location.create(2937, 3773, 0),255.0,8076), GWD("east of the God Wars dungeon temple", 87, 5157, Location.create(2937, 3773, 0), 255.0, 8076),
TEMPLE("",89,5158,Location.create(2946, 3836, 0),198.9), TEMPLE("north of the small temple in the Wilderness", 89, 5158, Location.create(2946, 3836, 0), 198.9),
PLATEAU("",92,5159,Location.create(2964, 3931, 0),147.9); PLATEAU("on the Frozen Waste Plateau", 92, 5159, Location.create(2964, 3931, 0), 147.9);
companion object { companion object {
fun forLocation(location: Location): AFUBeacon { fun forLocation(location: Location): AFUBeacon {
for (beacon in values()) { for (beacon in values()) {
if (beacon.location.equals(location)) return beacon if (beacon.location.equals(location)) return beacon
} }
return AFUBeacon.RIVER_SALVE.also { log(this::class.java, Log.WARN, "Unhandled Beacon Location ${location.toString()}") } return AFUBeacon.RIVER_SALVE.also { log(this::class.java, Log.WARN, "Unhandled Beacon Location ${location.toString()}") }
} }
fun resetAllBeacons(player: Player){ fun resetAllBeacons(player: Player){
@@ -42,19 +41,19 @@ enum class AFUBeacon(val title: String, val fmLevel: Int, val varbit: Int, val l
} }
fun light(player: Player){ fun light(player: Player){
setVarbit(player, varbit, 2) setVarbit(player, varbit, 2, true)
} }
fun diminish(player: Player){ fun diminish(player: Player){
setVarbit(player, varbit, 3) setVarbit(player, varbit, 3, true)
} }
fun extinguish(player: Player){ fun extinguish(player: Player){
setVarbit(player, varbit, 0) setVarbit(player, varbit, 0, true)
} }
fun lightGnomish(player: Player){ fun lightGnomish(player: Player){
setVarbit(player, varbit, 4) setVarbit(player, varbit, 4, true)
} }
fun fillWithLogs(player: Player){ fun fillWithLogs(player: Player){
@@ -4,13 +4,23 @@ import core.game.node.entity.npc.NPC
import core.game.node.entity.player.Player import core.game.node.entity.player.Player
import core.game.node.entity.skill.Skills import core.game.node.entity.skill.Skills
import core.game.node.item.Item import core.game.node.item.Item
import core.game.system.task.Pulse
import core.game.world.update.flag.context.Animation import core.game.world.update.flag.context.Animation
import org.rs09.consts.Items import org.rs09.consts.Items
import core.game.interaction.InteractionListener import core.game.interaction.InteractionListener
import core.game.interaction.IntType import core.game.interaction.IntType
import core.game.world.GameWorld
import content.data.Quests import content.data.Quests
import core.api.delayScript
import core.api.getAttribute
import core.api.getOrStartTimer
import core.api.getQuestStage
import core.api.lock
import core.api.queueScript
import core.api.removeAttribute
import core.api.sendMessage
import core.api.setAttribute
import core.api.setQuestStage
import core.api.stopExecuting
import core.game.interaction.QueueStrength
private val VALID_LOGS = intArrayOf(Items.LOGS_1511, Items.OAK_LOGS_1521,Items.WILLOW_LOGS_1519,Items.MAPLE_LOGS_1517,Items.YEW_LOGS_1515,Items.MAGIC_LOGS_1513) private val VALID_LOGS = intArrayOf(Items.LOGS_1511, Items.OAK_LOGS_1521,Items.WILLOW_LOGS_1519,Items.MAPLE_LOGS_1517,Items.YEW_LOGS_1515,Items.MAGIC_LOGS_1513)
private val FILL_ANIM = Animation(9136) private val FILL_ANIM = Animation(9136)
@@ -18,7 +28,7 @@ private val LIGHT_ANIM = Animation(7307)
/** /**
* Handles interactions for beacons * Handles interactions for beacons
* @author Ceikry * @author Ceikry, Player Name
*/ */
class AFUBeaconListeners : InteractionListener { class AFUBeaconListeners : InteractionListener {
@@ -86,112 +96,80 @@ class AFUBeaconListeners : InteractionListener {
val logs = getLogs(player,20) val logs = getLogs(player,20)
if (logs.id != 0 && player.inventory.remove(logs)) { if (logs.id != 0 && player.inventory.remove(logs)) {
player.lock() lock(player, FILL_ANIM.duration)
queueScript(player, 0, QueueStrength.SOFT) { stage ->
var session: AFUSession? = null if (stage == 1) {
if(questComplete){ player.animator.animate(FILL_ANIM)
session = player.getAttribute("afu-session", null) return@queueScript delayScript(player, FILL_ANIM.duration)
if(session == null) {
session = AFUSession(player)
session.init()
} }
setAttribute(player, "/save:beacon:${beacon.ordinal}:logsId", logs.id)
beacon.fillWithLogs(player)
return@queueScript stopExecuting(player)
} }
GameWorld.Pulser.submit(object : Pulse() {
var counter = 0
override fun pulse(): Boolean {
when (counter++) {
0 -> player.animator.animate(FILL_ANIM)
1 -> {
beacon.fillWithLogs(player)
if(questComplete){
session?.setLogs(beacon.ordinal,logs)
}
}
2 -> player.unlock().also {player.animator.animate(Animation.RESET); return true }
}
return false
}
})
} else { } else {
player.dialogueInterpreter.sendDialogue("You need some logs to do this.") player.dialogueInterpreter.sendDialogue("You need some logs to do this.")
} }
} }
fun lightBeacon(player: Player, beacon: AFUBeacon, questComplete: Boolean){ fun lightBeacon(player: Player, beacon: AFUBeacon, questComplete: Boolean) {
var session: AFUSession? = null
if(questComplete){
session = player.getAttribute("afu-session",null)
if(session == null) return
}
if(player.inventory.contains(Items.TINDERBOX_590,1)){ if(player.inventory.contains(Items.TINDERBOX_590,1)){
player.lock() lock(player, LIGHT_ANIM.duration)
GameWorld.Pulser.submit(object: Pulse(){ queueScript(player, 0, QueueStrength.SOFT) { stage ->
var counter = 0 if (stage == 1) {
override fun pulse(): Boolean { player.animator.animate(LIGHT_ANIM)
when(counter++){ return@queueScript delayScript(player, LIGHT_ANIM.duration)
0 -> player.animator.animate(LIGHT_ANIM)
1 -> {
beacon.light(player)
if(questComplete){
session?.startTimer(beacon.ordinal)
if(session?.getLitBeacons() == 6 && !player.hasFireRing()){
player.sendMessage("Congratulations on lighting 6 beacons at once! King Roald has something for you.")
player.setAttribute("/save:afu-mini:ring",true)
}
if(session?.getLitBeacons() == 10 && !player.hasFlameGloves()){
player.sendMessage("Congratulations on lighting 10 beacons at once! King Roald has something for you.")
player.setAttribute("/save:afu-mini:gloves",true)
}
if(session?.getLitBeacons() == 14 && !player.hasInfernoAdze()){
player.sendMessage("Congratulations on lighting all 14 beacons! King Roald has something special for you.")
player.setAttribute("/save:afu-mini:adze",true)
}
var experience = beacon.experience
experience += session?.getBonusExperience() ?: 0.0
player.skills.addExperience(Skills.FIREMAKING,experience)
} else {
player.questRepository.getQuest(Quests.ALL_FIRED_UP).setStage(player, player.questRepository.getStage(Quests.ALL_FIRED_UP) + 10)
}
}
2 -> player.unlock().also { return true }
}
return false
} }
}) val logsId = getAttribute(player, "/save:beacon:${beacon.ordinal}:logsId", Items.LOGS_1511)
removeAttribute(player, "/save:beacon:${beacon.ordinal}:logsId")
beacon.light(player)
if (!questComplete) {
setQuestStage(player, Quests.ALL_FIRED_UP, getQuestStage(player, Quests.ALL_FIRED_UP) + 10)
return@queueScript stopExecuting(player)
}
val timer = getOrStartTimer<AFUTimer>(player)
timer.addTime(beacon.ordinal, logsId, 20)
val lit = timer.getLitBeacons()
if (lit == 6 && !player.hasFireRing()) {
sendMessage(player, "Congratulations on lighting 6 beacons at once! King Roald has something for you.")
setAttribute(player, "/save:afu-mini:ring", true)
}
if (lit == 10 && !player.hasFlameGloves()) {
sendMessage(player, "Congratulations on lighting 10 beacons at once! King Roald has something for you.")
setAttribute(player, "/save:afu-mini:gloves", true)
}
if (lit == 14 && !player.hasInfernoAdze()) {
sendMessage(player, "Congratulations on lighting all 14 beacons! King Roald has something special for you.")
setAttribute(player, "/save:afu-mini:adze", true)
}
val xp = beacon.experience + timer.getBonusExperience()
player.skills.addExperience(Skills.FIREMAKING, xp)
return@queueScript stopExecuting(player)
}
} else { } else {
player.dialogueInterpreter.sendDialogue("You need a tinderbox to light this.") player.dialogueInterpreter.sendDialogue("You need a tinderbox to light this.")
} }
} }
fun restoreBeacon(player: Player, beacon: AFUBeacon, questComplete: Boolean){ fun restoreBeacon(player: Player, beacon: AFUBeacon, questComplete: Boolean){
var session: AFUSession? = null
if(questComplete){
session = player.getAttribute("afu-session",null)
if(session == null) return
}
val logs = getLogs(player, 5) val logs = getLogs(player, 5)
if (logs.id != 0 && player.inventory.remove(logs)) { if (logs.id != 0 && player.inventory.remove(logs)) {
player.lock() lock(player, FILL_ANIM.duration)
GameWorld.Pulser.submit(object: Pulse(){ queueScript(player, 0, QueueStrength.SOFT) { stage ->
var counter = 0 if (stage == 1) {
override fun pulse(): Boolean { player.animator.animate(LIGHT_ANIM)
when(counter++){ return@queueScript delayScript(player, LIGHT_ANIM.duration)
0 -> player.animator.animate(FILL_ANIM)
1 -> beacon.light(player).also {
if(questComplete){
session?.refreshTimer(beacon,logs.id)
} else {
player.questRepository.getQuest(Quests.ALL_FIRED_UP).setStage(player, 80)
}
}
2 -> player.unlock().also { return true }
}
return false
} }
}) val backupLogsId = getAttribute(player, "/save:beacon:${beacon.ordinal}:backupLogsId", Items.LOGS_1511)
removeAttribute(player, "/save:beacon:${beacon.ordinal}:backupLogsId")
beacon.light(player)
if (!questComplete) {
setQuestStage(player, Quests.ALL_FIRED_UP, 80)
return@queueScript stopExecuting(player)
}
val timer = getOrStartTimer<AFUTimer>(player)
timer.addTime(beacon.ordinal, backupLogsId, 5)
return@queueScript stopExecuting(player)
}
} else { } else {
player.dialogueInterpreter.sendDialogue("You need some logs to do this.") player.dialogueInterpreter.sendDialogue("You need some logs to do this.")
} }
@@ -1,121 +0,0 @@
package content.minigame.allfiredup
import core.api.LogoutListener
import core.game.node.entity.player.Player
import core.game.node.item.Item
import core.game.system.task.Pulse
import core.game.world.GameWorld
import org.rs09.consts.Items
import core.tools.colorize
/**
* Handles keeping track of lit beacons and their burn time remaining
* @author Ceikry
*/
class AFUSession(val player: Player? = null) : LogoutListener {
private val beaconTimers = Array(14){i -> BeaconTimer(0, AFUBeacon.values()[i]) }
private val logInventories = Array(14){Item(0,0)}
private val beaconWatched = Array(14){false}
private var isActive = false
fun init() {
isActive = true
GameWorld.Pulser.submit(object: Pulse(){
override fun pulse(): Boolean {
player!!.setAttribute("afu-pulse",this)
beaconTimers.forEach {timer ->
timer.ticks--
if(timer.ticks == 300) timer.beacon.diminish(player).also {
if(beaconWatched[timer.beacon.ordinal]){
beaconWatched[timer.beacon.ordinal] = false
timer.ticks += (getTicks(logInventories[timer.beacon.ordinal].id) * 5)
timer.beacon.light(player)
player.sendMessage(colorize("%RThe ${timer.beacon.name.toLowerCase().replace("_"," ")} watcher has used your backup logs."))
} else {
player.sendMessage(colorize("%RThe ${timer.beacon.name.toLowerCase().replace("_", " ")} beacon is dying!"))
}
}
if(timer.ticks == 0) timer.beacon.extinguish(player).also { player.sendMessage(colorize("%RThe ${timer.beacon.name.toLowerCase().replace("_"," ")} beacon has gone out!")) }
}
return !isActive
}
})
player!!.setAttribute("afu-session",this)
}
fun getLitBeacons(): Int{
return beaconTimers.count { it.ticks > 0 }
}
fun end(){
isActive = false
}
fun setLogs(beaconIndex: Int, logs: Item){
logInventories[beaconIndex] = logs
}
fun startTimer(beaconIndex: Int){
val ticks = getTicks(logInventories[beaconIndex].id) * 20
logInventories[beaconIndex] = Item(0,0)
beaconTimers[beaconIndex].ticks = ticks
}
fun refreshTimer(beacon: AFUBeacon, logID: Int){
val ticks = getTicks(logID) * 5
beaconTimers.forEach {
if(it.beacon.ordinal == beacon.ordinal) it.ticks += ticks
}
}
fun setWatcher(index: Int, logs: Item){
beaconWatched[index] = true
logInventories[index] = logs
}
fun isWatched(index: Int): Boolean{
return beaconWatched[index]
}
fun getTicks(logID: Int): Int{
val ticks = when(logID){
Items.LOGS_1511 -> 65
Items.OAK_LOGS_1521 -> 68
Items.WILLOW_LOGS_1519 -> 73
Items.MAPLE_LOGS_1517 -> 79
Items.YEW_LOGS_1515 -> 83
Items.MAGIC_LOGS_1513 -> 90
else -> 0
}
return ticks
}
fun getBonusExperience(): Double{
return when(getLitBeacons()){
1 -> 608.4
2 -> 1622.4
3 -> 1987.4
4 -> 2149.6
5 -> 2149.6
6 -> 2514.6
7 -> 2555.2
8 -> 2758.0
9 -> 2839.1
10 -> 3041.9
11 -> 3123.0
12 -> 3244.7
13 -> 3366.4
14 -> 4867.4
else -> 0.0
}
}
override fun logout(player: Player) {
AFUBeacon.resetAllBeacons(player)
val session: AFUSession? = player.getAttribute("afu-session",null)
session?.end()
player.removeAttribute("afu-session")
}
internal class BeaconTimer(var ticks: Int, val beacon: AFUBeacon)
}
@@ -0,0 +1,104 @@
package content.minigame.allfiredup
import core.api.getAttribute
import core.api.log
import core.api.removeAttribute
import core.api.sendMessage
import core.game.node.entity.Entity
import core.game.node.entity.player.Player
import core.game.system.timer.PersistTimer
import core.tools.Log
import core.tools.colorize
import org.json.simple.JSONArray
import org.json.simple.JSONObject
import org.rs09.consts.Items
class AFUTimer : PersistTimer(1, "AFU timer", isSoft = true) {
private val burnTicks = Array(14) { 0 }
fun addTime(index: Int, logsId: Int, numLogs: Int) {
val ticksPerLog = when (logsId) {
Items.LOGS_1511 -> 65
Items.OAK_LOGS_1521 -> 68
Items.WILLOW_LOGS_1519 -> 73
Items.MAPLE_LOGS_1517 -> 79
Items.YEW_LOGS_1515 -> 83
Items.MAGIC_LOGS_1513 -> 90
else -> 0
}
burnTicks[index] += numLogs * ticksPerLog
}
fun getBonusExperience(): Double {
return when (getLitBeacons()) {
1 -> 608.4
2 -> 1622.4
3 -> 1987.4
4 -> 2149.6
5 -> 2149.6
6 -> 2514.6
7 -> 2555.2
8 -> 2758.0
9 -> 2839.1
10 -> 3041.9
11 -> 3123.0
12 -> 3244.7
13 -> 3366.4
14 -> 4867.4
else -> 0.0
}
}
fun getLitBeacons(): Int {
return burnTicks.count { it > 0 }
}
override fun save(root: JSONObject, entity: Entity) {
val beaconArray = JSONArray()
for (i in 0..13) {
beaconArray.add(burnTicks[i])
}
root["beacons"] = beaconArray
}
override fun parse(root: JSONObject, entity: Entity) {
val beacons = root["beacons"] as JSONArray
for (i in 0..13) {
burnTicks[i] = beacons[i].toString().toInt()
}
}
override fun run(entity: Entity) : Boolean {
if (entity !is Player) {
log(this::class.java, Log.ERR, "How did a non-Player light an AFU beacon?")
return false
}
val player = entity
var keepRunning = false
for (i in 0..13) {
val beacon = AFUBeacon.values()[i]
if (burnTicks[i] > 0) {
burnTicks[i]--
if (burnTicks[i] > 0) {
keepRunning = true
}
if (burnTicks[i] == 300) {
val backupLogsId = getAttribute(player, "/save:beacon:$i:backupLogsId", 0)
if (backupLogsId != 0) {
addTime(i, backupLogsId, 5)
removeAttribute(player, "/save:beacon:$i:backupLogsId")
sendMessage(player, colorize("%RThe beacon watcher ${beacon.title} has used your backup logs."))
} else {
beacon.diminish(player)
sendMessage(player, colorize("%RThe beacon ${beacon.title} is dying!"))
}
} else if (burnTicks[i] == 0) {
beacon.extinguish(player)
removeAttribute(player, "/save:beacon:$i:logsId")
sendMessage(player, colorize("%RThe beacon ${beacon.title} has gone out!"))
}
}
}
return keepRunning
}
}
@@ -1,13 +1,13 @@
package content.minigame.allfiredup package content.minigame.allfiredup
import core.ServerConstants
import core.game.dialogue.* import core.game.dialogue.*
import core.game.node.entity.npc.NPC import core.game.node.entity.npc.NPC
import core.game.node.entity.player.Player import core.game.node.entity.player.Player
import core.game.node.entity.skill.Skills import core.game.node.entity.skill.Skills
import core.game.node.item.Item import core.game.node.item.Item
import core.plugin.Initializable import core.plugin.Initializable
import content.region.wilderness.dialogue.* import core.api.getAttribute
import core.api.setAttribute
import org.rs09.consts.Items import org.rs09.consts.Items
private val VALID_LOGS = arrayOf(Items.LOGS_1511, Items.OAK_LOGS_1521, Items.WILLOW_LOGS_1519, Items.MAPLE_LOGS_1517, Items.YEW_LOGS_1515, Items.MAGIC_LOGS_1513) private val VALID_LOGS = arrayOf(Items.LOGS_1511, Items.OAK_LOGS_1521, Items.WILLOW_LOGS_1519, Items.MAPLE_LOGS_1517, Items.YEW_LOGS_1515, Items.MAGIC_LOGS_1513)
@@ -41,10 +41,9 @@ class BeaconTenderDialogue(player: Player? = null) : DialoguePlugin(player) {
override fun handle(interfaceId: Int, buttonId: Int): Boolean { override fun handle(interfaceId: Int, buttonId: Int): Boolean {
val beacon = AFUBeacon.values()[index] val beacon = AFUBeacon.values()[index]
val logs = getLogs(player,5) val logs = getLogs(player,5)
val session: AFUSession? = player.getAttribute("afu-session",null)
when(stage){ when(stage){
0 -> player("Hello!").also { stage++ } 0 -> player("Hello!").also { stage++ }
1 -> if(beacon.getState(player) == BeaconState.LIT && session?.isWatched(index) == false){ 1 -> if (beacon.getState(player) == BeaconState.LIT && getAttribute(player, "/save:beacon:${beacon.ordinal}:backupLogsId", 0) == 0) {
options("Can you watch this beacon for me?","Nevermind.").also { stage = 10 } options("Can you watch this beacon for me?","Nevermind.").also { stage = 10 }
} else { } else {
npc("Carry on, adventurer.").also { stage = 1000 } npc("Carry on, adventurer.").also { stage = 1000 }
@@ -62,7 +61,7 @@ class BeaconTenderDialogue(player: Player? = null) : DialoguePlugin(player) {
13 -> npc("Great, hand them over.").also { stage++ } 13 -> npc("Great, hand them over.").also { stage++ }
14 -> player("Here you go!").also { 14 -> player("Here you go!").also {
player.inventory.remove(logs) player.inventory.remove(logs)
session?.setWatcher(index,logs) setAttribute(player, "/save:beacon:${beacon.ordinal}:backupLogsId", logs.id)
stage = 1000 stage = 1000
} }
@@ -150,7 +150,6 @@ class AllFiredUp : Quest(Quests.ALL_FIRED_UP, 157, 156, 1){
player.skills.addExperience(Skills.FIREMAKING, 5500.0) player.skills.addExperience(Skills.FIREMAKING, 5500.0)
player.inventory.add(Item(995,20000)) player.inventory.add(Item(995,20000))
AFUBeacon.resetAllBeacons(player) AFUBeacon.resetAllBeacons(player)
setVarbit(player, 1283, 0)
player.questRepository.syncronizeTab(player) player.questRepository.syncronizeTab(player)
} }