diff --git a/Server/src/main/content/global/skill/gather/fishing/FishingListener.kt b/Server/src/main/content/global/skill/gather/fishing/FishingListener.kt index 60dc2c404..01933d9ab 100644 --- a/Server/src/main/content/global/skill/gather/fishing/FishingListener.kt +++ b/Server/src/main/content/global/skill/gather/fishing/FishingListener.kt @@ -47,14 +47,16 @@ class FishingListener : InteractionListener{ return restartScript(player) if (state == 0) { + sendMessage(player, "You attempt to catch some fish...") + } + + if (state == 1) { if (!checkRequirements(player, op, node)) return clearScripts(player) forager?.let { val dest = player.location.transform(player.direction) Pathfinder.find(it, dest).walk(it) } - anim(player, op) - return delayScript(player, 5) } anim(player, op) @@ -74,7 +76,8 @@ class FishingListener : InteractionListener{ player.incrementAttribute("$STATS_BASE:$STATS_FISH") rewardXP(player, Skills.FISHING, fish.experience) - return restartScript(player) + setCurrentScriptState(player, 1) + return keepRunning(player) } private fun anim(player: Player, option: FishingOption) { diff --git a/Server/src/main/content/global/skill/gather/woodcutting/WoodcuttingListener.kt b/Server/src/main/content/global/skill/gather/woodcutting/WoodcuttingListener.kt index f21b8d336..987e7dc9e 100644 --- a/Server/src/main/content/global/skill/gather/woodcutting/WoodcuttingListener.kt +++ b/Server/src/main/content/global/skill/gather/woodcutting/WoodcuttingListener.kt @@ -6,9 +6,7 @@ import content.data.tables.BirdNest import content.global.skill.farming.FarmingPatch.Companion.forObject import content.global.skill.skillcapeperks.SkillcapePerks import content.global.skill.skillcapeperks.SkillcapePerks.Companion.isActive -import core.api.delayScript -import core.api.finishedMoving -import core.api.sendMessage +import core.api.* import core.cache.def.impl.ItemDefinition import core.game.container.impl.EquipmentContainer import core.game.event.ResourceProducedEvent @@ -61,13 +59,14 @@ class WoodcuttingListener : InteractionListener { return true if (state == 0) { + sendMessage(player, "You swing your axe at the tree...") + } + + if (state == 1) { if (!checkWoodcuttingRequirements(player, resource, node)) { player.scripts.reset() return true } - animateWoodcutting(player) - sendMessage(player, "You swing your axe at the tree...") - return delayScript(player, 3) } animateWoodcutting(player) @@ -129,7 +128,8 @@ class WoodcuttingListener : InteractionListener { delayScript(player, 3) rollDepletion(player, node.asScenery(), resource) - return true + setCurrentScriptState(player, 1) + return keepRunning(player) } private fun rollDepletion(player: Player, node: Scenery, resource: WoodcuttingNode): Boolean { diff --git a/Server/src/main/content/global/skill/slayer/NechryaelBehavior.kt b/Server/src/main/content/global/skill/slayer/NechryaelBehavior.kt index 9a849f191..3920cbbeb 100644 --- a/Server/src/main/content/global/skill/slayer/NechryaelBehavior.kt +++ b/Server/src/main/content/global/skill/slayer/NechryaelBehavior.kt @@ -67,6 +67,11 @@ class NechryaelBehavior : NPCBehavior(*Tasks.NECHRYAELS.npcs) { list.remove(spawn) setAttribute(self, ATTR_SPAWNS, list) } + + override fun shouldIgnoreMultiRestrictions(self: NPC, victim: Entity): Boolean { + val list = getSpawns(self) + return victim == self.properties.combatPulse.getVictim() || list.contains(victim.properties.combatPulse.getVictim()) + } } class DeathspawnBehavior : NPCBehavior(NPCs.DEATH_SPAWN_1614) { diff --git a/Server/src/main/core/api/ContentAPI.kt b/Server/src/main/core/api/ContentAPI.kt index 0d8cf593f..62e707f2b 100644 --- a/Server/src/main/core/api/ContentAPI.kt +++ b/Server/src/main/core/api/ContentAPI.kt @@ -2368,6 +2368,16 @@ fun isStunned(entity: Entity) : Boolean { return entity.clocks[Clocks.STUN] >= getWorldTicks() } +fun setCurrentScriptState(entity: Entity, state: Int) { + val script = entity.scripts.getActiveScript() + if (script == null) { + log(ContentAPI::class.java, Log.WARN, "Tried to set a script state when no script was being ran!") + if (GameWorld.settings?.isDevMode != true) return + throw IllegalStateException("Script execution mistake - check stack trace and above warning log!") + } + script.state = state - 1 //set it to 1 below the state so that on next execution the state is at the expected value. +} + /** * Modifies prayer points by value * @param player the player to modify prayer points diff --git a/Server/src/main/core/game/interaction/ScriptProcessor.kt b/Server/src/main/core/game/interaction/ScriptProcessor.kt index 38069a663..089d8dc9e 100644 --- a/Server/src/main/core/game/interaction/ScriptProcessor.kt +++ b/Server/src/main/core/game/interaction/ScriptProcessor.kt @@ -39,7 +39,7 @@ class ScriptProcessor(val entity: Entity) { var canProcess = !entity.delayed() if (entity is Player) - canProcess = canProcess && !entity.interfaceManager.isOpened && !entity.interfaceManager.hasChatbox() + canProcess = canProcess && !entity.hasModalOpen() if (entity !is Player) return if (!entity.delayed() && canProcess && interactTarget != null) { diff --git a/Server/src/main/core/game/node/entity/player/Player.java b/Server/src/main/core/game/node/entity/player/Player.java index 1a3e59533..c773bd1bb 100644 --- a/Server/src/main/core/game/node/entity/player/Player.java +++ b/Server/src/main/core/game/node/entity/player/Player.java @@ -1129,6 +1129,28 @@ public class Player extends Entity { return interfaceManager; } + public boolean hasModalOpen() { + int[] excludedIds = new int[] {372, 421, InterfaceManager.DEFAULT_CHATBOX}; //excludes plain message, plain message with scrollbar, and normal chatbox + Component openedIface = interfaceManager.getOpened(); + Component openChatbox = interfaceManager.getChatbox(); + + boolean hasModal = false; + + if (openedIface != null) { + for (int i = 0; i < excludedIds.length; i++) + if (excludedIds[i] == openedIface.getId()) break; + else if (i == excludedIds.length - 1) hasModal = true; + } + + if (openChatbox != null) { + for (int i = 0; i < excludedIds.length; i++) + if (excludedIds[i] == openChatbox.getId()) break; + else if (i == excludedIds.length - 1) hasModal = true; + } + + return hasModal; + } + /** * Gets the dialogue interpreter. * @return The dialogue interpreter. diff --git a/Server/src/test/kotlin/ExchangeTests.kt b/Server/src/test/kotlin/ExchangeTests.kt index 9c5cabfd8..b2f0cdd1b 100644 --- a/Server/src/test/kotlin/ExchangeTests.kt +++ b/Server/src/test/kotlin/ExchangeTests.kt @@ -37,7 +37,7 @@ import java.io.File return offer } - @AfterAll fun cleanup() { + @AfterAll @JvmStatic fun cleanup() { File(TEST_DB_PATH).delete() } }