Fixed some error spam about a nullref in animateWoodcutting

Fixed a general script processing oversight that could cause error-throwing scripts to continue executing
Scripts being processed now automatically cancel if the interaction-target-node is no longer active (fixes object could not be replaced spam)
Fixed the stopExecuting() spam
Fixed a CME in the disconnection queue (only affected server shutdown)
Future-proofed the ground spawn parser to work with the format Zaros now outputs
Added in proper SKILLING global clock for use with the script system - addresses some quirks and brings us closer to authenticity
This commit is contained in:
Ceikry
2023-03-21 03:50:27 +00:00
committed by Ryan
parent 48805eea66
commit 7ec901297b
8 changed files with 159 additions and 107 deletions
+23 -1
View File
@@ -2346,6 +2346,28 @@ fun queueScript(entity: Entity, delay: Int = 1, strength: QueueStrength = QueueS
entity.scripts.addToQueue(s, strength)
}
/**
* Sets the clock to the value of WORLD_TICSK + ticks.
* @param entity the entity whose clock we are updating
* @param clock the clock we are updating. Please use [core.game.interaction.Clocks] for this argument.
* @param ticks the number of ticks to delay by
* @return always returns false so this can be used as a script return value.
**/
fun delayClock(entity: Entity, clock: Int, ticks: Int) : Boolean {
entity.clocks[clock] = getWorldTicks() + ticks
return false
}
/**
* Checks if a clock is ready (have we elapsed any delay put into it)
* @param entity the entity whose clock we are checking
* @param clock the clock we are checking. Please use [core.game.interaction.Clocks] for this argument.
* @return true if we have elapsed the clock's wait
**/
fun clockReady(entity: Entity, clock: Int) : Boolean {
return entity.clocks[clock] <= getWorldTicks()
}
fun delayAttack(entity: Entity, ticks: Int) {
entity.properties.combatPulse.delayNextAttack(3)
entity.clocks[Clocks.NEXT_ATTACK] = getWorldTicks() + ticks
@@ -2389,4 +2411,4 @@ fun modPrayerPoints(player: Player, amount: Double) {
else return
}
private class ContentAPI
private class ContentAPI
@@ -8,4 +8,5 @@ object Clocks {
@JvmStatic val NEXT_DRINK = 4
@JvmStatic val NEXT_ATTACK = 5
@JvmStatic val STUN = 6
}
@JvmStatic val SKILLING = 7
}
@@ -13,6 +13,7 @@ import core.game.world.map.path.Pathfinder
import core.tools.Log
import core.tools.SystemLogger
import java.lang.Integer.max
import java.io.*
class ScriptProcessor(val entity: Entity) {
private var apScript: Script<*>? = null
@@ -182,6 +183,10 @@ class ScriptProcessor(val entity: Entity) {
}
fun processInteractScript(script: Script<*>) {
if (interactTarget == null || !interactTarget!!.isActive) {
log(this::class.java, Log.FINE, "Interact target $interactTarget no longer active, cancelling interaction.")
reset()
}
if (script.nextExecution < GameWorld.ticks) {
val finished = executeScript(script)
script.state++
@@ -193,11 +198,19 @@ class ScriptProcessor(val entity: Entity) {
fun executeScript(script: Script<*>) : Boolean {
currentScript = script
when (script) {
is Interaction -> return script.execution.invoke(entity as? Player ?: return true, interactTarget ?: return true, script.state)
is UseWithInteraction -> return script.execution.invoke(entity as? Player ?: return true, script.used, script.with, script.state)
is QueuedScript -> return script.execution.invoke(script.state)
is QueuedUseWith -> return script.execution.invoke(entity as? Player ?: return true, script.used, script.with, script.state)
try {
when (script) {
is Interaction -> return script.execution.invoke(entity as? Player ?: return true, interactTarget ?: return true, script.state)
is UseWithInteraction -> return script.execution.invoke(entity as? Player ?: return true, script.used, script.with, script.state)
is QueuedScript -> return script.execution.invoke(script.state)
is QueuedUseWith -> return script.execution.invoke(entity as? Player ?: return true, script.used, script.with, script.state)
}
} catch (e: Exception) {
val sw = StringWriter()
val pw = PrintWriter(sw)
e.printStackTrace(pw)
log(this::class.java, Log.ERR, "Error processing ${script::class.java.simpleName} - stopping the script. Exception follows: $sw")
reset()
}
currentScript = null
return true
@@ -243,6 +256,8 @@ class ScriptProcessor(val entity: Entity) {
}
fun setInteractionScript(target: Node, script: Script<*>?) {
if (apScript != null && script != null && script.execution == apScript!!.execution) return
if (opScript != null && script != null && script.execution == opScript!!.execution) return
reset()
interactTarget = target
if (script != null) {
@@ -298,4 +313,4 @@ class ScriptProcessor(val entity: Entity) {
private fun getActiveInteraction() : Script<*>? {
return opScript ?: apScript
}
}
}
@@ -14,7 +14,7 @@ import core.tools.SystemLogger
import core.game.world.GameWorld
import core.game.world.repository.Repository
import core.tools.Log
import java.io.FileReader
import java.io.*
import java.nio.ByteBuffer
class GroundSpawnLoader {
@@ -26,14 +26,22 @@ class GroundSpawnLoader {
reader = FileReader(ServerConstants.CONFIG_PATH + "ground_spawns.json")
var configs = parser.parse(reader) as JSONArray
for(config in configs){
val e = config as JSONObject
val datas = e["loc_data"].toString().split("-")
val id = e["item_id"].toString().toInt()
for(d in datas){
val tokens = d.replace("{", "").replace("}", "").split(",".toRegex()).toTypedArray()
val spawn = GroundSpawn(tokens[4].toInt(), Item(id, tokens[0].toInt()), Location(Integer.valueOf(tokens[1]), Integer.valueOf(tokens[2]), Integer.valueOf(tokens[3])))
spawn.init()
count++
try {
val e = config as JSONObject
val datas = e["loc_data"].toString().split("-")
val id = e["item_id"].toString().toInt()
for(d in datas){
if (d.isNullOrEmpty()) continue
val tokens = d.replace("{", "").replace("}", "").split(",".toRegex()).toTypedArray()
val spawn = GroundSpawn(tokens[4].toInt(), Item(id, tokens[0].toInt()), Location(Integer.valueOf(tokens[1]), Integer.valueOf(tokens[2]), Integer.valueOf(tokens[3])))
spawn.init()
count++
}
} catch (e: Exception) {
val sw = StringWriter()
val pw = PrintWriter(sw)
e.printStackTrace(pw)
log(this::class.java, Log.ERR, "Error parsing config entry ${config.toString()}: $sw")
}
}
log(this::class.java, Log.FINE, "Initialized $count ground items.")
@@ -118,4 +126,4 @@ class GroundSpawnLoader {
}
}
}
}
@@ -102,7 +102,7 @@ class DisconnectionQueue {
* Clears the queue.
*/
fun clear() {
for (entry in queue.values) {
for (entry in queue.values.toTypedArray()) {
finish(entry, true)
}
queue.clear()
@@ -139,4 +139,4 @@ class DisconnectionQueue {
}
return false
}
}
}