mirror of
https://gitlab.com/2009scape/2009scape.git
synced 2026-08-21 02:15:11 -06:00
grounditem Resoawns fixed, Runner escape logic better
This commit is contained in:
parent
2437d287f2
commit
46658026cd
6 changed files with 78 additions and 30 deletions
|
|
@ -32,14 +32,20 @@ class BAGroundSpawn(private var session: BarbassaultSession, private var respawn
|
|||
fun addLureRange(addRange: Int) { lureRange += addRange }
|
||||
|
||||
override fun respawn() {
|
||||
if (!autoSpawn || respawnRate < 0)
|
||||
if (!autoSpawn || respawnRate < 0) {
|
||||
return
|
||||
}
|
||||
|
||||
GameWorld.Pulser.submit(object : Pulse(respawnRate) {
|
||||
override fun pulse(): Boolean {
|
||||
active = true
|
||||
GroundItemManager.create(this@BAGroundSpawn)
|
||||
if (!session.BAgroundItems.contains(this@BAGroundSpawn)) {
|
||||
session.BAgroundItems.add(this@BAGroundSpawn)
|
||||
}
|
||||
return true
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -191,23 +191,30 @@ class BarbassaultSession( val activity: BAActivity ? = null) :LogoutListener, M
|
|||
tracker.defenderStats.runnersPast++
|
||||
}
|
||||
}
|
||||
fun isPenanceDead( type: PenanceType): Boolean = currentNPCDeathCount[type] >= currentNPCCount[type]
|
||||
fun isPenanceDead(type: PenanceType): Boolean = currentNPCDeathCount[type] >= currentWaveDefinition.caps[type]
|
||||
fun isAllPenanceDead(): Boolean = PenanceType.values().all { isPenanceDead(it) }
|
||||
|
||||
fun runnerEscaped(runner: NPC) {
|
||||
if (!sessionNpcs.remove(runner)) {
|
||||
return
|
||||
}
|
||||
|
||||
currentNPCEscapeCount[PenanceType.RUNNER] = currentNPCEscapeCount[PenanceType.RUNNER] + 1
|
||||
val defenders = team.getPlayersByRole(BarbRole.DEFENDER)
|
||||
val penalizedPlayers = if (defenders.isEmpty()) team.allPlayers() else defenders
|
||||
penalizedPlayers.forEach { eventBus.emit(BarbAssEvent.RunnerEscaped(it)) }
|
||||
runner.clear()
|
||||
|
||||
val spawn = npcTunnel.firstOrNull { it.type == PenanceType.RUNNER } ?: return
|
||||
runner.resetWalk()
|
||||
runner.teleport(base.transform(spawn.spawnOffset))
|
||||
}
|
||||
|
||||
fun runnerKilledByTrap(runner: NPC) {
|
||||
sessionNpcs.remove(runner)
|
||||
pennanceClearedMessage(runner)
|
||||
}
|
||||
|
||||
fun pennanceClearedMessage(npc: NPC) {
|
||||
val session = getBASession(npc) ?: return
|
||||
if (npc.getAttribute("ba:npc-death-counted", false)) {
|
||||
return
|
||||
}
|
||||
npc.setAttribute("ba:npc-death-counted", true)
|
||||
val type = npc.getAttribute<PenanceType>("barbass-type")
|
||||
session.currentNPCDeathCount[type]++
|
||||
if (session.isPenanceDead(type)) {
|
||||
|
|
@ -238,17 +245,20 @@ class BarbassaultSession( val activity: BAActivity ? = null) :LogoutListener, M
|
|||
}
|
||||
|
||||
fun tryPenanceSpawn(type: PenanceType, force: Boolean = false): Boolean {
|
||||
val current = currentNPCCount[type] - currentNPCEscapeCount[type]
|
||||
val cap = currentWaveDefinition.caps[type]
|
||||
val npcId = currentWaveDefinition.npcIds[type] ?: return false
|
||||
|
||||
if (currentNPCDeathCount[type] >= cap) return false
|
||||
|
||||
val current = currentNPCCount[type]
|
||||
if (!force && current >= cap) return false
|
||||
|
||||
val spawn = npcTunnel.firstOrNull { it.type == type } ?: return false
|
||||
val npc = sessionNPCSpawn(npcId, location(30, 31, 0), spawn.direction)
|
||||
|
||||
npc?.location = base.transform(spawn.spawnOffset)
|
||||
val npc = NPC.create(npcId, base.transform(location(30, 31, 0)), spawn.direction) ?: return false
|
||||
setBASession(npc as Entity,this)
|
||||
npc.location = base.transform(spawn.spawnOffset)
|
||||
npc.init()
|
||||
sessionNpcs.add(npc)
|
||||
|
||||
currentNPCCount[type]++
|
||||
return isCaveBlocked(type)
|
||||
|
|
@ -268,20 +278,28 @@ class BarbassaultSession( val activity: BAActivity ? = null) :LogoutListener, M
|
|||
|
||||
fun pickUpGroundItem(player: Player,node:BAGroundSpawn): Boolean {
|
||||
if (player.inventory.add(node)) {
|
||||
destroyGroundItem(node)
|
||||
destroyGroundItem(node, allowRespawn = isArenaSpawnItem(node))
|
||||
return true
|
||||
}
|
||||
sendMessage(player,"You don't have enough inventory space to hold that item.")
|
||||
return false
|
||||
}
|
||||
|
||||
fun destroyGroundItem(node: BAGroundSpawn){
|
||||
fun destroyGroundItem(node: BAGroundSpawn, allowRespawn: Boolean = false){
|
||||
node.isActive = false
|
||||
node.isAutoSpawn = false
|
||||
BAgroundItems.remove(node)
|
||||
if (!allowRespawn) {
|
||||
node.isAutoSpawn = false
|
||||
BAgroundItems.remove(node)
|
||||
}
|
||||
GroundItemManager.destroy(node)
|
||||
}
|
||||
|
||||
private fun isArenaSpawnItem(node: BAGroundSpawn): Boolean {
|
||||
return arenaSpawnItems.any { spawnItem ->
|
||||
node.id == spawnItem.id && node.location == base.transform(spawnItem.location)
|
||||
}
|
||||
}
|
||||
|
||||
fun findClosestLure(target: Location): BAGroundSpawn? {
|
||||
fun distance(a: Location, b: Location): Int =Math.abs(a.x - b.x) + Math.abs(a.y - b.y)
|
||||
return BAgroundItems
|
||||
|
|
|
|||
|
|
@ -1,10 +1,11 @@
|
|||
package content.minigame.barbassault.arena.npcs
|
||||
|
||||
import content.minigame.barbassault.BA_SESSION_KEY
|
||||
import content.minigame.barbassault.applyBAPoison
|
||||
import content.minigame.barbassault.isBAPoisoned
|
||||
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
|
||||
|
|
@ -73,15 +74,16 @@ class PenanceHealerNPC : NPCBehavior(*PENANCE_HEALER_IDS) {
|
|||
|
||||
val definition = PENANCE_HEALER_DEFINITIONS_BY_ID[self.id] ?: return
|
||||
|
||||
self.getSkills().setStaticLevel(Skills.ATTACK, definition.attack)
|
||||
self.getSkills().setStaticLevel(Skills.STRENGTH, definition.strength)
|
||||
self.getSkills().setStaticLevel(Skills.DEFENCE, definition.defence)
|
||||
self.getSkills().setStaticLevel(Skills.RANGE, definition.range)
|
||||
self.getSkills().setStaticLevel(Skills.MAGIC, definition.magic)
|
||||
self.getSkills().setLevel(Skills.ATTACK, definition.attack)
|
||||
self.getSkills().setLevel(Skills.STRENGTH, definition.strength)
|
||||
self.getSkills().setLevel(Skills.DEFENCE, definition.defence)
|
||||
self.getSkills().setLevel(Skills.RANGE, definition.range)
|
||||
self.getSkills().setLevel(Skills.MAGIC, definition.magic)
|
||||
self.getSkills().setLevel(Skills.HITPOINTS, definition.hp)
|
||||
self.getSkills().setStaticLevel(Skills.HITPOINTS, definition.hp)
|
||||
|
||||
}
|
||||
//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
|
||||
|
||||
|
|
@ -113,6 +115,7 @@ class PenanceHealerNPC : NPCBehavior(*PENANCE_HEALER_IDS) {
|
|||
val target = currentTarget<Player>(self) ?: visiblePlayer(self, session)?.also { setTarget(self, it) }
|
||||
if (target == null || !isValidPlayerTarget(self, target)) {
|
||||
clearTarget(self)
|
||||
wander(self)
|
||||
return
|
||||
}
|
||||
|
||||
|
|
@ -123,17 +126,20 @@ class PenanceHealerNPC : NPCBehavior(*PENANCE_HEALER_IDS) {
|
|||
|
||||
self.resetWalk()
|
||||
self.face(target)
|
||||
target.impactHandler.manualHit(self, PLAYER_POISON_DAMAGE, ImpactHandler.HitsplatType.POISON)
|
||||
applyBAPoison(target, self, 6)
|
||||
if (!isBAPoisoned(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)
|
||||
self.setAttribute(WANDER_TICKS, 1)
|
||||
}
|
||||
|
||||
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)
|
||||
wander(self)
|
||||
return
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -67,6 +67,7 @@ class PenanceRunnerNPC : NPCBehavior(*PENANCE_RUNNER_IDS.toIntArray()) {
|
|||
return 0.0
|
||||
}
|
||||
override fun onCreation(self: NPC) {
|
||||
self.isRespawn = false
|
||||
self.isWalks = false
|
||||
self.walkRadius = 0
|
||||
self.destinationFlag
|
||||
|
|
@ -95,6 +96,7 @@ class PenanceRunnerNPC : NPCBehavior(*PENANCE_RUNNER_IDS.toIntArray()) {
|
|||
self.resetWalk()
|
||||
if (escapeRemoveTicks <= 1) {
|
||||
session.runnerEscaped(self)
|
||||
resetAfterEscape(self)
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
|
@ -321,7 +323,8 @@ class PenanceRunnerNPC : NPCBehavior(*PENANCE_RUNNER_IDS.toIntArray()) {
|
|||
}
|
||||
|
||||
private fun isAtEscapeTunnel(session: BarbassaultSession, location: Location): Boolean {
|
||||
return location.y <= escapeLocation(session).y
|
||||
val escape = escapeLocation(session)
|
||||
return location.y <= escape.y || (location.y <= escape.y + 1 && abs(location.x - escape.x) <= 2)
|
||||
}
|
||||
|
||||
private fun beginEscape(self: NPC) {
|
||||
|
|
@ -331,6 +334,19 @@ class PenanceRunnerNPC : NPCBehavior(*PENANCE_RUNNER_IDS.toIntArray()) {
|
|||
self.setAttribute(ESCAPE_REMOVE_TICKS, 1)
|
||||
}
|
||||
|
||||
private fun resetAfterEscape(self: NPC) {
|
||||
sendChat(self, "")
|
||||
clearTarget(self)
|
||||
self.removeAttribute(SKIP_NEXT_HUNT)
|
||||
self.removeAttribute(BAD_FOOD_WALK_TICKS)
|
||||
self.removeAttribute(EAT_PAUSE_TICKS)
|
||||
self.removeAttribute(ESCAPE_REMOVE_TICKS)
|
||||
self.setAttribute(MODE, RunnerMode.RANDOM_WALKING)
|
||||
self.setAttribute(MODE_TICKS, (0..4).random())
|
||||
self.setAttribute(HUNT_TICKS, (0..2).random())
|
||||
self.resetWalk()
|
||||
}
|
||||
|
||||
private fun escapeLocation(session: BarbassaultSession): Location {
|
||||
return session.base.transform(35, 15, 0)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@ import content.minigame.barbassault.getBASession
|
|||
import core.api.*
|
||||
import core.game.node.entity.Entity
|
||||
import core.game.node.entity.combat.DeathTask
|
||||
import core.game.node.entity.npc.NPC
|
||||
import core.game.node.entity.player.Player
|
||||
import core.game.system.task.Pulse
|
||||
import core.game.world.GameWorld
|
||||
|
|
@ -91,6 +92,7 @@ class DefenderTrap : MapArea {
|
|||
val bait = goodTrapBait(session, trapLocation) ?: return false
|
||||
session.destroyGroundItem(bait)
|
||||
entity.sendChat(GOOD_EAT)
|
||||
(entity as? NPC)?.let { session.runnerKilledByTrap(it) }
|
||||
killRunner(entity)
|
||||
updateTrap(scenery, trapLocation)
|
||||
session.broadcastToRole(BarbRole.DEFENDER, "A Penance Runner broke a trap to the ${trapDirectionFor(session, trapLocation)}!")
|
||||
|
|
|
|||
|
|
@ -20,13 +20,13 @@ class HealerBehavior : RoleBehavior {
|
|||
val bot = ctx.bot
|
||||
val session = ctx.session ?: return
|
||||
|
||||
ctx.insultDefender()
|
||||
if (healTeamMate(ctx, session)) return
|
||||
if (stockUp(ctx)) return
|
||||
if (fillVial(ctx)) return
|
||||
if (healSelf(ctx)) return
|
||||
if (poisonPenanceHealer(ctx, session)) return
|
||||
if (healAnyTeammate(ctx, session)) return
|
||||
ctx.insultDefender()
|
||||
|
||||
if (ctx.poolIdle("BA-Healer: Idling at pool")) return
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue