mirror of
https://gitlab.com/2009scape/2009scape.git
synced 2026-08-21 10:25:13 -06:00
penance healer logic
This commit is contained in:
parent
bffefaab30
commit
5291b13ff7
3 changed files with 209 additions and 9 deletions
|
|
@ -3,7 +3,9 @@ package content.minigame.barbassault
|
|||
import content.minigame.barbassault.arena.BarbassaultSession
|
||||
import content.minigame.barbassault.arena.PenanceType
|
||||
import core.api.getTimer
|
||||
import core.api.hasTimerActive
|
||||
import core.api.registerTimer
|
||||
import core.api.removeTimer
|
||||
import core.api.spawnTimer
|
||||
import core.game.node.entity.Entity
|
||||
import core.game.node.entity.combat.ImpactHandler
|
||||
|
|
@ -265,3 +267,13 @@ fun applyBAPoison (entity: Entity, source: Entity, severity: Int) {
|
|||
}
|
||||
}
|
||||
|
||||
fun cureBAPoison(entity: Entity) {
|
||||
if (!hasTimerActive<BAPoison>(entity)) {
|
||||
return
|
||||
}
|
||||
removeTimer<BAPoison>(entity)
|
||||
}
|
||||
|
||||
fun isBAPoisoned(entity: Entity): Boolean {
|
||||
return hasTimerActive<BAPoison>(entity)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -145,10 +145,17 @@ class BarbassaultArenaListener : InteractionListener {
|
|||
Pulser.submit(object : Pulse(3, player) {
|
||||
override fun pulse(): Boolean {
|
||||
val restoreAmount = getHealerHealAmount(player)
|
||||
val curedPoison = isBAPoisoned(player)
|
||||
heal(player, restoreAmount)
|
||||
cureBAPoison(player)
|
||||
player.settings.updateRunEnergy((-restoreAmount).toDouble())
|
||||
player.unlock()
|
||||
sendMessage(player,"You've been healed $restoreAmount hitpoints.")
|
||||
val message = if (curedPoison) {
|
||||
"You've been healed $restoreAmount hitpoints and your poison cured."
|
||||
} else {
|
||||
"You've been healed $restoreAmount hitpoints."
|
||||
}
|
||||
sendMessage(player, message)
|
||||
getBASession(player)?.updateBarbHealerIfaceHPOfPlayer(player)
|
||||
return true
|
||||
}
|
||||
|
|
@ -172,7 +179,8 @@ class BarbassaultArenaListener : InteractionListener {
|
|||
onUseWithPlayer(*All_HEALING_VIALS) { player, _, target ->
|
||||
target as Player
|
||||
//todo find Healing sound
|
||||
if (target.skills.lifepoints >= target.skills.maximumLifepoints) {
|
||||
val targetPoisoned = isBAPoisoned(target)
|
||||
if (target.skills.lifepoints >= target.skills.maximumLifepoints && !targetPoisoned) {
|
||||
sendMessage(player, "The player's hitpoints are full.")
|
||||
return@onUseWithPlayer true
|
||||
}
|
||||
|
|
@ -188,10 +196,11 @@ class BarbassaultArenaListener : InteractionListener {
|
|||
|
||||
val restoreAmount =
|
||||
minOf(getHealerHealAmount(player), target.skills.maximumLifepoints - target.skills.lifepoints)
|
||||
sendMessage(target, "You've been healed $restoreAmount hitpoints.")
|
||||
sendMessage(player, "You healed $restoreAmount hitpoints.")
|
||||
val curedPoison = isBAPoisoned(target)
|
||||
sendHealerVialMessages(player, target, restoreAmount, curedPoison)
|
||||
player.animate(Animation(537))
|
||||
heal(target, restoreAmount)
|
||||
cureBAPoison(target)
|
||||
target.settings.updateRunEnergy((-restoreAmount).toDouble())
|
||||
session?.updateBarbHealerIfaceHPOfPlayer(target)
|
||||
session?.eventBus?.emit(HitpointsHealed(player, restoreAmount))
|
||||
|
|
@ -347,6 +356,24 @@ class BarbassaultArenaListener : InteractionListener {
|
|||
val level = getBALevels(player).heal
|
||||
return healerHealAmounts.getOrElse(level) { healerHealAmounts.last() }
|
||||
}
|
||||
|
||||
private fun sendHealerVialMessages(player: Player, target: Player, restoreAmount: Int, curedPoison: Boolean) {
|
||||
when {
|
||||
restoreAmount > 0 && curedPoison -> {
|
||||
sendMessage(target, "You've been healed $restoreAmount hitpoints and your poison cured.")
|
||||
sendMessage(player, "You healed $restoreAmount hitpoints and cured their poison.")
|
||||
}
|
||||
restoreAmount > 0 -> {
|
||||
sendMessage(target, "You've been healed $restoreAmount hitpoints.")
|
||||
sendMessage(player, "You healed $restoreAmount hitpoints.")
|
||||
}
|
||||
curedPoison -> {
|
||||
sendMessage(target, "Your poison has been cured.")
|
||||
sendMessage(player, "You cured their poison.")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun fillHealerVial(player: Player){
|
||||
queueScript(player,1, QueueStrength.STRONG) {
|
||||
if (player.inventory.containsAtLeastOneItem(All_HEALING_VIALS)) {
|
||||
|
|
@ -478,4 +505,4 @@ Blocking off entrance, does NOT STOP runners entering, only slows
|
|||
Announce in game room when All of a monster has been killed
|
||||
" All of the $PENANCE Name have been killed!
|
||||
|
||||
* */
|
||||
* */
|
||||
|
|
|
|||
|
|
@ -1,15 +1,24 @@
|
|||
package content.minigame.barbassault.arena.npcs
|
||||
|
||||
import content.minigame.barbassault.arena.BarbAssEvent
|
||||
import content.minigame.barbassault.arena.BarbassaultSession
|
||||
import content.minigame.barbassault.arena.PenanceType
|
||||
import content.minigame.barbassault.BA_SESSION_KEY
|
||||
import content.minigame.barbassault.applyBAPoison
|
||||
import content.minigame.barbassault.getBASession
|
||||
import core.api.forceWalk
|
||||
import core.api.hasLineOfSight
|
||||
import core.game.node.entity.Entity
|
||||
import core.game.node.entity.combat.ImpactHandler
|
||||
import core.game.node.entity.npc.NPC
|
||||
import core.game.node.entity.npc.NPCBehavior
|
||||
import core.game.node.entity.player.Player
|
||||
import core.game.node.entity.skill.Skills
|
||||
import core.game.world.map.Location
|
||||
import core.game.world.map.RegionManager
|
||||
import core.game.world.update.flag.context.Animation
|
||||
import org.rs09.consts.NPCs
|
||||
import kotlin.math.abs
|
||||
|
||||
val PENANCE_HEALER_IDS = intArrayOf(
|
||||
//NPCs.PENANCE_HEALER_5043,//tut
|
||||
|
|
@ -33,14 +42,29 @@ val PENANCE_HEALER_DEFINITIONS = listOf(
|
|||
)
|
||||
|
||||
class PenanceHealerNPC : NPCBehavior(*PENANCE_HEALER_IDS) {
|
||||
private enum class HealerMode { TARGET_PLAYER, TARGET_RUNNER, WANDER }
|
||||
|
||||
private companion object {
|
||||
const val MODE = "ba-healer:mode"
|
||||
const val TARGET = "ba-healer:target"
|
||||
const val WANDER_TICKS = "ba-healer:wander-ticks"
|
||||
const val WANDER_MOVE_TICKS = "ba-healer:wander-move-ticks"
|
||||
|
||||
const val VISION_RANGE = 15
|
||||
const val WANDER_AFTER_ACTION_TICKS = 4
|
||||
const val WANDER_STEP_TICKS = 5
|
||||
const val PLAYER_POISON_DAMAGE = 2
|
||||
}
|
||||
|
||||
override fun getXpMultiplier(self: NPC, attacker: Entity): Double {
|
||||
return 0.0
|
||||
}
|
||||
|
||||
override fun onCreation (self: NPC) {
|
||||
self.setAttribute("barbass-type", PenanceType.HEALER)
|
||||
self.isWalks = true
|
||||
self.walkRadius = 24
|
||||
self.setAttribute(MODE, HealerMode.TARGET_PLAYER)
|
||||
self.isWalks = false
|
||||
self.walkRadius = 0
|
||||
self.isRespawn = false
|
||||
|
||||
self.properties.defenceAnimation = Animation(5105)
|
||||
|
|
@ -59,10 +83,147 @@ class PenanceHealerNPC : NPCBehavior(*PENANCE_HEALER_IDS) {
|
|||
}
|
||||
//sendMessage(player,"that's the wrong type of poisoned food to use! Penalty!")
|
||||
override fun tick(self: NPC): Boolean {
|
||||
val session = self.getAttribute<BarbassaultSession>(BA_SESSION_KEY) ?: return false
|
||||
|
||||
return true
|
||||
if (!hasLivingRunners(session)) {
|
||||
wander(self)
|
||||
self.shouldPreventStacking(self)
|
||||
return false
|
||||
}
|
||||
|
||||
val wanderTicks = self.getAttribute(WANDER_TICKS, 0)
|
||||
if (wanderTicks > 0) {
|
||||
self.setAttribute(WANDER_TICKS, wanderTicks - 1)
|
||||
wander(self)
|
||||
self.shouldPreventStacking(self)
|
||||
return false
|
||||
}
|
||||
|
||||
when (self.getAttribute(MODE, HealerMode.TARGET_PLAYER)) {
|
||||
HealerMode.TARGET_PLAYER -> tickPlayerTarget(self, session)
|
||||
HealerMode.TARGET_RUNNER -> tickRunnerTarget(self, session)
|
||||
HealerMode.WANDER -> wander(self)
|
||||
}
|
||||
|
||||
self.shouldPreventStacking(self)
|
||||
return false
|
||||
}
|
||||
|
||||
private fun tickPlayerTarget(self: NPC, session: BarbassaultSession) {
|
||||
val target = currentTarget<Player>(self) ?: visiblePlayer(self, session)?.also { setTarget(self, it) }
|
||||
if (target == null || !isValidPlayerTarget(self, target)) {
|
||||
clearTarget(self)
|
||||
return
|
||||
}
|
||||
|
||||
if (!isCloseEnough(self, target)) {
|
||||
forceWalk(self, target.location, "DUMB")
|
||||
return
|
||||
}
|
||||
|
||||
self.resetWalk()
|
||||
self.face(target)
|
||||
target.impactHandler.manualHit(self, PLAYER_POISON_DAMAGE, ImpactHandler.HitsplatType.POISON)
|
||||
applyBAPoison(target, self, 6)
|
||||
clearTarget(self)
|
||||
self.setAttribute(MODE, HealerMode.TARGET_RUNNER)
|
||||
self.setAttribute(WANDER_TICKS, WANDER_AFTER_ACTION_TICKS)
|
||||
}
|
||||
|
||||
private fun tickRunnerTarget(self: NPC, session: BarbassaultSession) {
|
||||
val target = currentTarget<NPC>(self) ?: visibleRunner(self, session)?.also { setTarget(self, it) }
|
||||
if (target == null || !isValidRunnerTarget(self, target)) {
|
||||
clearTarget(self)
|
||||
return
|
||||
}
|
||||
|
||||
if (!isCloseEnough(self, target)) {
|
||||
forceWalk(self, target.location, "DUMB")
|
||||
return
|
||||
}
|
||||
|
||||
self.resetWalk()
|
||||
self.face(target)
|
||||
target.skills.heal(target.skills.maximumLifepoints)
|
||||
clearTarget(self)
|
||||
self.setAttribute(MODE, HealerMode.TARGET_PLAYER)
|
||||
self.setAttribute(WANDER_TICKS, WANDER_AFTER_ACTION_TICKS)
|
||||
}
|
||||
|
||||
private fun visiblePlayer(self: NPC, session: BarbassaultSession): Player? {
|
||||
return session.team.allPlayers()
|
||||
.filter { isValidPlayerTarget(self, it) }
|
||||
.minByOrNull { it.location.getDistance(self.location) }
|
||||
}
|
||||
|
||||
private fun visibleRunner(self: NPC, session: BarbassaultSession): NPC? {
|
||||
return session.sessionNpcs
|
||||
.filter { isValidRunnerTarget(self, it) }
|
||||
.minByOrNull { it.location.getDistance(self.location) }
|
||||
}
|
||||
|
||||
private fun isValidPlayerTarget(self: NPC, player: Player): Boolean {
|
||||
return player.skills.lifepoints > 0 &&
|
||||
tileRadius(self.location, player.location) <= VISION_RANGE &&
|
||||
hasLineOfSight(self, player)
|
||||
}
|
||||
|
||||
private fun isValidRunnerTarget(self: NPC, runner: NPC): Boolean {
|
||||
return runner.getAttribute<PenanceType?>("barbass-type", null) == PenanceType.RUNNER &&
|
||||
runner.skills.lifepoints > 0 &&
|
||||
tileRadius(self.location, runner.location) <= VISION_RANGE &&
|
||||
hasLineOfSight(self, runner)
|
||||
}
|
||||
|
||||
private fun hasLivingRunners(session: BarbassaultSession): Boolean {
|
||||
return session.sessionNpcs.any {
|
||||
it.getAttribute<PenanceType?>("barbass-type", null) == PenanceType.RUNNER &&
|
||||
it.skills.lifepoints > 0
|
||||
}
|
||||
}
|
||||
|
||||
private fun wander(self: NPC) {
|
||||
val moveTicks = self.getAttribute(WANDER_MOVE_TICKS, 0) + 1
|
||||
if (moveTicks < WANDER_STEP_TICKS) {
|
||||
self.setAttribute(WANDER_MOVE_TICKS, moveTicks)
|
||||
return
|
||||
}
|
||||
|
||||
self.setAttribute(WANDER_MOVE_TICKS, 0)
|
||||
val destination = randomWalkableTile(self.location) ?: return
|
||||
forceWalk(self, destination, "DUMB")
|
||||
}
|
||||
|
||||
private fun randomWalkableTile(location: Location): Location? {
|
||||
val options = listOf(
|
||||
location.transform(0, 1, 0),
|
||||
location.transform(1, 0, 0),
|
||||
location.transform(0, -1, 0),
|
||||
location.transform(-1, 0, 0),
|
||||
).filter { RegionManager.isTeleportPermitted(it) }
|
||||
|
||||
return options.randomOrNull()
|
||||
}
|
||||
|
||||
private fun isCloseEnough(self: NPC, target: Entity): Boolean {
|
||||
return self.location == target.location || self.location.isNextTo(target)
|
||||
}
|
||||
|
||||
private fun tileRadius(a: Location, b: Location): Int {
|
||||
return maxOf(abs(a.x - b.x), abs(a.y - b.y))
|
||||
}
|
||||
|
||||
private fun setTarget(self: NPC, target: Entity) {
|
||||
self.setAttribute(TARGET, target)
|
||||
}
|
||||
|
||||
private inline fun <reified T : Entity> currentTarget(self: NPC): T? {
|
||||
return self.getAttribute<Entity?>(TARGET, null) as? T
|
||||
}
|
||||
|
||||
private fun clearTarget(self: NPC) {
|
||||
self.removeAttribute(TARGET)
|
||||
}
|
||||
|
||||
override fun onDeathFinished(self: NPC, killer: Entity) {
|
||||
super.onDeathFinished(self, killer)
|
||||
|
|
@ -93,4 +254,4 @@ healer_Idle_5104
|
|||
healer_hit_5105
|
||||
healer_Death_5106
|
||||
Healer_attack_5107?
|
||||
*/
|
||||
*/
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue