From 8ba45e0ee1088785c730fb43ec7226420fab3df3 Mon Sep 17 00:00:00 2001 From: Player Name Date: Thu, 27 Nov 2025 11:55:00 +0000 Subject: [PATCH] Corrected the deep wildy murder message to the authentic one Fixed a bug that caused the prayer-recharge jingle to be played over the death jingle when the player died Fixed redundant overload checks Fixed lunar spells consuming double runes when a previous cast attempt failed Fixed HP on halloween random-event spiders Corrected the Dream spell logic --- .../skill/magic/lunar/LunarListeners.kt | 94 ++++++++++--------- .../core/game/node/entity/player/Player.java | 11 +-- .../core/game/node/entity/skill/Skills.java | 3 - .../game/system/timer/impl/SkillRestore.kt | 2 +- .../world/map/zone/impl/WildernessZone.java | 11 --- .../randoms/SpiderHolidayRandomNPC.kt | 6 +- 6 files changed, 55 insertions(+), 72 deletions(-) diff --git a/Server/src/main/content/global/skill/magic/lunar/LunarListeners.kt b/Server/src/main/content/global/skill/magic/lunar/LunarListeners.kt index fedf14c27..b89b1a3c7 100644 --- a/Server/src/main/content/global/skill/magic/lunar/LunarListeners.kt +++ b/Server/src/main/content/global/skill/magic/lunar/LunarListeners.kt @@ -23,6 +23,7 @@ import core.game.system.command.Privilege import core.game.system.config.NPCConfigParser import core.game.system.task.Pulse import core.game.system.timer.impl.PoisonImmunity +import core.game.system.timer.impl.SkillRestore import core.game.world.map.Location import core.game.world.map.RegionManager import core.game.world.repository.Repository @@ -299,7 +300,7 @@ class LunarListeners : SpellListener("lunar"), Commands { if(playerPies.isEmpty()){ player.sendMessage("You have no pies which you have the level to cook.") - return + throw IllegalStateException() } player.pulseManager.run(object : Pulse(){ @@ -327,33 +328,33 @@ class LunarListeners : SpellListener("lunar"), Commands { fun curePlant(player: Player, obj: Scenery) { if (CompostBins.forObject(obj) != null) { sendMessage(player, "Bins don't often get diseased.") - return + throw IllegalStateException() } val fPatch = FarmingPatch.forObject(obj) if (fPatch == null) { sendMessage(player, "Umm... this spell won't cure that!") - return + throw IllegalStateException() } val patch = fPatch.getPatchFor(player) if (patch.isWeedy()) { sendMessage(player, "The weeds are healthy enough already.") - return + throw IllegalStateException() } if (patch.isEmptyAndWeeded()) { sendMessage(player, "There's nothing there to cure.") - return + throw IllegalStateException() } if (patch.isGrown()) { sendMessage(player, "That's not diseased.") - return + throw IllegalStateException() } if (patch.isDead) { sendMessage(player, "It says 'Cure' not 'Resurrect'. Although death may arise from disease, it is not in itself a disease and hence cannot be cured. So there.") - return + throw IllegalStateException() } if (!patch.isDiseased) { sendMessage(player, "It is growing just fine.") - return + throw IllegalStateException() } patch.cureDisease() @@ -367,7 +368,7 @@ class LunarListeners : SpellListener("lunar"), Commands { private fun monsterExamine(player: Player, npc: NPC){ if(!npc.location.withinDistance(player.location)){ sendMessage(player, "You must get closer to use this spell.") - return + throw IllegalStateException() } face(player, npc) visualizeSpell(player, Animations.LUNAR_SPELLBOOK_STATSPY_6293, Graphics.LUNAR_SPELLBOOK_STAT_SPY_OVER_PLAYER_1060, soundID = Sounds.LUNAR_STAT_SPY_3620) @@ -403,20 +404,20 @@ class LunarListeners : SpellListener("lunar"), Commands { private fun cureOther(player: Player, target: Node) { if(!isPlayer(target)) { sendMessage(player, "You can only cast this spell on other players.") - return + throw IllegalStateException() } val p = target.asPlayer() if(!p.isActive || p.locks.isInteractionLocked) { sendMessage(player, "This player is busy.") - return + throw IllegalStateException() } if(!p.settings.isAcceptAid) { sendMessage(player, "This player is not accepting any aid.") - return + throw IllegalStateException() } if(!isPoisoned(p)) { sendMessage(player, "This player is not poisoned.") - return + throw IllegalStateException() } player.face(p) visualizeSpell(player, Animations.LUNAR_SPELLBOOK_CURE_OTHER_4411, Graphics.LUNAR_SPELLBOOK_CURE_OTHER_736, 130, Sounds.LUNAR_CURE_OTHER_2886) @@ -461,7 +462,7 @@ class LunarListeners : SpellListener("lunar"), Commands { private fun cureMe(player: Player) { if(!isPoisoned(player)) { sendMessage(player, "You are not poisoned.") - return + throw IllegalStateException() } removeRunes(player, true) visualizeSpell(player, Animations.LUNAR_SPELLBOOK_CURE_ME_4411, Graphics.LUNAR_SPELLBOOK_CURE_ME_742, 90, Sounds.LUNAR_CURE_2884) @@ -504,7 +505,7 @@ class LunarListeners : SpellListener("lunar"), Commands { private fun statSpy(player: Player, target: Node) { if(target !is Player) { sendMessage(player, "You can only cast this spell on players.") - return + throw IllegalStateException() } val stat = Components.DREAM_PLAYER_STATS_523 val statCloseEvent = CloseEvent { p, _ -> @@ -583,33 +584,36 @@ class LunarListeners : SpellListener("lunar"), Commands { private fun dream(player: Player) { if(player.skills.lifepoints >= getStatLevel(player, Skills.HITPOINTS)) { sendMessage(player, "You have no need to cast this spell since your hitpoints are already full.") - return + throw IllegalStateException() } + // https://runescape.wiki/w/Dream?oldid=880976 claims Dream makes you heal 1 hp every 20 seconds + // https://oldschool.runescape.wiki/w/Dream claims that Dream has its own timer, so the Dream heals don't need + // to align with the natural heals + val timer = getOrStartTimer(player) animate(player, Animations.LUNAR_SPELLBOOK_DREAM_START_6295) + removeRunes(player, true) + addXP(player, 82.0) delayEntity(player, 4) queueScript(player, 4, QueueStrength.WEAK) { stage: Int -> - when(stage) { - 0 -> { - animate(player, Animations.LUNAR_SPELLBOOK_DREAM_MID_6296) - sendGraphics(Graphics.LUNAR_SPELLBOOK_DREAM_1056, player.location) - playAudio(player, Sounds.LUNAR_SLEEP_3619) - return@queueScript delayScript(player, 5) - } - else -> { - sendGraphics(Graphics.LUNAR_SPELLBOOK_DREAM_1056, player.location) - // This heals 2 HP every min. Naturally you heal 1 for a total of 3 - // The script steps every 5 ticks and we want 50 ticks before a heal - if (stage.mod(10) == 0){ - heal(player, 1) - if(player.skills.lifepoints >= getStatLevel(player, Skills.HITPOINTS)) { - animate(player, Animations.LUNAR_SPELLBOOK_DREAM_END_6297) - return@queueScript stopExecuting(player) - } - } - return@queueScript delayScript(player, 5) + if (stage == 0) { + sendGraphics(Graphics.LUNAR_SPELLBOOK_DREAM_1056, player.location) + playAudio(player, Sounds.LUNAR_SLEEP_3619) + return@queueScript delayScript(player, 5) + } + animate(player, Animations.LUNAR_SPELLBOOK_DREAM_MID_6296) + sendGraphics(Graphics.LUNAR_SPELLBOOK_DREAM_1056, player.location) + // This heals 2 HP every min. Naturally you heal 1 for a total of 3 + // The script steps every 5 ticks and we want 50 ticks before a heal + if (stage.mod(10) == 0) { + val amt = timer.getHealAmount(player) //accounts for regen brace + heal(player, amt) + if (player.skills.lifepoints >= getStatLevel(player, Skills.HITPOINTS)) { + animate(player, Animations.LUNAR_SPELLBOOK_DREAM_END_6297) + return@queueScript stopExecuting(player) } } + return@queueScript delayScript(player, 5) } } @@ -661,23 +665,23 @@ class LunarListeners : SpellListener("lunar"), Commands { private fun fertileSoil(player: Player, target: Scenery) { if (CompostBins.forObjectID(target.id) != null) { sendMessage(player, "No, that would be silly.") - return + throw IllegalStateException() } val fPatch = FarmingPatch.forObject(target) if(fPatch == null) { sendMessage(player, "Um... I don't want to fertilize that!") - return + throw IllegalStateException() } val patch = fPatch.getPatchFor(player) if (patch.isGrown()) { sendMessage(player, "Composting isn't going to make it get any bigger.") - return + throw IllegalStateException() } if (patch.isFertilized()) { sendMessage(player, "This patch has already been composted.") - return + throw IllegalStateException() } removeRunes(player, true) animate(player, Animations.LUNAR_SPELLBOOK_FERTILE_SOIL_4413) @@ -698,11 +702,11 @@ class LunarListeners : SpellListener("lunar"), Commands { val plankType = PlankType.getForLog(item) if (plankType == null) { sendMessage(player, "You need to use this spell on logs.") - return + throw IllegalStateException() } if (amountInInventory(player, Items.COINS_995) < plankType.price || !removeItem(player, Item(Items.COINS_995, plankType.price))) { sendMessage(player, "You need ${plankType.price} coins to convert that log into a plank.") - return + throw IllegalStateException() } lock(player, 3) setDelay(player, false) @@ -717,20 +721,20 @@ class LunarListeners : SpellListener("lunar"), Commands { private fun energyTransfer(player: Player, target: Node) { if(!isPlayer(target)) { sendMessage(player, "You can only cast this spell on other players.") - return + throw IllegalStateException() } val targetPlayer = target.asPlayer() if(!targetPlayer.isActive || targetPlayer.locks.isInteractionLocked) { sendMessage(player, "This player is busy.") - return + throw IllegalStateException() } if(!targetPlayer.settings.isAcceptAid) { sendMessage(player, "This player is not accepting any aid.") - return + throw IllegalStateException() } if(10 >= player.skills.lifepoints) { sendMessage(player, "You need more hitpoints to cast this spell.") - return + throw IllegalStateException() } player.face(targetPlayer) visualizeSpell(player, Animations.LUNAR_SPELLBOOK_ENERGY_TRANSFER_4411, Graphics.LUNAR_SPELLBOOK_ENERGY_TRANSFER_738, 90, Sounds.LUNAR_ENERGY_TRANSFER_2885) 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 0bac8c9f7..dfe357ff0 100644 --- a/Server/src/main/core/game/node/entity/player/Player.java +++ b/Server/src/main/core/game/node/entity/player/Player.java @@ -4,10 +4,8 @@ import content.global.handlers.item.equipment.BarrowsEquipment; import content.global.handlers.item.equipment.special.SalamanderSwingHandler; import content.global.skill.runecrafting.PouchManager; import core.api.ContentAPIKt; -import core.api.EquipmentSlot; import core.game.component.Component; import core.game.container.Container; -import core.game.container.ContainerType; import core.game.container.impl.BankContainer; import core.game.container.impl.EquipmentContainer; import core.game.container.impl.InventoryListener; @@ -616,13 +614,8 @@ public class Player extends Entity { if (this.isArtificial() && killer instanceof NPC) { return; } - if (killer instanceof Player && killer.getName() != getName()) { // the latter happens if you died via typeless damage from an external cause, e.g. bugs in a dark cave without a light source - long unixSeconds = System.currentTimeMillis() / 1000L; - if (unixSeconds - killer.getAttribute("/save:last-murder-news", 0L) >= 300) { - Item wep = getItemFromEquipment((Player) killer, EquipmentSlot.WEAPON); - sendNews(killer.getUsername() + " has murdered " + getUsername() + " with " + (wep == null ? "their fists." : (StringUtils.isPlusN(wep.getName()) ? "an " : "a ") + wep.getName())); - killer.setAttribute("/save:last-murder-news", unixSeconds); - } + if (killer instanceof Player && !Objects.equals(killer.getName(), getName())) { // the latter happens if you died via typeless damage from an external cause, e.g. bugs in a dark cave without a light source + ContentAPIKt.sendMessage((Player) killer, "You have defeated " + getUsername() + "."); } getPacketDispatch().sendMessage("Oh dear, you are dead!"); incrementAttribute("/save:"+STATS_BASE+":"+STATS_DEATHS); diff --git a/Server/src/main/core/game/node/entity/skill/Skills.java b/Server/src/main/core/game/node/entity/skill/Skills.java index a9f1bfd5a..c545ed949 100644 --- a/Server/src/main/core/game/node/entity/skill/Skills.java +++ b/Server/src/main/core/game/node/entity/skill/Skills.java @@ -363,9 +363,6 @@ public final class Skills { int staticLevel = getStaticLevel(i); setLevel(i, staticLevel); } - if (entity instanceof Player) { - playAudio(entity.asPlayer(), Sounds.PRAYER_RECHARGE_2674); - } rechargePrayerPoints(); } diff --git a/Server/src/main/core/game/system/timer/impl/SkillRestore.kt b/Server/src/main/core/game/system/timer/impl/SkillRestore.kt index b6b456618..f14d46abe 100644 --- a/Server/src/main/core/game/system/timer/impl/SkillRestore.kt +++ b/Server/src/main/core/game/system/timer/impl/SkillRestore.kt @@ -48,7 +48,7 @@ class SkillRestore : RSTimer (1, "skillrestore", isAuto = true, isSoft = true) { (entity as? Player)?.debug("Registered skill restoration timer.") } - private fun getHealAmount (entity: Entity) : Int { + fun getHealAmount (entity: Entity) : Int { if (entity !is Player) return 1 val gloves = getItemFromEquipment (entity, EquipmentSlot.HANDS) diff --git a/Server/src/main/core/game/world/map/zone/impl/WildernessZone.java b/Server/src/main/core/game/world/map/zone/impl/WildernessZone.java index c06ba08ce..e4886e5f6 100644 --- a/Server/src/main/core/game/world/map/zone/impl/WildernessZone.java +++ b/Server/src/main/core/game/world/map/zone/impl/WildernessZone.java @@ -153,17 +153,6 @@ public final class WildernessZone extends MapZone { p.getSkullManager().setWilderness(true); p.getSkullManager().setLevel(getWilderness(p)); } - for (int i = 0; i < 7; i++) { - if (i == 5 || i == 3) { - continue; - } - if(p.getAttributes().containsKey("overload") || p.getSkills().getLevel(i) > 118){ - if (p.getSkills().getLevel(i) > p.getSkills().getStaticLevel(i)) { - p.getSkills().setLevel(i, p.getSkills().getStaticLevel(i)); - p.removeAttribute("overload"); - } - } - } if (p.getFamiliarManager().hasFamiliar() && !p.getFamiliarManager().hasPet()) { Familiar familiar = p.getFamiliarManager().getFamiliar(); familiar.transform(); diff --git a/Server/src/main/core/game/worldevents/holiday/halloween/randoms/SpiderHolidayRandomNPC.kt b/Server/src/main/core/game/worldevents/holiday/halloween/randoms/SpiderHolidayRandomNPC.kt index dea7ff063..037c9ba10 100644 --- a/Server/src/main/core/game/worldevents/holiday/halloween/randoms/SpiderHolidayRandomNPC.kt +++ b/Server/src/main/core/game/worldevents/holiday/halloween/randoms/SpiderHolidayRandomNPC.kt @@ -15,7 +15,7 @@ class SpiderHolidayRandomNPC() : HolidayRandomEventNPC(61) { this.behavior = SpiderHolidayRandomBehavior() playGlobalAudio(this.location, Sounds.SPIDER_4375) var stomped = false - queueScript(this,4, QueueStrength.SOFT) { stage: Int -> + queueScript(this, 4, QueueStrength.SOFT) { stage: Int -> when (stage) { 0 -> { sendChat(player, "Eww a spider!") @@ -32,7 +32,7 @@ class SpiderHolidayRandomNPC() : HolidayRandomEventNPC(61) { } 2 -> { if (stomped) { - impact(this, 1, ImpactHandler.HitsplatType.NORMAL) + impact(this, 2, ImpactHandler.HitsplatType.NORMAL) } else { sendMessage(player, "The spider runs away.") playGlobalAudio(this.location, Sounds.SPIDER_4375) @@ -47,4 +47,4 @@ class SpiderHolidayRandomNPC() : HolidayRandomEventNPC(61) { override fun talkTo(npc: NPC) { } -} \ No newline at end of file +}