From fd5998453d9070f03e9a93a1095ae3fff7a80141 Mon Sep 17 00:00:00 2001 From: Ceikry Date: Wed, 2 Aug 2023 00:52:19 +0000 Subject: [PATCH] Fixed infinite lunar cast range --- .../global/skill/magic/SpellListener.kt | 10 +-- .../global/skill/magic/SpellListeners.kt | 66 ++++++++++++++----- Server/src/main/core/api/ContentAPI.kt | 9 +-- 3 files changed, 61 insertions(+), 24 deletions(-) diff --git a/Server/src/main/content/global/skill/magic/SpellListener.kt b/Server/src/main/content/global/skill/magic/SpellListener.kt index 95498b3a1..01eae8785 100644 --- a/Server/src/main/content/global/skill/magic/SpellListener.kt +++ b/Server/src/main/content/global/skill/magic/SpellListener.kt @@ -26,12 +26,12 @@ abstract class SpellListener(val bookName: String) : Listener { @JvmField val GROUND_ITEM = -6 } - fun onCast(spellID: Int,type: Int,method: (player: Player, node: Node?) -> Unit){ - SpellListeners.add(spellID,type,bookName,method) + fun onCast(spellID: Int, type: Int, range: Int = 10, method: (player: Player, node: Node?) -> Unit){ + SpellListeners.add(spellID, type, bookName, range, method) } - fun onCast(spellID: Int, type: Int, vararg ids: Int, method: (player: Player, node: Node?) -> Unit){ - SpellListeners.add(spellID,type,ids,bookName,method) + fun onCast(spellID: Int, type: Int, vararg ids: Int, range: Int = 10, method: (player: Player, node: Node?) -> Unit){ + SpellListeners.add(spellID, type, ids, bookName, range, method) } fun requires(player: Player, magicLevel: Int = 0, runes: Array = arrayOf(), specialEquipment: IntArray = intArrayOf()) { @@ -95,4 +95,4 @@ abstract class SpellListener(val bookName: String) : Listener { fun showMagicTab(player: Player){ player.interfaceManager.setViewedTab(6) } -} \ No newline at end of file +} diff --git a/Server/src/main/content/global/skill/magic/SpellListeners.kt b/Server/src/main/content/global/skill/magic/SpellListeners.kt index c6c1e933e..95ff686a0 100644 --- a/Server/src/main/content/global/skill/magic/SpellListeners.kt +++ b/Server/src/main/content/global/skill/magic/SpellListeners.kt @@ -1,45 +1,81 @@ package content.global.skill.magic import core.game.event.SpellCastEvent -import core.api.log +import core.api.* import core.game.node.Node import core.game.node.entity.player.Player import core.game.node.entity.player.link.SpellBookManager import core.tools.Log import core.tools.SystemLogger +import core.game.interaction.* +import core.game.world.map.path.Pathfinder object SpellListeners { val castMap = HashMap Unit>() + val spellRanges = HashMap() - fun add(spellID: Int, type: Int, book: String, method: (Player,Node?) -> Unit){ + fun add(spellID: Int, type: Int, book: String, distance: Int, method: (Player,Node?) -> Unit){ castMap["$book:$spellID:$type"] = method + spellRanges["$book:$spellID:$type"] = distance } - fun add(spellID: Int, type: Int, ids: IntArray, book: String, method: (Player, Node?) -> Unit){ + fun add(spellID: Int, type: Int, ids: IntArray, book: String, distance: Int, method: (Player, Node?) -> Unit){ for(id in ids) { castMap["$book:$spellID:$type:$id"] = method + spellRanges["$book:$spellID:$type:$id"] = distance } } - fun get(spellID: Int, type: Int, book: String): ((Player,Node?) -> Unit)?{ + fun get(spellID: Int, type: Int, book: String): Pair Unit)?> { log(this::class.java, Log.FINE, "Getting $book:$spellID:$type") - return castMap["$book:$spellID:$type"] + return Pair (spellRanges["$book:$spellID:$type"] ?: 10, castMap["$book:$spellID:$type"]) } - fun get(spellID: Int, type: Int, id: Int, book: String): ((Player,Node?) -> Unit)?{ + fun get(spellID: Int, type: Int, id: Int, book: String): Pair Unit)?> { log(this::class.java, Log.FINE, "Getting $book:$spellID:$type:$id") - return castMap["$book:$spellID:$type:$id"] + return Pair (spellRanges["$book:$spellID:$type:$id"] ?: 10, castMap["$book:$spellID:$type:$id"]) } @JvmStatic fun run(button: Int, type: Int, book: String, player: Player, node: Node? = null){ - val method = get(button,type,node?.id ?: 0,book) ?: get(button,type,book) ?: return - try { - method.invoke(player, node) - player.dispatch(SpellCastEvent(SpellBookManager.SpellBook.valueOf(book.uppercase()), button, node)) - } catch (e: IllegalStateException){ - player.removeAttribute("spell:runes") - return + var (range, method) = get (button, type, node?.id ?: 0, book) + if (method == null) { + var next = get (button, type, book) + range = next.first + method = next.second ?: return + } + + if (type in intArrayOf (SpellListener.NPC, SpellListener.OBJECT, SpellListener.PLAYER, SpellListener.GROUND_ITEM)) { + player.pulseManager.run (object : MovementPulse (player, node, Pathfinder.SMART) { + override fun pulse() : Boolean { + try { + method?.invoke (player, node) + } catch (e: IllegalStateException) { + player.removeAttribute ("spell:runes") + return true + } + return true + } + + override fun update () : Boolean { + if (player.location.withinMaxnormDistance (node!!.centerLocation, range) && hasLineOfSight (player, node!!)) { + player.faceLocation (node.getFaceLocation(player.location)) + player.walkingQueue.reset() + pulse() + stop() + return true + } + return super.update() + } + }) + } else { + try { + method?.invoke(player, node) + player.dispatch(SpellCastEvent(SpellBookManager.SpellBook.valueOf(book.uppercase()), button, node)) + } catch (e: IllegalStateException){ + player.removeAttribute("spell:runes") + return + } } } -} \ No newline at end of file +} diff --git a/Server/src/main/core/api/ContentAPI.kt b/Server/src/main/core/api/ContentAPI.kt index 28cbfc6c2..1845ecf70 100644 --- a/Server/src/main/core/api/ContentAPI.kt +++ b/Server/src/main/core/api/ContentAPI.kt @@ -75,6 +75,7 @@ import core.net.packet.context.MusicContext import core.net.packet.out.MusicPacket import core.game.system.timer.* import core.game.system.timer.impl.* +import core.game.node.entity.combat.CombatSwingHandler import java.util.regex.* import java.io.* import kotlin.math.* @@ -974,7 +975,7 @@ fun registerTimer (entity: Entity, timer: RSTimer?) { entity.timers.registerTimer (timer) } -/** +/** * Used to fetch the existing, active, non-abstract and non-anonymous timer with the given identifier, or start a new timer if none exists and return that. * @param entity the entity whose timers we're retrieving * @param identifier the identifier of the timer, refer to the individual timer class for this token. @@ -1014,7 +1015,7 @@ fun spawnTimer (identifier: String, vararg args: Any) : RSTimer? { /** * Used to fetch a new instance of a registered (see: non-anonymous, non-abstract) timer with the given configuration args - * @param T the type of the timer you're trying to retrieve. The timer registry will be searched for a timer of this type. + * @param T the type of the timer you're trying to retrieve. The timer registry will be searched for a timer of this type. * @param args various arbitrary arguments to be passed to the timer's constructor. Refer to the timer in question for what the args are expected to be. * @return a timer instance configured with your given args, or null if the timer is not listed in the registry (if this happens, your timer is either abstract or anonymous.) **/ @@ -2713,7 +2714,7 @@ fun apRange(entity: Entity, apRange: Int) { } fun hasLineOfSight(entity: Entity, target: Node) : Boolean { - return ProjectilePathfinder.find(entity, target).isSuccessful + return CombatSwingHandler.isProjectileClipped (entity, target, false) } fun animationFinished(entity: Entity) : Boolean { @@ -2805,7 +2806,7 @@ fun isStunned(entity: Entity) : Boolean { **/ fun applyPoison (entity: Entity, source: Entity, severity: Int) { val existingTimer = getTimer(entity) - + if (existingTimer != null) { existingTimer.severity = severity existingTimer.damageSource = source