Fixed deadlock regression in bots

Added some runecrafting player scripts
This commit is contained in:
Pine Stone 2023-07-29 05:02:38 +00:00 committed by Ryan
parent 661390e66f
commit 421c419f69
6 changed files with 599 additions and 8 deletions

View file

@ -0,0 +1,181 @@
package content.global.bots
import content.global.skill.runecrafting.MysteriousRuin
import core.cache.def.impl.SceneryDefinition
import core.game.bots.*
import core.game.node.item.Item
import core.game.node.scenery.Scenery
import core.game.world.map.Location
import core.game.world.map.RegionManager
import core.game.world.map.zone.ZoneBorders
import core.net.packet.PacketProcessor
import org.rs09.consts.Items
@PlayerCompatible
@ScriptName("Cosmic Rune Crafter")
@ScriptDescription("Crafts cosmic runes. Start in Zanaris w/ cosmic tiara.")
@ScriptIdentifier("cosmic_crafter")
class CosmicCrafter : Script() {
var state = State.INIT
var runeCounter = 0
var overlay: ScriptAPI.BottingOverlay? = null
var startLocation = Location(0,0,0)
var timer = 0
var bank_deposit = true
var bank = Location(2384, 4457)
var squeezeZone = ZoneBorders(2413, 4400, 2416, 4406)
var endZone = ZoneBorders(2405, 4392, 2410, 4397)
var agility_part = 0
var ruinsZone = ZoneBorders(2400, 4370, 2410, 4385)
var cosmicZone = ZoneBorders(2160, 4830, 2170, 4840)
var ruinPoint = Location(2407, 4379, 0)
var agility2ExitPoint = Location(2408, 4394, 0)
var agility2EntryPoint = Location(2408, 4396, 0)
var agility1ExitPoint = Location(2415, 4401, 0)
var agility1EntryPoint = Location(2415, 4403, 0)
override fun tick() {
if (timer-- > 0) {
return
}
if (bot.settings.runEnergy > 10.0) {
bot.settings.isRunToggled = true
}
when(state){
State.INIT -> {
if (!bot.equipment.containsAtLeastOneItem(Items.COSMIC_TIARA_5539)) {
bot.sendMessage("Please equip a cosmic tiara first.")
state = State.INVALID
} else {
overlay = scriptAPI.getOverlay()
overlay!!.init()
overlay!!.setTitle("Cosmic Runes")
overlay!!.setTaskLabel("Runes Crafted:")
overlay!!.setAmount(0)
startLocation = bot.location
state = State.BANKING
}
}
State.BANKING -> {
if(bot.location != bank) {
scriptAPI.walkTo(bank)
return
}
val runes = bot.inventory.getAmount(Item(Items.COSMIC_RUNE_564))
if (runes > 0) {
runeCounter += runes
overlay!!.setAmount(runeCounter)
bot.sendMessage("You have crafted a total of: $runeCounter runes.")
scriptAPI.bankItem(Items.COSMIC_RUNE_564)
} else {
scriptAPI.withdraw(Items.PURE_ESSENCE_7936, 28)
state = State.FIRST_AGILITY
}
}
State.FIRST_AGILITY -> {
val squeezeWall = scriptAPI.getNearestNode(12127, true)
if (agility_part == 0) {
if (!squeezeZone.insideBorder(bot))
scriptAPI.walkTo(agility1EntryPoint)
else {
scriptAPI.interact(bot, squeezeWall, "squeeze-past")
agility_part = 1
timer = 6
}
} else if (agility_part == 1) {
if (!endZone.insideBorder(bot))
scriptAPI.walkTo(agility2EntryPoint)
else {
scriptAPI.interact(bot, squeezeWall, "squeeze-past")
state = State.RUNNING_TO_ALTER
timer = 6
}
}
}
State.RUNNING_TO_ALTER -> {
if (cosmicZone.insideBorder(bot))
state = State.CRAFTING
val ruins = scriptAPI.getNearestNode(2458,true)
if (!ruinsZone.insideBorder(bot)) {
scriptAPI.walkTo(ruinPoint)
} else if (ruins != null && ruins.location.withinDistance(bot.location, 20)) {
if (!bot.equipment.containsAtLeastOneItem(Items.COSMIC_TIARA_5539)) {
bot.sendMessage("Please equip a cosmic tiara first.")
state = State.INVALID
} else {
val ruinsChild = (ruins as Scenery).getChild(bot)
scriptAPI.interact(bot, ruinsChild, "enter")
timer = 4
}
}
}
State.CRAFTING -> {
val alter = scriptAPI.getNearestNode(2484,true)
scriptAPI.interact(bot, alter, "craft-rune")
if(bot.inventory.containsAtLeastOneItem(Item(Items.COSMIC_RUNE_564)))
state = State.LEAVING_ALTER
}
State.LEAVING_ALTER -> {
var portalOut = scriptAPI.getNearestNode(2471, true)
scriptAPI.interact(bot, portalOut, "use")
if (ruinsZone.insideBorder(bot)) {
state = State.RETURN_AGILITY
timer = 2
}
}
State.RETURN_AGILITY -> {
val squeezeWall = scriptAPI.getNearestNode(12127, true)
if (agility_part == 1) {
if (!endZone.insideBorder(bot))
scriptAPI.walkTo(agility2ExitPoint)
else {
scriptAPI.interact(bot, squeezeWall, "squeeze-past")
agility_part = 0
timer = 6
}
} else if (agility_part == 0) {
if (!squeezeZone.insideBorder(bot))
scriptAPI.walkTo(agility1ExitPoint)
else {
scriptAPI.interact(bot, squeezeWall, "squeeze-past")
state = State.BANKING
timer = 6
}
}
}
State.INVALID -> {
timer = 25
state = State.INIT
}
}
}
override fun newInstance(): Script {
return this
}
enum class State {
INIT,
BANKING,
FIRST_AGILITY,
RETURN_AGILITY,
RUNNING_TO_ALTER,
CRAFTING,
LEAVING_ALTER,
INVALID
}
}

View file

@ -0,0 +1,210 @@
package content.global.bots
import content.global.travel.ship.Ships
import core.cache.def.impl.ItemDefinition
import core.game.bots.*
import core.game.node.item.Item
import core.game.node.scenery.Scenery
import core.game.world.map.Location
import core.game.world.map.zone.ZoneBorders
import org.rs09.consts.Items
@PlayerCompatible
@ScriptName("Law Rune Crafter")
@ScriptDescription("Crafts law runes. Start near Draynor bank w/ law tiara.")
@ScriptIdentifier("law_crafter")
class LawCrafter : Script() {
var state = State.INIT
var runeCounter = 0
var overlay: ScriptAPI.BottingOverlay? = null
var startLocation = Location(0,0,0)
var timer = 0
var bank = ZoneBorders(3092, 3242, 3092, 3245)
var boatNPC = Location(3047, 3234, 0)
var ruinsZone = ZoneBorders(2850, 3375, 2860, 3382)
var ruinPoint = Location(2857, 3380, 0)
var onBoat = ZoneBorders(2824, 3328, 2840, 3333)
var offBoat = ZoneBorders(2827, 3335, 2836, 3336)
var lawLocation = Location(2464, 4830, 0)
var lawZone = ZoneBorders(2439, 4808, 2488, 4855)
var returnNPC = Location(2835, 3335, 0)
var halfBank = Location(3069, 3275, 0)
override fun tick() {
if (timer-- > 0) {
return
}
if (bot.settings.runEnergy > 10.0) {
bot.settings.isRunToggled = true
}
when(state){
State.INIT -> {
if (!bot.equipment.containsAtLeastOneItem(Items.LAW_TIARA_5545) || !ItemDefinition.canEnterEntrana(bot)) {
bot.sendMessage("Please equip a law tiara first.")
bot.sendMessage("AND REMOVE ALL WEAPONS AND ARMOR.")
state = State.INVALID
} else {
overlay = scriptAPI.getOverlay()
overlay!!.init()
overlay!!.setTitle("Law Runes")
overlay!!.setTaskLabel("Runes Crafted:")
overlay!!.setAmount(0)
startLocation = bot.location
state = State.BANKING
}
}
State.BANKING -> {
endDialogue = true
bot.interfaceManager.closeChatbox()
bot.interfaceManager.openChatbox(137)
bot.interfaceManager.closeChatbox()
bot.dialogueInterpreter.close()
if(!bank.insideBorder(bot)) {
scriptAPI.walkTo(bank.randomLoc)
return
}
val runes = bot.inventory.getAmount(Item(Items.LAW_RUNE_563))
if (runes > 0) {
runeCounter += runes
overlay!!.setAmount(runeCounter)
bot.sendMessage("You have crafted a total of: $runeCounter runes.")
scriptAPI.bankItem(Items.LAW_RUNE_563)
} else {
scriptAPI.withdraw(Items.PURE_ESSENCE_7936, 28)
state = State.HALF_BANK
}
}
State.TO_BOAT_GUY -> {
var boatGuy = scriptAPI.getNearestNode(2729, false)
if (boatGuy != null){
if (boatGuy.location.withinDistance(bot.location,2)) {
if (ItemDefinition.canEnterEntrana(bot)) {
endDialogue = false
Ships.PORT_SARIM_TO_ENTRANA.sail(bot)
state = State.CROSS_GANGPLANK
} else {
state = State.INVALID
}
} else {
scriptAPI.walkTo(boatGuy.location)
}
} else {
scriptAPI.walkTo(boatNPC)
}
}
State.CROSS_GANGPLANK -> {
if (onBoat.insideBorder(bot)) {
var gangplank = scriptAPI.getNearestNode(2415, true)
if (gangplank != null) {
scriptAPI.interact(bot, gangplank, "cross")
}
} else if (offBoat.insideBorder(bot)) {
state = State.RUNNING_TO_ALTER
endDialogue = true
}
}
State.RUNNING_TO_ALTER -> {
if (lawZone.insideBorder(bot))
state = State.CRAFTING
val ruins = scriptAPI.getNearestNode(2459,true)
if (!ruinsZone.insideBorder(bot)) {
scriptAPI.walkTo(ruinPoint)
} else if (ruins != null && ruins.location.withinDistance(bot.location, 20)) {
val ruinsChild = (ruins as Scenery).getChild(bot)
scriptAPI.interact(bot, ruinsChild, "enter")
timer = 4
}
}
State.CRAFTING -> {
if (!lawZone.insideBorder(bot)) {
return
}
if (bot.location != lawLocation) {
scriptAPI.walkTo(lawLocation)
}
val alter = scriptAPI.getNearestNode(2485,true)
scriptAPI.interact(bot, alter, "craft-rune")
if(bot.inventory.containsAtLeastOneItem(Item(Items.LAW_RUNE_563)))
state = State.LEAVING_ALTER
}
State.LEAVING_ALTER -> {
var portalOut = scriptAPI.getNearestNode(2472, true)
scriptAPI.interact(bot, portalOut, "use")
if (ruinsZone.insideBorder(bot)) {
state = State.RETURN_TO_BOAT_GUY
timer = 2
}
}
State.RETURN_TO_BOAT_GUY -> {
var boatGuy = scriptAPI.getNearestNode(2730, false)
if (boatGuy != null){
if (boatGuy.location.withinDistance(bot.location,2)) {
endDialogue = false
Ships.ENTRANA_TO_PORT_SARIM.sail(bot)
state = State.HALF_BANK
} else {
scriptAPI.walkTo(boatGuy.location)
}
} else {
scriptAPI.walkTo(returnNPC)
}
}
// Splits up the journey into two parts.
// This is because the dialogue can't be ended until you are safely on the
// mainland side. But new chunks won't load while dialogue is still displayed.
State.HALF_BANK -> {
if (bot.inventory.containsAtLeastOneItem(Items.PURE_ESSENCE_7936)) {
if ( (bot.location.x - 2) > halfBank.x) {
scriptAPI.walkTo(halfBank)
} else {
state = State.TO_BOAT_GUY
}
} else {
if ( (bot.location.x + 2) < halfBank.x) {
scriptAPI.walkTo(halfBank)
} else {
state = State.BANKING
}
}
}
State.INVALID -> {
timer = 25
state = State.INIT
}
}
}
override fun newInstance(): Script {
return this
}
enum class State {
INIT,
BANKING,
TO_BOAT_GUY,
CROSS_GANGPLANK,
RUNNING_TO_ALTER,
CRAFTING,
LEAVING_ALTER,
RETURN_TO_BOAT_GUY,
HALF_BANK,
INVALID
}
}

View file

@ -0,0 +1,173 @@
package content.global.bots
import content.global.skill.runecrafting.MysteriousRuin
import core.api.teleport
import core.game.bots.*
import core.game.interaction.IntType
import core.game.interaction.InteractionListeners
import core.game.node.entity.player.link.TeleportManager
import core.game.node.item.Item
import core.game.node.scenery.Scenery
import core.game.world.map.Location
import core.game.world.map.zone.ZoneBorders
import org.rs09.consts.Items
@PlayerCompatible
@ScriptName("Nature Rune Crafter")
@ScriptDescription("Crafts nat runes. Start in Zanaris w/ dramen staff + Nat tiara.")
@ScriptIdentifier("nature_crafter")
class NatureCrafter : Script() {
var state = State.INIT
var runeCounter = 0
var overlay: ScriptAPI.BottingOverlay? = null
var startLocation = Location(0,0,0)
var timer = 0
var teleWaitTime = 16 // 18 ticks needed to rotate the clocks, 2 to teleport
var bank = Location(2384, 4457)
var ruinsZone = ZoneBorders(2866, 3017, 2873, 3022)
var faeRingDestination = Location(2412, 4435, 0) // You don't walk to the fae rings
// you can only walk next to them. so path to the nearest point that isn't in the ring.
var faeRingCenter = Location(2412, 4434, 0)
var karamjaRingDestination = Location(2801, 3002, 0)
var karamjaRingCenter = Location(2801, 3003, 0)
var natureZone = ZoneBorders(2387, 4828, 2416, 4856)
override fun tick() {
if (timer-- > 0) {
return
}
if (bot.settings.runEnergy > 10.0) {
bot.settings.isRunToggled = true
}
when(state){
State.INIT -> {
if (checkValid()) {
overlay = scriptAPI.getOverlay()
overlay!!.init()
overlay!!.setTitle("Nature Runes")
overlay!!.setTaskLabel("Runes Crafted:")
overlay!!.setAmount(0)
startLocation = bot.location
state = State.BANKING
}
}
State.BANKING -> {
if(bot.location != bank) {
scriptAPI.walkTo(bank)
return
}
val runes = bot.inventory.getAmount(Item(Items.NATURE_RUNE_561))
if (runes > 0) {
runeCounter += runes
overlay!!.setAmount(runeCounter)
bot.sendMessage("You have crafted a total of: $runeCounter runes.")
scriptAPI.bankItem(Items.NATURE_RUNE_561)
} else {
scriptAPI.withdraw(Items.PURE_ESSENCE_7936, 28)
state = State.RUNNING_TO_TELE
}
}
State.RUNNING_TO_TELE -> {
if (bot.location != faeRingDestination) {
scriptAPI.walkTo(faeRingDestination)
} else {
if (checkValid()) {
timer = teleWaitTime
state = State.TELE_WAIT
bot.sendMessage("Entering Fairy Ring Codes. Please wait...")
}
}
}
State.TELE_WAIT -> {
teleport(bot, karamjaRingCenter, TeleportManager.TeleportType.FAIRY_RING)
state = State.RUNNING_TO_ALTER
// tele takes 4 ticks so wait that long.
timer = 4
}
State.RETURN_WAIT -> {
teleport(bot, faeRingCenter, TeleportManager.TeleportType.FAIRY_RING)
state = State.BANKING
}
State.RUNNING_TO_ALTER -> {
val ruins = scriptAPI.getNearestNode(2460,true)
if (natureZone.insideBorder(bot))
state = State.CRAFTING
if (!ruinsZone.insideBorder(bot)) {
scriptAPI.walkTo(ruinsZone.randomLoc)
} else if (ruins != null && ruins.location.withinDistance(bot.location, 20) && checkValid()) {
val ruinsChild = (ruins as Scenery).getChild(bot)
scriptAPI.interact(bot, ruinsChild, "enter")
timer = 4
}
}
State.CRAFTING -> {
val alter = scriptAPI.getNearestNode(2486,true)
scriptAPI.interact(bot, alter, "craft-rune")
if(bot.inventory.containsAtLeastOneItem(Item(Items.NATURE_RUNE_561)))
state = State.LEAVING_ALTER
}
State.LEAVING_ALTER -> {
var portalOut = scriptAPI.getNearestNode(2473, true)
scriptAPI.interact(bot, portalOut, "use")
if (ruinsZone.insideBorder(bot))
state = State.RETURNING_TO_TELE
}
State.RETURNING_TO_TELE -> {
if (bot.location != karamjaRingDestination) {
scriptAPI.walkTo(karamjaRingDestination)
} else {
if (checkValid()) {
var portalOut = scriptAPI.getNearestNode(14130, true)
portalOut?.interaction?.handle(bot, portalOut.interaction[0])
timer = 4
state = State.RETURN_WAIT
}
}
}
State.INVALID -> {
timer = 25
state = State.INIT
}
}
}
// Terminates if you have invalid inventory to avoid cheating
private fun checkValid(): Boolean {
if (!bot.equipment.containsAtLeastOneItem(Items.DRAMEN_STAFF_772) or !bot.equipment.containsAtLeastOneItem(Items.NATURE_TIARA_5541)) {
bot.sendMessage("Please equip a dramen staff and nature tiara first.")
state = State.INVALID
return false
}
return true
}
override fun newInstance(): Script {
return this
}
enum class State {
INIT,
BANKING,
RUNNING_TO_TELE,
TELE_WAIT,
RUNNING_TO_ALTER,
CRAFTING,
LEAVING_ALTER,
RETURNING_TO_TELE,
RETURN_WAIT,
INVALID
}
}

View file

@ -2,12 +2,12 @@ package content.global.bots
import core.game.bots.*
import core.game.interaction.DestinationFlag
import core.game.interaction.IntType
import core.game.interaction.InteractionListeners
import core.game.interaction.MovementPulse
import core.game.world.map.Location
import core.game.world.map.zone.ZoneBorders
import org.rs09.consts.Items
import core.game.interaction.IntType
import core.game.interaction.InteractionListeners
@PlayerCompatible
@ScriptDescription("Start in varrock bank with rune mysteries complete and a pickaxe equipped/in inventory")
@ -18,6 +18,7 @@ class VarrockEssenceMiner : Script(){
var state = State.TO_ESSENCE
val auburyZone = ZoneBorders(3252, 3398, 3254, 3402)
val bankZone = ZoneBorders(3251, 3420,3254, 3422)
// Used for automatic failure prevention eg from levelup
override fun tick() {
when(state){
@ -49,10 +50,13 @@ class VarrockEssenceMiner : Script(){
}
State.MINING -> {
val essence = scriptAPI.getNearestNode(2491,true)
essence?.let { InteractionListeners.run(essence.id, IntType.SCENERY,"mine",bot,essence) }
if(bot.inventory.isFull)
if(bot.inventory.isFull) {
state = State.TO_BANK
}
else {
val essence = scriptAPI.getNearestNode(2491,true)
essence?.let { InteractionListeners.run(essence.id, IntType.SCENERY,"mine",bot,essence) }
}
}
State.TO_BANK -> {
@ -114,4 +118,4 @@ class VarrockEssenceMiner : Script(){
script.bot = SkillingBotAssembler().produce(SkillingBotAssembler.Wealth.POOR,bot.startLocation)
return script
}
}
}

View file

@ -1,12 +1,12 @@
package core.game.bots
import content.global.bots.Idler
import core.Server
import core.game.node.entity.player.Player
import core.game.system.task.Pulse
import core.game.world.GameWorld
import core.game.world.map.Location
import core.tools.RandomFunction
import core.Server
import content.global.bots.Idler
class GeneralBotCreator {
//org/crandor/net/packet/in/InteractionPacket.java <<< This is a very useful class for learning to code bots
@ -40,6 +40,28 @@ class GeneralBotCreator {
randomDelay -= 1
return false
}
/*
* Chatboxes and interfaces will cause the authentic interaction subsystem
* to pause any currently running authentically-implemented interactions.
*
* When this happens, if the interfaces are not handled by the script and closed,
* execution will remain paused as the game believes the bot is still doing something
* (because they still have an authentic interaction in the queue, that is not advancing
* because it is paused) and so the script does not execute, but the pulse is waiting on botscript input.
*
* This deadlock can be worked around by just closing these.
*
* Set endDialogue to FALSE if you want
* to avoid automatic dialogue termination (useful for, for example, boat travel)
*/
if (botScript.bot.scripts.getActiveScript() != null && botScript.bot.hasModalOpen() && botScript.endDialogue) {
botScript.bot.interfaceManager.closeChatbox()
botScript.bot.interfaceManager.openChatbox(137)
botScript.bot.interfaceManager.close()
botScript.bot.dialogueInterpreter.close()
}
if (!botScript.bot.pulseManager.hasPulseRunning() && botScript.bot.scripts.getActiveScript() == null) {
/*if (ticks++ >= RandomFunction.random(90000,120000)) {

View file

@ -19,6 +19,7 @@ public abstract class Script {
public Player bot;
public boolean running = true;
public boolean endDialogue = true;
public void init(boolean isPlayer)
{