collector behavior started,

defender behavior started,
switched tick() order in SmartBABot()
DefenderInsult during idle fixed
This commit is contained in:
Tooze 2026-06-09 16:23:34 -04:00
parent 00d876485b
commit 35738bb170
8 changed files with 478 additions and 69 deletions

View file

@ -35,7 +35,7 @@ class CollectorBagManager(val player: Player) {
fun totalEggs(): Int = container.toArray().filterNotNull().sumOf { it.amount }
fun freeEggSpace(): Int = capacity - totalEggs()
fun getEggCount(itemId: Int): Int = container.toArray().filterNotNull().count { it.id == itemId }
fun getEggCount(itemId: Int): Int = container.toArray().filterNotNull().filter { it.id == itemId }.sumOf { it.amount }
}
@ -48,4 +48,4 @@ class CollectorBagManager(val player: Player) {
sendMessage(player, "You put the egg in the bag.")
return true
}
}
}

View file

@ -1,10 +1,12 @@
package content.minigame.barbassault.bots.roles
import content.minigame.barbassault.BarbRole
import content.minigame.barbassault.arena.PenanceType
import content.minigame.barbassault.arena.BarbassaultSession.AttackerStyle
import content.minigame.barbassault.bots.RoleBehavior
import content.minigame.barbassault.bots.core.BABotContext
import content.minigame.barbassault.getBASession
import core.game.node.entity.combat.DeathTask
import core.game.node.entity.Entity
import core.game.node.entity.combat.equipment.WeaponInterface.AttackStyle
import core.game.node.entity.combat.equipment.WeaponInterface.BONUS_SLASH
@ -16,13 +18,11 @@ class AttackerBehavior : RoleBehavior {
override fun tick(ctx: BABotContext) {
val bot = ctx.bot
val api = ctx.api
ctx.insultDefender()
useCalledAttackStyle(bot)
if (attackPenance(ctx)) return
if (ctx.poolIdle()) return
if (ctx.insultDefender(bot)) return
if (ctx.poolIdle("BA-Attacker: Idling at pool")) return
}
@ -36,6 +36,9 @@ class AttackerBehavior : RoleBehavior {
}
private fun checkValidTargets(target: NPC): Boolean {
if (!target.isActive()) return false
if (target.skills.lifepoints <= 0 || DeathTask.isDead(target)) return false
val penanceType = target.getAttribute<PenanceType?>("barbass-type", null)
if (penanceType != PenanceType.FIGHTER && penanceType != PenanceType.RANGER) return false
if (!target.getProperties().isMultiZone() && target.inCombat()) return false
if (!target.getDefinition().hasAction("attack")) return false
return true
@ -59,4 +62,4 @@ class AttackerBehavior : RoleBehavior {
return true
}
}
}

View file

@ -1,12 +1,18 @@
package content.minigame.barbassault.bots.core
import content.minigame.barbassault.BarbRole
import content.minigame.barbassault.arena.BAGroundSpawn
import content.minigame.barbassault.arena.BarbassaultSession
import content.minigame.barbassault.arena.PenanceType
import core.game.bots.Script
import core.game.bots.ScriptAPI
import core.game.global.action.PickupHandler
import core.game.interaction.IntType
import core.game.interaction.InteractionListeners
import core.game.node.Node
import core.game.node.entity.player.Player
import core.game.node.item.GroundItemManager
import core.game.world.map.Location
import core.game.world.map.zone.ZoneBorders
@ -18,7 +24,7 @@ class BABotContext( val bot: Player,val api: ScriptAPI ) {
var role: BarbRole? = null
private var delayTicks = 0
internal var insultNextTick = 0
private var defenderInsultNextTick = 0
var tick: Int = 0
@ -51,32 +57,103 @@ class BABotContext( val bot: Player,val api: ScriptAPI ) {
return false
}
fun poolIdle(): Boolean {
val base = session?.base ?: return false
fun poolIdle(state: String = "BA-Bot: Idling at pool"): Boolean {
val s = session ?: return false
val base = s.base
val poolArea = ZoneBorders(base.x+27, base.y+18, base.x+24, base.y+16, 0)
if (poolArea.insideBorder(bot.location)) {
return false
}
api.walkTo(poolArea.randomWalkableLoc)
bot.customState = state
api.walkTo(base.transform(25, 17, 0))
return true
}
fun insultDefender(bot: Player): Boolean {
val s = session!!
if (!s.isPenanceDead(PenanceType.HEALER) && !s.isPenanceDead(PenanceType.RANGER )&& !s.isPenanceDead(PenanceType.FIGHTER)) return false
fun sameTile(a: Location, b: Location): Boolean {
return a.x == b.x && a.y == b.y && a.z == b.z
}
fun walkToTile(loc: Location, state: String, delay: Int = 2): Boolean {
if (sameTile(bot.location, loc)) return false
bot.customState = state
api.walkTo(loc)
tickDelay(delay)
return true
}
fun findBAGroundItem(itemId: Int, spawnLoc: Location? = null): BAGroundSpawn? {
val s = session ?: return null
return s.BAgroundItems
.filter {
it.id == itemId &&
it.isActive &&
GroundItemManager.getItems().contains(it) &&
(spawnLoc == null || sameTile(it.location, spawnLoc))
}
.minByOrNull { it.location.getDistance(bot.location) }
}
fun findNearestBAGroundItem(itemId: Int, spawnLocs: List<Location>): BAGroundSpawn? {
val s = session ?: return null
return s.BAgroundItems
.filter { item ->
item.id == itemId &&
item.isActive &&
GroundItemManager.getItems().contains(item) &&
spawnLocs.any { sameTile(item.location, it) }
}
.minByOrNull { it.location.getDistance(bot.location) }
}
fun takeBAGroundItem(item: BAGroundSpawn, state: String, delay: Int = 3): Boolean {
if (walkToTile(item.location, state)) return true
bot.customState = state
val takeListener = InteractionListeners.get(item.id, IntType.GROUNDITEM.ordinal, "Take")
?: InteractionListeners.get("Take", IntType.GROUNDITEM.ordinal)
if (takeListener != null) {
takeListener.invoke(bot, item)
} else {
PickupHandler.take(bot, item)
}
tickDelay(delay)
return true
}
fun pickUpBAGroundItem(itemId: Int, spawnLoc: Location, state: String): Boolean {
val item = findBAGroundItem(itemId, spawnLoc) ?: return walkToTile(spawnLoc, state)
return takeBAGroundItem(item, state)
}
fun pickUpNearestBAGroundItem(itemId: Int, spawnLocs: List<Location>, state: String): Boolean {
val item = findNearestBAGroundItem(itemId, spawnLocs)
if (item != null) return takeBAGroundItem(item, state)
val nearestSpawn = spawnLocs.minByOrNull { it.getDistance(bot.location) } ?: return false
return walkToTile(nearestSpawn, state)
}
fun insultDefender() {
val s = session ?: return
if (!s.isPenanceDead(PenanceType.HEALER) || !s.isPenanceDead(PenanceType.RANGER) ||
!s.isPenanceDead(PenanceType.FIGHTER) || s.isPenanceDead(PenanceType.RUNNER)
) {
return
}
if (tick < defenderInsultNextTick) return
if (tick < insultNextTick) return false
val defenderInsults = listOf(
"you defend like Ryan codes Barbass",
"You defend like Ryan codes Barbass",
"R u asleep?",
"get szued",
"Get szued",
"I've seen better defense from a broken gate",
"do you even see the runners?",
"my grandma can do better then that!"
"Do you even see the runners?",
"My grandma can do better then that!"
)
api.sendChat(defenderInsults.random())
insultNextTick = tick + (8..20).random()
return true
defenderInsultNextTick = tick + (8..20).random()
}
}

View file

@ -1,25 +1,149 @@
package content.minigame.barbassault.bots.roles
import content.minigame.barbassault.BarbRole
import content.minigame.barbassault.arena.BarbassaultSession
import content.minigame.barbassault.bots.RoleBehavior
import content.minigame.barbassault.bots.core.BABotContext
import core.game.interaction.IntType
import core.game.interaction.InteractionListeners
import content.minigame.barbassault.arena.scenery.EggCannon
import core.api.amountInInventory
import core.api.freeSlots
import getCollectorBag
import org.rs09.consts.Items
import org.rs09.consts.NPCs
import org.rs09.consts.Scenery
class CollectorBehavior : RoleBehavior {
override fun tick(ctx: BABotContext) {
val bot = ctx.bot
val api = ctx.api
val session = ctx.session ?: return
ctx.script?.preventRandomIdle = true
if (ctx.insultDefender(bot)) return
ctx.insultDefender()
if (isHopperFull(session)) {
bot.customState = "BA-Collector: Hopper full, idling at cannon"
idleAtCannon(ctx)
return
}
bot.customState = "Collector"
if (hasLoadableCarriedEggs(ctx, session)) {
if (loadHopper(ctx)) return
}
val calledEgg = getCalledEgg(session) ?: run {
bot.customState = "BA-Collector: Waiting for attacker call"
idleAtCannon(ctx)
return
}
val cannon = api.getNearestNode(2213, true)
if (cannon != null) {
api.walkTo(cannon.location)
if (bot.skills.lifepoints <= MIN_SAFE_EGG_HP) {
bot.customState = "BA-Collector: Low HP (${bot.skills.lifepoints}), not picking eggs"
idleAtCannon(ctx)
return
}
if (!canHopperTake(session, calledEgg.itemId)) {
bot.customState = "BA-Collector: Hopper already full for ${calledEgg.name.lowercase()} eggs"
idleAtCannon(ctx)
return
}
if (pickUpCalledEgg(ctx, calledEgg)) return
bot.customState = "BA-Collector: No ${calledEgg.name.lowercase()} eggs nearby"
idleAtCannon(ctx)
}
private fun getCalledEgg(session: BarbassaultSession): BarbassaultSession.EggColor? {
val call = session.roleCalls[BarbRole.COLLECTOR] as? BarbassaultSession.CollectorCall
return call?.called
}
private fun loadHopper(ctx: BABotContext): Boolean {
val hopper = ctx.api.getNearestNode(Scenery.EGG_HOPPER_20264, true) ?: run {
ctx.bot.customState = "BA-Collector: Looking for egg hopper"
return false
}
if (hopper.location.getDistance(ctx.bot.location) > 2) {
ctx.bot.customState = "BA-Collector: Walking to egg hopper"
ctx.api.walkTo(hopper.location)
ctx.tickDelay(2)
return true
}
val session = ctx.session ?: return false
val redBefore = session.eggHopper.red
val carriedBefore = carriedEggCount(ctx, Items.RED_EGG_10532)
ctx.bot.customState = "BA-Collector: Loading red eggs into hopper carried=$carriedBefore hopper=$redBefore"
PRIORITY_HOPPER_EGGS.filter { carriedEggCount(ctx, it) > 0 && canHopperTake(session, it) }
.forEach { EggCannon.loadHopperEggs(ctx.bot, it) }
ctx.bot.customState = "BA-Collector: Loaded red eggs carried=$carriedBefore hopper=$redBefore->${session.eggHopper.red}"
ctx.tickDelay(5)
return true
}
private fun pickUpCalledEgg(ctx: BABotContext, calledEgg: BarbassaultSession.EggColor): Boolean {
if (!canCarryMoreEggs(ctx)) return false
val egg = ctx.findBAGroundItem(calledEgg.itemId) ?: return false
return ctx.takeBAGroundItem(
egg,
"BA-Collector: Picking up ${calledEgg.name.lowercase()} egg id=${egg.id} loc=${egg.location}"
)
}
private fun canCarryMoreEggs(ctx: BABotContext): Boolean {
return getCollectorBag(ctx.bot).bag.freeEggSpace() > 0 || freeSlots(ctx.bot) > 0
}
private fun hasLoadableCarriedEggs(ctx: BABotContext, session: BarbassaultSession): Boolean {
return PRIORITY_HOPPER_EGGS.any { carriedEggCount(ctx, it) > 0 && canHopperTake(session, it) }
}
private fun carriedEggCount(ctx: BABotContext, itemId: Int): Int {
val bot = ctx.bot
return getCollectorBag(bot).bag.getEggCount(itemId) + amountInInventory(bot, itemId)
}
private fun canHopperTake(session: BarbassaultSession, itemId: Int): Boolean {
val hopper = session.eggHopper
return when (itemId) {
Items.GREEN_EGG_10531 -> hopper.green < MAX_HOPPER_EGGS_PER_COLOR
Items.RED_EGG_10532 -> hopper.red < MAX_HOPPER_EGGS_PER_COLOR
Items.BLUE_EGG_10533 -> hopper.blue < MAX_HOPPER_EGGS_PER_COLOR
Items.OMEGA_EGG_10537 -> hopper.yellow < MAX_HOPPER_EGGS_PER_COLOR
else -> false
}
}
}
private fun isHopperFull(session: BarbassaultSession): Boolean {
val hopper = session.eggHopper
return hopper.green >= MAX_HOPPER_EGGS_PER_COLOR &&
hopper.red >= MAX_HOPPER_EGGS_PER_COLOR &&
hopper.blue >= MAX_HOPPER_EGGS_PER_COLOR
}
private fun idleAtCannon(ctx: BABotContext) {
val cannon = ctx.api.getNearestNode(NPCs.EGG_LAUNCHER_5026, false)
if (cannon != null && cannon.location.getDistance(ctx.bot.location) > 2) {
ctx.api.walkTo(cannon.location)
ctx.tickDelay(2)
return
}
val hopper = ctx.api.getNearestNode(Scenery.EGG_HOPPER_20264, true)
if (hopper != null && hopper.location.getDistance(ctx.bot.location) > 2) {
ctx.api.walkTo(hopper.location)
ctx.tickDelay(2)
}
}
private companion object {
private const val MIN_SAFE_EGG_HP = 6
private const val MAX_HOPPER_EGGS_PER_COLOR = 5
private val PRIORITY_HOPPER_EGGS = intArrayOf(Items.RED_EGG_10532)
}
}

View file

@ -1,44 +1,230 @@
package content.minigame.barbassault.bots.roles
import content.minigame.barbassault.BarbRole
import content.minigame.barbassault.LureItems
import content.minigame.barbassault.arena.BAGroundSpawn
import content.minigame.barbassault.arena.BarbassaultSession
import content.minigame.barbassault.arena.PenanceType
import content.minigame.barbassault.bots.RoleBehavior
import content.minigame.barbassault.bots.core.BABotContext
import content.minigame.barbassault.getBASession
import core.api.sendChat
import core.game.node.entity.player.Player
import core.api.getWorldTicks
import core.api.setAttribute
import core.game.node.item.Item
import core.game.world.map.Location
import core.game.world.map.RegionManager
import org.rs09.consts.Items
import org.rs09.consts.Scenery
class DefenderBehavior : RoleBehavior {
override fun tick(ctx: BABotContext) {
val bot = ctx.bot
val api = ctx.api
val session = ctx.session ?: return
ctx.script?.preventRandomIdle = true
if (!bot.walkingQueue.isMoving) {
//ctx.api.walkTo(null)
ctx.tickDelay(3)
if (session.isPenanceDead(PenanceType.RUNNER)) {
if (ctx.poolIdle("BA-Defender: Idling at pool")) return
bot.customState = "BA-Defender: Idle at pool"
return
}
if (defendInsults(ctx)) return
bot.customState = "Defender: "
val calledFood = getCalledFood(session) ?: run {
bot.customState = "BA-Defender: Waiting for healer call"
return
}
if (stockUp(ctx, session, calledFood)) return
if (repairTrap(ctx, session)) return
if (dropTrapFood(ctx, session, calledFood)) return
if (dropTrailFood(ctx, session, calledFood)) return
if (pickUpTools(ctx)) return
bot.customState = "BA-Defender: Guarding trap"
walkNearTrap(ctx, session)
}
fun defendInsults(ctx: BABotContext): Boolean {
val s = ctx.session!!
if (!s.isPenanceDead(PenanceType.HEALER) && !s.isPenanceDead(PenanceType.RANGER )&& !s.isPenanceDead(PenanceType.FIGHTER)) return false
if (ctx.tick < ctx.insultNextTick) return false
val defenderInsults = listOf(
"Have you seen the size of these things?",
"them leggs",
"get szued",
"like to see you try...",
"Where? what runners? I CANT SEEE!!",
"...",
"call the right food!"
)
ctx.api.sendChat(defenderInsults.random())
ctx.insultNextTick = ctx.tick + (8..20).random()
return true
private fun getCalledFood(session: BarbassaultSession): Int? {
val call = session.roleCalls[BarbRole.DEFENDER] as? BarbassaultSession.DefenderCall
return call?.called?.itemId
}
private fun stockUp(ctx: BABotContext, session: BarbassaultSession, calledFood: Int): Boolean {
val bot = ctx.bot
if (!needsMoreFood(session) || bot.inventory.containsAtLeastOneItem(calledFood)) {
return false
}
val machine = ctx.api.getNearestNode(Scenery.DEFENDER_ITEM_MACHINE_20242, true) ?: return false
val option = defenderMachineOption(calledFood) ?: "Stock-up"
bot.customState = "BA-Defender: Taking food id=$calledFood ($option)"
ctx.api.interact(bot, machine, option)
ctx.tickDelay(5)
return true
}
}
private fun repairTrap(ctx: BABotContext, session: BarbassaultSession): Boolean {
val bot = ctx.bot
if (!bot.inventory.containsAtLeastOneItem(Items.HAMMER_2347) || !bot.inventory.containsAtLeastOneItem(Items.LOGS_11760)) {
return false
}
val trap = RegionManager.getObject(trapLocation(session)) ?: return false
if (trap.id != Scenery.RUNNER_TRAP1_20230 && trap.id != Scenery.BROKEN_TRAP0_20231) {
return false
}
bot.customState = "BA-Defender: Repairing trap"
ctx.api.interact(bot, trap, "Fix")
ctx.tickDelay(6)
return true
}
private fun dropTrapFood(ctx: BABotContext, session: BarbassaultSession, calledFood: Int): Boolean {
val existingTrapFood = countTrapFood(session)
if (existingTrapFood >= TRAP_DROP_COUNT) return false
val botLoc = ctx.bot.location
val inTrapArea = trapTiles(session).any { sameTile(botLoc, it) }
if (!inTrapArea || hasLureFoodAt(session, botLoc)) {
val trapDropLoc = trapDropLocation(session, botLoc)
if (ctx.walkToTile(trapDropLoc, "BA-Defender: Moving to trap bait")) return true
}
if (!dropFood(ctx, session, calledFood, "BA-Defender: Dropping trap bait ${existingTrapFood + 1}/$TRAP_DROP_COUNT")) {
return false
}
return true
}
private fun dropTrailFood(ctx: BABotContext, session: BarbassaultSession, calledFood: Int): Boolean {
val nextTrail = TRAIL_SPOTS
.mapIndexed { index, offset -> index to session.base.transform(offset) }
.firstOrNull { (_, loc) -> !hasLureFoodAt(session, loc) }
?: return false
val (trailIndex, loc) = nextTrail
if (ctx.walkToTile(loc, "BA-Defender: Walking trail ${trailIndex + 1}/${TRAIL_SPOTS.size}")) return true
if (!dropFood(ctx, session, calledFood, "BA-Defender: Dropping trail food ${trailIndex + 1}/${TRAIL_SPOTS.size}")) {
return false
}
return true
}
private fun pickUpTools(ctx: BABotContext): Boolean {
val bot = ctx.bot
val base = ctx.session?.base ?: return false
if (!bot.inventory.containsAtLeastOneItem(Items.HAMMER_2347)) {
return ctx.pickUpBAGroundItem(
Items.HAMMER_2347,
base.transform(32, 42, 0),
"BA-Defender: Getting hammer"
)
}
if (!bot.inventory.containsAtLeastOneItem(Items.LOGS_11760)) {
return ctx.pickUpNearestBAGroundItem(
Items.LOGS_11760,
listOf(base.transform(30, 46, 0), base.transform(29, 47, 0)),
"BA-Defender: Getting logs"
)
}
return false
}
private fun dropFood(ctx: BABotContext, session: BarbassaultSession, foodId: Int, state: String): Boolean {
val bot = ctx.bot
val inventoryItem = bot.inventory.getItem(Item(foodId)) ?: run {
bot.customState = "$state - missing food id=$foodId"
return false
}
val item = Item(foodId, 1)
val droppedItem = item.dropItem
val requiredFood = (session.roleCalls[BarbRole.DEFENDER] as? BarbassaultSession.DefenderCall)?.required?.itemId
val isGoodFood = foodId == requiredFood
if (!bot.inventory.remove(item)) {
bot.customState = "$state - failed remove ${inventoryItem.name} id=${inventoryItem.id}"
return false
}
bot.customState = "$state - ${inventoryItem.name} id=${inventoryItem.id}"
BAGroundSpawn(session, 60, droppedItem, bot.location, isGoodFood).init()
setAttribute(bot, "droppedItem:${droppedItem.id}", getWorldTicks() + 2)
ctx.tickDelay(2)
return true
}
private fun walkNearTrap(ctx: BABotContext, session: BarbassaultSession) {
ctx.walkToTile(trapDropLocation(session, ctx.bot.location), "BA-Defender: Returning to trap")
}
private fun trapLocation(session: BarbassaultSession): Location {
return session.base.transform(45, 34, 0)
}
private fun trapDropLocation(session: BarbassaultSession, from: Location): Location {
val center = trapLocation(session)
if (!hasLureFoodAt(session, center)) return center
return trapTiles(session)
.filter { !hasLureFoodAt(session, it) }
.minByOrNull { it.getDistance(from) }
?: center
}
private fun countTrapFood(session: BarbassaultSession): Int {
val trapTiles = trapTiles(session)
return session.BAgroundItems.count {
it.id in LureItems &&
it.isActive &&
trapTiles.any { tile -> sameTile(it.location, tile) }
}
}
private fun needsMoreFood(session: BarbassaultSession): Boolean {
return countTrapFood(session) < TRAP_DROP_COUNT ||
TRAIL_SPOTS.any { !hasLureFoodAt(session, session.base.transform(it)) }
}
private fun hasLureFoodAt(session: BarbassaultSession, loc: Location): Boolean {
return session.BAgroundItems.any {
it.id in LureItems &&
it.isActive &&
sameTile(it.location, loc)
}
}
private fun sameTile(a: Location, b: Location): Boolean {
return a.x == b.x && a.y == b.y && a.z == b.z
}
private fun trapTiles(session: BarbassaultSession): List<Location> {
return trapLocation(session).get3x3Tiles()
}
private fun defenderMachineOption(foodId: Int): String? {
return when (foodId) {
Items.WORMS_10515 -> "Take-worms"
Items.CRACKERS_10513 -> "Take-crackers"
Items.TOFU_10514 -> "Take-tofu"
else -> null
}
}
private companion object {
private const val TRAP_DROP_COUNT = 2
private val TRAIL_SPOTS = listOf(
Location.create(44, 36, 0),
Location.create(41, 37, 0),
Location.create(36, 37, 0),
Location.create(34, 40, 0)
)
}
}

View file

@ -20,15 +20,17 @@ 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
if (ctx.insultDefender(bot)) return
bot.customState = "BA-Healer: Idle"
if (ctx.poolIdle("BA-Healer: Idling at pool")) return
bot.customState = "BA-Healer: Idle at pool"
}
private fun healTeamMate(ctx: BABotContext, session: BarbassaultSession): Boolean {
@ -69,8 +71,16 @@ class HealerBehavior : RoleBehavior {
}
val machine = ctx.api.getNearestNode(Scenery.HEALER_ITEM_MACHINE_20243, true) ?: return false
bot.customState = "BA-Healer: Stocking up"
ctx.api.interact(bot, machine, "Stock-up")
val healerCall = ctx.session?.roleCalls?.get(BarbRole.HEALER) as? BarbassaultSession.HealerCall
val calledPoison = healerCall?.called?.itemId
val option = when {
!hasAnyVial(bot) -> "Take-vial"
calledPoison != null && !bot.inventory.containsAtLeastOneItem(calledPoison) -> healerMachineOption(calledPoison)
else -> "Stock-up"
} ?: "Stock-up"
bot.customState = "BA-Healer: Taking supplies ($option)"
ctx.api.interact(bot, machine, option)
ctx.tickDelay(5)
return true
}
@ -108,8 +118,9 @@ class HealerBehavior : RoleBehavior {
if (!bot.inventory.containsAtLeastOneItem(poison.itemId)) {
val machine = ctx.api.getNearestNode(Scenery.HEALER_ITEM_MACHINE_20243, true) ?: return false
bot.customState = "BA-Healer: Restocking ${poison.ui}"
ctx.api.interact(bot, machine, "Stock-up")
val option = healerMachineOption(poison.itemId) ?: "Stock-up"
bot.customState = "BA-Healer: Restocking ${poison.ui} ($option)"
ctx.api.interact(bot, machine, option)
ctx.tickDelay(5)
return true
}
@ -148,6 +159,15 @@ class HealerBehavior : RoleBehavior {
!DeathTask.isDead(npc)
}
private fun healerMachineOption(foodId: Int): String? {
return when (foodId) {
Items.POISONED_TOFU_10539 -> "Take-tofu"
Items.POISONED_WORMS_10540 -> "Take-worms"
Items.POISONED_MEAT_10541 -> "Take-meat"
else -> null
}
}
private companion object {
private const val TEAM_HEAL_PERCENT = 0.65
private const val SELF_HEAL_PERCENT = 0.40

View file

@ -31,9 +31,8 @@ class LobbyBehavior : RoleBehavior {
private fun state(ctx: BABotContext): LobbyState {
val loc = ctx.bot.location
val session = getBASession(ctx.bot)
ctx.bot.debug(
"loc=$loc waiting=${isWaitingArea(loc)} halls=${isInHalls(loc)} session=${session != null}"
)
ctx.bot.debug("loc=$loc waiting=${isWaitingArea(loc)} halls=${isInHalls(loc)} session=${session != null}")
return when {
(session?.state == BarbassaultState.IN_ARENA) -> LobbyState.IN_ARENA
(session?.state == BarbassaultState.END) -> LobbyState.IN_ARENA
@ -53,8 +52,8 @@ class LobbyBehavior : RoleBehavior {
return
}
if (ctx.tick % 50 == 0) {
ctx.bot.sendChat("Cmon, we need more people!!")
if (ctx.tick % 150 == 0) {
ctx.api.sendChat("Cmon, we need more people!!")
}
}
private fun getToBA(ctx: BABotContext) {

View file

@ -70,8 +70,8 @@ class SmartBABot(l: Location) : PvMBots(l) {
}
override fun tick() {
super.tick()
brain.tick()
super.tick()
}
}