mirror of
https://gitlab.com/2009scape/2009scape.git
synced 2026-08-21 18:35:11 -06:00
more defender insults,
attempt at better runner logic. defender trap,
This commit is contained in:
parent
35738bb170
commit
174ae95e8b
4 changed files with 414 additions and 68 deletions
|
|
@ -57,6 +57,7 @@ class BarbassaultSession( val activity: BAActivity ? = null) :LogoutListener, M
|
|||
val sessionNpcs = mutableListOf<NPC>()
|
||||
var currentNPCCount = SpawnCaps(0,0,0,0)
|
||||
var currentNPCDeathCount = SpawnCaps(0,0,0,0)
|
||||
var currentNPCEscapeCount = SpawnCaps(0,0,0,0)
|
||||
|
||||
var npcTunnel: List<PenanceNpcTunnel> = listOf(
|
||||
PenanceNpcTunnel(PenanceType.RANGER,location(17,47,0),location(18,46,0),Direction.SOUTH),
|
||||
|
|
@ -193,6 +194,18 @@ class BarbassaultSession( val activity: BAActivity ? = null) :LogoutListener, M
|
|||
fun isPenanceDead( type: PenanceType): Boolean = currentNPCDeathCount[type] >= currentNPCCount[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()
|
||||
}
|
||||
|
||||
fun pennanceClearedMessage(npc: NPC) {
|
||||
val session = getBASession(npc) ?: return
|
||||
val type = npc.getAttribute<PenanceType>("barbass-type")
|
||||
|
|
@ -225,7 +238,7 @@ class BarbassaultSession( val activity: BAActivity ? = null) :LogoutListener, M
|
|||
}
|
||||
|
||||
fun tryPenanceSpawn(type: PenanceType, force: Boolean = false): Boolean {
|
||||
val current = currentNPCCount[type]
|
||||
val current = currentNPCCount[type] - currentNPCEscapeCount[type]
|
||||
val cap = currentWaveDefinition.caps[type]
|
||||
val npcId = currentWaveDefinition.npcIds[type] ?: return false
|
||||
|
||||
|
|
@ -625,9 +638,9 @@ class BarbassaultSession( val activity: BAActivity ? = null) :LogoutListener, M
|
|||
}
|
||||
|
||||
enum class LureFood(override val ui: String, val itemId:Int, override val hornShout:String):HasUIText {
|
||||
TOFU( "Tofu", Items.WORMS_10515, "Defender: Drop Tofu!"),
|
||||
TOFU( "Tofu", Items.TOFU_10514, "Defender: Drop Tofu!"),
|
||||
CRACKERS("Crackers",Items.CRACKERS_10513,"Defender: Drop Crackers!"),
|
||||
WORMS( "Worms", Items.TOFU_10514, "Defender: Drop Worms!");
|
||||
WORMS( "Worms", Items.WORMS_10515, "Defender: Drop Worms!");
|
||||
}
|
||||
|
||||
class AttackerCall( override val required: AttackerStyle ) : RoleCall<AttackerStyle>()
|
||||
|
|
|
|||
|
|
@ -2,17 +2,25 @@ package content.minigame.barbassault.arena.npcs
|
|||
|
||||
import content.minigame.barbassault.BA_SESSION_KEY
|
||||
import content.minigame.barbassault.BarbRole
|
||||
import content.minigame.barbassault.LureItems
|
||||
import content.minigame.barbassault.getBALevels
|
||||
import core.game.node.entity.Entity
|
||||
import core.game.node.entity.npc.NPC
|
||||
import core.game.node.entity.npc.NPCBehavior
|
||||
import org.rs09.consts.NPCs
|
||||
import content.minigame.barbassault.arena.*
|
||||
import content.minigame.barbassault.arena.scenery.DefenderTrap
|
||||
import content.minigame.barbassault.getBASession
|
||||
|
||||
import core.api.forceWalk
|
||||
import core.api.hasLineOfSight
|
||||
import core.api.sendChat
|
||||
import core.game.node.item.GroundItemManager
|
||||
import core.game.node.entity.player.Player
|
||||
import core.game.world.map.Location
|
||||
import core.game.world.map.RegionManager
|
||||
import kotlin.math.abs
|
||||
import kotlin.math.max
|
||||
|
||||
|
||||
val PENANCE_RUNNER_IDS = listOf(
|
||||
|
|
@ -32,82 +40,292 @@ class PenanceRunnerNPC : NPCBehavior(*PENANCE_RUNNER_IDS.toIntArray()) {
|
|||
val BAD_EAT = "Blurghh"
|
||||
val TRAP_HIT = "Urghhh!"
|
||||
val ESCAPE = "Raaa!!"
|
||||
var actionState = ACTION_STATE.SEEK_FOOD
|
||||
private val defenderTrap = DefenderTrap()
|
||||
|
||||
enum class ACTION_STATE { SEEK_FOOD, SEEK_PLAYER, STALLED, SEEK_ESCAPE, EATING, THINKING }
|
||||
private enum class RunnerMode { RANDOM_WALKING, HUNTING }
|
||||
|
||||
private companion object {
|
||||
const val MODE = "ba-runner:mode"
|
||||
const val MODE_TICKS = "ba-runner:mode-ticks"
|
||||
const val HUNT_TICKS = "ba-runner:hunt-ticks"
|
||||
const val TARGET = "ba-runner:target"
|
||||
const val TARGET_CYCLES = "ba-runner:target-cycles"
|
||||
const val TARGET_LAST_LOC = "ba-runner:target-last-loc"
|
||||
const val SKIP_NEXT_HUNT = "ba-runner:skip-next-hunt"
|
||||
const val BAD_FOOD_WALK_TICKS = "ba-runner:bad-food-walk-ticks"
|
||||
const val EAT_PAUSE_TICKS = "ba-runner:eat-pause-ticks"
|
||||
const val ESCAPE_REMOVE_TICKS = "ba-runner:escape-remove-ticks"
|
||||
|
||||
val HUNT_ZONE_ORDER = (0 downTo -5).flatMap { x ->
|
||||
(0 downTo -5).map { y -> x to y }
|
||||
}
|
||||
}
|
||||
|
||||
override fun getXpMultiplier(self: NPC, attacker: Entity): Double {
|
||||
return 0.0
|
||||
}
|
||||
override fun onCreation(self: NPC) {
|
||||
self.isWalks = true
|
||||
self.walkRadius = 24
|
||||
self.isWalks = false
|
||||
self.walkRadius = 0
|
||||
self.destinationFlag
|
||||
|
||||
self.setAttribute("barbass-type", PenanceType.RUNNER)
|
||||
|
||||
self.setAttribute(MODE, RunnerMode.RANDOM_WALKING)
|
||||
self.setAttribute(MODE_TICKS, (0..4).random())
|
||||
self.setAttribute(HUNT_TICKS, (0..2).random())
|
||||
}
|
||||
var stateTicks = 0
|
||||
|
||||
override fun tick(self: NPC): Boolean {
|
||||
val session = self.getAttribute<BarbassaultSession>(BA_SESSION_KEY) ?: return false
|
||||
|
||||
stateTicks++
|
||||
|
||||
if (stateTicks >= 6) {
|
||||
stateTicks = 0
|
||||
pickNewState()
|
||||
if (defenderTrap.tryTriggerTrap(self)) {
|
||||
return false
|
||||
}
|
||||
|
||||
when (actionState) {
|
||||
ACTION_STATE.SEEK_FOOD -> seekFood(self, session)
|
||||
ACTION_STATE.SEEK_PLAYER -> seekPlayers(self, session)
|
||||
ACTION_STATE.SEEK_ESCAPE -> escape(self, session)
|
||||
ACTION_STATE.STALLED -> stalled(self)
|
||||
ACTION_STATE.EATING -> eating(self)
|
||||
ACTION_STATE.THINKING -> self.resetWalk()
|
||||
val escapeRemoveTicks = self.getAttribute(ESCAPE_REMOVE_TICKS, 0)
|
||||
if (escapeRemoveTicks > 0) {
|
||||
self.setAttribute(ESCAPE_REMOVE_TICKS, escapeRemoveTicks - 1)
|
||||
self.resetWalk()
|
||||
if (escapeRemoveTicks <= 1) {
|
||||
session.runnerEscaped(self)
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
if (isAtEscapeTunnel(session, self.location)) {
|
||||
beginEscape(self)
|
||||
return false
|
||||
}
|
||||
|
||||
val eatPauseTicks = self.getAttribute(EAT_PAUSE_TICKS, 0)
|
||||
if (eatPauseTicks > 0) {
|
||||
self.setAttribute(EAT_PAUSE_TICKS, eatPauseTicks - 1)
|
||||
self.resetWalk()
|
||||
self.shouldPreventStacking(self)
|
||||
return false
|
||||
}
|
||||
|
||||
val modeChanged = tickModeTimer(self)
|
||||
tickHuntTimer(self, session)
|
||||
|
||||
val badWalkTicks = self.getAttribute(BAD_FOOD_WALK_TICKS, 0)
|
||||
if (badWalkTicks > 0) {
|
||||
self.setAttribute(BAD_FOOD_WALK_TICKS, badWalkTicks - 1)
|
||||
walkAfterBadFood(self, session)
|
||||
self.shouldPreventStacking(self)
|
||||
return false
|
||||
}
|
||||
|
||||
val target = self.getAttribute<BAGroundSpawn?>(TARGET, null)
|
||||
if (target != null) {
|
||||
chaseFood(self, session, target)
|
||||
} else if (modeChanged && self.getAttribute(MODE, RunnerMode.RANDOM_WALKING) == RunnerMode.RANDOM_WALKING) {
|
||||
randomWalk(self, session)
|
||||
}
|
||||
|
||||
self.shouldPreventStacking(self)
|
||||
return false
|
||||
}
|
||||
|
||||
private fun tickModeTimer(self: NPC): Boolean {
|
||||
val modeTicks = self.getAttribute(MODE_TICKS, 0) + 1
|
||||
if (modeTicks < 5) {
|
||||
self.setAttribute(MODE_TICKS, modeTicks)
|
||||
return false
|
||||
}
|
||||
|
||||
self.setAttribute(MODE_TICKS, 0)
|
||||
val nextMode = when (self.getAttribute(MODE, RunnerMode.RANDOM_WALKING)) {
|
||||
RunnerMode.RANDOM_WALKING -> RunnerMode.HUNTING
|
||||
RunnerMode.HUNTING -> RunnerMode.RANDOM_WALKING
|
||||
}
|
||||
|
||||
self.setAttribute(MODE, nextMode)
|
||||
if (nextMode == RunnerMode.HUNTING) {
|
||||
val targetCycles = self.getAttribute(TARGET_CYCLES, 0) + 1
|
||||
self.setAttribute(TARGET_CYCLES, targetCycles)
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
|
||||
fun seekFood(self: NPC, session: BarbassaultSession) {
|
||||
val groundItem = session.findClosestLure(self.location) ?: return
|
||||
val target = groundItem.location
|
||||
val occupied = RegionManager.getLocalEntitys(target, 0).any { it != self && it.location == target }
|
||||
|
||||
if (occupied) {
|
||||
val adjacent = target.getCardinalTiles().firstOrNull { it.isNextTo(self) }
|
||||
if (adjacent != null) { forceWalk(self, adjacent, "DUMB") }
|
||||
|
||||
self.resetWalk()
|
||||
self.faceLocation(target)
|
||||
private fun tickHuntTimer(self: NPC, session: BarbassaultSession) {
|
||||
if (self.getAttribute(MODE, RunnerMode.RANDOM_WALKING) != RunnerMode.HUNTING) {
|
||||
return
|
||||
}
|
||||
|
||||
forceWalk(self, target, "DUMB")
|
||||
val huntTicks = self.getAttribute(HUNT_TICKS, 0) + 1
|
||||
if (huntTicks < 3) {
|
||||
self.setAttribute(HUNT_TICKS, huntTicks)
|
||||
return
|
||||
}
|
||||
|
||||
if (self.location == target) {
|
||||
sendChat(self, if (groundItem.flag == true) GOOD_EAT else BAD_EAT)
|
||||
session.destroyGroundItem(groundItem)
|
||||
self.resetWalk()
|
||||
self.setAttribute(HUNT_TICKS, 0)
|
||||
if (self.getAttribute(SKIP_NEXT_HUNT, false)) {
|
||||
self.setAttribute(SKIP_NEXT_HUNT, false)
|
||||
clearTarget(self)
|
||||
return
|
||||
}
|
||||
|
||||
val currentTarget = self.getAttribute<BAGroundSpawn?>(TARGET, null)
|
||||
if (currentTarget != null && self.getAttribute(TARGET_CYCLES, 0) < 2 && isFoodStillActive(session, currentTarget)) {
|
||||
return
|
||||
}
|
||||
|
||||
selectFood(self, session)?.let { food ->
|
||||
self.setAttribute(TARGET, food)
|
||||
self.setAttribute(TARGET_CYCLES, 0)
|
||||
self.setAttribute(TARGET_LAST_LOC, food.location)
|
||||
}
|
||||
}
|
||||
fun pickNewState() {
|
||||
actionState = when ((0..2).random()) {
|
||||
0 -> ACTION_STATE.SEEK_FOOD
|
||||
1 -> ACTION_STATE.SEEK_PLAYER
|
||||
else -> ACTION_STATE.SEEK_ESCAPE
|
||||
|
||||
private fun chaseFood(self: NPC, session: BarbassaultSession, food: BAGroundSpawn) {
|
||||
val foodLocation = food.location
|
||||
if (!isFoodStillActive(session, food)) {
|
||||
clearTarget(self)
|
||||
forceWalk(self, foodLocation, "DUMB")
|
||||
return
|
||||
}
|
||||
|
||||
if (self.location == foodLocation) {
|
||||
eatFood(self, session, food)
|
||||
return
|
||||
}
|
||||
|
||||
val occupied = RegionManager.getLocalEntitys(foodLocation, 0).any { it != self && it.location == foodLocation }
|
||||
if (occupied) {
|
||||
if (!foodLocation.isNextTo(self)) {
|
||||
val adjacent = foodLocation.cardinalTiles
|
||||
.filter { RegionManager.isTeleportPermitted(it) }
|
||||
.minByOrNull { it.getDistance(self.location) }
|
||||
if (adjacent != null) {
|
||||
forceWalk(self, adjacent, "DUMB")
|
||||
}
|
||||
} else {
|
||||
self.resetWalk()
|
||||
}
|
||||
self.faceLocation(foodLocation)
|
||||
return
|
||||
}
|
||||
|
||||
forceWalk(self, foodLocation, "DUMB")
|
||||
}
|
||||
private fun escape(self: NPC, session1: BarbassaultSession) { }
|
||||
private fun stalled(self: NPC) { }
|
||||
private fun eating(self:NPC){ }
|
||||
|
||||
private fun eatFood(self: NPC, session: BarbassaultSession, food: BAGroundSpawn) {
|
||||
val goodFood = food.flag == true
|
||||
sendChat(self, if (goodFood) GOOD_EAT else BAD_EAT)
|
||||
session.destroyGroundItem(food)
|
||||
clearTarget(self)
|
||||
self.resetWalk()
|
||||
|
||||
fun seekPlayers(self: NPC,session: BarbassaultSession) {
|
||||
return
|
||||
if (goodFood) {
|
||||
self.setAttribute(EAT_PAUSE_TICKS, 5)
|
||||
if (self.getAttribute(MODE, RunnerMode.RANDOM_WALKING) == RunnerMode.HUNTING) {
|
||||
self.setAttribute(MODE, RunnerMode.RANDOM_WALKING)
|
||||
self.setAttribute(MODE_TICKS, 0)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
self.setAttribute(SKIP_NEXT_HUNT, true)
|
||||
self.setAttribute(BAD_FOOD_WALK_TICKS, 5)
|
||||
walkAfterBadFood(self, session)
|
||||
}
|
||||
|
||||
private fun selectFood(self: NPC, session: BarbassaultSession): BAGroundSpawn? {
|
||||
val radius = lureRadius(session)
|
||||
val allVisibleFood = session.BAgroundItems
|
||||
.filter { isFoodStillActive(session, it) }
|
||||
.filter { it.id in LureItems }
|
||||
.filter { hasLineOfSight(self, it) }
|
||||
|
||||
if (allVisibleFood.none { tileRadius(self.location, it.location) <= radius }) {
|
||||
return null
|
||||
}
|
||||
|
||||
for (zone in HUNT_ZONE_ORDER) {
|
||||
val food = allVisibleFood.lastOrNull { zoneFor(session, it.location) == zone }
|
||||
if (food != null) {
|
||||
return food
|
||||
}
|
||||
}
|
||||
|
||||
return null
|
||||
}
|
||||
|
||||
private fun randomWalk(self: NPC, session: BarbassaultSession) {
|
||||
val location = self.location
|
||||
val destination = if (isAtSouthernWall(session, location)) {
|
||||
furthestWalkableStraight(location, 0, -1, 5) ?: escapeLocation(session)
|
||||
} else {
|
||||
when ((0..5).random()) {
|
||||
0 -> furthestWalkableStraight(location, -1, 0, 5)
|
||||
1 -> furthestWalkableStraight(location, 1, 0, 5)
|
||||
else -> furthestWalkableStraight(location, 0, -1, 5)
|
||||
}
|
||||
} ?: return
|
||||
|
||||
forceWalk(self, destination, "DUMB")
|
||||
}
|
||||
|
||||
private fun walkAfterBadFood(self: NPC, session: BarbassaultSession) {
|
||||
val directionY = if (self.location.y >= session.base.y + 42) -1 else 1
|
||||
val destination = furthestWalkableStraight(self.location, 0, directionY, 5) ?: return
|
||||
forceWalk(self, destination, "DUMB")
|
||||
}
|
||||
|
||||
private fun lureRadius(session: BarbassaultSession): Int {
|
||||
return if (session.team.getPlayersByRole(BarbRole.DEFENDER).any { getBALevels(it).def >= 2 }) 5 else 4
|
||||
}
|
||||
|
||||
private fun isFoodStillActive(session: BarbassaultSession, food: BAGroundSpawn): Boolean {
|
||||
return food.isActive && !food.isRemoved && session.BAgroundItems.contains(food) && GroundItemManager.getItems().contains(food)
|
||||
}
|
||||
|
||||
private fun clearTarget(self: NPC) {
|
||||
self.removeAttribute(TARGET)
|
||||
self.removeAttribute(TARGET_CYCLES)
|
||||
self.removeAttribute(TARGET_LAST_LOC)
|
||||
}
|
||||
|
||||
private fun zoneFor(session: BarbassaultSession, location: Location): Pair<Int, Int> {
|
||||
val relativeX = location.x - session.base.x
|
||||
val relativeY = location.y - session.base.y
|
||||
return Math.floorDiv(relativeX - 40, 8) to Math.floorDiv(relativeY - 40, 8)
|
||||
}
|
||||
|
||||
private fun tileRadius(a: Location, b: Location): Int {
|
||||
return max(abs(a.x - b.x), abs(a.y - b.y))
|
||||
}
|
||||
|
||||
private fun furthestWalkableStraight(start: Location, dx: Int, dy: Int, maxSteps: Int): Location? {
|
||||
var destination: Location? = null
|
||||
for (step in 1..maxSteps) {
|
||||
val next = start.transform(dx * step, dy * step, 0)
|
||||
if (!RegionManager.isTeleportPermitted(next)) {
|
||||
break
|
||||
}
|
||||
destination = next
|
||||
}
|
||||
return destination
|
||||
}
|
||||
|
||||
private fun isAtSouthernWall(session: BarbassaultSession, location: Location): Boolean {
|
||||
return location.y <= session.base.y + 16
|
||||
}
|
||||
|
||||
private fun isAtEscapeTunnel(session: BarbassaultSession, location: Location): Boolean {
|
||||
return location.y <= escapeLocation(session).y
|
||||
}
|
||||
|
||||
private fun beginEscape(self: NPC) {
|
||||
sendChat(self, ESCAPE)
|
||||
clearTarget(self)
|
||||
self.resetWalk()
|
||||
self.setAttribute(ESCAPE_REMOVE_TICKS, 1)
|
||||
}
|
||||
|
||||
private fun escapeLocation(session: BarbassaultSession): Location {
|
||||
return session.base.transform(35, 15, 0)
|
||||
}
|
||||
|
||||
override fun onDeathFinished(self: NPC, killer: Entity) {
|
||||
|
|
@ -130,4 +348,4 @@ Runner emote
|
|||
runner_hit_5101
|
||||
runner_Move_5100
|
||||
runner_Idle 5099
|
||||
*/
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -1,8 +1,14 @@
|
|||
package content.minigame.barbassault.arena.scenery
|
||||
|
||||
import content.minigame.barbassault.LureItems
|
||||
import content.minigame.barbassault.BarbRole
|
||||
import content.minigame.barbassault.arena.BAGroundSpawn
|
||||
import content.minigame.barbassault.arena.BarbassaultSession
|
||||
import content.minigame.barbassault.arena.npcs.PENANCE_RUNNER_IDS
|
||||
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.player.Player
|
||||
import core.game.system.task.Pulse
|
||||
import core.game.world.GameWorld
|
||||
|
|
@ -28,23 +34,35 @@ class DefenderTrap : MapArea {
|
|||
val GOOD_EAT = "Chomp, chomp"
|
||||
val BAD_EAT = "Blurghh"
|
||||
val TRAP_HIT = "Urghhh!"
|
||||
val TRAP_EAST_ZONE: ZoneBorders = ZoneBorders(1900, 5475, 1902, 5473, 0)
|
||||
val TRAP_EAST = Location.create(1901, 5474, 0)
|
||||
val TRAP_WEST_ZONE: ZoneBorders = ZoneBorders(1870, 5474, 1872, 5472, 0)
|
||||
val TRAP_WEST = Location.create(1871, 5473, 0)
|
||||
val TRAP_EAST_ZONE: ZoneBorders = zoneFrom3x3(TRAP_EAST)
|
||||
val TRAP_WEST_ZONE: ZoneBorders = zoneFrom3x3(TRAP_WEST)
|
||||
val TRAPS_ZONE = arrayOf(TRAP_EAST_ZONE,TRAP_WEST_ZONE)
|
||||
val Fix_trap_IDs = intArrayOf( Scenery.RUNNER_TRAP1_20230, Scenery.BROKEN_TRAP0_20231 )
|
||||
val TRAPS = arrayOf(TRAP_WEST,TRAP_EAST)
|
||||
val TRAP_EAST_OFFSET = Location.create(45, 34, 0)
|
||||
val TRAP_WEST_OFFSET = Location.create(15, 33, 0)
|
||||
val playersInArea = mutableListOf<Player>()
|
||||
|
||||
override fun defineAreaBorders(): Array<ZoneBorders> {
|
||||
return TRAPS_ZONE
|
||||
}
|
||||
|
||||
private fun zoneFrom3x3(center: Location): ZoneBorders {
|
||||
val tiles = center.get3x3Tiles()
|
||||
return ZoneBorders(
|
||||
tiles.minOf { it.x },
|
||||
tiles.minOf { it.y },
|
||||
tiles.maxOf { it.x },
|
||||
tiles.maxOf { it.y },
|
||||
center.z
|
||||
)
|
||||
}
|
||||
|
||||
override fun areaEnter(entity: Entity) {
|
||||
if (PENANCE_RUNNER_IDS.contains(entity.id)) {
|
||||
killRunner(entity)
|
||||
updateTrap(entity.location)
|
||||
sendMessageArea()
|
||||
tryTriggerTrap(entity)
|
||||
}
|
||||
|
||||
val player = entity as? Player ?: return
|
||||
|
|
@ -58,37 +76,75 @@ class DefenderTrap : MapArea {
|
|||
playersInArea.remove(player)
|
||||
}
|
||||
|
||||
fun tryTriggerTrap(entity: Entity): Boolean {
|
||||
if (DeathTask.isDead(entity)) {
|
||||
return false
|
||||
}
|
||||
|
||||
val session = getBASession(entity) ?: return false
|
||||
val trapLocation = trapLocationFor(session, entity.location) ?: return false
|
||||
val scenery = getScenery(trapLocation) ?: return false
|
||||
if (scenery.id != Scenery.RUNNER_TRAP2_20135 && scenery.id != Scenery.RUNNER_TRAP1_20230) {
|
||||
return false
|
||||
}
|
||||
|
||||
val bait = goodTrapBait(session, trapLocation) ?: return false
|
||||
session.destroyGroundItem(bait)
|
||||
entity.sendChat(GOOD_EAT)
|
||||
killRunner(entity)
|
||||
updateTrap(scenery, trapLocation)
|
||||
session.broadcastToRole(BarbRole.DEFENDER, "A Penance Runner broke a trap to the ${trapDirectionFor(session, trapLocation)}!")
|
||||
sendMessageArea()
|
||||
return true
|
||||
}
|
||||
|
||||
fun killRunner(entity: Entity){
|
||||
entity.sendChat(TRAP_HIT)
|
||||
entity.startDeath(entity)
|
||||
val thistrap = Location.create(1901, 5474, 0)
|
||||
val scenery = getScenery(thistrap)
|
||||
//animateScenery(scenery!!, 5076)//5076
|
||||
|
||||
}
|
||||
|
||||
|
||||
//step on to trap area, if good food "chomp chomp" stay in location
|
||||
//set trap off
|
||||
|
||||
fun updateTrap(location: Location) {
|
||||
var thistrap = Location.create(1901, 5474, 0)
|
||||
val scenery = getScenery(thistrap)
|
||||
animateScenery(scenery!!, 5076)//5076
|
||||
fun updateTrap(scenery: core.game.node.scenery.Scenery, trapLocation: Location) {
|
||||
val nextTrap = when (scenery.id) {
|
||||
Scenery.RUNNER_TRAP2_20135 -> Scenery.RUNNER_TRAP1_20230
|
||||
Scenery.RUNNER_TRAP1_20230 -> Scenery.BROKEN_TRAP0_20231
|
||||
else -> return
|
||||
}
|
||||
|
||||
animateScenery(scenery, 5076)//5076
|
||||
GameWorld.Pulser.submit(object : Pulse(3, scenery) {
|
||||
override fun pulse(): Boolean {
|
||||
replaceScenery(scenery,Scenery.RUNNER_TRAP1_20230,-1,thistrap)
|
||||
replaceScenery(scenery, nextTrap, -1, trapLocation)
|
||||
return true
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
//replaceScenery(getScenery(thistrap)!!,Scenery.RUNNER_TRAP1_20230,-1,thistrap)
|
||||
if (TRAPS.contains(location)){
|
||||
// replaceScenery(getScenery(location)!!,Scenery.RUNNER_TRAP1_20230,40,location)
|
||||
|
||||
private fun goodTrapBait(session: BarbassaultSession, trapLocation: Location): BAGroundSpawn? {
|
||||
val trapTiles = trapLocation.get3x3Tiles()
|
||||
return session.BAgroundItems.firstOrNull {
|
||||
it.isActive &&
|
||||
!it.isRemoved &&
|
||||
it.id in LureItems &&
|
||||
it.flag == true &&
|
||||
trapTiles.contains(it.location)
|
||||
}
|
||||
}
|
||||
|
||||
private fun trapLocationFor(session: BarbassaultSession, location: Location): Location? {
|
||||
return listOf(
|
||||
session.base.transform(TRAP_EAST_OFFSET),
|
||||
session.base.transform(TRAP_WEST_OFFSET)
|
||||
).firstOrNull { trapLocation -> trapLocation.get3x3Tiles().contains(location) }
|
||||
}
|
||||
|
||||
private fun trapDirectionFor(session: BarbassaultSession, trapLocation: Location): String {
|
||||
return if (trapLocation == session.base.transform(TRAP_EAST_OFFSET)) "east" else "west"
|
||||
}
|
||||
|
||||
|
||||
fun sendMessageArea(){
|
||||
playersInArea.forEach { player ->
|
||||
|
|
|
|||
|
|
@ -150,7 +150,66 @@ class BABotContext( val bot: Player,val api: ScriptAPI ) {
|
|||
"Get szued",
|
||||
"I've seen better defense from a broken gate",
|
||||
"Do you even see the runners?",
|
||||
"My grandma can do better then that!"
|
||||
"My grandma can do better then that!",
|
||||
|
||||
"Runner escaped. Again.",
|
||||
"Nice lure, shame it did nothing.",
|
||||
"Did you place the food in Lumbridge?",
|
||||
"The runners thank you for your service.",
|
||||
"Wrong food, wrong place, classic.",
|
||||
"You had one job.",
|
||||
"The runners are speedrunning because of you.",
|
||||
"I've seen level 5s defend better.",
|
||||
"Did you forget to pick a call?",
|
||||
"The runners are literally laughing at you.",
|
||||
"Blink twice if you're AFK.",
|
||||
"That runner just waved as it passed.",
|
||||
"Maybe try feeding them the right bait?",
|
||||
"You're defending their right to escape.",
|
||||
"At this rate we'll finish next week.",
|
||||
"The healer is doing your job too.",
|
||||
"Even the collector is judging you.",
|
||||
"Attacker called. Wants their role back.",
|
||||
"No wonder nobody picks Defender.",
|
||||
"This is why Defender is always last.",
|
||||
"You make runners look smart.",
|
||||
"The trap isn't decorative, you know.",
|
||||
"Another runner escaped. Impressive.",
|
||||
"The runners have achieved freedom.",
|
||||
"I think the runners own the arena now.",
|
||||
"Outstanding performance. For the runners.",
|
||||
"The queen will hatch before you finish.",
|
||||
"Did you learn Defender from YouTube shorts?",
|
||||
"You lure like a drunk goblin.",
|
||||
"Food goes on the ground, not in your pocket.",
|
||||
"The runners aren't supposed to reach the cave.",
|
||||
"This wave is sponsored by missed runners.",
|
||||
"Your lure path looks like modern art.",
|
||||
"The runners are farming YOU for points.",
|
||||
"Defender? More like Spectator.",
|
||||
"I've seen bots defend better.",
|
||||
"The horn gave a call. Did you miss it?",
|
||||
"Wrong bait any% speedrun.",
|
||||
"You're boosting the runners' confidence.",
|
||||
"Defender is not a cosmetic role.",
|
||||
"Every escaped runner adds 5 minutes.",
|
||||
"The runners have filed for citizenship.",
|
||||
"You couldn't defend a sandwich from seagulls.",
|
||||
"The cave entrance misses you.",
|
||||
"Maybe the runners are the defenders now.",
|
||||
"The runners are following YOU.",
|
||||
"I can hear the healers crying.",
|
||||
"This is why quick-starts fail.",
|
||||
"The runner path is not a suggestion.",
|
||||
"Congratulations, you've unlocked free-range runners.",
|
||||
"One more escape and they get a pension.",
|
||||
"Your trap placement scares nobody.",
|
||||
"Did the runners bribe you?",
|
||||
"The runners are playing on easy mode.",
|
||||
"You're the reason Defender guides exist.",
|
||||
"At least you're consistently bad.",
|
||||
"The runners have stopped respecting you.",
|
||||
"Even the penance know you're lost."
|
||||
)
|
||||
api.sendChat(defenderInsults.random())
|
||||
defenderInsultNextTick = tick + (8..20).random()
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue