# Wheat Farmer (intermediate)

**FarmTask.cs**

Task responsible for finding, breaking, and replanting wheat.

{% tabs %}
{% tab title="Commented Code" %}

```csharp
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());
            }
        }
    }
```

{% endtab %}

{% tab title="Raw Code" %}

```csharp
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());
            }
        }
    }
```

{% endtab %}
{% endtabs %}

**StoreTask.cs**

Task responsible for storing items into the nearest non-full chest when the bot's inventory is full.

{% tabs %}
{% tab title="Commented Code" %}

```csharp
    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();
        }
    }
```

{% endtab %}

{% tab title="Raw Code" %}

```csharp
    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();
        }
    }
```

{% endtab %}
{% endtabs %}

{% file src="/files/-LtGklFWfTGaYXyZJES4" %}
Full Plugin Source Code
{% endfile %}


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.minecraftbot.com/examples/start-plugins/wheat-farmer-intermediate.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
