Wheat Farmer (intermediate)
This will show you code for a wheat farmer, meaning that it finds the closest fully grown wheat blocks, moves to them, breaks them, and finally replants them.
FarmTask.cs
Task responsible for finding, breaking, and replanting wheat.
public class FarmTask : ITask, ITickListener
{
// Add additional costs to Jumping in order to discourage
// the bot from jumping on our crops.
private static MapOptions MO = new MapOptions()
{
AdditionalWeights = new MapOptionWeights()
{
JumpGap = 25,
JumpUp = 25
}
};
// https://docs.minecraftbot.com/api/utility/locationblacklistcollection
private static LocationBlacklistCollection BLACKLIST = LocationBlacklistCollection.CreateGlobal(3, // blacklist location globally after 3 bots fail to reach it.
600000, 1); // blacklist location for 10 minutes.
private const int GROWN_WHEAT_METADATA = 7;
private const int WHEAT_ID = 59;
private const int SEED_ID = 295;
public override bool Exec() {
return !Context.Player.IsDead() &&
!Context.Player.State.Eating && !Context.Player.State.EatRequestQueued && // do not run if we are about to eat/are eating.
!Inventory.IsFull() && Context.Containers.GetOpenWindow() == null; // do not run if a chest is open or our inventory is full, as in that case the store task is running.
}
public async Task OnTick() {
var block = await Context.World.FindClosest(64, 8, // search 64x64x8 area
WHEAT_ID, CpuMode.Medium_Usage,
consideredBlock => consideredBlock.GetMetadata() == GROWN_WHEAT_METADATA // filter to only fully grown blocks (determined by metadata).
&& !BLACKLIST.IsBlocked(Context, consideredBlock.GetLocation())); // filter by blacklist as well.
if (block == null)
// We didn't find any grown wheat blocks close to the bot.
return;
if ((await block.MoveTo(MO).Task).Result == MoveResultType.Completed) {
// Successfully moved to block, attempt to mine it.
var mineAction = await block.Dig();
await mineAction.DigTask;
// Attempt to replant at the position that we mined at.
if(await Inventory.Select(SEED_ID))
await block.PlaceAt(); // attempt to place the seeds at the block that we just mined.
}
else {
// Could not path to the block, add it to our temporary block.
BLACKLIST.AddToBlockCounter(Context, block.GetLocation());
}
}
}
public class FarmTask : ITask, ITickListener
{
private static MapOptions MO = new MapOptions()
{
AdditionalWeights = new MapOptionWeights() { JumpGap = 25, JumpUp = 25 }
};
private static LocationBlacklistCollection BLACKLIST = LocationBlacklistCollection.CreateGlobal(3, 600000, 1);
private const int GROWN_WHEAT_METADATA = 7;
private const int WHEAT_ID = 59;
private const int SEED_ID = 295;
public override bool Exec() {
return !Context.Player.IsDead() &&
!Context.Player.State.Eating && !Context.Player.State.EatRequestQueued &&
!Inventory.IsFull() && Context.Containers.GetOpenWindow() == null;
}
public async Task OnTick() {
var block = await Context.World.FindClosest(64, 8,
WHEAT_ID, CpuMode.Medium_Usage,
consideredBlock => consideredBlock.GetMetadata() == GROWN_WHEAT_METADATA
&& !BLACKLIST.IsBlocked(Context, consideredBlock.GetLocation()));
if (block == null) return;
if ((await block.MoveTo(MO).Task).Result == MoveResultType.Completed) {
var mineAction = await block.Dig();
await mineAction.DigTask;
if(await Inventory.Select(SEED_ID))
await block.PlaceAt();
else {
BLACKLIST.AddToBlockCounter(Context, block.GetLocation());
}
}
}
StoreTask.cs
Task responsible for storing items into the nearest non-full chest when the bot's inventory is full.
public class StoreTask : ITask, ITickListener
{
public override bool Exec() {
return !Context.Player.IsDead() &&
!Context.Player.State.Eating && !Context.Player.State.EatRequestQueued && // do not run if we are about to eat/are eating.
(Inventory.IsFull() || Context.Containers.GetOpenWindow() != null); // run when our inventory is full or we have a chest open.
}
public async Task OnTick() {
// Locate the nearest chests.
var chestMap = Context.Functions.CreateChestMap();
await chestMap.UpdateChestList();
// Attempt to open a chest that is not full.
var window = await chestMap.Open(ChestStatus.NotFull);
if (window == null) return;
// In this case we deposite all of our items, however
// you could extend this by not storing food.
await window.Deposit();
await window.Close();
}
}
public class StoreTask : ITask, ITickListener
{
public override bool Exec() {
return !Context.Player.IsDead() &&
!Context.Player.State.Eating && !Context.Player.State.EatRequestQueued &&
(Inventory.IsFull() || Context.Containers.GetOpenWindow() != null);
}
public async Task OnTick() {
var chestMap = Context.Functions.CreateChestMap();
await chestMap.UpdateChestList();
var window = await chestMap.Open(ChestStatus.NotFull);
if (window == null) return;
await window.Deposit();
await window.Close();
}
}
Last updated