Skip to content

Instantly share code, notes, and snippets.

@shenjackyuanjie
Last active June 3, 2024 13:23
Show Gist options
  • Save shenjackyuanjie/47e568e0e4e9f36c24cb0d3bb9f02e31 to your computer and use it in GitHub Desktop.
Save shenjackyuanjie/47e568e0e4e9f36c24cb0d3bb9f02e31 to your computer and use it in GitHub Desktop.
自动收菜-20230610
import java.io.File
import baritone.api.BaritoneAPI
import baritone.api.pathing.goals.*
val script_version = "1.3.1+20230610"
// by shenjackyuanjie
// [email protected] 禁止商用
val run_type = "call"
// farm | call
val EVENT_TYPE = event?.getEventName()
val baritone_api = BaritoneAPI.getProvider().getPrimaryBaritone()
val allow_sprint = false
val scan_range = 3
// 允许的容器方块
val ALLOW_CONTAINER = listOf(
"minecraft:chest",
"minecraft:trapped_chest",
"minecraft:ender_chest",
"minecraft:barrel",
"minecraft:shulker_box",
"minecraft:white_shulker_box",
"minecraft:orange_shulker_box",
"minecraft:magenta_shulker_box",
"minecraft:light_blue_shulker_box",
"minecraft:yellow_shulker_box",
"minecraft:lime_shulker_box",
"minecraft:pink_shulker_box",
"minecraft:gray_shulker_box",
"minecraft:light_gray_shulker_box",
"minecraft:cyan_shulker_box",
"minecraft:purple_shulker_box",
"minecraft:blue_shulker_box",
"minecraft:brown_shulker_box",
"minecraft:green_shulker_box",
"minecraft:red_shulker_box",
"minecraft:black_shulker_box",
"minecraft:dispenser",
"minecraft:dropper",
"minecraft:hopper",
)
val PLANT_COLLECT = listOf(
"minecraft:potato",
"minecraft:poisonous_potato",
"minecraft:carrot",
"minecraft:wheat",
"minecraft:wheat_seeds",
"minecraft:beetroot",
"minecraft:beetroot_seeds",
"minecraft:nether_wart",
)
var player = Player.getPlayer()
var inventory = Player.openInventory()
// 初始化 Baritone 设置 同时保存原有设置 用map 的形式返回
fun baritone_init(): MutableMap<String, Boolean> {
Chat.log("初始化 Baritone 设置")
val old_settings = mutableMapOf<String, Boolean>()
old_settings["allowBreak.value"] = BaritoneAPI.getSettings().allowBreak.value
old_settings["allowSprint.value"] = BaritoneAPI.getSettings().allowSprint.value
old_settings["allowInventory.value"] = BaritoneAPI.getSettings().allowInventory.value
old_settings["allowPlace.value"] = BaritoneAPI.getSettings().allowPlace.value
BaritoneAPI.getSettings().allowBreak.value = false
BaritoneAPI.getSettings().allowSprint.value = allow_sprint
BaritoneAPI.getSettings().allowInventory.value = true
BaritoneAPI.getSettings().allowPlace.value = false
// Chat.log("Baritone 设置: ${old_settings}")
Chat.log("Baritone 设置完成")
return old_settings
}
// by shenjackyuanjie
// [email protected] 禁止商用
// 重置 Baritone 设置
fun reset_baritone(settings: MutableMap<String, Boolean>) {
Chat.log("重置 Baritone 设置")
BaritoneAPI.getSettings().allowBreak.value = settings["allowBreak.value"]!!
BaritoneAPI.getSettings().allowSprint.value = settings["allowSprint.value"]!!
BaritoneAPI.getSettings().allowInventory.value = settings["allowInventory.value"]!!
BaritoneAPI.getSettings().allowPlace.value = settings["allowPlace.value"]!!
Chat.log("Baritone 设置重置完成")
}
fun reach_goal(goal: GoalBlock): Boolean {
if (goal.x-1.0 < player.x && player.x < goal.x+1.0) {
if (goal.y-0.5 < player.y && player.y < goal.y+0.5) {
if (goal.z-1.0 < player.z && player.z < goal.z+1.0) {
// Chat.log("YES reach_goal ${goal} ${player.x} ${player.y} ${player.z}")
return true
}
}
}
// Chat.log("NOT reach_goal ${goal} ${player.x} ${player.y} ${player.z}")
return false
}
fun guess_real_cost(guess_tick: Int): Int {
var guess_tick = guess_tick
var extra_guess = 0
if (guess_tick > 20) {
// 大于 20 tick (1s) 的移动
BaritoneAPI.getSettings().allowSprint.value = true
extra_guess = guess_tick / 10
// 允许疾跑
if (guess_tick > 50) {
extra_guess = 20
if (guess_tick > 80) {
extra_guess = 80
}
}
}
// Chat.log("guess_tick: ${guess_tick} extra_guess: ${extra_guess}")
guess_tick += extra_guess
return guess_tick
}
// by shenjackyuanjie
// [email protected] 禁止商用
fun goto_pos(x: Int, y: Int, z: Int): Boolean {
var player = Player.getPlayer()
val goto_goal = GoalBlock(x, y, z)
baritone_api.getCustomGoalProcess().setGoalAndPath(goto_goal)
// 开始寻路
val first_guess_tick = goto_goal.heuristic(player.x.toInt(), player.y.toInt(), player.z.toInt()).toInt()
val first_guess_cost = guess_real_cost(first_guess_tick)
Client.waitTick(first_guess_cost)
// 等待寻路完成
if (!reach_goal(goto_goal)) {
val guess_tick = goto_goal.heuristic(player.x.toInt(), player.y.toInt(), player.z.toInt()).toInt()
val guess_cost = guess_real_cost(first_guess_tick)
Client.waitTick(guess_cost)
}
// 默认重置为禁止疾跑
BaritoneAPI.getSettings().allowSprint.value = false
return true
}
fun search_item(item: String): Int {
// 搜索背包里的物品
for (i in 0..44) {
val slot_item = inventory.getSlot(i)
if (slot_item.getItemId() == item) {
return i
}
}
return -1
}
fun swap_item_to_hand(item: String) {
inventory = Player.openInventory()
if (item == "no_need") {
return
}
// 首先检测手上是不是已经有了
val hand_item = inventory.getSlot(36 + inventory.getSelectedHotbarSlotIndex())
if (hand_item.getItemId() == item) {
return
}
// 检测背包里有没有
val item_slot = search_item(item)
if (item_slot == -1) {
Chat.log("背包里没有 $item")
return
}
// 交换
if (36 + inventory.getSelectedHotbarSlotIndex() == item_slot) {
// 如果是手上的物品就不用交换了
return
}
// Chat.log("交换 $item ${36 + inventory.getSelectedHotbarSlotIndex()} $item_slot")
inventory.swap(36 + inventory.getSelectedHotbarSlotIndex(), item_slot)
Client.waitTick(1)
}
// by shenjackyuanjie
// [email protected] 禁止商用
fun give_back() {
// 先检查是否有空位
val chest_slot_count = inventory.getTotalSlots() - 36 - 1
var empty_slot = -1
var plant_items: MutableList<Int> = mutableListOf()
for (i in 0..inventory.getTotalSlots() - 36 - 1) {
// 箱子内
val slot_item = inventory.getSlot(i)
// Chat.log("箱子第 $i 格是 ${slot_item.getItemId()}")
if (slot_item.getItemId() == "minecraft:air") {
empty_slot += 1
} else if (slot_item.getItemId() in ALLOW_CONTAINER) {
empty_slot += 1
}
}
for (i in chest_slot_count + 1..inventory.getTotalSlots() - 1) {
// 背包内
val slot_item = inventory.getSlot(i)
// Chat.log("背包第 $i 格是 ${slot_item.getItemId()}")
if (slot_item.getItemId() in PLANT_COLLECT) {
plant_items.add(i)
}
}
Chat.log("空位: $empty_slot 作物: $plant_items")
for (i in plant_items) {
inventory.quick(i)
Client.waitTick(2)
}
Client.waitTick(2)
inventory.close()
}
// by shenjackyuanjie
// [email protected] 禁止商用
fun main() {
// 初始化
Chat.log("农场脚本初始化......")
val old_settings = baritone_init()
val view_block = Player.rayTraceBlock(3.0, false)
Chat.log("观察的方块是: $view_block")
if ((view_block == null) || (view_block.getId() !in ALLOW_CONTAINER)) {
Chat.log("观察的方块不是容器,初始化失败")
return
}
player.interact()
Client.waitTick(1)
inventory = Player.openInventory()
// Chat.log("${inventory.getTotalSlots()} ${inventory.getTotalSlots() - 36} 个空位 ${inventory.getSelectedHotbarSlotIndex()}")
Client.waitTick(10)
inventory.close()
val start_block = player.getPos()
val farm_chest = view_block
// 检测农场
// val farm_blocks = World.getWorldScanner().withStringBlockFilter().contains("farmland", "soul_sand", "sweet_berry_bush", "melon", "pumpkin").build().scanAroundPlayer(scan_range)
val farm_blocks = World.getWorldScanner().withStringBlockFilter().contains("farmland").build().scanAroundPlayer(scan_range)
// val farm_blocks = World.getWorldScanner().build().scanAroundPlayer(scan_range)
if(farm_blocks.isEmpty()) {
Chat.log("没有检测到农场,初始化失败")
return
}
Chat.log("检测到农场: ${farm_blocks.size} 个方块")
var valid_farm_blocks = 0
for (block in farm_blocks) {
val the_block = World.getBlock(block)
var check_upper = true
when (the_block.getId()) {
"minecraft:farmland" -> {}
"minecraft:soul_sand" -> {}
"minecraft:sweet_berry_bush" -> { check_upper = false }
"minecraft:melon" -> { check_upper = false }
"minecraft:pumpkin" -> { check_upper = false }
else -> continue
}
val upper_block = World.getBlock(block.add(0.0, 1.0, 0.0))
// if (upper_block.getId() in PLANTES && check_upper) {continue}
// 排除农田上方是不会压坏耕地的非作物方块
// 根据作物名称判断 age 最大值
var max_age = 3
var need_item = "no_need"
when (upper_block.getId()) {
"minecraft:potatoes" -> {
max_age = 7
need_item = "minecraft:potato"
}
"minecraft:carrots" -> {
max_age = 7
need_item = "minecraft:carrot"
}
"minecraft:wheat" -> {
max_age = 7
need_item = "minecraft:wheat_seeds"
}
"minecraft:beetroots" -> {
max_age = 3
need_item = "minecraft:beetroot_seeds"
}
"minecraft:nether_wart" -> {
max_age = 3
need_item = "minecraft:nether_wart"
}
else -> 3
}
val block_age = upper_block.getBlockState().get("age")?.toInt() ?: 0
// 获取作物的 age
// Chat.log("$block_age $max_age ${block_age < max_age}")
if (block_age < max_age) {continue}
// 排除作物 age 不满足条件的方块
goto_pos(block.x.toInt(), block.y.toInt()+1, block.z.toInt())
// 移动到作物上方
Client.waitTick(2)
player.lookAt(block.x + 0.5, block.y, block.z + 0.5)
Client.waitTick(2)
player.attack()
// 收割作物
Client.waitTick(15)
swap_item_to_hand(need_item)
Client.waitTick(2)
// 切换手上物品
player.interact()
Client.waitTick(2)
// 种植作物
valid_farm_blocks += 1
}
Chat.log("有效农场方块: $valid_farm_blocks")
// 返回初始位置
goto_pos(start_block.x.toInt(), start_block.y.toInt(), start_block.z.toInt())
goto_pos(start_block.x.toInt(), start_block.y.toInt(), start_block.z.toInt())
player.lookAt(farm_chest.x.toDouble() + 0.5, farm_chest.y.toDouble() + 0.5, farm_chest.z.toDouble() + 0.5)
Client.waitTick(10)
// 打开箱子
player.interact()
Client.waitTick(10)
inventory = Player.openInventory()
give_back()
// 重置 Baritone 设置
reset_baritone(old_settings)
}
// by shenjackyuanjie
// [email protected] 禁止商用
fun farm_main() {
// 基于纯调用 baritone farm 的脚本
Chat.log("农场脚本初始化......")
val old_settings = baritone_init()
val view_block = Player.rayTraceBlock(3.0, false)
Chat.log("观察的方块是: $view_block")
if ((view_block == null) || (view_block.getId() !in ALLOW_CONTAINER)) {
Chat.log("观察的方块不是容器,初始化失败")
return
}
player.interact()
Client.waitTick(1)
inventory = Player.openInventory()
Client.waitTick(10)
inventory.close()
val start_block = view_block.getPos()
val farm_chest = view_block
// # farm
Chat.say("#farm 100")
Client.waitTick(20*60)
Chat.say("#stop")
// 返回初始位置
// goto_pos(start_block.x.toInt(), start_block.y.toInt(), start_block.z.toInt())
Chat.say("#goto ${start_block.x.toInt()} ${start_block.y.toInt()} ${start_block.z.toInt()}")
goto_pos(start_block.x.toInt(), start_block.y.toInt() + 1, start_block.z.toInt())
player.lookAt(farm_chest.x.toDouble() + 0.5, farm_chest.y.toDouble() + 0.5, farm_chest.z.toDouble() + 0.5)
Client.waitTick(10)
// 打开箱子
player.interact()
Client.waitTick(10)
inventory = Player.openInventory()
give_back()
// 重置 Baritone 设置
reset_baritone(old_settings)
}
var runinf = true
// by shenjackyuanjie
// [email protected] 禁止商用
while (runinf) {
Chat.log("by shenjackyuanjie")
Chat.log("禁止商用")
if (run_type == "call") {
farm_main()
} else {
main()
}
var cache = GlobalVars.getBoolean("farm_run")
if (cache == null) {
GlobalVars.putBoolean("farm_run", false)
cache = false
runinf = false
}
runinf = cache
if (runinf) {
Chat.log("等待五分钟")
Client.waitTick(20*60)
// 等待五分钟
}
}
Chat.log("农场脚本结束")
// by shenjackyuanjie
// [email protected] 禁止商用
GlobalVars.toggleBoolean("farm_run");
Chat.log("Farm: " + GlobalVars.getBoolean("farm_run"));
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment