mirror of
https://gitlab.com/2009scape/2009scape.git
synced 2026-08-21 18:35:11 -06:00
bot bots bots bot bot bots bot Yes,.
This commit is contained in:
parent
1266a1b459
commit
00d876485b
15 changed files with 664 additions and 51 deletions
|
|
@ -1,6 +1,6 @@
|
|||
package content.minigame.barbassault
|
||||
|
||||
import content.minigame.barbassault.bots.BABot
|
||||
import content.minigame.barbassault.bots.oldbot.BABot
|
||||
import content.minigame.barbassault.lobby.BALobby
|
||||
import core.api.*
|
||||
import core.game.container.impl.EquipmentContainer
|
||||
|
|
@ -8,9 +8,14 @@ import core.game.node.item.Item
|
|||
import core.game.system.command.Privilege
|
||||
import core.game.system.command.sets.CommandSet
|
||||
import core.game.world.map.Location
|
||||
import core.game.world.repository.Repository
|
||||
import core.plugin.Initializable
|
||||
import org.rs09.consts.Items
|
||||
import org.rs09.consts.Scenery
|
||||
import content.minigame.barbassault.bots.SmartBAPlayerScript
|
||||
import content.minigame.barbassault.bots.SmartBABot
|
||||
import core.game.bots.AIPlayer
|
||||
import core.game.bots.GeneralBotCreator
|
||||
|
||||
@Initializable
|
||||
class BADevHelper : CommandSet(Privilege.ADMIN) {
|
||||
|
|
@ -74,6 +79,48 @@ class BADevHelper : CommandSet(Privilege.ADMIN) {
|
|||
return@define
|
||||
|
||||
}
|
||||
define("smartbabot") { player, _ ->
|
||||
if (babotcount >= 25) {
|
||||
sendMessage(player, "25 is max amount of BA bots allowed")
|
||||
return@define
|
||||
}
|
||||
|
||||
SmartBABot(BALobby.MAIN_LOBBY.randomWalkableLoc)
|
||||
|
||||
babotcount++
|
||||
sendMessage(player, "Spawned Smart BA bot.")
|
||||
return@define
|
||||
}
|
||||
|
||||
define("smartbaplayer") { player, _ ->
|
||||
GeneralBotCreator(SmartBAPlayerScript(), player, true)
|
||||
sendMessage(player, "Started Smart BA bot script on your player.")
|
||||
return@define
|
||||
}
|
||||
|
||||
define("babotstate") { player, args ->
|
||||
val nameFilter = args.getOrNull(1)?.lowercase()
|
||||
val bots = Repository.players
|
||||
.filterIsInstance<AIPlayer>()
|
||||
.filter { nameFilter == null || it.username.lowercase().contains(nameFilter) }
|
||||
|
||||
val bot = bots.minByOrNull { it.location.getDistance(player.location) }
|
||||
if (bot == null) {
|
||||
sendMessage(player, "No BA bot found.")
|
||||
return@define
|
||||
}
|
||||
|
||||
sendMessage(player, "${bot.username}: ${bot.customState} : loc: ${bot.location}")
|
||||
return@define
|
||||
}
|
||||
define("iswait"){player,_ ->
|
||||
val iswait = BALobby.isWaitingArea(player.location)
|
||||
sendMessage(player,"isWaiting : ${iswait}")
|
||||
}
|
||||
define("ishall"){player,_ ->
|
||||
val ishall = BALobby.isInHalls(player.location)
|
||||
sendMessage(player,"isInhall : ${ishall}")
|
||||
}
|
||||
|
||||
define("hch"){ player,args->
|
||||
val chId = args[1].toIntOrNull()
|
||||
|
|
@ -178,4 +225,4 @@ class BADevHelper : CommandSet(Privilege.ADMIN) {
|
|||
return@define
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -56,7 +56,7 @@ class BAHornSystem : InteractionListener {
|
|||
when (optionClicked) {
|
||||
"tell-red" -> eggToTell = BarbassaultSession.EggColor.RED
|
||||
"tell-green" -> eggToTell = BarbassaultSession.EggColor.GREEN
|
||||
"tell-blue" -> eggToTell = BarbassaultSession.EggColor.RED
|
||||
"tell-blue" -> eggToTell = BarbassaultSession.EggColor.BLUE
|
||||
"drop" -> { sendMessage(player, "I need that!");return@on true }
|
||||
"medic" -> { sendChat(player, "Medic!"); session.alertHealers(player);return@on true }
|
||||
}
|
||||
|
|
|
|||
|
|
@ -47,7 +47,6 @@ data class PenanceNpcTunnel( val type: PenanceType, val caveLocation: Location,
|
|||
data class ArenaSpawnItems(val id: Int, val location: Location)
|
||||
|
||||
class BarbassaultSession( val activity: BAActivity ? = null) :LogoutListener, MapArea {
|
||||
//constructor(region: DynamicRegion, activity: BarbassaultActivity) : this(activity) {this.region = region; this.base = region.baseLocation}
|
||||
lateinit var region: DynamicRegion
|
||||
lateinit var base: Location
|
||||
lateinit var currentWaveDefinition: WaveDefinition
|
||||
|
|
@ -76,11 +75,10 @@ class BarbassaultSession( val activity: BAActivity ? = null) :LogoutListener, M
|
|||
val scoreManager = BarbScoreManager()
|
||||
val eventBus = BarbAssEventBus()
|
||||
|
||||
private val countDoown = if(GameWorld.settings?.isDevMode == true) 10 else 30
|
||||
private var countDoown = if(GameWorld.settings?.isDevMode == true) 10 else 30
|
||||
private var countdownPulse: Pulse? = null
|
||||
|
||||
|
||||
|
||||
fun beginStartingPhase(quickStart: Boolean = false) {
|
||||
if (state != BarbassaultState.PARTY_CREATION) return
|
||||
state = BarbassaultState.STARTING
|
||||
|
|
@ -133,7 +131,8 @@ class BarbassaultSession( val activity: BAActivity ? = null) :LogoutListener, M
|
|||
}
|
||||
|
||||
private fun startCountdown(quickStart: Boolean) {
|
||||
var ticks = secondsToTicks(countDoown)//60
|
||||
countDoown = if (quickStart) 1 else countDoown
|
||||
var ticks = secondsToTicks(countDoown)//30
|
||||
if(!quickStart){ team.allPlayers().forEach { openOverlay(it, 494);setInterfaceText(it, "30", 494, 0) } }
|
||||
countdownPulse = object : Pulse(1) {
|
||||
override fun pulse(): Boolean {
|
||||
|
|
@ -149,8 +148,9 @@ class BarbassaultSession( val activity: BAActivity ? = null) :LogoutListener, M
|
|||
|
||||
val secondsLeft = ticksToSeconds(ticks)
|
||||
val display = secondsLeft.toString().padStart(2, '0')
|
||||
|
||||
team.allPlayers().forEach { setInterfaceText(it, display, 494, 0) }
|
||||
if(!quickStart) {
|
||||
team.allPlayers().forEach { setInterfaceText(it, display, 494, 0) }
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
|
@ -190,11 +190,14 @@ class BarbassaultSession( val activity: BAActivity ? = null) :LogoutListener, M
|
|||
tracker.defenderStats.runnersPast++
|
||||
}
|
||||
}
|
||||
fun isPenanceDead( type: PenanceType): Boolean = currentNPCDeathCount[type] >= currentNPCCount[type]
|
||||
fun isAllPenanceDead(): Boolean = PenanceType.values().all { isPenanceDead(it) }
|
||||
|
||||
fun pennanceClearedMessage(npc: NPC) {
|
||||
val session = getBASession(npc) ?: return
|
||||
val type = npc.getAttribute<PenanceType>("barbass-type")
|
||||
session.currentNPCDeathCount[type]++
|
||||
if (session.currentNPCDeathCount[type] == session.currentWaveDefinition.caps[type]) {
|
||||
if (session.isPenanceDead(type)) {
|
||||
type.toString()
|
||||
session.broadcast("All of the Penance ${type.name.lowercase().replaceFirstChar { it.uppercase() }}s have been killed!")
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,62 @@
|
|||
package content.minigame.barbassault.bots.roles
|
||||
|
||||
import content.minigame.barbassault.BarbRole
|
||||
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.Entity
|
||||
import core.game.node.entity.combat.equipment.WeaponInterface.AttackStyle
|
||||
import core.game.node.entity.combat.equipment.WeaponInterface.BONUS_SLASH
|
||||
import core.game.node.entity.npc.NPC
|
||||
import core.game.node.entity.player.Player
|
||||
|
||||
class AttackerBehavior : RoleBehavior {
|
||||
|
||||
override fun tick(ctx: BABotContext) {
|
||||
|
||||
val bot = ctx.bot
|
||||
val api = ctx.api
|
||||
|
||||
useCalledAttackStyle(bot)
|
||||
if (attackPenance(ctx)) return
|
||||
if (ctx.poolIdle()) return
|
||||
if (ctx.insultDefender(bot)) return
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
private fun useCalledAttackStyle(bot: Player) {
|
||||
val baSession = getBASession(bot) ?: return
|
||||
val called = (baSession.roleCalls[BarbRole.ATTACKER]?.called ?: AttackerStyle.values().random() ) as AttackerStyle
|
||||
if (bot.properties.attackStyle.style == called.attackStyle) return
|
||||
|
||||
bot.properties.attackStyle = AttackStyle(called.attackStyle, BONUS_SLASH)
|
||||
}
|
||||
private fun checkValidTargets(target: NPC): Boolean {
|
||||
if (!target.isActive()) return false
|
||||
if (!target.getProperties().isMultiZone() && target.inCombat()) return false
|
||||
if (!target.getDefinition().hasAction("attack")) return false
|
||||
return true
|
||||
}
|
||||
private fun findTargets(entity: Entity): List<Entity> = getBASession(entity)?.sessionNpcs?.filter { checkValidTargets(it) }?.sortedBy { it.location.getDistance(entity.location) }?.take(5)?: emptyList()
|
||||
|
||||
fun attackPenance(ctx: BABotContext): Boolean {
|
||||
val bot = ctx.bot
|
||||
if (bot.inCombat()) return true
|
||||
var target = ctx.currentTarget as? Entity
|
||||
|
||||
if (target != null && !checkValidTargets(target as NPC)) { ctx.currentTarget = null; target = null }
|
||||
|
||||
if (target == null) {
|
||||
target = findTargets(bot).firstOrNull { !it.inCombat() }?: findTargets(bot).firstOrNull()
|
||||
if (target == null) return false
|
||||
ctx.currentTarget = target
|
||||
}
|
||||
|
||||
bot.attack(target)
|
||||
return true
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,82 @@
|
|||
package content.minigame.barbassault.bots.core
|
||||
|
||||
import content.minigame.barbassault.BarbRole
|
||||
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.node.Node
|
||||
import core.game.node.entity.player.Player
|
||||
import core.game.world.map.zone.ZoneBorders
|
||||
|
||||
|
||||
|
||||
class BABotContext( val bot: Player,val api: ScriptAPI ) {
|
||||
var currentTarget: Node? = null
|
||||
var script: Script? = null
|
||||
var session: BarbassaultSession? = null
|
||||
var role: BarbRole? = null
|
||||
|
||||
private var delayTicks = 0
|
||||
internal var insultNextTick = 0
|
||||
|
||||
var tick: Int = 0
|
||||
|
||||
fun tickDelay(ticks: Int) { delayTicks = ticks }
|
||||
|
||||
fun processDelay(): Boolean {
|
||||
if (delayTicks > 0) {
|
||||
delayTicks--
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
fun clickDialogueOption(buttonId: Int): Boolean {
|
||||
val chatbox = bot.interfaceManager.chatbox ?: return false
|
||||
|
||||
val action = bot.dialogueInterpreter.actions.removeFirstOrNull()
|
||||
if (action != null) {
|
||||
action.handle(bot, buttonId)
|
||||
bot.interfaceManager.closeChatbox()
|
||||
bot.dialogueInterpreter.close()
|
||||
return true
|
||||
}
|
||||
|
||||
if (bot.dialogueInterpreter.dialogue != null) {
|
||||
bot.dialogueInterpreter.handle(chatbox.id, buttonId)
|
||||
return true
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
fun poolIdle(): Boolean {
|
||||
val base = session?.base ?: return false
|
||||
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)
|
||||
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
|
||||
|
||||
if (tick < insultNextTick) return false
|
||||
val defenderInsults = listOf(
|
||||
"you defend like Ryan codes Barbass",
|
||||
"R u asleep?",
|
||||
"get szued",
|
||||
"I've seen better defense from a broken gate",
|
||||
"do you even see the runners?",
|
||||
"my grandma can do better then that!"
|
||||
)
|
||||
api.sendChat(defenderInsults.random())
|
||||
insultNextTick = tick + (8..20).random()
|
||||
return true
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,25 @@
|
|||
package content.minigame.barbassault.bots.roles
|
||||
|
||||
import content.minigame.barbassault.bots.RoleBehavior
|
||||
import content.minigame.barbassault.bots.core.BABotContext
|
||||
import core.game.interaction.IntType
|
||||
import core.game.interaction.InteractionListeners
|
||||
|
||||
class CollectorBehavior : RoleBehavior {
|
||||
|
||||
override fun tick(ctx: BABotContext) {
|
||||
|
||||
val bot = ctx.bot
|
||||
val api = ctx.api
|
||||
|
||||
if (ctx.insultDefender(bot)) return
|
||||
|
||||
bot.customState = "Collector"
|
||||
|
||||
|
||||
val cannon = api.getNearestNode(2213, true)
|
||||
if (cannon != null) {
|
||||
api.walkTo(cannon.location)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,44 @@
|
|||
package content.minigame.barbassault.bots.roles
|
||||
|
||||
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.game.world.map.Location
|
||||
|
||||
class DefenderBehavior : RoleBehavior {
|
||||
|
||||
override fun tick(ctx: BABotContext) {
|
||||
val bot = ctx.bot
|
||||
val api = ctx.api
|
||||
|
||||
if (!bot.walkingQueue.isMoving) {
|
||||
//ctx.api.walkTo(null)
|
||||
ctx.tickDelay(3)
|
||||
}
|
||||
if (defendInsults(ctx)) return
|
||||
|
||||
bot.customState = "Defender: "
|
||||
}
|
||||
|
||||
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
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,176 @@
|
|||
package content.minigame.barbassault.bots.roles
|
||||
|
||||
import content.minigame.barbassault.BarbRole
|
||||
import content.minigame.barbassault.arena.BarbassaultSession
|
||||
import content.minigame.barbassault.arena.npcs.PENANCE_HEALER_IDS
|
||||
import content.minigame.barbassault.bots.RoleBehavior
|
||||
import content.minigame.barbassault.bots.core.BABotContext
|
||||
import core.game.interaction.IntType
|
||||
import core.game.interaction.InteractionListeners
|
||||
import core.game.node.entity.combat.DeathTask
|
||||
import core.game.node.entity.npc.NPC
|
||||
import core.game.node.entity.player.Player
|
||||
import core.game.node.item.Item
|
||||
import org.rs09.consts.Items
|
||||
import org.rs09.consts.Scenery
|
||||
|
||||
class HealerBehavior : RoleBehavior {
|
||||
|
||||
override fun tick(ctx: BABotContext) {
|
||||
val bot = ctx.bot
|
||||
val session = ctx.session ?: return
|
||||
|
||||
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"
|
||||
}
|
||||
|
||||
private fun healTeamMate(ctx: BABotContext, session: BarbassaultSession): Boolean {
|
||||
val bot = ctx.bot
|
||||
val target = session.team.allPlayers()
|
||||
.filter { it != bot && healthPercent(it) <= TEAM_HEAL_PERCENT && it.skills.lifepoints > 0 }
|
||||
.minByOrNull { healthPercent(it) }
|
||||
?: return false
|
||||
|
||||
val vial = getBestUsableVial(bot) ?: return false
|
||||
bot.customState = "BA-Healer: Healing ${target.username} (${target.skills.lifepoints}/${target.skills.maximumLifepoints})"
|
||||
InteractionListeners.run(vial, target, IntType.PLAYER, bot)
|
||||
ctx.tickDelay(3)
|
||||
return true
|
||||
}
|
||||
private fun healAnyTeammate(ctx: BABotContext, session: BarbassaultSession): Boolean {
|
||||
val bot = ctx.bot
|
||||
|
||||
val target = session.team.allPlayers()
|
||||
.filter { it != bot && it.skills.lifepoints > 0 }
|
||||
.minByOrNull { healthPercent(it) }
|
||||
?: return false
|
||||
|
||||
val vial = getBestUsableVial(bot) ?: return false
|
||||
if (healthPercent(target) >= 0.95) return false
|
||||
|
||||
bot.customState = "BA-Healer: Idle-heal ${target.username}"
|
||||
InteractionListeners.run(vial, target, IntType.PLAYER, bot)
|
||||
ctx.tickDelay(2)
|
||||
return true
|
||||
}
|
||||
|
||||
private fun stockUp(ctx: BABotContext): Boolean {
|
||||
val bot = ctx.bot
|
||||
|
||||
if (hasAnyVial(bot) && POISON_FOODS.any { bot.inventory.containsAtLeastOneItem(it) }) {
|
||||
return false
|
||||
}
|
||||
|
||||
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")
|
||||
ctx.tickDelay(5)
|
||||
return true
|
||||
}
|
||||
|
||||
private fun fillVial(ctx: BABotContext): Boolean {
|
||||
val bot = ctx.bot
|
||||
|
||||
if (!hasAnyVial(bot) || bot.inventory.containsAtLeastOneItem(Items.HEALING_VIAL4_10542)) {
|
||||
return false
|
||||
}
|
||||
|
||||
val spring = ctx.api.getNearestNode(Scenery.HEALER_SPRING_20150, true) ?: return false
|
||||
bot.customState = "BA-Healer: Filling vial"
|
||||
ctx.api.interact(bot, spring, "Take-from")
|
||||
ctx.tickDelay(4)
|
||||
return true
|
||||
}
|
||||
|
||||
private fun healSelf(ctx: BABotContext): Boolean {
|
||||
val bot = ctx.bot
|
||||
|
||||
if (healthPercent(bot) > SELF_HEAL_PERCENT) return false
|
||||
|
||||
val spring = ctx.api.getNearestNode(Scenery.HEALER_SPRING_20150, true) ?: return false
|
||||
bot.customState = "BA-Healer: Drinking from spring"
|
||||
ctx.api.interact(bot, spring, "Drink-from")
|
||||
ctx.tickDelay(5)
|
||||
return true
|
||||
}
|
||||
|
||||
private fun poisonPenanceHealer(ctx: BABotContext, session: BarbassaultSession): Boolean {
|
||||
val bot = ctx.bot
|
||||
val poison = (session.roleCalls[BarbRole.HEALER] as? BarbassaultSession.HealerCall)?.called
|
||||
?: return false
|
||||
|
||||
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")
|
||||
ctx.tickDelay(5)
|
||||
return true
|
||||
}
|
||||
|
||||
val target = session.sessionNpcs
|
||||
.filter { isValidPenanceHealer(it) }
|
||||
.minByOrNull { it.location.getDistance(bot.location) }
|
||||
?: return false
|
||||
|
||||
bot.customState = "BA-Healer: Poisoning ${target.name} with ${poison.ui}"
|
||||
ctx.api.useWith(bot, poison.itemId, target)
|
||||
ctx.tickDelay(3)
|
||||
return true
|
||||
}
|
||||
|
||||
private fun getBestUsableVial(player: Player): Item? {
|
||||
return USABLE_HEALING_VIALS
|
||||
.firstOrNull { player.inventory.containsAtLeastOneItem(it) }
|
||||
?.let { player.inventory.getItem(Item(it)) }
|
||||
}
|
||||
|
||||
private fun hasAnyVial(player: Player): Boolean {
|
||||
return ALL_HEALING_VIALS.any { player.inventory.containsAtLeastOneItem(it) }
|
||||
}
|
||||
|
||||
private fun healthPercent(player: Player): Double {
|
||||
val max = player.skills.maximumLifepoints
|
||||
if (max <= 0) return 1.0
|
||||
return player.skills.lifepoints.toDouble() / max.toDouble()
|
||||
}
|
||||
|
||||
private fun isValidPenanceHealer(npc: NPC): Boolean {
|
||||
return npc.id in PENANCE_HEALER_IDS &&
|
||||
npc.isActive &&
|
||||
npc.skills.lifepoints > 0 &&
|
||||
!DeathTask.isDead(npc)
|
||||
}
|
||||
|
||||
private companion object {
|
||||
private const val TEAM_HEAL_PERCENT = 0.65
|
||||
private const val SELF_HEAL_PERCENT = 0.40
|
||||
|
||||
private val ALL_HEALING_VIALS = intArrayOf(
|
||||
Items.HEALING_VIAL_10546,
|
||||
Items.HEALING_VIAL1_10545,
|
||||
Items.HEALING_VIAL2_10544,
|
||||
Items.HEALING_VIAL3_10543,
|
||||
Items.HEALING_VIAL4_10542
|
||||
)
|
||||
|
||||
private val USABLE_HEALING_VIALS = intArrayOf(
|
||||
Items.HEALING_VIAL4_10542,
|
||||
Items.HEALING_VIAL3_10543,
|
||||
Items.HEALING_VIAL2_10544,
|
||||
Items.HEALING_VIAL1_10545
|
||||
)
|
||||
|
||||
private val POISON_FOODS = intArrayOf(
|
||||
Items.POISONED_TOFU_10539,
|
||||
Items.POISONED_WORMS_10540,
|
||||
Items.POISONED_MEAT_10541
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,88 @@
|
|||
package content.minigame.barbassault.bots
|
||||
|
||||
import content.minigame.barbassault.arena.BarbassaultState
|
||||
import content.minigame.barbassault.bots.core.BABotContext
|
||||
import content.minigame.barbassault.getBASession
|
||||
|
||||
import content.minigame.barbassault.lobby.BALobby
|
||||
import content.minigame.barbassault.lobby.BALobby.Companion.QUICK_START
|
||||
import core.game.world.map.Location
|
||||
import org.rs09.consts.Scenery
|
||||
|
||||
|
||||
class LobbyBehavior : RoleBehavior {
|
||||
private enum class LobbyState { GET_TO_BA, FINDING_ROOM, WAITING_IN_ROOM,IN_ARENA }
|
||||
|
||||
|
||||
override fun tick(ctx: BABotContext) {
|
||||
|
||||
val state = state(ctx)
|
||||
ctx.bot.customState = "BA-Lobby: $state"
|
||||
ctx.bot.debug("$state")
|
||||
|
||||
when (state) {
|
||||
LobbyState.GET_TO_BA -> getToBA(ctx)
|
||||
LobbyState.FINDING_ROOM -> enterRoom(ctx)
|
||||
LobbyState.WAITING_IN_ROOM -> waitingInRoom(ctx)
|
||||
LobbyState.IN_ARENA -> return
|
||||
}
|
||||
}
|
||||
|
||||
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}"
|
||||
)
|
||||
return when {
|
||||
(session?.state == BarbassaultState.IN_ARENA) -> LobbyState.IN_ARENA
|
||||
(session?.state == BarbassaultState.END) -> LobbyState.IN_ARENA
|
||||
(session?.state == BarbassaultState.COMPLETE) -> LobbyState.IN_ARENA
|
||||
isWaitingQuick(loc) -> LobbyState.WAITING_IN_ROOM
|
||||
isWaitingArea(loc) && (session != null) -> LobbyState.WAITING_IN_ROOM
|
||||
isInHalls(loc) -> LobbyState.FINDING_ROOM
|
||||
|
||||
else -> LobbyState.GET_TO_BA
|
||||
}
|
||||
}
|
||||
|
||||
private fun waitingInRoom(ctx: BABotContext) {
|
||||
if (ctx.tick % 12 == 0 && !ctx.bot.walkingQueue.isMoving) {
|
||||
ctx.api.walkTo(QUICK_START.randomWalkableLoc)
|
||||
ctx.tickDelay(3)
|
||||
return
|
||||
}
|
||||
|
||||
if (ctx.tick % 50 == 0) {
|
||||
ctx.bot.sendChat("Cmon, we need more people!!")
|
||||
}
|
||||
}
|
||||
private fun getToBA(ctx: BABotContext) {
|
||||
ctx.bot.teleport(BALobby.MAIN_LOBBY.randomWalkableLoc)
|
||||
ctx.tickDelay(4)
|
||||
}
|
||||
|
||||
private fun enterRoom(ctx: BABotContext) {
|
||||
if (ctx.bot.interfaceManager.hasChatbox()) {
|
||||
ctx.clickDialogueOption(6)
|
||||
ctx.tickDelay(8)
|
||||
return
|
||||
}
|
||||
val quickDoor = ctx.api.getNearestNode(Scenery.DOOR_20209, true)
|
||||
ctx.api.interact(ctx.bot, quickDoor, "Pass")
|
||||
ctx.tickDelay(16)
|
||||
|
||||
}
|
||||
|
||||
private fun isInHalls(location: Location): Boolean {
|
||||
return BALobby.isInHalls(location)
|
||||
}
|
||||
|
||||
private fun isWaitingQuick(location: Location): Boolean {
|
||||
return QUICK_START.insideBorder(location)
|
||||
}
|
||||
private fun isWaitingArea(location: Location): Boolean {
|
||||
return BALobby.isWaitingArea(location)
|
||||
}
|
||||
|
||||
}
|
||||
100
Server/src/main/content/minigame/barbassault/bots/SmartBABot.kt
Normal file
100
Server/src/main/content/minigame/barbassault/bots/SmartBABot.kt
Normal file
|
|
@ -0,0 +1,100 @@
|
|||
package content.minigame.barbassault.bots
|
||||
|
||||
import content.minigame.barbassault.BarbRole
|
||||
import content.minigame.barbassault.arena.BarbassaultState
|
||||
import content.minigame.barbassault.bots.core.BABotContext
|
||||
import content.minigame.barbassault.bots.roles.AttackerBehavior
|
||||
import content.minigame.barbassault.bots.roles.CollectorBehavior
|
||||
import content.minigame.barbassault.bots.roles.DefenderBehavior
|
||||
import content.minigame.barbassault.bots.roles.HealerBehavior
|
||||
import content.minigame.barbassault.getBARoleForPlayer
|
||||
import content.minigame.barbassault.getBASession
|
||||
import core.game.bots.AIPlayer
|
||||
import core.game.bots.CombatBotAssembler
|
||||
import core.game.bots.PvMBots
|
||||
import core.game.bots.Script
|
||||
import core.game.bots.ScriptAPI
|
||||
import core.game.container.impl.EquipmentContainer
|
||||
import core.game.global.action.EquipHandler
|
||||
import core.game.world.map.Location
|
||||
|
||||
interface RoleBehavior {
|
||||
fun tick(ctx: BABotContext)
|
||||
}
|
||||
|
||||
private class SmartBABotBrain(private val ctx: BABotContext) {
|
||||
private val lobby = LobbyBehavior()
|
||||
private val attacker = AttackerBehavior()
|
||||
private val collector = CollectorBehavior()
|
||||
private val defender = DefenderBehavior()
|
||||
private val healer = HealerBehavior()
|
||||
|
||||
private var tickTimer = 0
|
||||
|
||||
fun tick() {
|
||||
tickTimer++
|
||||
ctx.tick = tickTimer
|
||||
|
||||
if (ctx.processDelay()) return
|
||||
|
||||
ctx.session = getBASession(ctx.bot)
|
||||
|
||||
if (ctx.session?.state == BarbassaultState.IN_ARENA) {
|
||||
ctx.role = getBARoleForPlayer(ctx.bot)
|
||||
when (ctx.role) {
|
||||
BarbRole.ATTACKER -> attacker.tick(ctx)
|
||||
BarbRole.COLLECTOR -> collector.tick(ctx)
|
||||
BarbRole.DEFENDER -> defender.tick(ctx)
|
||||
BarbRole.HEALER -> healer.tick(ctx)
|
||||
null -> return
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
lobby.tick(ctx)
|
||||
}
|
||||
}
|
||||
|
||||
class SmartBABot(l: Location) : PvMBots(l) {
|
||||
private val ctx = BABotContext(this, ScriptAPI(this))
|
||||
private val brain = SmartBABotBrain(ctx)
|
||||
|
||||
init {
|
||||
(this as AIPlayer).fullRestore()
|
||||
CombatBotAssembler().gearPCiMeleeBot(this)
|
||||
|
||||
val cape = equipment.get(EquipmentContainer.SLOT_CAPE)
|
||||
if (cape != null) {
|
||||
EquipHandler.unequip(this, EquipmentContainer.SLOT_CAPE, cape.id)
|
||||
}
|
||||
}
|
||||
|
||||
override fun tick() {
|
||||
super.tick()
|
||||
brain.tick()
|
||||
}
|
||||
}
|
||||
|
||||
class SmartBAPlayerScript : Script() {
|
||||
private lateinit var brain: SmartBABotBrain
|
||||
|
||||
init {
|
||||
endDialogue = false
|
||||
preventRandomIdle = true
|
||||
}
|
||||
|
||||
override fun init(isPlayer: Boolean) {
|
||||
super.init(isPlayer)
|
||||
val ctx = BABotContext(bot, scriptAPI)
|
||||
ctx.script = this
|
||||
brain = SmartBABotBrain(ctx)
|
||||
}
|
||||
|
||||
override fun tick() {
|
||||
brain.tick()
|
||||
}
|
||||
|
||||
override fun newInstance(): Script {
|
||||
return SmartBAPlayerScript().also { it.bot = this.bot }
|
||||
}
|
||||
}
|
||||
|
|
@ -1,23 +1,18 @@
|
|||
package content.minigame.barbassault.bots
|
||||
package content.minigame.barbassault.bots.oldbot
|
||||
|
||||
import content.minigame.barbassault.BarbRole
|
||||
import content.minigame.barbassault.arena.BarbassaultState
|
||||
import content.minigame.barbassault.arena.scenery.ItemMachine
|
||||
import content.minigame.barbassault.arena.scenery.ItemMachine.DispenserType
|
||||
import content.minigame.barbassault.getBARoleForPlayer
|
||||
import content.minigame.barbassault.getBASession
|
||||
import content.minigame.barbassault.lobby.BALobby.Companion.MAIN_LOBBY
|
||||
import content.minigame.barbassault.lobby.BALobby.Companion.QUICK_START
|
||||
import content.minigame.barbassault.lobby.BALobby.Companion.waveLobbies
|
||||
import content.minigame.barbassault.lobby.BarbassQuickWaveActivity.Companion.addToQueue
|
||||
import content.minigame.barbassault.lobby.BALobby
|
||||
import content.minigame.barbassault.lobby.BarbassQuickWaveActivity
|
||||
import core.api.forceMove
|
||||
import core.api.getRegionBorders
|
||||
import core.api.log
|
||||
import core.api.queueScript
|
||||
import core.api.stopExecuting
|
||||
import core.game.bots.AIPlayer
|
||||
import core.game.bots.CombatBotAssembler
|
||||
import core.game.bots.PvMBots
|
||||
import core.game.bots.ScriptAPI
|
||||
import core.game.global.action.EquipHandler
|
||||
import core.game.node.entity.Entity
|
||||
import core.game.node.entity.player.Player
|
||||
|
|
@ -25,8 +20,6 @@ import core.game.node.item.Item
|
|||
import core.game.world.map.Location
|
||||
import core.tools.Log
|
||||
import org.rs09.consts.Scenery
|
||||
import org.rs09.consts.Scenery.COLLECTOR_CONVERTER_21250
|
||||
|
||||
|
||||
class BABot(l: Location) : PvMBots(legitimizeLocation(l)) {
|
||||
|
||||
|
|
@ -36,7 +29,7 @@ class BABot(l: Location) : PvMBots(legitimizeLocation(l)) {
|
|||
|
||||
val cape: Item? = equipment.get(1)
|
||||
if (cape != null) {
|
||||
EquipHandler.unequip(this, 1, cape.id)
|
||||
EquipHandler.Companion.unequip(this, 1, cape.id)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -44,6 +37,7 @@ class BABot(l: Location) : PvMBots(legitimizeLocation(l)) {
|
|||
private var tickTimer = 0
|
||||
private var moveTimer = 0
|
||||
var hasVendingItems = false
|
||||
var scriptAPI: ScriptAPI? = null
|
||||
|
||||
enum class State { GET_TO_BA, OUTSIDE_ROOM, ENTER_ROOM, WAITING_IN_ROOM, PLAY_GAME }
|
||||
|
||||
|
|
@ -89,22 +83,15 @@ class BABot(l: Location) : PvMBots(legitimizeLocation(l)) {
|
|||
}
|
||||
|
||||
private fun getToBA() {
|
||||
teleport(MAIN_LOBBY.randomWalkableLoc)
|
||||
teleport(BALobby.Companion.MAIN_LOBBY.randomWalkableLoc)
|
||||
moveTimer = 3
|
||||
}
|
||||
|
||||
fun useRoleVendingMachine() {
|
||||
if (hasVendingItems) return
|
||||
|
||||
val roleMachine = getClosestNodeWithEntry(60, getBARoleForPlayer(this)!!.machineId) ?: return
|
||||
if (roleMachine.id == COLLECTOR_CONVERTER_21250) return
|
||||
queueScript(this,3) {
|
||||
roleMachine.interaction.handle(this, roleMachine.interaction[0])
|
||||
// ItemMachine().handleAddItemMachine(this, roleMachine,10558, STOCK_UP_DEF, 1,DispenserType.FOOD)
|
||||
|
||||
hasVendingItems = true
|
||||
return@queueScript stopExecuting(this)
|
||||
}
|
||||
val roleMachine = scriptAPI?.getNearestNode(getBARoleForPlayer(this)!!.machineId, true)
|
||||
if (roleMachine?.id == Scenery.COLLECTOR_CONVERTER_21250) return
|
||||
scriptAPI?.interact(this, roleMachine, "Stock-up")
|
||||
|
||||
}
|
||||
|
||||
|
|
@ -121,8 +108,8 @@ class BABot(l: Location) : PvMBots(legitimizeLocation(l)) {
|
|||
quickDoor.interaction.handle(this, quickDoor.interaction[0])
|
||||
|
||||
forceMove(this, location, location.transform(0, -1, 0), 25, 60, null, 819) {
|
||||
addToQueue(this, null)
|
||||
combatHandler.walkTo(QUICK_START.randomWalkableLoc)
|
||||
BarbassQuickWaveActivity.Companion.addToQueue(this, null)
|
||||
combatHandler.walkTo(BALobby.Companion.QUICK_START.randomWalkableLoc)
|
||||
}
|
||||
|
||||
moveTimer = 4
|
||||
|
|
@ -146,20 +133,20 @@ class BABot(l: Location) : PvMBots(legitimizeLocation(l)) {
|
|||
|
||||
fun isInLobbyOnly(location: Location): Boolean {
|
||||
return getRegionBorders(10322).insideBorder(location)
|
||||
&& waveLobbies.none {
|
||||
it != MAIN_LOBBY
|
||||
&& it != QUICK_START
|
||||
&& BALobby.Companion.waveLobbies.none {
|
||||
it != BALobby.Companion.MAIN_LOBBY
|
||||
&& it != BALobby.Companion.QUICK_START
|
||||
&& it.insideBorder(location)
|
||||
}
|
||||
}
|
||||
|
||||
private fun isWaitingArea(location: Location): Boolean {
|
||||
hasVendingItems = false
|
||||
return QUICK_START.insideBorder(location) || waveLobbies.any { it.insideBorder(location) && it != MAIN_LOBBY }
|
||||
return BALobby.Companion.QUICK_START.insideBorder(location) || BALobby.Companion.waveLobbies.any { it.insideBorder(location) && it != BALobby.Companion.MAIN_LOBBY }
|
||||
}
|
||||
|
||||
fun debugthis(info : Any) {
|
||||
log(this.javaClass, Log.FINE,state.toString())
|
||||
log(this.javaClass, Log.FINE, state.toString())
|
||||
}
|
||||
|
||||
override fun AttackNpcsInRadius(bot: Player, radius: Int): Boolean {
|
||||
|
|
@ -1,19 +1,15 @@
|
|||
package content.minigame.barbassault.bots
|
||||
package content.minigame.barbassault.bots.oldbot
|
||||
|
||||
import content.minigame.barbassault.BarbRole
|
||||
import content.minigame.barbassault.arena.BarbassaultSession.AttackerStyle
|
||||
import content.minigame.barbassault.arena.scenery.ItemMachine
|
||||
import content.minigame.barbassault.arena.scenery.ItemMachine.DispenserType
|
||||
import content.minigame.barbassault.arena.BarbassaultSession
|
||||
import content.minigame.barbassault.getBARoleForPlayer
|
||||
import content.minigame.barbassault.getBASession
|
||||
import core.game.interaction.MovementPulse
|
||||
import core.game.node.entity.combat.equipment.WeaponInterface.AttackStyle
|
||||
import core.game.node.entity.combat.equipment.WeaponInterface.BONUS_SLASH
|
||||
import core.game.node.entity.combat.equipment.WeaponInterface
|
||||
import core.game.world.GameWorld
|
||||
import core.game.world.map.Location
|
||||
import core.game.world.map.path.Pathfinder
|
||||
import core.tools.RandomFunction
|
||||
import org.rs09.consts.Scenery
|
||||
|
||||
class BACombatState(private val bot: BABot) {
|
||||
|
||||
|
|
@ -23,8 +19,8 @@ class BACombatState(private val bot: BABot) {
|
|||
bot.AttackNpcsInRadius(bot,25)
|
||||
//use Called AttackStyle
|
||||
val baSession = getBASession(bot) ?: return
|
||||
val called = (baSession.roleCalls[BarbRole.ATTACKER]?.called ?: AttackerStyle.values().random() ) as AttackerStyle
|
||||
bot.properties.attackStyle = AttackStyle(called.attackStyle, BONUS_SLASH)
|
||||
val called = (baSession.roleCalls[BarbRole.ATTACKER]?.called ?: BarbassaultSession.AttackerStyle.values().random() ) as BarbassaultSession.AttackerStyle
|
||||
bot.properties.attackStyle = WeaponInterface.AttackStyle(called.attackStyle, WeaponInterface.BONUS_SLASH)
|
||||
|
||||
}
|
||||
|
||||
|
|
@ -102,7 +102,7 @@ class GeneralBotCreator {
|
|||
return false
|
||||
|
||||
val idleRoll = RandomFunction.random(10)
|
||||
if(idleRoll == 2 && botScript !is Idler){
|
||||
if(idleRoll == 2 && botScript !is Idler && !botScript.preventRandomIdle){
|
||||
randomDelay += RandomFunction.random(20,50)
|
||||
return false
|
||||
}
|
||||
|
|
|
|||
|
|
@ -22,6 +22,8 @@ public abstract class Script {
|
|||
public boolean running = true;
|
||||
public boolean endDialogue = true;
|
||||
|
||||
public boolean preventRandomIdle = false;
|
||||
|
||||
public void init(boolean isPlayer)
|
||||
{
|
||||
//bot.init();
|
||||
|
|
|
|||
|
|
@ -104,7 +104,8 @@ class ScriptAPI(private val bot: Player) {
|
|||
|
||||
val item = bot.inventory.getItem(Item(itemId))
|
||||
|
||||
val childNode = node.asScenery()?.getChild(bot)
|
||||
//val childNode = node.asScenery()?.getChild(bot)
|
||||
val childNode = if (node is Scenery) node.getChild(bot) else null
|
||||
|
||||
if (InteractionListeners.run(item, node, type, bot))
|
||||
return
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue