Corrected all four DT bosses' despawn behaviors

Added the missing music definition for the eastern half of Damis's cave
Buffed Kamil's ice barrage attack to always hit two 5s
Fixed a bug where Fareed's weapon unequip message would fire even if you did not have a weapon equipped
This commit is contained in:
Player Name 2025-08-18 12:04:40 +00:00 committed by Ryan
parent 1106cbac25
commit 12049d8ffb
6 changed files with 57 additions and 46 deletions

View file

@ -1095,6 +1095,10 @@
"region": "10829", "region": "10829",
"id": "378" "id": "378"
}, },
{
"region": "10831",
"id": "393"
},
{ {
"region": "10833", "region": "10833",
"id": "249" "id": "249"

View file

@ -14,8 +14,23 @@ import org.rs09.consts.Items
import org.rs09.consts.NPCs import org.rs09.consts.NPCs
class DamisBehavior : NPCBehavior(NPCs.DAMIS_1974, NPCs.DAMIS_1975) { class DamisBehavior : NPCBehavior(NPCs.DAMIS_1974, NPCs.DAMIS_1975) {
private var disappearing = false
var clearTime = 0 override fun tick(self: NPC): Boolean {
if (disappearing) {
return true
}
val player: Player? = getAttribute<Player?>(self, "target", null)
if (player == null || !self.location.withinDistance(self.properties.spawnLocation, self.walkRadius)) {
if (player != null && !disappearing) {
disappearing = true
sendMessage(player, "Damis has vanished once more into the shadows...")
removeAttribute(player, DesertTreasure.attributeDamisInstance)
}
poofClear(self)
}
return true
}
override fun canBeAttackedBy(self: NPC, attacker: Entity, style: CombatStyle, shouldSendMessage: Boolean): Boolean { override fun canBeAttackedBy(self: NPC, attacker: Entity, style: CombatStyle, shouldSendMessage: Boolean): Boolean {
if (attacker is Player) { if (attacker is Player) {
@ -27,19 +42,6 @@ class DamisBehavior : NPCBehavior(NPCs.DAMIS_1974, NPCs.DAMIS_1975) {
return false return false
} }
override fun tick(self: NPC): Boolean {
val player: Player? = getAttribute<Player?>(self, "target", null)
if (clearTime++ > 800) {
clearTime = 0
if (player != null) {
sendMessage(player, "Damis has vanished once more into the shadows...")
removeAttribute(player, DesertTreasure.attributeDamisInstance)
}
poofClear(self)
}
return true
}
override fun beforeDamageReceived(self: NPC, attacker: Entity, state: BattleState) { override fun beforeDamageReceived(self: NPC, attacker: Entity, state: BattleState) {
if (attacker is Player) { if (attacker is Player) {
if (state.estimatedHit + Integer.max(state.secondaryHit, 0) >= self.skills.lifepoints && self.id == NPCs.DAMIS_1974) { if (state.estimatedHit + Integer.max(state.secondaryHit, 0) >= self.skills.lifepoints && self.id == NPCs.DAMIS_1974) {
@ -65,8 +67,6 @@ class DamisBehavior : NPCBehavior(NPCs.DAMIS_1974, NPCs.DAMIS_1975) {
} }
} }
override fun onDeathFinished(self: NPC, killer: Entity) { override fun onDeathFinished(self: NPC, killer: Entity) {
if (killer is Player) { if (killer is Player) {
if (self.id == NPCs.DAMIS_1975) { if (self.id == NPCs.DAMIS_1975) {

View file

@ -20,8 +20,7 @@ import core.tools.END_DIALOGUE
import org.rs09.consts.NPCs import org.rs09.consts.NPCs
class DessousMeleeBehavior : NPCBehavior(NPCs.DESSOUS_1914, NPCs.DESSOUS_1915) { class DessousMeleeBehavior : NPCBehavior(NPCs.DESSOUS_1914, NPCs.DESSOUS_1915) {
private var disappearing = false;
var clearTime = 0
override fun canBeAttackedBy(self: NPC, attacker: Entity, style: CombatStyle, shouldSendMessage: Boolean): Boolean { override fun canBeAttackedBy(self: NPC, attacker: Entity, style: CombatStyle, shouldSendMessage: Boolean): Boolean {
if (attacker is Player) { if (attacker is Player) {
@ -34,12 +33,24 @@ class DessousMeleeBehavior : NPCBehavior(NPCs.DESSOUS_1914, NPCs.DESSOUS_1915) {
} }
override fun tick(self: NPC): Boolean{ override fun tick(self: NPC): Boolean{
if (disappearing) {
return true
}
val player: Player? = getAttribute<Player?>(self, "target", null)
if (player == null || !self.location.withinDistance(self.properties.spawnLocation, self.walkRadius)) {
if (player != null && !disappearing) {
disappearing = true
sendMessage(player, "Dessous returns to his grave, bored of toying with you.")
removeAttribute(player, DesertTreasure.attributeDessousInstance)
}
poofClear(self)
}
// Dessous just continually hisses independently of projectile fires. // Dessous just continually hisses independently of projectile fires.
if (self.id == NPCs.DESSOUS_1915 && self.properties.combatPulse.isInCombat) { if (self.id == NPCs.DESSOUS_1915 && self.properties.combatPulse.isInCombat) {
animate(self, Animation(1914)) animate(self, Animation(1914))
} }
// This is probably the prayer flicking nonsense. // This is probably the prayer flicking nonsense.
val player: Player? = getAttribute<Player?>(self, "target", null)
if (self.id == NPCs.DESSOUS_1914 && player != null && player.prayer.get(PrayerType.PROTECT_FROM_MELEE)) { if (self.id == NPCs.DESSOUS_1914 && player != null && player.prayer.get(PrayerType.PROTECT_FROM_MELEE)) {
self.transform(NPCs.DESSOUS_1915) self.transform(NPCs.DESSOUS_1915)
Graphics.send(Graphics(86), self.location) Graphics.send(Graphics(86), self.location)
@ -47,16 +58,7 @@ class DessousMeleeBehavior : NPCBehavior(NPCs.DESSOUS_1914, NPCs.DESSOUS_1915) {
self.transform(NPCs.DESSOUS_1914) self.transform(NPCs.DESSOUS_1914)
Graphics.send(Graphics(86), self.location) Graphics.send(Graphics(86), self.location)
} }
if (clearTime++ > 800) { return true
self.transform(NPCs.DESSOUS_1914)
clearTime = 0
if (player != null) {
removeAttribute(player, DesertTreasure.attributeDessousInstance)
sendMessage(player, "Dessous returns to his grave, bored of toying with you.")
}
poofClear(self)
}
return false
} }
override fun getSwingHandlerOverride(self: NPC, original: CombatSwingHandler): CombatSwingHandler { override fun getSwingHandlerOverride(self: NPC, original: CombatSwingHandler): CombatSwingHandler {

View file

@ -261,5 +261,4 @@ class ShadowDungeonAttack : MapArea {
} }
} }
} }
} }

View file

@ -14,8 +14,7 @@ import org.rs09.consts.Items
import org.rs09.consts.NPCs import org.rs09.consts.NPCs
class FareedBehavior : NPCBehavior(NPCs.FAREED_1977) { class FareedBehavior : NPCBehavior(NPCs.FAREED_1977) {
private var disappearing = false
var clearTime = 0
override fun canBeAttackedBy(self: NPC, attacker: Entity, style: CombatStyle, shouldSendMessage: Boolean): Boolean { override fun canBeAttackedBy(self: NPC, attacker: Entity, style: CombatStyle, shouldSendMessage: Boolean): Boolean {
if (attacker is Player) { if (attacker is Player) {
@ -28,10 +27,13 @@ class FareedBehavior : NPCBehavior(NPCs.FAREED_1977) {
} }
override fun tick(self: NPC): Boolean { override fun tick(self: NPC): Boolean {
if (disappearing) {
return true
}
val player: Player? = getAttribute<Player?>(self, "target", null) val player: Player? = getAttribute<Player?>(self, "target", null)
if (clearTime++ > 800) { if (player == null || !self.location.withinDistance(self.properties.spawnLocation, self.walkRadius)) {
clearTime = 0 if (player != null && !disappearing) {
if (player != null) { disappearing = true
sendMessage(player, "Fareed has lost interest in you, and returned to his flames.") sendMessage(player, "Fareed has lost interest in you, and returned to his flames.")
removeAttribute(player, DesertTreasure.attributeFareedInstance) removeAttribute(player, DesertTreasure.attributeFareedInstance)
} }
@ -50,14 +52,14 @@ class FareedBehavior : NPCBehavior(NPCs.FAREED_1977) {
if (victim is Player) { if (victim is Player) {
if (!inEquipment(victim, Items.ICE_GLOVES_1580)) { if (!inEquipment(victim, Items.ICE_GLOVES_1580)) {
val weapon = getItemFromEquipment(victim, EquipmentSlot.WEAPON) val weapon = getItemFromEquipment(victim, EquipmentSlot.WEAPON)
if(weapon != null) { if (weapon != null) {
EquipHandler.unequip(victim, EquipmentContainer.SLOT_WEAPON, weapon.id) EquipHandler.unequip(victim, EquipmentContainer.SLOT_WEAPON, weapon.id)
sendMessage(victim, "The heat from the warrior causes you to drop your weapon.")
} }
// val weapon = getItemFromEquipment(victim, EquipmentSlot.WEAPON) // val weapon = getItemFromEquipment(victim, EquipmentSlot.WEAPON)
// if(weapon != null && removeItem(victim, weapon.id, Container.EQUIPMENT)) { // if(weapon != null && removeItem(victim, weapon.id, Container.EQUIPMENT)) {
// addItemOrDrop(victim, weapon.id) // addItemOrDrop(victim, weapon.id)
// } // }
sendMessage(victim, "The heat from the warrior causes you to drop your weapon.")
} }
} }
} }
@ -72,5 +74,4 @@ class FareedBehavior : NPCBehavior(NPCs.FAREED_1977) {
} }
} }
} }
} }

View file

@ -14,8 +14,7 @@ import org.rs09.consts.NPCs
// https://www.youtube.com/watch?v=xeu6Ncmt1fY // https://www.youtube.com/watch?v=xeu6Ncmt1fY
class KamilBehavior : NPCBehavior(NPCs.KAMIL_1913) { class KamilBehavior : NPCBehavior(NPCs.KAMIL_1913) {
private var disappearing = false
var clearTime = 0
override fun canBeAttackedBy(self: NPC, attacker: Entity, style: CombatStyle, shouldSendMessage: Boolean): Boolean { override fun canBeAttackedBy(self: NPC, attacker: Entity, style: CombatStyle, shouldSendMessage: Boolean): Boolean {
if (attacker is Player) { if (attacker is Player) {
@ -28,10 +27,13 @@ class KamilBehavior : NPCBehavior(NPCs.KAMIL_1913) {
} }
override fun tick(self: NPC): Boolean { override fun tick(self: NPC): Boolean {
if (disappearing) {
return true
}
val player: Player? = getAttribute<Player?>(self, "target", null) val player: Player? = getAttribute<Player?>(self, "target", null)
if (clearTime++ > 800) { if (player == null || !self.location.withinDistance(self.properties.spawnLocation, (self.walkRadius*1.5).toInt())) {
clearTime = 0 if (player != null && !disappearing) {
if (player != null) { disappearing = true
sendMessage(player, "Kamil vanishes on an icy wind...") sendMessage(player, "Kamil vanishes on an icy wind...")
removeAttribute(player, DesertTreasure.attributeKamilInstance) removeAttribute(player, DesertTreasure.attributeKamilInstance)
} }
@ -64,16 +66,19 @@ class KamilCombatHandler: MultiSwingHandler(
// This is following RevenantCombatHandler.java, no idea if this is good. // This is following RevenantCombatHandler.java, no idea if this is good.
// I can't be bothered to fix fucking frozen. The player can hit through frozen. What the fuck is frozen for then, to glue his fucking legs??? // I can't be bothered to fix fucking frozen. The player can hit through frozen. What the fuck is frozen for then, to glue his fucking legs???
if (RandomFunction.roll(3) && !hasTimerActive(victim, "frozen") && !hasTimerActive(victim, "frozen:immunity")) { if (RandomFunction.roll(3) && !hasTimerActive(victim, "frozen") && !hasTimerActive(victim, "frozen:immunity")) {
sendChat(entity as NPC, "Sallamakar Ro!") // Salad maker roll.
impact(victim, 5)
impact(victim, 5)
registerTimer(victim, spawnTimer("frozen", 7, true)) registerTimer(victim, spawnTimer("frozen", 7, true))
sendMessage(victim, "You've been frozen!") sendMessage(victim, "You've been frozen!")
sendChat(entity as NPC, "Sallamakar Ro!") // Salad maker roll. // FIXME: before the below vfx hits, there should be another one that looks kinda like a wind wave exploding at the player's feet. Hope somebody finds the id.
sendGraphics(539, victim.location) sendGraphics(539, victim.location)
victim.properties.combatPulse.stop() // Force the victim to stop fighting. Whatever. victim.properties.combatPulse.stop() // Force the victim to stop fighting. Whatever.
// Audio? // FIXME: sfx
}else { }else {
animate(entity!!, Animation(440)) animate(entity!!, Animation(440))
} }
} }
super.impact(entity, victim, state) super.impact(entity, victim, state)
} }
} }