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,29 +2,28 @@ package content.minigame.allfiredup
import core.api.*
import core.game.node.entity.player.Player
import core.tools.SystemLogger
import core.game.world.map.Location
import core.tools.Log
/**
* 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) {
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),
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),
GRAND_EXCHANGE("",59,5150,Location.create(3170, 3536, 0),194.3,8069),
EDGEVILLE("",62,5151,Location.create(3087, 3516, 0),86.7,8070),
MONASTERY("",68,5152,Location.create(3034, 3518, 0),224.4,8071),
GOBLIN_VILLAGE("",72,5153,Location.create(2968, 3516, 0),194.8,8072),
BURTHORPE("",76,5154,Location.create(2940, 3565, 0),195.3,8073),
DEATH_PLATEAU("",79,5155,Location.create(2944, 3622, 0),249.9,8074),
TROLLHEIM("",83,5156,Location.create(2939, 3680, 0),201.0,8075),
GWD("",87,5157,Location.create(2937, 3773, 0),255.0,8076),
TEMPLE("",89,5158,Location.create(2946, 3836, 0),198.9),
PLATEAU("",92,5159,Location.create(2964, 3931, 0),147.9);
RIVER_SALVE("near the River Salve", 43, 5146, Location.create(3396, 3464, 0), 216.2, 8065),
RAG_AND_BONE("near the Rag and Bone Man", 43, 5147, Location.create(3343, 3510, 0), 235.8, 8066),
JOLLY_BOAR("north of the Jolly Boar", 48, 5148, Location.create(3278, 3525, 0), 193.8, 8067),
NORTH_VARROCK_CASTLE("north of Varrock Palace", 53, 5149, Location.create(3236, 3527, 0), 178.5, 8068),
GRAND_EXCHANGE("north of the Grand Exchange", 59, 5150, Location.create(3170, 3536, 0), 194.3, 8069),
EDGEVILLE("near Edgeville", 62, 5151, Location.create(3087, 3516, 0), 86.7, 8070),
MONASTERY("near the Black Knights' Fortress", 68, 5152, Location.create(3034, 3518, 0), 224.4, 8071),
GOBLIN_VILLAGE("near Goblin Village", 72, 5153, Location.create(2968, 3516, 0), 194.8, 8072),
BURTHORPE("near Burthorpe", 76, 5154, Location.create(2940, 3565, 0), 195.3, 8073),
DEATH_PLATEAU("east of Death Plateau", 79, 5155, Location.create(2944, 3622, 0), 249.9, 8074),
TROLLHEIM("east of Trollheim", 83, 5156, Location.create(2939, 3680, 0), 201.0, 8075),
GWD("east of the God Wars dungeon temple", 87, 5157, Location.create(2937, 3773, 0), 255.0, 8076),
TEMPLE("north of the small temple in the Wilderness", 89, 5158, Location.create(2946, 3836, 0), 198.9),
PLATEAU("on the Frozen Waste Plateau", 92, 5159, Location.create(2964, 3931, 0), 147.9);
companion object {
fun forLocation(location: Location): AFUBeacon {
@@ -42,19 +41,19 @@ enum class AFUBeacon(val title: String, val fmLevel: Int, val varbit: Int, val l
}
fun light(player: Player){
setVarbit(player, varbit, 2)
setVarbit(player, varbit, 2, true)
}
fun diminish(player: Player){
setVarbit(player, varbit, 3)
setVarbit(player, varbit, 3, true)
}
fun extinguish(player: Player){
setVarbit(player, varbit, 0)
setVarbit(player, varbit, 0, true)
}
fun lightGnomish(player: Player){
setVarbit(player, varbit, 4)
setVarbit(player, varbit, 4, true)
}
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.skill.Skills
import core.game.node.item.Item
import core.game.system.task.Pulse
import core.game.world.update.flag.context.Animation
import org.rs09.consts.Items
import core.game.interaction.InteractionListener
import core.game.interaction.IntType
import core.game.world.GameWorld
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 FILL_ANIM = Animation(9136)
@@ -18,7 +28,7 @@ private val LIGHT_ANIM = Animation(7307)
/**
* Handles interactions for beacons
* @author Ceikry
* @author Ceikry, Player Name
*/
class AFUBeaconListeners : InteractionListener {
@@ -86,112 +96,80 @@ class AFUBeaconListeners : InteractionListener {
val logs = getLogs(player,20)
if (logs.id != 0 && player.inventory.remove(logs)) {
player.lock()
var session: AFUSession? = null
if(questComplete){
session = player.getAttribute("afu-session", null)
if(session == null) {
session = AFUSession(player)
session.init()
lock(player, FILL_ANIM.duration)
queueScript(player, 0, QueueStrength.SOFT) { stage ->
if (stage == 1) {
player.animator.animate(FILL_ANIM)
return@queueScript delayScript(player, FILL_ANIM.duration)
}
}
GameWorld.Pulser.submit(object : Pulse() {
var counter = 0
override fun pulse(): Boolean {
when (counter++) {
0 -> player.animator.animate(FILL_ANIM)
1 -> {
setAttribute(player, "/save:beacon:${beacon.ordinal}:logsId", logs.id)
beacon.fillWithLogs(player)
if(questComplete){
session?.setLogs(beacon.ordinal,logs)
return@queueScript stopExecuting(player)
}
}
2 -> player.unlock().also {player.animator.animate(Animation.RESET); return true }
}
return false
}
})
} else {
player.dialogueInterpreter.sendDialogue("You need some logs to do this.")
}
}
fun lightBeacon(player: Player, beacon: AFUBeacon, questComplete: Boolean){
var session: AFUSession? = null
if(questComplete){
session = player.getAttribute("afu-session",null)
if(session == null) return
}
fun lightBeacon(player: Player, beacon: AFUBeacon, questComplete: Boolean) {
if(player.inventory.contains(Items.TINDERBOX_590,1)){
player.lock()
GameWorld.Pulser.submit(object: Pulse(){
var counter = 0
override fun pulse(): Boolean {
when(counter++){
0 -> player.animator.animate(LIGHT_ANIM)
1 -> {
lock(player, LIGHT_ANIM.duration)
queueScript(player, 0, QueueStrength.SOFT) { stage ->
if (stage == 1) {
player.animator.animate(LIGHT_ANIM)
return@queueScript delayScript(player, LIGHT_ANIM.duration)
}
val logsId = getAttribute(player, "/save:beacon:${beacon.ordinal}:logsId", Items.LOGS_1511)
removeAttribute(player, "/save:beacon:${beacon.ordinal}:logsId")
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 (!questComplete) {
setQuestStage(player, Quests.ALL_FIRED_UP, getQuestStage(player, Quests.ALL_FIRED_UP) + 10)
return@queueScript stopExecuting(player)
}
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)
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(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)
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)
}
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)
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)
}
2 -> player.unlock().also { return true }
}
return false
}
})
} else {
player.dialogueInterpreter.sendDialogue("You need a tinderbox to light this.")
}
}
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)
if (logs.id != 0 && player.inventory.remove(logs)) {
player.lock()
GameWorld.Pulser.submit(object: Pulse(){
var counter = 0
override fun pulse(): Boolean {
when(counter++){
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)
lock(player, FILL_ANIM.duration)
queueScript(player, 0, QueueStrength.SOFT) { stage ->
if (stage == 1) {
player.animator.animate(LIGHT_ANIM)
return@queueScript delayScript(player, LIGHT_ANIM.duration)
}
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)
}
2 -> player.unlock().also { return true }
val timer = getOrStartTimer<AFUTimer>(player)
timer.addTime(beacon.ordinal, backupLogsId, 5)
return@queueScript stopExecuting(player)
}
return false
}
})
} else {
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
import core.ServerConstants
import core.game.dialogue.*
import core.game.node.entity.npc.NPC
import core.game.node.entity.player.Player
import core.game.node.entity.skill.Skills
import core.game.node.item.Item
import core.plugin.Initializable
import content.region.wilderness.dialogue.*
import core.api.getAttribute
import core.api.setAttribute
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)
@@ -41,10 +41,9 @@ class BeaconTenderDialogue(player: Player? = null) : DialoguePlugin(player) {
override fun handle(interfaceId: Int, buttonId: Int): Boolean {
val beacon = AFUBeacon.values()[index]
val logs = getLogs(player,5)
val session: AFUSession? = player.getAttribute("afu-session",null)
when(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 }
} else {
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++ }
14 -> player("Here you go!").also {
player.inventory.remove(logs)
session?.setWatcher(index,logs)
setAttribute(player, "/save:beacon:${beacon.ordinal}:backupLogsId", logs.id)
stage = 1000
}
@@ -150,7 +150,6 @@ class AllFiredUp : Quest(Quests.ALL_FIRED_UP, 157, 156, 1){
player.skills.addExperience(Skills.FIREMAKING, 5500.0)
player.inventory.add(Item(995,20000))
AFUBeacon.resetAllBeacons(player)
setVarbit(player, 1283, 0)
player.questRepository.syncronizeTab(player)
}