Farming Station #568

Merged
ferriarnus merged 39 commits from farm into dev/1.21.1-7.2 2025-04-25 21:38:46 +00:00
ferriarnus commented 2023-11-23 22:09:36 +00:00 (Migrated from github.com)

Description

Adding the farming station

Closes #142

Todo

  • Make proper API
  • Energy balance
  • Model

Checklist:

  • My code follows the style guidelines of this project (.editorconfig, most IDEs will use this for you).
  • I have performed a self-review of my own code.
  • I have commented my code in areas it may be challenging to understand.
  • I have made corresponding changes to the documentation.
  • My changes are ready for review from a contributor.

Summary by CodeRabbit

  • New Features
    • Introduced a Farming Station machine with a dedicated, user-friendly interface that displays energy levels, range, and activity states.
    • Enabled various farming tasks including planting, bonemeal application, and harvesting, streamlining in-game agricultural processes.
    • Integrated custom energy management parameters to balance capacity and consumption.
    • Expanded localisation support, including an Afrikaans entry for the Farming Station.
# Description Adding the farming station Closes #142 <!-- Follow this exact pattern for every issue you've fixed to help GitHub automatically link your PR to the relevant issues --> <!-- Remove this section if you're submitting an already-complete PR --> # Todo - [x] Make proper API - [ ] Energy balance - [x] Model <!-- For drafts, fill this in as you go; if you are leaving draft, make sure these are all done --> # Checklist: - [x] My code follows the style guidelines of this project (.editorconfig, most IDEs will use this for you). - [x] I have performed a self-review of my own code. - [x] I have commented my code in areas it may be challenging to understand. <!-- (Although we prefer code that is readable instead of over-commented) --> - [x] I have made corresponding changes to the documentation. - [x] My changes are ready for review from a contributor. <!-- Thanks to: https://embeddedartistry.com/blog/2017/08/04/a-github-pull-request-template-for-your-projects/ for the building blocks of this template --> <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit - **New Features** - Introduced a Farming Station machine with a dedicated, user-friendly interface that displays energy levels, range, and activity states. - Enabled various farming tasks including planting, bonemeal application, and harvesting, streamlining in-game agricultural processes. - Integrated custom energy management parameters to balance capacity and consumption. - Expanded localisation support, including an Afrikaans entry for the Farming Station. <!-- end of auto-generated comment: release notes by coderabbit.ai -->
Rover656 commented 2023-11-23 22:10:10 +00:00 (Migrated from github.com)

Does this supersede/build on #463 ?

Does this supersede/build on #463 ?
Rover656 commented 2024-07-03 18:29:24 +00:00 (Migrated from github.com)

Before I review, is this PR functionality-wise complete?

Before I review, is this PR functionality-wise complete?
ferriarnus commented 2024-07-03 19:55:13 +00:00 (Migrated from github.com)

I think so yes

I think so yes
Rover656 commented 2024-07-07 01:48:39 +00:00 (Migrated from github.com)

Not possible to merge this into 1.21 as-is, but I will help you with the migration to 1.21 after the project reorganisation :)

Not possible to merge this into 1.21 as-is, but I will help you with the migration to 1.21 after the project reorganisation :)
dphaldes commented 2025-01-09 04:13:26 +00:00 (Migrated from github.com)

@Rover656 how do I get the CI to work? If I run spotless locally, it changes a bunch of things unrelated to this PR

@Rover656 how do I get the CI to work? If I run spotless locally, it changes a bunch of things unrelated to this PR
thatmaxplayle commented 2025-02-22 18:30:05 +00:00 (Migrated from github.com)

Hey everyone! 👋

Just wondering if there's any progress on this (as a new viewer of the project) as I'm looking to backport this implementation into the 1.20.1 version, for my personal server.

If anyone could give me any heads up/OK to go ahead with that, I'd be much appreciative.

Cheers! 👍

Hey everyone! 👋 Just wondering if there's any progress on this (as a new viewer of the project) as I'm looking to backport this implementation into the 1.20.1 version, for my personal server. If anyone could give me any heads up/OK to go ahead with that, I'd be much appreciative. Cheers! 👍
coderabbitai[bot] commented 2025-03-16 20:25:58 +00:00 (Migrated from github.com)

Walkthrough

This pull request introduces a comprehensive Farming Station feature to the mod. It adds new APIs (enum, interfaces, and a task manager) for farming interactions and tasks, alongside the implementation of a block entity, GUI, and menu for the Farming Station. The changes also integrate energy configuration parameters, network packet handling for farm soul data, additional recipes, soul data management, and utility functions for tree detection, as well as a JSON model for the block. Overall, the modifications establish the core functionality and interaction flow for the Farming Station.

Changes

File(s) Change Summary
enderio-base/.../FarmInteraction.java, FarmTask.java, FarmTaskManager.java, FarmingStation.java Added new enum, interfaces, and a manager to handle farming interactions and tasks.
enderio-base/.../Integration.java Introduced a default method registerFarmTasks in the Integration interface for task registration.
enderio-base/.../EIOTags.java, .../lang/af_za.json Added a new FERTILIZERS tag constant and an Afrikaans localisation entry for the Farming Station block.
enderio-machines/.../FarmingStationScreen.java, FarmingStationBlockEntity.java, FarmingStationMenu.java, package-info.java, MachineBlockEntities.java, MachineBlocks.java, MachineMenus.java Implemented the Farming Station block entity, GUI, and menu, and registered the block and menu within the system.
enderio-machines/.../MachineFarmingTasks.java Added lambda implementations of FarmTask for various planting and harvesting operations.
enderio-machines/.../EnergyConfig.java Introduced new configuration parameters FARM_CAPACITY and FARM_USAGE for farming energy management.
enderio-machines/.../MachineNetwork.java, FarmStationSoulPacket.java, MachinePayloadHandler.java, FarmSoul.java Integrated a network packet (FarmStationSoulPacket) and handling logic for managing farm soul data.
enderio-machines/.../SoulBindingRecipeProvider.java, SoulDataProvider.java Extended the recipe generation and soul data provider to include Farming Station data.
enderio-machines/.../TreeHelper.java, .../models/block/farming_station.json Added utility functions for tree detection and defined the block model for the Farming Station.

Sequence Diagram(s)

sequenceDiagram
    participant U as User
    participant GUI as FarmingStationScreen/Menu
    participant FS as FarmingStationBlockEntity
    participant TM as FarmTaskManager
    participant MT as MachineFarmingTasks
    participant NC as NetworkHandler

    U->>GUI: Interact with Farming Station (e.g., toggle range)
    GUI->>FS: Relay user command
    FS->>TM: Request registered farming tasks
    TM-->>FS: Return list of FarmTasks
    FS->>MT: Execute FarmTask (plant/harvest)
    MT-->>FS: Return FarmInteraction result
    FS->>FS: Consume energy & update internal state
    FS->>NC: Send/update farm soul data packet
    NC-->>FS: Acknowledge and update soul data

Assessment against linked issues

Objective Addressed Explanation
Farming Station feature (#142)

Poem

I’m a hopping coder, full of cheer,
With Farming Station magic now so near,
Crops, energy, and tasks in a row,
My code garden continues to grow,
A merry dance on digital ground –
In fields of bytes, true joy is found! 🐇🌾

Tip

🧪 Multi-step agentic review comment chat (experimental)
  • We're introducing multi-step agentic chat in review comments. This experimental feature enhances review discussions with the CodeRabbit agentic chat by enabling advanced interactions, including the ability to create pull requests directly from comments.
    - To enable this feature, set early_access to true under in the settings.
Finishing Touches
  • 📝 Generate Docstrings

🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Generate unit testing code for this file.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai generate unit testing code for this file.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and generate unit testing code.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.
<!-- This is an auto-generated comment: summarize by coderabbit.ai --> <!-- walkthrough_start --> ## Walkthrough This pull request introduces a comprehensive Farming Station feature to the mod. It adds new APIs (enum, interfaces, and a task manager) for farming interactions and tasks, alongside the implementation of a block entity, GUI, and menu for the Farming Station. The changes also integrate energy configuration parameters, network packet handling for farm soul data, additional recipes, soul data management, and utility functions for tree detection, as well as a JSON model for the block. Overall, the modifications establish the core functionality and interaction flow for the Farming Station. ## Changes | File(s) | Change Summary | |---------|----------------| | `enderio-base/.../FarmInteraction.java`, `FarmTask.java`, `FarmTaskManager.java`, `FarmingStation.java` | Added new enum, interfaces, and a manager to handle farming interactions and tasks. | | `enderio-base/.../Integration.java` | Introduced a default method `registerFarmTasks` in the Integration interface for task registration. | | `enderio-base/.../EIOTags.java`, `.../lang/af_za.json` | Added a new `FERTILIZERS` tag constant and an Afrikaans localisation entry for the Farming Station block. | | `enderio-machines/.../FarmingStationScreen.java`, `FarmingStationBlockEntity.java`, `FarmingStationMenu.java`, `package-info.java`, `MachineBlockEntities.java`, `MachineBlocks.java`, `MachineMenus.java` | Implemented the Farming Station block entity, GUI, and menu, and registered the block and menu within the system. | | `enderio-machines/.../MachineFarmingTasks.java` | Added lambda implementations of `FarmTask` for various planting and harvesting operations. | | `enderio-machines/.../EnergyConfig.java` | Introduced new configuration parameters `FARM_CAPACITY` and `FARM_USAGE` for farming energy management. | | `enderio-machines/.../MachineNetwork.java`, `FarmStationSoulPacket.java`, `MachinePayloadHandler.java`, `FarmSoul.java` | Integrated a network packet (`FarmStationSoulPacket`) and handling logic for managing farm soul data. | | `enderio-machines/.../SoulBindingRecipeProvider.java`, `SoulDataProvider.java` | Extended the recipe generation and soul data provider to include Farming Station data. | | `enderio-machines/.../TreeHelper.java`, `.../models/block/farming_station.json` | Added utility functions for tree detection and defined the block model for the Farming Station. | ## Sequence Diagram(s) ```mermaid sequenceDiagram participant U as User participant GUI as FarmingStationScreen/Menu participant FS as FarmingStationBlockEntity participant TM as FarmTaskManager participant MT as MachineFarmingTasks participant NC as NetworkHandler U->>GUI: Interact with Farming Station (e.g., toggle range) GUI->>FS: Relay user command FS->>TM: Request registered farming tasks TM-->>FS: Return list of FarmTasks FS->>MT: Execute FarmTask (plant/harvest) MT-->>FS: Return FarmInteraction result FS->>FS: Consume energy & update internal state FS->>NC: Send/update farm soul data packet NC-->>FS: Acknowledge and update soul data ``` ## Assessment against linked issues | Objective | Addressed | Explanation | |----------------------------------|:---------:|-------------| | Farming Station feature (#142) | ✅ | | ## Poem > I’m a hopping coder, full of cheer, > With Farming Station magic now so near, > Crops, energy, and tasks in a row, > My code garden continues to grow, > A merry dance on digital ground – > In fields of bytes, true joy is found! 🐇🌾 <!-- walkthrough_end --> <!-- announcements_start --> > [!TIP] > <details> > <summary>⚡🧪 Multi-step agentic review comment chat (experimental)</summary> > > - We're introducing multi-step agentic chat in review comments. This experimental feature enhances review discussions with the CodeRabbit agentic chat by enabling advanced interactions, including the ability to create pull requests directly from comments. > - To enable this feature, set early_access to true under in the settings. > > </details> <!-- announcements_end --> <!-- internal state start --> <!-- DwQgtGAEAqAWCWBnSTIEMB26CuAXA9mAOYCmGJATmriQCaQDG+Ats2bgFyQAOFk+AIwBWJBrngA3EsgEBPRvlqU0AgfFwA6NPEgQAfACgjoCEYDEZyAAUASpADK2VmgqyjcEj2wAbb5AokAI7Y0riQ4rjedJAARABiLszwGEQOuNTw+BgxkADuaMgMAdTRcuGwntiIlJAAZpQU8C4YVegY9KjwShjitfDRBdZ2LcwCNQCsAGwAHPxYAOLqABLYAhowFTyNzC7y3NgU3PjV/LXlqLYoyAQoPRSK2AyeaJDkuXUk1AckADTlnrVEslUoh0uIsn9cggGLArrcaO1ojcyLBME9/nVsBgxJkMGhvOp5PgzrhNrx8CIxOsPEN0LRaAFENVkEhECFIGYAIwAFgATH8CRgANbAlBhWjwAJibzyWr4PhoPAsDIMcJUBgilLrIwASSwpM8SkQRXg3HBGD+9QojWarXweEF0nQ4UItHwkAJoPK1FuDG82CN4QKQuQbJh6EKxXEKWd5O4NQAglYdX8BPi0aKyJQiLI/ph6EopN58NxRS9mIoSN51gnkMSMQwDgEepBQSVThjbH8DZAkzq2vQK0o/OlECHIKipJAxmQFMxuFEaLRIQgohisxQc9P09jPKOhf4SDtksgsX0MEgKrQa/T1Lj8TK84wKhrPWFUOSJF06H8mBg+hQSQxqSPo9kwSh0hUjIuhi5KUrgADkoa4LIa5ENg36OogfyoqeiKblknjVN4tRgAEX4kLkfzJH6AZOkwrDsMgcp8H6LiEnm7QToMTDWtIRztKKbqNmwPQZFkkDYNwtAlIg1KbIqpLyrcEoMLJ3phGBqIpE6LieMUtCysp5H9O8ZR/rgjQCEqFByeYlgAMIsKJuDII4ziuO4mwMS5db6pslw0f6EHJMEkr9Mg+aQBKxpVIguKRRWMYSOx9qFFklnwNZBC2YeRAuBKwGbG2uCtFF8DzgSanmnWJLedppDIHGxylLKDRNBQLRyZARg2PgUgUJMUx1JKXrBsgUIkAafCkhcdhsvGtl0E6ynWfA3i0KeAmxiZaW0gAFGY3KTAAzAAlNRgnVWWCi7p1dTKT2ATeOJGCIAg3DTlNuQkLOPa4Lk7owpgjXrHE+C+PguSirN2GQH1A1DZMra/eOf4ATs5pzHkFTTRitRYjiWT4oSHY9oF6WVVNnhjCxnjkk8dCitDpLOiZlFg+1trIIyAmbegtQYxkRa5q22BEI10apCBmmbAT2LmiTKFwskSjRAxC7UxoRhLFDJADX8COUEjrz4DQ1yorLniNnxLYlZ49bk3YakYBgZtfZAbCbtEyQ3AN8USZyGi8pyEZiq26TtN1HhEoLNQFPFba7nk6iwj2SREFQWMM9I1zukHIcCzQCpbBSohhAE8r5ReABer2XapGQxi80O+MC5BMjBFTeJ9vskJn7Y9m8HxfAE8Luj2UkMaK/u4trBgJm7eMWVZNl/LQ3Coht0h/FQSC6eEoiwBeal+MEoS4ugAj2mEpC4FLGJOT0yTYHteo0APWP7Q5Opna2sigiPDBQGFAhR/BcriGGlt/BYgvEVIiRxIi5xdBDD0+BT4ynQN4YuyAdgYHkFiZ6JR6B9CiHDKE8BwxMB8PQDWVVB6bHZu8HOTJ54ABkCiRFFjLHYAAPBcaBUKeBIPwxkzJ4SUFCLcWC9xM7IMdgFGweYLYkHkHpW68UlCNBjGmDURwKAPx7BVTWLlXrj0gLPQOwcAAMGhQ4sR4JQRAxM/BVAdv5EgkoUYUAGvJVRKMSAHnRpKTGl9lJoG4J+fEdR7jMAbBlVeOU86l0ZvQFmacEAyDQHo+UD8SCC1yQ3ShTdUgvCNJKAEykmC+BUPKMxUUfJYmKVjdJyR4msCaShee+hjDgCgGQeg9ZFKEFIOQLO6tnLsC4Lwfgwhy6SCdOZSsVBVDqC0DoHpJgoBwE6JFLAwziAbmIXOFyXAqDvDZB5eQSytEqDUJobQugwCGF6aYAwAzKCZDAGmaoAB6RAFAGC/OPBgX5Qg0ApV+QxX5HzGj4F+T8kgvyInwF+YCQCvyEiAXfsoImGANDgpShwAwMRSUGAsL2HUhyxnHMuTsVwHZgY6UQEYBMrxKKQDIE4ZQWM8RsHoAAAyxcwHF6pzQCu4jIX6WBfb3FoI8H2HjIACoYhoWFmQNCIq0KWDQ6LmASu4NkoUaBSDyVQFyuJShzxOjlAcDRkdXJcCFTqAAcjqewSwACiAARAVfwBVWAAPIAHVPU2B9X65VAAhNhgaHIAGkI2cUFTqeYLrA3ht9X4k4f4k6uQ9PAIUVZ5ABF4NIdg0V4Bx2bGEe2dY+B9zFQlQ8L0lwwT1aKEsPLm2tKVREhczS55GHsr2bB3asjJJ7EoNiWdm31hEfottyl9gCCqpy5+4hpBGCgC6jlFq6RKFoE64VorsniukYajUJrPAqpYGq/CGqtUot1YkCV6T7WYHzc6t1Hqk3KqDaGzNkaBUxrjYm31yblWpvTUB7WpKYjbreeqwgiL/mAuBdoUFhK0BQpYDCh98LUMorRYkTFiRoDBgJRCtAxL4PkssAmKloyeXRDpbsRlDUt0L3Ze8RtgJ0R8uiEK8jwYJW4S+rOWVDwngdCVbe5g96tGPoKCQbV8AX2AQNUa69ZqWQ9EoPxw0+TkgH3iikNcbAlLLmVXqyNFDwzpCLdcQGPAXBoEs04rgLwQPFg1FYY4ErBDwUPGW6oz94GtnwOtHgxw7wSSit54VwJ7BglxIFuZYgQuMnYFAgEiRpy+YPDlrpGxPCWdgIoQ8pVOqRWVSe/TTasjpfgkU66EXG1nsvjLfgDAbbIHldo6WcsgQxhYXZYdFKExjtnROmCU7RAvRm29DsC7cnRGXasNdxWIrbsgLu3jDXDMHroMekTY4JVtPk4pz5+BNUqbUxp/VBgoAAFkpoVfoGgekJ26uJFPXiuoiR9pRsK/50MUXvB/CSykFLZi9Ug/QUKT1G7ZBnQuzKw72Sb3Coo+d6RV3kN3eqA92zJKyXPaQwR75Km0NApBWC6juHmD4aU4RmnxG9VkcArjoUL3MDXooFRolZOEOTaY0cttbGGX1iZY1VlPHGAvU7sJ7nwY+d4lIBQMTgwZwY8stJxVGICcEaJ6p59tnXNXtNRsVAbFO54OvbVt8HYO3AXGuUe44tYSYAkZ1aJAqEzWkEWwpAuBAtnAFTz5HllZDNfLuQ6EsIyBqW4GyVtzwgxjiQlsTIjRlZRX+sGMUxFah+MVwnUuX5AwvBKpQz273KsCrvjzxA+00caVuHeEmNcnSF7HAWr0ZQAhEFD58t3Y4Lae6IBkm9OLP64nVwLi7Zx1CStNmEXXWx9aZCqJg5IXeCQ9+vKVzP451HOIMaUFTgyPFeN4Ln0mVRcvKo1npaA+AJXlcq1akzsmjdR7uFj0PF4mPxpDt0im8GcV9GCgPi/0FS+1oB532l9hz3lA4kgBxyL33HbwcQQNFGHn3EnU2DfBvAlEVl8G4VgACCIlS1VD7k1w/R6B5hIFCxyxjAlGrQrX3HCFkHjGQH2isDYQTBdWgD+CjUDRdU9Re09QTDYT+CWATBsAADVPV7BoA/51Ef9yBrxh16NR1i5XoiCjMZ1DCVt+E1tBk+AV0tsN0dtntIAHIldIpvsj1ftVcxxF9Nd0cX871Ccn0dVSdXsG9PsXCnVrC69a9VQQ9QRgBMCxw9BIBm9xo29vDwC3DmAedPDKABV7C3srNjtXCBVwjVQJAosQjEDgxkCWx780CUIoczsDxsDUinD0jMj+cvD7CbBRB5RyiftI9gxo9XBmiK8VcMi1d2jsjcjgiCiwjNs68UDX8Ah399oAABF1M2F1HwPwOI3nCYwXAAmPfgdvNpKUHo5VA4oYkXRDMAIwZDanP5AFOnTDBnSFaFZDBFdnUsEjDFaHIgWHc0IXGjK4sXalFjegKXWOZ8EGLjNlYePjLHV4dzITX4/4tLNfTfKTeVGTaRHsY3VnU3EnV9S3Y1a3HZPTYuI7LQp0aoAaaJOA5g9PegG4V3VILtJbOGIKAMUUAITKbfGMaoOgZicJVseMBgKtOvI4eKc0cBdo0UI4H6ViCdJwM0XESDbSWgQUVIFKOFVoFklBSAsWcMQYCrHedAXhU0qKd6T4WydYHUMIT8b8XBYI5JO+BsJsCteUmoXNZU6Ug9ObbyJU/lGLBUyDb0tgddbMeQd9H3EsLGG4eKZgHwBhZ4PFbUAwGkeE9EfEKAzkwMekmCQQdINpHsARWQGoE8SOJ4bsMkWLLGBRPLQCUUWvCEAcfGEbVIKgHSUguLPECg6iMIcTcsaYhxMM0Ua+cgNgaJKKdUzU6Ke4VPGJFgHgF6JglcShNONAJzcxbJahFsEslcxCZCEoP4SUnsv4ZxaLU8301dRHddCIUWcqGgOJNsDUNM2Es2FQNcK1RUbBevKzf1NxWHDUSNB8KGFRZcwRGoG4NxNoMUIBF8g8eLEU0QcU1jCHGLKU1U1sCqJMwxTYDrAHd9HsG8jUVsnkg4OBIbfSaQHwMIes9AVMm3J0/Ip8/RdiTBaofNfcyCigbPbuDoJ838KMA+CyERMIBxIxBrTrFsqKbLLizYfiuCuJNAWoYuDEaSmVJqAzeUfleeQNWk3was7Hds1EprX3I7ZPCJNPdSHseWPFJWEtIIDCAIEhYUvU5sjHDEfKNgE8+4KvG6UECgR4araIfIeQG4AisId9PUtgJlShcbEdKbAwmqf04wxbUw+dcwy/SwrwVdOvbbLjKAUVI7BAvolE1LMyy7VVPw+7c3V9KY/I0qwou0o8ICg8O+ewX6TacGCgMHYHUHY4DC44rAUY5LCqjAHIoIxq0I5VFAu+J+S5OgfzBUlI/Hcq16SayAPIj7GY5VUoroA9Ba7lWgZaygKo98Ya9Isajahqnapqp1BYwMkgZHSM86iMzcUWa+CGT4LABM3CkgS60amHcaza7ayre6qDJ8tqxIqaXWEgVay7da8VW68GmagVFq5gaGu+BMc0hGkapGtLFG3o5qqG9IUijqioFwVvQGgmprIm3a4TItKwF6MsvgO+ZmnivGq64Gm6qau6tGhHPzQa9m2s3ELmoGv4kG+miGgVOaqaX4mwaE8W2mia6WtGr6qIH3MMkgKNQiSc7wZWkyqWvm1Gw9J1NhfWKsGG3AC2osQ2xsnm5Gk24mp1DWn67idoKIb1ec1vQWoUf4+mA8sQgapqY4YOxHMHSLdacOjUaPUmEipHFHP4DG6GhCmmo23mra6YmWwNFUlxYALo5xA4J4NhdBV6BIu+OOlCaAXg+G9Oh2yWzOsGl25Vb82iyAf7c0Qu9uwCsmoUfqiOwai8yHDu0mo1COI1euoCRu5GujCnG495KnVDR4jDZIF4nDN4gjD4v5YjegpbX5OfJbQE2jMlEE5jcZcEpwelSE2XLjGkDglfO4A3WrYeOA6KBbNzLGYszYdG/TefSqzHJ4dYewUU8UjBUWVfBA8Ct+gVNu38/a+gYfUfCgHY1vHYrIvgB3TXP+AAbwAF8BVdM/ydrOh9NEQmT3RQLeMqZTEUr6Lf6P4lt0cKSESbgkHAE+A9VT9TwzNSlWjxiNdsjbgk4gG9t3QRFQ9RR8yFTqKKwpAcqhxULrMC9Nh+plBfAI4gqxBvgyZ8LAHZHMM8Jb6dD0yFJbw6y6pUA36F18xwK7LyDSZ6HD6NrzKESygHTCo+HYrtIkA4kHE96SlAdAJT9PYJiXI1zwx8hkAl4t8vw0pMFqN1pPzVNdDJtptTCbh5sTC6GzhVtsr+ArC5jVQCqWU1azbW78kfywgEG8pkHUH9p0G9jQnBGKBLrMzZ8/6mH8c7jl70N6dsMmcWcbtt6kVd7OnXoD7xmATsMci56IAF6emacV7+nGdN7WcRmmckpfl0giBflPUdRA0KMiA5JsMT7RcGNxcaVJcr72MZdONSnYSOVc0HU6sw1oAdQ2EdQAAtMNewbXKVWcJq1KyGo8RACVNI3tI3fZw5k1MF8vVhJixg98frYzbQsObzI5+NVRYADGvQCVcqPTA/eAI/SSXho3HyLII5z/aYoi4qTKGMGIK0cQQ/JxGIdYdYgtDuPISRQ8OR9bTBxQJRnEzJFGPFVrQJ7rHsPAr+5CPeafXAFifICgT7LiN0J0GJ/ENSiR0EUUex+8AkZWZSYsEfBgeeGkaVsJOqbHN5j57535iVHZrBYsXIIUmabyEoIgNAuuCxpShk45ZkygZl4lpxP4FEDMCLHZkffkgBJ8lOWaOTDGuF8AsvNRqgDRwK4KnRqKfM+itIgIEFSSbETjExxK9JlKzJzYaddKnJzlLKpdQpvK4p2wwqvbJ5idF5mW4oie8QVUc8aJTF7F3FjAm1z5n5mwP56RNI9Gp8uFy7RZh4vp54gZtZ4Z1DCl0FHZvZg5o5k56jWZ8neZ24pepZxdtexke0QFaQZFJkKaRAIZuFX5Fc3ZlSgAfTrgJWcQwDOb0MY1BIvrFiuQ42hIeYV3YAZXE03yBYrc8AACl7AJCRo1wJLNgExahGhjVMBkAn3sBr00FT5iWzF6LkctEO7A1PZFAy9HRlUYgE7rs4VHtgQX2PKYguB4h2y0hXoYgfh/mJM9c5UFVrN7NvcmR0EmhzYMQi15ABVaPCcWSmOQa42Z8LF8R2Q2OG6OPzQ2XEWLWJIbGo4MRfNu8zEFpF0Ho3XPBfiNPL4E7FPv6ytFA8xIZoYYxV8bgxhK1EBSzDdUP0O0BMP55S3krm1oP37sm51cm63+XcqbCIg7Cd091ACGaaPCs6ONU5PmPWPLPTLshvCBV52kVlnnjz3i6r2E5b373MhH2QZkVag320AP26a5nKdWcwAdgYQTM73Cu17l28N3i2uEAO4oUCR2Bfl0JUVjRqDQUVb7AihpVj7gSLm/3aUbnpczhb6QPh4p3pvZuyAeOMSn6sTDdcTqqTd+uOuNA/R+gegNAxuNAJvpUtMrdfha2ERPHlU+d2vyAZvJvYiM7zQ3sWg8WiG82WDssmCvKqBN5ilXFqgG19GzOMQsvxrQnPvVNR737rV0o3oHVXXtwNRM57QuIopsoCB9QxLvg4ZBgfoNHBgJRRIA5ltkOiIdv8UT9nmtGcpO9xBu9e9ioWfFOZF+pvxBwuVLopAeh5QHyuIIgohzypo8LPAKpcO6eyAGfxsaRZaLww9iHKtUBU3Ghvt9R3ROLJJPoex5gABVfsDWQiJg20sIDBcChaSgcA7PTX9Qalxqon+kUMS2tNw8fCZJlOWgO+Dk7EYKG6AVByCJbJdQeUF6j64NLoO+CVBxDcLcUEOpUgDz0sp8AVLozaUnkgJ+fXbwKwShItCgJPkPqaVP4yQUov26UvlGe+YESnonrAA526PodCJbfgAaFm7s8gx8cOXMg+EniSCS/ACWWcnsL8eKNQA1yEp6aE1sn3APHEL8FCavlPmCGKUsjEM78gbPOtM1n+5sLRKNIgT3khiAqA/XroboLufMNcYio1AnrERB9VGMeiy3lMUl5/FSXoC6IhQH/aXuTwCB6UDKI9WGPC2QCWVU8/1cCsazrz+MteTQQ/GWC4gX8x8VFDAux2y7Z4/+l0RhoE21I74JoyfW9gjzcRw8DCqZVJgxjLbBcJ4lbD+uyTMKLoouXbEprtkcIV4Za23SbrlxO74kj+0gC7sN2u63d7uu3K4vPSPYtdxBnXU9lhlWa9ct6ygzZlkARSFY72qGfcL8g+4DcSAvxFvPNzoxn0JcrGFbjfXuZeRPAw8UhDemMEmYzB40QEsw345PBassPCKB2EiL8M8cxiKILQ2bQOJyBe0PUmyVMKQsXgL2EzEUBUphAhw6wT1Nkg3L95UAQA9Fh6HcwCAZImIBWF1mgSOYD4PmQenC1LRg8FeUdPwAlhsyJA/aVdIAoMENRUAPMNpE/IQWgJ0QIK4WVIEUBLBwwE6cMRABEk1Lt96A5APGEq1wDKJuWNPZAKiB8QXwYwQw1PJaGdYhtWylkX6N1AcFoITWCPT4A5iLxjAo2MgeQDCFECahUgVaDEMPThBsh1AQffaDEyPBmg1EXEDVpKDOi2kzgKUAkOCS6r1pfW6AMeKwR6BGUQm1AVilxXdCLQWIcSKVgDn2gCIBhBTbiKsJ1YpANCXEG4RqHAqMh269FDSgCPUoA5UAYYHwYgAJh+AqkT1PZEpX7LPhbh4FT0oqTejHVpw4VH+vDkKwtDCGHdM4GyEFiUIru9pPWA2kigpQkmq6TwPtB9Ca0vQ3IaxBdHDiHpgqHI6UWRSmgUVas54S8KxjBBo8dQZwD4W7C9zBlyyso7QC9AVGsi4RnwhERom5TvUtwslfUTVljDSiTRJQNMp6mtDKQZyooUhrxDYptobgWDa2CpgmhQQ9wjCJyhUgoYQx+CBIItM6BNJYi0A5pDQmPCSBMhgQu8b0ZRWdAJ1/RNAHGLOHIC0jdgQ/fViPx7ArCpAuI6WO7kJEHgmeoTXhDhTiQE9cgrMNsNnxlw+1WyM5Q0GOP7TzkbQNAEfqrwOBQJQIAZPiJlgIBpiIRlQaoK5T4Ati1hRAMvD0OzLugYxjw00boxph6DhWngbyp4BAQbQ/gUkGSArxRGUMvEk0LAHuMAQmN9K6jGASK2cHroU81lcTrZXY7eNMA8VRzs611bKRIql8d9JENaAYjNItdPZPQAXGDYO86fa4YGTzqaU1QRqJEFQXtDT4b4GIGITVAC4/tmBs2ELlW0/rhda2XAnKjwObalMoA/AzuDLVcHkB3BE+XLncS0Fdc1BrxDQesy0HrtdBiOfQTTkMG8TTB7ZcwTM3sKokSi7EIPp2yKbds68OxawEIREIvsHINgQNFYFy4KT+JIYTampOU42gFRDNLtoEL0mCFhC0AF9qBgTTmSMhbgpSeNGsm0FbJTQeyVpMbY6TVQzkgyW5PsBJhPmLqeYF5NR6WSwWqkgKeQM0lo1HJAUiKa5JfaSFoAXqGwC+2DSKFoACUkwUlP8kqhAp6U8pkUW0lOSGikAcQpIWkKyEypPkhui3kqk9tqpwUjKfVKymNSFCyhVQm5OMmmT2pfE3yQJJSlVS0pfU2qZlKql6ThpKhNQi+2TDQAHIBUyaYpM6l+TZpPU+aWuBClroGp7hA8KtNGkvs4gsaQDLtIqmHS68x054P1NCnnSxi/eK6etLUJSEjJJkqwBO0uwWTppVkp6epLsknS3pZ0waRdMgDfS3JHk+NA9NBnJSoANkl6Q5IGnLShpihNaW5OgDhpPUKM/aTNPRmpSNJC0voktJ6krS8Z10vKQVKKklSSZ09LqfIMPaL0lB3kwbiJPXqDM+uPMq9lJNGHfFp68nCZirWaEo4LBp9RbufWW6Ac7mwHQ4U4PWjGUG62XaWfeU8EoAaGTEcsYVjvKkxcCQTaejpIkhtIXgt40Nrwle6igA0fo2gApO1mEh8WXEEIUeDYL3D9GyAfPtCVoAJgxA8od2YKhVrCi7S8IbwTakJgONlYDiLBrq3Y6EFLotEN7lK0X6kwIqUlTLO+ieGjCZSgjfUvwVzHPcTS55SmrZA1HTkX+wiMZFuDDL4Sy8aREFEWWWwvBnc9YK8iwLNndh1Q44MCO6T3LBhIMMYw0ZuUDo8UEeepDSgcIMBYs2oo8J0GP2JRQA2UwSXvppIBydls+DiaIYtEMLaxnauPTig/Cih3xahGlfwNCQWHU96huCWUu1gwDi8co8gFmuRKn4biooN8fYK5CPm9hlUsPAaNAAr439Ks3WMbDamTnu4Hhf4Mgs2nUSWZIM3mS7uwBAXAUdeO4ixEgBw5+B8k9QMQHZCgCl1jhDiUMewTHFoclyX4ttChLD5pzMwRbT9C5E5RxxCF24bcdjCLp+Bnx9Xewgny3AxiWFpIKfLCHzIjlAyjCyMrsP7mihta9ATkf/M6o2hD89SVVuWhUUEcsY4i5SOMK/DNwuIxYL7M/hs7FZZAJ/U0anIj7Nxt5q/KKGYuijUA+Fpja2C0WPG9DAwltFsOQtSAOIpQpoSoNJHUjlQpmToWljeKRLZ5eFc4ASBWkQAxsgECcx+fcMqgSiHeLAWJXb0YH6Fx0y2eiewIyoRcWJWItibFxbZcTnCtUqWYKJRwiDfCp3IWXJHXaao9BDHFIBLKdpZ1pqi07SdUsRwtCB6QtCaPKA2hg4zyTUwrAHQKyI4A6U9a6uaFdkoRQa2daGfMRbB3w+cvCRWjpHtrT0tZNS+8ssu6XUztJQcruqv2xp4ptlpAXZfMtxCLLY8ZTE5aFJqacUzluIa5fDXeVZBPlDFc5TpDmWO17lByt2U8sKLkgaAYgaIGsS2JB8FJeoF+ZLw4SyByJs3EoAivYBIrBEN8W5UCqyAPKjl/NHpS8rKLeJgFFfXFTPWBX9LalYK2YiSoOqoKeg6C/uoCqpX4qQVSyulcqi7Zu0fcSAd5VIEpX7KaVhy7lXVNCl+1I67NFwD2yiCl1roWQYVeNQJXireV+Ab6j7gnHe1hhgy/2ueJQkx0hQkdSUkasjrD0jVLQ6ZbHSTqj1WqfdCehqDZUiqbVYq52ljNCl8qsA1SKIGIB1Wp59o0RXADizHoagEiDIYYX8BhU1J7JUqoehDmdUqrOVjy91adLWW3wpoR1flKdQoDKrXoqq1NaspKKkqECWapatKLeqcjE1+a5NYStNrPK10Xqt0WwF1oTlPgBtatQstrVqrtJKdB1R1VBE9U+qca0OogE7XUrXVoKwtcSrXR9rx62NXGuOo5Wiqp1XSolQ2rrxzryasNfAHXVy59LJ1XK6dRutVBbr2qU0ewJXOpr7q/uE6xOm6rXX1rwVvSieRzVZrW031Z1JdRgALWPqW6EqtdCOo/Wi0lV3639c3Q9Vro5auABWkrTA3drj1z60KY9W5FsABFsgN6jhNTAarNav1HCunng0rqj1f6yDXXlzrkEC60gC9iXTLrmgK6U0FoTXXjB5qu1RGlNSRrTXFqDqnFRjbXX2iF1qNJABVWYjMVMaAaN6zWUmrY11r/10ah0WuBWK/jrQ34aLnXgTACBAqZ6EvphkoAA9sAjAYSnpreoWQdNFAHUNZgxUS8GUXnMzc/MxWuA/gn6qwizUoCEbD17GiDZxosSkq9FJABMOY31bfwMlhPCou2KIDyEIYWiUuvgCFBSQNAVgPyt+D4DFgYtUkBLULy0Rub71q6zzRlPuCQq20ryiFH5oC0uJ7AsgXcLQCC3zgQtRzIMOFvhmRbKA0W2LdwHi2JaSO7DXkmOok17KpN7mmTaRq430AjFgc0rb2Wq1HBP+dWnZhFu3gUAWtcW9LVXhqApbWty2pLVlqFFqr8t5caIDU37QygdQqSsUrgCcg1byATBfaN6icXnbMluAPUL/JiW29XIW22lYhrCK7aoV9AGpj6vLjHaB0p2u7S9tbw3b0gwOy7bgD5xtao0GEebc9sh09a1qt65dQNvBmYKGaKxRwBppNBjBPUL8sKd5oOo/Kqw+AL7PxpQp8ELeQSpcPjorReLcAb2sVU1wWZU5hJqg/mSuwfaSTnIOg0Wel3Gpc4+tr0PTbLPOaUolu1zJWWt3sHcZNuLRCWtlz017dpUUcg3NZjEoDIHZOaugApL02/dJNNatjUD0RZpEPGB8Wga43RDdikeZiUxSjmvGJEkS9vDxb3hczs9gq8oRAFwEIgd5983PFltAy5QC8XgJmkzHwB1DeoTyLmuHoioc2tl7d95ZBUvCgh+70BPPFkGECfzNxlUXREfIFVkBxBGgAyGUFGlkA0BYdtQYURrwQL2BiwrkMBR0BRbWoKGLfU3oFL2iIB69uPdcQaUfKgsrFXJfkt3oR4+5S5OEXdRXOtKQZxyXs/ELfKrD3z+AeAJ7V3rNg97Ng4g7PJRIShl4367isfrVgERPAKs8OnyBWgcSIIcs0SAmCFXXTaQngvkPKAVBhg4aYlGQTOcrH36D8eoLiuASPBCq1YYGSAT5UoSQBZQogDraBJ2PArz8so60UmPbAvHWqisKObPDvLR7+b4FLiEfqvgf6BhjuVUXnFylh33wzKb9G4BOOnB4BSeiuCvmMNAZ9BwGLoGfs/jgOf7l+jCVfh+IxDlIiAeINtBPwImhZtxe+6YuRR9EvAm1qsQdDGEmh4xiKNBiSJd1IpRNDStI+kZgkgU/joBMIxXeNWV3/6EBIE3np4BQG9tlIiciLLbvNDZ5Ld7TQfW9zX0pCwmFaYnkob1y4oAS2SpKrkqMKhdq2TEvJvW1U1NsylHEhwm4rRoq1DDVVepWIMaUXded+KUYW0qIAdLCaLOxQTdla6NLacq9USRvXEnDMedrAPnXoLFmMcPKvyS9CSRIBgBkgcoMXT+0uZgkAO19IDsynlxqy1wRRbTKQAaP/hbsMzdEqrqg6sCb0ogm7BoGUFJGyjKR1pQLpca1GdMiLQCYfraBLwMm0CTzihVqB8ifQD4VzB0Opi5Rv6H4fo88DHhuwMAYAFoBozKBwMwgKjH0PmXONNRLjVWCiqbFuP3G/AQIkIFcIx5VNs0zwV2B+RSrdxPoZAFiAJi2KtgVKU0NREMM7gllLj1EtJkFzokTGAjjE2bJlWKUbZQpvA+wvtmJLK8Cl5oMIp8amP0dZjzS1I0sfNAABuXLisYGONHhje7Dmc1xyPs6ni3XdQczkFmo872UkjedoNBToan4PfZo1YKuY2DpdUJLo3/vW5q7Du4QFzJtyyA98DgZidoUiRwTAsBU0pnU/AGv5wDj0ihF7EZKTAJgf40AAAJqhy6s1pl9hb2inzBiZoJ444aacSbiMev+MOAKheyKAZT5pkBqIA0DhmiAShFTiQBxZ/1KAeLHgnwQiawhdjYpfY+uHrnXCY+p274bQjwlYxTZMVI+JBMQBxJIW6cCjifiFRumHIdph086eeFTQQ9wJ9ugCYdhnBJg3IH4NYgHMeiCEWvBPOrNdM2AbTHphMF6YuzN6gz0ZDhXXOkWNyfWnIaxEOcLbqAtKM0CvmXmHgGnOhkUMeOMfiT/hzTeprGGtHh2f944CuaoADgdFVhogjLRID8ByBCc4Q+wK0iqwUUlh4wf+MCGac3lYxOKUkFJLnHPIVQkmM0d0GbFT3asH4B5049HBFY6csAYbXcOBQ3l6mODyBnCf/EARxIygVDJsowYiLy82+089smRCrDHJ8LQi9gBiaYFYm8lOJhiRwIJMWESl2kkk/F3eCYyvNfbPwKGdoAxnIzprGM3Gf9AJm58yZjAg2abM6gnTrJydgrtNNnmLTc7NnXkb5k9dhTmgvI+KaAuSm9muZmM54NJMcoBLRakaL2S2phmgL4l6M0BakshBEzH8OS3EDdNTmvTKltpFO3Us99BJ2l0U/kZWZiT9LEkwy8kdwwaWTLgV80xZayNcy+TOljnXpYq7wpSjWzf3UYKFmLKIocp+WdYMvpKn1u3RjlDTNQHJBokmM+sxOddTzAX2ahBMO8wkLh5UzN6PPQgYr3JqDdwu1je5pTMQcxjLhY0y7M5URRwWThIhpjNQBdbJEaSVOBiEEyxAmTuIHIASwjDOIxSxycJdzXZU/ra19qDnuEml4rjeYWQN7jZyoVxIQz+V1pV5YatxTmr0AVqwcxdTV6kx+eyyPqfuC0isEUBQ7f4IBhAwY+n+iKGESdkTW2N0fQ1BDekAumBUtQf0F0CWC1yKAcNlQD1djxn9Xp2BrAAolQBzWDuCqF+hykT1Zza641h60RqmtwDQ2GAB/WGPzR6sXE8dNRE52fxda++2bVwy2HoruVkelN5WNWc2C3js8Itxyj9dcBMWclHA/JWF3xNFKuLRJmLneBbZknrLM6iIgFKEvwx+4PVnWn1YPXZaUICRJ6y9kauvX3r7V1SyMRhuHr6bWl7maFd0tCnMrGGUK1JNyuO2zbhVlSclaElpWBThRgWQZe9sxXfbtNokUVYl0KypdHR5WSqceZmQjZWhHsqPtiA2GNroxwFmNZC73XUeftJNjNe07jbXdxIw25pp9bEUjZ+1mzjzdFiZmq0sgFm01HnKBsIoAoDVZpGSapgjZOzEYUbKQPm6KAkGMCFGEtbF4FAfETzldbHJGz1AR4MvPVatsvWWrbVz6ygbhA5DBg3mbqwa2NuI4OrKEeMP+lkRiI/bkaPAAgZrjP4i7JggqxIMtvW3N7H1iVGYrLxxgu7ukIsfwaRCsDUANnMfs6ECpkAiArMesLyA0DjA1+h4ROJWW7OQBpgZeEB9cBNSkBW9AQMKMeZlT3AjeqCBOfvgMVN7PYJmIPgudLBXpzSaDkewao622i290FE4DXk9k72hwVtRFDfgxAJ1s8gmOh7eWXtxJbcwlH8wUWBbCPamBe38B6y9bRAbz5nWIC9ntNLBXUqhHIGivEBTh0gawHw7RNYu8HKTQRyLqxJ4vsTdsZJmzl5sCH63D7y9v2sAHS1yImQfti29abftvWt7wxZXH7dnYjVg7bt9Kx7ZFMmCxTUdrXnleLutLA7B7Xk3ClyNBPQ7nO4o9zuivzHfk0d1Hnpt3bC5LBxVhU6VaTsy6VZqp+5uqYVTOhX6wenm3DkeibAc7EkMWy4KFk5PprCcYBmRfAZPg4SNWgxN2y9ktgHE+h16N9we5wgmqjnLIKkGjIyo+n4lZSCM/+5covrjgjlFRxlyVhpHRpnsI06wCiR9N+1kM56hdQW8X24aeYO6kJnOnlEO1sTizYF64kYjKz1sludnuXXBI/JFnv6iEEPciGaF6KLuuibuxFG2ZzAPIAQu6tY5+reOngGYm2ND+we2MggrlHybFeSqeJYRbxvIUszdeKjkCyQDEoBUxL7DAYCqu9sarfgexzQH13PPAe8l5601ffsIcAAvFtROdnOLnVzmwI6YMCQB+XkADQAtYoBGaXzDdDI1kC474DDdyzloBwA4BvA/gbeXQBbZR0YAxnZAeV28DOjMmDAxLnIgYA5ZYRuWY8fNmowUaCs+gR3SgMwFqi1tJGMYNm72UJBy3fDCtti8Y+VvMTVbDbdW5ugiO5adbqoWx5S4Nsj4j7tLtV3pvceMubb3j+2749adcp/HyqQJ2E7CtLsQnEd9Nz7cid67k3SVuJ6ztdvpv3bEVz29lZ0FZOTBu6UG6Ajju/sE7ip4p8qblxlPgOFT63dC/ZvKwiEUYnE6MWy72B7QZfIidryiiDuR3wo8S2AwfAPkFcxiXJAM5YXDPhUQ7kd1YDHezmCiUzuQ8tf5XzOEek7nwBHLkzCvG9PzxIMO58AaBLbd3VYBNyyh+bEA5W7EMkwaZXvxq170dxqCmhavKIxxSpYA6dZQwjca7qdzBDZA46rIe4Ad2u6/cbut3DYnA/O+HhUdUAJ5tE6hDJ1f8ZbLgZ/p7UTEazMaCHnwJu9/dh5zyXTud06lqeC5Sy7+RwpKI/eAR13ZHsdxoCdNWBPU9RVj6R5/dFpNAahcNAmBtMORA03qT1A5D+AKTN32Hr7OjcI+C4mPjFu+HqBEZ115XE46biO7RxEMqOwrjkWO86uvP80CcUTrSj2HuYFA06BHkyoHIv9gQUAv8TCNBeDpZsGF9ELZW7fOvDWVrd7kLNrcgIhQ7TzuGUACa1DB3/H8j4J5dNvPeIHzt7j4qOGUJXXBj/w+xcKXev8mat/KhY8svUNTOMtRd/09pMap6TyRjQDMOC+3vP3ozxDxR78sjUFJQX+UEKAst8W9ZRXtGiV/SUKZCcFX+Y3dxHe8LavrHkd014C+o9Wv9blSe6qfHEJTs43m93e6g+PuxgtYV92pAVEseSP9X9jxR//e5AdXu0mb+17m8ca0adHjQAx/wAqeegu3tjwJ6micfHT3H3j3t/NDfuYvL34TzITE8SepPMnoWXJ9G2KeNSlAaM1IM0BqfseaITTxwG09qvv3J3/HC1++htfC3CGBQSlYSf8mCjKTyKyUfSc5WpmCUUy1ogOYKSX3VYWoM42mbUZv28ptoxCU6NtuwC5TzEpU5eDVP8iAqYV6g28K4liOlAKn40s6okR6faJcAuma6+hCDZuJKXwAxYaiMySGOsobVlGJtEWm+LI/W5k6F6ifr/pmkuozNkwx3c2evAQKgQI85G9yBrXwIyXyHj3cwrxVGnM8BISmoB5LAfQBoVlg8UYwx4MJ36EPwNhw9mSeeQmFt9IMMw1PXMIX1LDsRrY0Pz7S2HSi4YpYXADcOc2foxhsbMPwPYj9qh9hMf97DUDmFl4AXRN5ijtU8+mGJE/9DANnidcOVeRIH5zvcM0gniJiZv8fOOArBjx8F8yEWGl5YsZfPXy2Tizl99d5fwju2QNyeqJ24e6mDRNBg0QwbNMBcl1AK/hDF+imJfdPsnwA1TchXS3wT8t6E464mWIv5PkX2ZsDTU+D/Sv/FLE+x+cy03V/st0UaJ9pPI7GT6r215C6T3j96aApzAtzx2JVu0a3MJTinYK4gElF77ez3qAF7sednxzq668Kiw3QpxMqzpEwAVu5+6+suDy4kDkFUAEAzACAGg+OHswwGYWOEQzYBGEm+6IC6eEAYRIHYPnxUaJXMJrnoNwMe7Vg37mDpoAEcu+Dh8dEL4J62obla4bQ5xG97EyHeC3ZWuRnhR4melvmzAcBl7HhyvQZeIBLuKVJJr5/eonkZKA+DkHXx8AyeIKykOoXOYF4CtRm2a8Kj4kGz32OejbxSkNBMUBxI4EKIAd4OwAuRToTipoyZsY8DcDeY6Nu9DQ6woocIe6wcnwD1gCAV94NesXgxRPAZoJr5F6V3BqSyAZehXrYAVenqJfYLAZ9C3WYoCuA8spwkniJcuaKHh2uB9moE0aiqhNTwOvARoD8BTinHhiAsvrbjtsHPNECFBihtWhRKTish69kTYj/Rn2e6hjoSGeSmSDGeowWmRKaD4NWSoAgEqECfkxok7yWQAQWCYgimit6yXw5hlnYABoCMSRtmfbsB5cM3Co4rpAjunf5d8qQvo5j+wLJl41swRtwLmOc/gV7AEZxF5r0B0rp964g33mO77Q0OpRpF0l7FwFYU4Hje7NB6QAkTeBU9HgEUeHXq2wXI4gXZaSB/6uS62W/bLXT9W8IYJ4JEXHrIGI0dXnEEHegnoiFkmIblWDoh2Mj1IpYbgU5DTowAJkE602QR964hU0AkT6BAPpJ7GByOnx6IBIAeSFts2PKdYKgNlvB4ChAIakEl6GQeXoshZwNZC1AcIdF4ceF3mSb76NlmJrAAAAPwvcAyMgAkBmfOQFjulAV9gJEowbsrshyASlD7sb/vE5fI+PuFbf+FbiT46CBwUKBROJgqaG0A4PlECC4YAfk4QBhTlAGrcrbnfT1QHblz5ZkCuDAxI+Mrn8EQednMqj3e2vGkT0MsnoIhg+GNhKgwc1GIhxo8avm/TzW/EBOgQGlSLuKOeo2GO52uowbgEqhFHsKLBoFQBjilERaNZir4biOBS3o+mHbL3o58CEDBobXnb7RirAb4GXBPQVMFKBPARCHVgd7t4FfWGHhXZ1+djD56t+6YSD6ZhOHr6FCMxFlzYucXfuBadwQtsZwjuRwa5Cy+MjOvixMFApggTioBPhSHu9sCu6LOM4du7uKJ5juS86z4omKoATgquFL82LpC4xgsYbXLfuyOFGwkA37hKj5shjIWzGMv4BlAvwr+h7QQ+yqGBEpAJmP8ENhZ4XpiPCSJM0xjIYcLTDygKTDRL3BitoEZeuzwWY7Em+Xh9o8q2kjUxxhA1gmE+Aj3vWGCeZ4cnTehJfGJRN8YlNv4K6GYfJ4+hGNlD6SiwViW6f+5/s6GX+g3FJLuhnoSZjeh24f6HcmRVIe7Feh7mV63Yg3klDDeNCAMEzhk3nlyn+0kck4ZWckcLIxWikcJFZhSnlj7XE2Rnj4h2BPpZHZuV/lJLcKvCkAEjuDbq0b/srPsnZtuqdpAC5hKUP/q8BKupJik22JEmHsmkxvEbTGekVkAGRG0C0HA8LRLoGqBIBGhEjuAgVAY+gxhkgIXBLwCcGt6epCUyOGurP0AbQuPKZH3kowRKhKiuejUFCatGmlgai0nHrTtqzUS8Ao2ZOozr+oApJtB9RnhtgyQYRRNKJ9RdQEYqM6q9lCGCBHwTgGeyT+kOR8+d8AvKrU3WBMFdhZik1HYuaRBsY14AUlHyVgDADiF+Ri0SmYOIfgkZxYwUUEaCfI90dPYCoi0ejgaecMJEFtoKgewEgEDIaICw660FogLh6ULZ5UMuPMi4uII0FSGUCrME8bKc0lvVGz6+tMBgjRYLJNGcihDKyjjac7nnx0hnwMwAAxF0cyGV6bIVdH5RTiimbZCqLN0G6KVnubJ2BkkA4EOypMdkHExcLGnzYgVga2TToPMbZS1R/MDEHvR88OvLtsn6MqguoonoSFzmaLPtZdma1okBSuDQm9GUx6QF0SjaQahuCXRkIWrFoAKZoJhhy1ptu4Vkn6GJyhUy1riRSx0hEjbiePIeEGqmLRBh7gmpoktaswAqCsR06PQLDovuD7rjrZE4rA/Cr4a3v7HJIDOrhE9gt4vxG9hACoEIwMCBAJolc27kAKy+IcTB5dhlthKhvgG4MaZYGGsTh5axYyF7GUe7fg85sMJYdLzugxXOoHPQOHpygvyCVGRF+GDwRP52u1Edxa0RbwZxJRGVSle6JhI1DpEzGiRs0reRLQZ0TdEOATLSLRFOiCG1BImijijBafj6Aox7aiQIBIm0EvFSiCpIJEjEr4fYTExQ2oTr62xMTrF8BesQkR2xUnj45+ye8eTL0h50YfGBCBMe5gnxbMbUDkxusT4ACBnIYTL/ehgfbEJuN8X3Enu+8eLEtgNjiiHRIdIaKDWxhId6oK6t8ZABxmkMvjaL+IbnZaLR+cV9iFxlAKfFNB58Qy4vY18bgFTuPau9KpSJavSCJxl7PtB5xpOtgmj4RcQToM6O8crh7xQdmZG8yMkeHZRWf/lsy32S/L8jQA1BEsBVgi0P5GS6zbtAFhhG3ByjhRoegrrCJv0KIk9wQjCNYxR+uIdwAWk4XUY+E/Xg0qimcxvpECJbsplEV4YenkouYccc6QPUiAEokkASNs3jUEqzrNR2Jzier4Tymvn7QB0uvrBQuA6ECwoNIL4OOAPCq+NULlo4PC8B7CNMPIADQrdmGIr4G+KTopA/hgKixo8wBOyLObCDIRrSEqDZxD2q9k4m/QdvjyTF6rYmA5tmMQSOrQRoPBEmGI1BBhQ9kcMQNxgOZFtEAYG0iNbILII1LbRVgQgVzwYCwbE7ih4jKPmBdA7YN3KzYbYAYi6ssSK0l7G/QIKjXwZBvqiNJD0VxCdh5YgZCkgYAABBeg1QC4BGkkSPcAZCMEAujFgx5rQDgoTwC2CpGGBMpClBayVhSr4MBigD+e6Ds6DRJrzokkIm4gHSIg2ZIIw6CoyQJ8oGoLlM0hmiCoXBa3QBNkeZlYU0DCKTJBEph5JiaeLWgIprZOQDmmsANfBYSSKXCmQA/YXTGcMBwHjDnJdSACQn4b9LtEVJdFGcBNI58MX70wIGozwha0UIuIRYByYCiwAo/s3EUReJpP4q20/qEbGy/rnwI9xfRPYkqJi0HUr6JCRoYnNKJicRoL+SGjDJVS0hm4m/QeqlMoJ0sysQmR4IiWImTE9EQBq62VUp1TBqI6vRq4A9iYGqW0fgFEBFgZqoNTLJZAY5rgp1UAmZWptwJ8qsJfslKlGpWuDybFuqVkk5uRWbrwnpuPkf4p8EvyN+5RoMhikBdEYpPGAbaWiBIlNuRTtInlW7bsyiduGeMPAxp5YWB4eOG9l44f2O9s055RPgAmmfORAMmkBKaaUIzJsDgNR59kVTus4mYEzgXYDuV5rQANpfBBe44w65IwAPgXYX2l2+76EhZGmCXhXHpycHqWlMu5ae1ZEMGxnXa3kAQFaDJ4z3PyopA4KRWhKY8jIuQoimwCA6uQtPozbLmxwPMLMSnyNukxYvsFMKqBW6cnDThwCdWCwJwoka4dcJrrIzmuWIm550AzJuuC9ibYkUL2US/LyywRvsGejDpa4Jrp1pGIEWmjp8Nj1Yg27oKA5POi6XG4f22LgC7LhSGZTo3iEuJfBjYbfjf4RYa9p462229r7A4mQEb4onGwXtBJQwZce6Duc2hthRJAi2Jgg3AcFjUCjCWCAZDyAOQkmFwEvKe65GOStoKnZeIRqUoa2ERhyyasfKR67SZbcaY4dxfrv4KXhOwCFD+Q2QlWil4wac5EOhrkU6E8JxPqFY+Ro8ekBxpesU2lqReTnLJBhLPrYJs+4YdbCc+sUWs7vALfpBmF2i0Q5mheQJngTARzpC2j+s7oFwyjeraQsndOHuL9CjpvgMkjW+9IMKgFR3EFOCQcY1lWnSccOrQDvRGOt2ImmKOGJoaAUaJ6jEy/qLxrxgGgEoQfMQhF6Y2AIFFxAlZ95GVn2AbqHEBxAYaMKLpCVCEcbyB/gtOn+mDiCvHz668U+mcisvuojPQ+sBLHMk4EuWYnwc8lgY9keMR2nMIjQClBVi8cWlmJAGWeolYAKccOlnCW5CNm5QwzjVkOJ2Gm2pTkFYFiA3pI0QoCPZJ5NKLIKzajUB7y++N+aRYPgKVFEMb9N9EpB76fglfxLQbMjBYKgSWRApvpoea7CmwGYroGbURoG+kBoFgCGoN7BbDZCfgSFza0guL/pzBhlA2DlOdfvjD/hjjP56qx4OekBBZ5GWT6OuiQDRaMkpUYeFksdGSBkOuIIKeHRKfaaKDmGEmRkyqZlETJntxuXmEYKZ8/isqLS22e2AHa+2YBACB+0Ndk6hCRKJq10m8dOA9RE2SgToxmudNkOET1BQCxEJ4FeCLRquQkTng35otFlqrTPqmBZjDlrjdMnCVexf+Fmb/5RpTiv8gjeXuQ7kZakPq/5ORuPqZlhp9ONXE+C17JxR3sfXJWCQE0khqCVG7Sh5QNcX7OAGNukAUFEwBIUQrhwcCHIBJHZ+aVgo1mw4MgbHhl5kvZKod/qRzkc94YsFjmQ2fX7tCFaJw5L6MQEBCiAVAKpQcACdFCirAJAJtbqKmPBiA0AdshTwnCpyUdi5sfeYeIQCy8iIEQQMQNwovs4gi+yupLADkDdia+X4xY4fwIvkjuy+ULIvsBANwAb59TrB4FBO+a2Riu4sh5RMc34KflKOnwKCB/AbsAYiwA55DfDv5rZD9BeghmChb0wsqpQiv8s+RM6QExvG2Y3A1+VUbjUd+UoBssdwSplSZIuepmEmM/hLlip7wS3n5hBmp8BLgTqOtapRQgJ+ySRoaWf7JO4eaVw3srkBW6x5+goVi/ItoYhgvIWyOuiDIZwAciZpJyFMjXyFyG5k3IygKsgPIGyM8gGALBT5DqAL7F0CIAL7Ewh0AEsv049IohX0iQA1iJMCTAAAJzTA0wGua1AvICdDqFnILyC0AvILUACAvIKIDcg3IF9jTAkwLQDcgtANYgkAAAOzqFAgOoUMA2hZ4CKFYhc5ASFUhTIXb4lEHIUDITyHoBAAA= --> <!-- internal state end --> <!-- finishing_touch_checkbox_start --> <details> <summary>✨ Finishing Touches</summary> - [ ] <!-- {"checkboxId": "7962f53c-55bc-4827-bfbf-6a18da830691"} --> 📝 Generate Docstrings </details> <!-- finishing_touch_checkbox_end --> <!-- tips_start --> --- <details> <summary>🪧 Tips</summary> ### Chat There are 3 ways to chat with [CodeRabbit](https://coderabbit.ai?utm_source=oss&utm_medium=github&utm_campaign=Team-EnderIO/EnderIO&utm_content=568): - Review comments: Directly reply to a review comment made by CodeRabbit. Example: - `I pushed a fix in commit <commit_id>, please review it.` - `Generate unit testing code for this file.` - `Open a follow-up GitHub issue for this discussion.` - Files and specific lines of code (under the "Files changed" tab): Tag `@coderabbitai` in a new review comment at the desired location with your query. Examples: - `@coderabbitai generate unit testing code for this file.` - `@coderabbitai modularize this function.` - PR comments: Tag `@coderabbitai` in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples: - `@coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.` - `@coderabbitai read src/utils.ts and generate unit testing code.` - `@coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.` - `@coderabbitai help me debug CodeRabbit configuration file.` Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments. ### CodeRabbit Commands (Invoked using PR comments) - `@coderabbitai pause` to pause the reviews on a PR. - `@coderabbitai resume` to resume the paused reviews. - `@coderabbitai review` to trigger an incremental review. This is useful when automatic reviews are disabled for the repository. - `@coderabbitai full review` to do a full review from scratch and review all the files again. - `@coderabbitai summary` to regenerate the summary of the PR. - `@coderabbitai generate docstrings` to [generate docstrings](https://docs.coderabbit.ai/finishing-touches/docstrings) for this PR. - `@coderabbitai resolve` resolve all the CodeRabbit review comments. - `@coderabbitai configuration` to show the current CodeRabbit configuration for the repository. - `@coderabbitai help` to get help. ### Other keywords and placeholders - Add `@coderabbitai ignore` anywhere in the PR description to prevent this PR from being reviewed. - Add `@coderabbitai summary` to generate the high-level summary at a specific location in the PR description. - Add `@coderabbitai` anywhere in the PR title to generate the title automatically. ### CodeRabbit Configuration File (`.coderabbit.yaml`) - You can programmatically configure CodeRabbit by adding a `.coderabbit.yaml` file to the root of your repository. - Please see the [configuration documentation](https://docs.coderabbit.ai/guides/configure-coderabbit) for more information. - If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: `# yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json` ### Documentation and Community - Visit our [Documentation](https://docs.coderabbit.ai) for detailed information on how to use CodeRabbit. - Join our [Discord Community](http://discord.gg/coderabbit) to get help, request features, and share feedback. - Follow us on [X/Twitter](https://twitter.com/coderabbitai) for updates and announcements. </details> <!-- tips_end -->
Rover656 commented 2025-03-16 20:26:37 +00:00 (Migrated from github.com)

How close is this from being mergeable? Even if we still have some polish to do, it'd be good at this point to get this really old PR merged. We can refine later.

How close is this from being mergeable? Even if we still have some polish to do, it'd be good at this point to get this really old PR merged. We can refine later.
coderabbitai[bot] (Migrated from github.com) reviewed 2025-03-16 20:29:29 +00:00
coderabbitai[bot] (Migrated from github.com) left a comment

Actionable comments posted: 9

🧹 Nitpick comments (21)
enderio-machines/src/main/java/com/enderio/machines/common/blocks/farming_station/package-info.java (1)

4-5: Package Declaration Is Clear

The package declaration clearly reflects the file's location and responsibility within the project structure. For improved maintainability, consider adding package-level documentation to summarise the purpose and functionality of the Farming Station feature. This can be particularly useful for new developers or for future reference.

enderio-base/src/main/java/com/enderio/base/api/farm/FarmTask.java (1)

7-7: Consider documenting the parameters and return values.

Adding Javadoc would improve understanding of how the interface should be implemented.

+/**
+ * Interface for farm tasks that can be performed by a farming station.
+ */
 public interface FarmTask {

+    /**
+     * Performs a farming operation at the specified soil location.
+     *
+     * @param soil The position of the soil block to farm
+     * @param farmBlockEntity The farming station performing the operation
+     * @return The result of the farming interaction
+     */
     FarmInteraction farm(BlockPos soil, FarmingStation farmBlockEntity);
 }
enderio-base/src/main/resources/assets/enderio/lang/af_za.json (1)

76-76: Consider localizing to actual Afrikaans.

The entry just uses English "Farming Station" while this is the Afrikaans language file. Consider translating it to proper Afrikaans (possibly "Boerdery Stasie").

enderio-machines/src/main/java/com/enderio/machines/common/init/MachineBlocks.java (1)

276-283: Consider using the helper method and specifying the type parameter.

While the implementation works, there are two potential improvements:

  1. The type parameter for ProgressMachineBlock is not specified, unlike other similar machine blocks that use ProgressMachineBlock<SpecificBlockEntityType>.

  2. This implementation directly uses the block registry rather than the helper method progressMachine() (line 341) that's used by most other machine blocks.

Consider refactoring to use the helper method for consistency:

-public static final RegiliteBlock<ProgressMachineBlock> FARMING_STATION = BLOCK_REGISTRY
-    .registerBlock("farming_station", properties -> new ProgressMachineBlock(MachineBlockEntities.FARMING_STATION, properties),
-        BlockBehaviour.Properties.of().strength(2.5f, 8))
-    .setLootTable(MachinesLootTable::copyComponents)
-    .addBlockTags(BlockTags.NEEDS_IRON_TOOL, BlockTags.MINEABLE_WITH_PICKAXE)
-    .setBlockStateProvider((prov, ctx) -> prov.simpleBlock(ctx.get(),
-        prov.models().getExistingFile(EnderIO.loc("block/" + ctx.getName()))))
-    .createBlockItem(ITEM_REGISTRY, item -> item.setTab(EIOCreativeTabs.MACHINES));
+public static final RegiliteBlock<ProgressMachineBlock<?>> FARMING_STATION = progressMachine("farming_station",
+    () -> MachineBlockEntities.FARMING_STATION);
enderio-base/src/main/java/com/enderio/base/api/farm/FarmTaskManager.java (3)

10-43: Declare constants as final for better code safety

The integer constants PLANT, BONEMEAL, and HARVEST should be declared as final since they represent fixed task priorities and shouldn't be modified.

-    public static int PLANT = 1;
-    public static int BONEMEAL = 3;
-    public static int HARVEST = 5;
+    public static final int PLANT = 1;
+    public static final int BONEMEAL = 3;
+    public static final int HARVEST = 5;

22-30: Consider potential race conditions in static initialization

The current implementation of getTasks() might cause issues if called concurrently from multiple threads. Consider using thread-safe initialization patterns like an AtomicReference or synchronization.

You could use a thread-safe initialization approach:

-    private static ImmutableList<FarmTask> TASKS_IMMUTABLE;
+    private static volatile ImmutableList<FarmTask> TASKS_IMMUTABLE;

     public static List<FarmTask> getTasks() {
         if (TASKS_IMMUTABLE == null) {
-            FarmTaskManager manager = new FarmTaskManager();
-            IntegrationManager.forAll(integration -> integration.registerFarmTasks(manager));
-            manager.tasks.sort(TaskEntry::compareTo);
-            TASKS_IMMUTABLE = ImmutableList.copyOf(manager.tasks.stream().map(e -> e.task).toList());
+            synchronized (FarmTaskManager.class) {
+                if (TASKS_IMMUTABLE == null) {
+                    FarmTaskManager manager = new FarmTaskManager();
+                    IntegrationManager.forAll(integration -> integration.registerFarmTasks(manager));
+                    manager.tasks.sort(TaskEntry::compareTo);
+                    TASKS_IMMUTABLE = ImmutableList.copyOf(manager.tasks.stream().map(e -> e.task).toList());
+                }
+            }
         }
         return TASKS_IMMUTABLE;
     }

36-42: Consider a more efficient compareTo implementation

The current implementation works correctly but can be improved by using Integer.compare for better readability and to avoid potential integer overflow issues.

        @Override
        public int compareTo(@NotNull FarmTaskManager.TaskEntry o) {
-            return priority - o.priority;
+            return Integer.compare(priority, o.priority);
        }
enderio-machines/src/main/java/com/enderio/machines/common/utility/TreeHelper.java (1)

19-40: Add a size limit to prevent server performance issues

For very large trees or connected forest structures, the algorithm could potentially process thousands of blocks, causing server lag.

Add a maximum size limit to prevent performance issues:

-public static Set<BlockPos> getTree(Level level, BlockPos bottom, Predicate<BlockPos> inRange) {
+public static Set<BlockPos> getTree(Level level, BlockPos bottom, Predicate<BlockPos> inRange) {
+    return getTree(level, bottom, inRange, 1000); // Default max size of 1000 blocks
+}
+
+public static Set<BlockPos> getTree(Level level, BlockPos bottom, Predicate<BlockPos> inRange, int maxSize) {
    LinkedList<BlockPos> candidates = new LinkedList<>();
    HashSet<BlockPos> tree = new HashSet<>();
    HashSet<BlockPos> seen = new HashSet<>();

    candidates.add(bottom);

    while(!candidates.isEmpty()) {
        BlockPos pos = candidates.removeFirst();
        BlockState state = level.getBlockState(pos);
        seen.add(pos);
        if(isTree(state) && inRange.test(pos)) {
            tree.add(pos);
+           // Stop if we've reached the maximum size
+           if (tree.size() >= maxSize) {
+               break;
+           }
            BlockPos.betweenClosed(pos.offset(1, 1, 1), pos.offset(-1, -1, -1))
                .forEach(next -> {
                    if(seen.contains(next)) return;
                    candidates.add(next);
                });
        }
    }
    return tree;
}
enderio-machines/src/main/java/com/enderio/machines/client/gui/screen/FarmingStationScreen.java (2)

10-10: Unused import

The import for NewCapacitorEnergyWidget on line 10 appears to be unused as the code uses CapacitorEnergyWidget on line 34. Consider removing this unused import to keep the code clean.

-import com.enderio.machines.client.gui.widget.NewCapacitorEnergyWidget;

55-57: Consider adding tooltips for slots

The current implementation handles background rendering but doesn't implement any custom tooltips for the farming station's specialized slots. Consider adding tooltips to improve user experience by explaining the purpose of each specialized slot (axe, hoe, shears, etc.).

enderio-machines/src/main/java/com/enderio/machines/common/blocks/farming_station/FarmingStationMenu.java (2)

59-59: Consider refactoring duplicated code

The // noinspection DuplicatedCode comment suggests there might be duplicated code across different menu classes. Consider refactoring the common code into a shared utility method.

What are best practices for handling duplicated code in Java?

29-51: Consider using constants for slot positions

The slot positions are currently hard-coded with magic numbers. Consider using constants for the base positions and offsets to make the layout more maintainable.

-    private void addSlots() {
-        addCapacitorSlot(12, 63);
-
-        var inventory = getMachineInventory();
-        // Tool inputs TODO: Shadow slots to show compatible tools?
-        addSlot(new MachineSlot(inventory, FarmingStationBlockEntity.AXE, 44, 19));
-        addSlot(new MachineSlot(inventory, FarmingStationBlockEntity.HOE, 44 + 18, 19));
-        addSlot(new MachineSlot(inventory, FarmingStationBlockEntity.SHEAR, 44 + 18 * 2, 19));
+    private static final int TOOL_SLOT_X = 44;
+    private static final int TOOL_SLOT_Y = 19;
+    private static final int SLOT_SIZE = 18;
+    private static final int SEED_SLOT_X = 53;
+    private static final int SEED_SLOT_Y = 44;
+    private static final int OUTPUT_SLOT_X = 107;
+    private static final int OUTPUT_SLOT_Y = 44;
+    
+    private void addSlots() {
+        addCapacitorSlot(12, 63);
+
+        var inventory = getMachineInventory();
+        // Tool inputs TODO: Shadow slots to show compatible tools?
+        addSlot(new MachineSlot(inventory, FarmingStationBlockEntity.AXE, TOOL_SLOT_X, TOOL_SLOT_Y));
+        addSlot(new MachineSlot(inventory, FarmingStationBlockEntity.HOE, TOOL_SLOT_X + SLOT_SIZE, TOOL_SLOT_Y));
+        addSlot(new MachineSlot(inventory, FarmingStationBlockEntity.SHEAR, TOOL_SLOT_X + SLOT_SIZE * 2, TOOL_SLOT_Y));
enderio-machines/src/main/java/com/enderio/machines/common/network/FarmStationSoulPacket.java (1)

25-31: Consider refactoring SoulData construction

The packet is directly constructing a FarmSoul.SoulData from the buffer. If the structure of SoulData changes, both this code and the codec would need to be updated. Consider adding a static factory method in FarmSoul.SoulData to read from a buffer.

-    public FarmStationSoulPacket(FriendlyByteBuf buf) {
-        this(
-            buf.readMap(FriendlyByteBuf::readResourceLocation, buff ->
-                new FarmSoul.SoulData(buff.readResourceLocation(), buff.readFloat(), buff.readInt(), buff.readFloat())
-            )
-        );
-    }
+    public FarmStationSoulPacket(FriendlyByteBuf buf) {
+        this(
+            buf.readMap(FriendlyByteBuf::readResourceLocation, FarmSoul.SoulData::fromBuffer)
+        );
+    }

And in the FarmSoul class:

public static SoulData fromBuffer(FriendlyByteBuf buf) {
    return new SoulData(buf.readResourceLocation(), buf.readFloat(), buf.readInt(), buf.readFloat());
}
enderio-machines/src/main/java/com/enderio/machines/common/souldata/FarmSoul.java (1)

17-22: Consider verifying default values for resilience.
The SoulData record sets defaults of 1f for bonemeal and power, and 0 for seeds. If you anticipate future changes or expansions to these fields, ensure these defaults reflect the intended mod behaviour and do not inadvertently unsettle balance.

enderio-base/src/main/java/com/enderio/base/api/farm/FarmingStation.java (2)

1-57: Please fix Spotless formatting issues.
The pipeline failure indicates you must run ./gradlew :enderio-base:spotlessApply to satisfy formatting rules. This is critical before merging.

If you need help automating this or verifying the fix, I can provide a script – let me know.

🧰 Tools
🪛 GitHub Actions: Verify Build

[error] 1-6: The following files had format violations: Spotless formatting check failed. Run './gradlew :enderio-base:spotlessApply' to fix these violations.


49-55: Check concurrency usage of FakePlayer.
useStack might be called concurrently if multiple tasks run in parallel. Ensure there's no concurrent access to the same FakePlayer instance to avoid item or world interaction conflicts.

enderio-machines/src/main/java/com/enderio/machines/common/blocks/base/task/MachineFarmingTasks.java (2)

180-180: TODO reference: "no general 2 block crop?"
This comment suggests partial or unimplemented two-block crop logic. If you foresee future expansions (like tall crops), clarifying or implementing a standard approach to multi-block crops would be ideal.


34-354: Overall code organisation is solid, but be mindful of complexity.
Having many static tasks in a single file is convenient but can become unwieldy. Consider grouping tasks by theme (plant vs. harvest) or splitting them into sub-classes to aid maintenance.

enderio-machines/src/main/java/com/enderio/machines/common/blocks/farming_station/FarmingStationBlockEntity.java (3)

90-93: Clarify usage of a shared fake player across machines
There is a TODO remark suggesting a single fake player might be used for all farming stations. A shared fake player may lead to concurrency and player-state issues if multiple stations operate simultaneously (e.g. concurrent item usage or partial item states).

If you expect multiple stations to perform tasks concurrently, consider provisioning a separate fake player per machine or carefully synchronising all interactions to avoid unexpected behaviour.


163-173: Discuss the global static reload flag
The logic at lines 163–167 depends on a static reload boolean to refresh soul data once. If multiple block entities exist or if the server reload state changes unpredictably, this might fail or update unexpectedly.

Consider a more local mechanism or an event-based callback to reinitialise internal caches. This avoids potential confusion from having a single reload variable affecting multiple entities.


417-419: Reassess the onReload toggling approach
The event listener simply flips reload using reload = !reload;. This might cause confusion if reloaded multiple times in quick succession (e.g. repeated data pack reloads).

Consider storing a reload counter or a timestamp rather than toggling a boolean. This way, you can reliably detect changes without having to guess the “true–false” cycle.

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 9ea99e81e1 and 06698810f2.

Files ignored due to path filters (17)
  • enderio-base/src/generated/resources/assets/enderio/blockstates/farming_station.json is excluded by !**/generated/**
  • enderio-base/src/generated/resources/assets/enderio/models/block/farming_station_active_combined.json is excluded by !**/generated/**
  • enderio-base/src/generated/resources/assets/enderio/models/block/farming_station_combined.json is excluded by !**/generated/**
  • enderio-base/src/generated/resources/assets/enderio/models/item/farming_station.json is excluded by !**/generated/**
  • enderio-base/src/generated/resources/data/enderio/loot_table/blocks/farming_station.json is excluded by !**/generated/**
  • enderio-base/src/generated/resources/data/minecraft/tags/block/mineable/pickaxe.json is excluded by !**/generated/**
  • enderio-machines/src/generated/resources/assets/enderio/blockstates/farming_station.json is excluded by !**/generated/**
  • enderio-machines/src/generated/resources/assets/enderio/lang/en_us.json is excluded by !**/generated/**
  • enderio-machines/src/generated/resources/assets/enderio/models/item/farming_station.json is excluded by !**/generated/**
  • enderio-machines/src/generated/resources/data/enderio/eio_soul/farm/minecraft_bee.json is excluded by !**/generated/**
  • enderio-machines/src/generated/resources/data/enderio/eio_soul/farm/minecraft_sniffer.json is excluded by !**/generated/**
  • enderio-machines/src/generated/resources/data/enderio/eio_soul/farm/minecraft_villager.json is excluded by !**/generated/**
  • enderio-machines/src/generated/resources/data/enderio/loot_table/blocks/farming_station.json is excluded by !**/generated/**
  • enderio-machines/src/generated/resources/data/enderio/recipe/soulbinding/farming_station.json is excluded by !**/generated/**
  • enderio-machines/src/generated/resources/data/minecraft/tags/block/mineable/pickaxe.json is excluded by !**/generated/**
  • enderio-machines/src/generated/resources/data/minecraft/tags/block/needs_iron_tool.json is excluded by !**/generated/**
  • enderio-machines/src/main/resources/assets/enderio/textures/block/farming_station_side.png is excluded by !**/*.png
📒 Files selected for processing (25)
  • enderio-base/src/main/java/com/enderio/base/api/farm/FarmInteraction.java (1 hunks)
  • enderio-base/src/main/java/com/enderio/base/api/farm/FarmTask.java (1 hunks)
  • enderio-base/src/main/java/com/enderio/base/api/farm/FarmTaskManager.java (1 hunks)
  • enderio-base/src/main/java/com/enderio/base/api/farm/FarmingStation.java (1 hunks)
  • enderio-base/src/main/java/com/enderio/base/api/integration/Integration.java (2 hunks)
  • enderio-base/src/main/java/com/enderio/base/common/tag/EIOTags.java (1 hunks)
  • enderio-base/src/main/resources/assets/enderio/lang/af_za.json (1 hunks)
  • enderio-machines/src/main/java/com/enderio/machines/client/gui/screen/FarmingStationScreen.java (1 hunks)
  • enderio-machines/src/main/java/com/enderio/machines/common/blocks/base/task/MachineFarmingTasks.java (1 hunks)
  • enderio-machines/src/main/java/com/enderio/machines/common/blocks/farming_station/FarmingStationBlockEntity.java (1 hunks)
  • enderio-machines/src/main/java/com/enderio/machines/common/blocks/farming_station/FarmingStationMenu.java (1 hunks)
  • enderio-machines/src/main/java/com/enderio/machines/common/blocks/farming_station/package-info.java (1 hunks)
  • enderio-machines/src/main/java/com/enderio/machines/common/config/common/EnergyConfig.java (2 hunks)
  • enderio-machines/src/main/java/com/enderio/machines/common/init/MachineBlockEntities.java (2 hunks)
  • enderio-machines/src/main/java/com/enderio/machines/common/init/MachineBlocks.java (1 hunks)
  • enderio-machines/src/main/java/com/enderio/machines/common/init/MachineMenus.java (3 hunks)
  • enderio-machines/src/main/java/com/enderio/machines/common/init/MachineNetwork.java (4 hunks)
  • enderio-machines/src/main/java/com/enderio/machines/common/integrations/EnderIOMachinesSelfIntegration.java (2 hunks)
  • enderio-machines/src/main/java/com/enderio/machines/common/network/FarmStationSoulPacket.java (1 hunks)
  • enderio-machines/src/main/java/com/enderio/machines/common/network/MachinePayloadHandler.java (2 hunks)
  • enderio-machines/src/main/java/com/enderio/machines/common/souldata/FarmSoul.java (1 hunks)
  • enderio-machines/src/main/java/com/enderio/machines/common/utility/TreeHelper.java (1 hunks)
  • enderio-machines/src/main/java/com/enderio/machines/data/recipes/SoulBindingRecipeProvider.java (2 hunks)
  • enderio-machines/src/main/java/com/enderio/machines/data/souldata/SoulDataProvider.java (3 hunks)
  • enderio-machines/src/main/resources/assets/enderio/models/block/farming_station.json (1 hunks)
🧰 Additional context used
🪛 GitHub Actions: Verify Build
enderio-base/src/main/java/com/enderio/base/api/farm/FarmInteraction.java

[error] 1-5: The following files had format violations: Spotless formatting check failed. Run './gradlew :enderio-base:spotlessApply' to fix these violations.

enderio-base/src/main/java/com/enderio/base/api/integration/Integration.java

[error] 1-1: Spotless Java check failed: Format violations detected. Please run './gradlew :enderio-base:spotlessApply' to fix.

enderio-base/src/main/java/com/enderio/base/api/farm/FarmTaskManager.java

[error] 2-10: The following files had format violations: Spotless formatting check failed. Run './gradlew :enderio-base:spotlessApply' to fix these violations.

enderio-base/src/main/java/com/enderio/base/api/farm/FarmingStation.java

[error] 1-6: The following files had format violations: Spotless formatting check failed. Run './gradlew :enderio-base:spotlessApply' to fix these violations.

🔇 Additional comments (32)
enderio-machines/src/main/java/com/enderio/machines/common/blocks/farming_station/package-info.java (1)

1-2: Null Safety Annotations Are Correctly Applied

The utilisation of @javax.annotation.ParametersAreNonnullByDefault along with @net.minecraft.MethodsReturnNonnullByDefault ensures that all methods and parameters in this package are treated as non-null by default. This approach enhances the reliability of the code by reducing potential null pointer issues.

enderio-base/src/main/java/com/enderio/base/api/farm/FarmTask.java (1)

5-7: Well-designed task interface.

The interface is concise and follows the single responsibility principle. It provides a clear contract for implementing farming tasks.

enderio-base/src/main/resources/assets/enderio/lang/af_za.json (1)

76-76: Good localization addition.

The localization entry for the farming station is properly added and follows the same format as existing entries.

enderio-machines/src/main/resources/assets/enderio/models/block/farming_station.json (2)

1-12: Well-structured block model.

The JSON model is properly formatted and includes all necessary faces and particle texture definitions.


3-11:

Verification successful

Verify texture resources exist.

Ensure that all referenced textures exist in the resource paths:

  • enderio:block/soul_machine_bottom
  • enderio:block/farming_station_side
  • enderio:block/soul_machine_top

This will prevent resource loading errors at runtime.


🏁 Script executed:

#!/bin/bash
# Check if the referenced textures exist in the resource paths
echo "Checking for referenced textures..."

textures=(
  "soul_machine_bottom"
  "farming_station_side"
  "soul_machine_top"
)

for texture in "${textures[@]}"; do
  echo "Looking for $texture..."
  found=$(fd "$texture.png" enderio-machines/src/main/resources/assets/enderio/textures/block)
  
  if [ -z "$found" ]; then
    echo "WARNING: Texture $texture.png not found!"
  else
    echo "Found: $found"
  fi
done

Length of output: 1982


Verified: All texture resources exist as expected.

The textures for:

  • enderio:block/soul_machine_bottom
  • enderio:block/farming_station_side
  • enderio:block/soul_machine_top

have been confirmed to exist in the corresponding resource directories. There are no changes required in the JSON file.

enderio-base/src/main/java/com/enderio/base/common/tag/EIOTags.java (1)

123-124: Addition of fertilizer tag looks good.

The introduction of the FERTILIZERS tag fits well with the existing tag structure and will be useful for the farming station feature to identify valid fertilizer items.

enderio-base/src/main/java/com/enderio/base/api/integration/Integration.java (1)

3-3: Import addition is appropriate.

This import is necessary for the new method parameter.

enderio-machines/src/main/java/com/enderio/machines/data/recipes/SoulBindingRecipeProvider.java (2)

12-12: Import addition is appropriate.

This import is necessary for accessing the FarmSoul.NAME constant in the new recipe.


49-49: Soul binding recipe for farming station follows established pattern.

The recipe parameters match other similar machine recipes, using appropriate energy and experience values. This will enable players to create farming stations with soul binding mechanics.

enderio-machines/src/main/java/com/enderio/machines/common/integrations/EnderIOMachinesSelfIntegration.java (2)

4-5: Required imports for farm task functionality.

These imports are necessary for implementing the farm task registration method.


18-32: Comprehensive implementation of farm task registration.

The implementation properly registers various planting, fertilizing, and harvesting tasks with appropriate priorities. The method follows a consistent pattern for task registration using the priority constants from FarmTaskManager.

These tasks provide the farming station with capabilities to handle different crops, trees, and plant types, making it a versatile farming solution.

enderio-machines/src/main/java/com/enderio/machines/common/init/MachineBlockEntities.java (2)

12-12: Appropriate import for the new farming station block entity.

The import for the FarmingStationBlockEntity follows the package structure conventions of the codebase.


202-205: Good implementation of the farming station block entity registration.

The registration follows the established pattern in the codebase:

  1. Properly named using the same convention as other block entities
  2. Correctly applies both the powered machine capabilities and fluid handler capability
  3. Associates with the appropriate block from MachineBlocks

This implementation ensures the farming station will function with energy and fluid capabilities like other similar machines.

enderio-machines/src/main/java/com/enderio/machines/common/init/MachineMenus.java (3)

10-10: Appropriate import for the FarmingStationScreen.

The import follows the existing pattern for GUI screen imports.


53-53: Appropriate import for the FarmingStationMenu.

The import follows the established pattern of menu imports in the file.


104-105: Good implementation of the farming station menu registration.

The menu registration correctly:

  1. Uses a consistent naming scheme
  2. Links the appropriate menu and screen classes
  3. Follows the same pattern as other menu registrations

This ensures that the farming station GUI will be properly accessible in the game.

enderio-machines/src/main/java/com/enderio/machines/common/network/MachinePayloadHandler.java (2)

6-6: Appropriate import for the FarmSoul class.

The import follows the established pattern for soul data imports.


28-30: Well-implemented handler for farming station soul packets.

The implementation follows the pattern established by the other soul data handlers:

  1. Uses context.enqueueWork() to safely handle the packet processing
  2. Updates the appropriate soul data map
  3. Maintains a consistent naming and method signature pattern

This ensures that farming station soul data can be properly synchronized between client and server.

enderio-machines/src/main/java/com/enderio/machines/data/souldata/SoulDataProvider.java (2)

145-147: Well-structured farm data configuration for entities

The implementation correctly adds farm data for bees, villagers, and sniffers with appropriate parameters tailored to each entity type. This is a good approach for entity-specific farming characteristics.


199-203: Good implementation of the farm data helper method

The addFarmData method follows the same pattern as other data addition methods in this class, ensuring consistency with the existing codebase.

enderio-machines/src/main/java/com/enderio/machines/common/config/common/EnergyConfig.java (1)

45-46: Configuration additions for farming station

The energy configuration for the farming station follows the same pattern as other machines, with appropriate capacity and usage parameters.

Have you considered whether the default energy usage of 10 uI/t is sufficient for farming operations? This seems quite low compared to other machines like the SAG Mill (20), Crafter (80), or Painting Machine (30).

Consider reviewing the balance of energy consumption for the farming station compared to other machines in the mod. The current value (10 uI/t) is on the low end.

Also applies to: 150-153

enderio-machines/src/main/java/com/enderio/machines/common/utility/TreeHelper.java (1)

15-17: Simple and effective tree detection

Using the vanilla block tags LOGS and LEAVES is a good approach for compatibility with modded tree variants.

enderio-machines/src/main/java/com/enderio/machines/client/gui/screen/FarmingStationScreen.java (1)

17-54: Screen implementation looks good

The FarmingStationScreen implementation follows the pattern used in other machine screens in the mod, with good separation of concerns. All necessary components are properly added and positioned.

enderio-machines/src/main/java/com/enderio/machines/common/init/MachineNetwork.java (1)

4-4: Soul packet registration looks correct

The FarmStationSoulPacket and FarmSoul integration follows the established pattern used for other soul types in the mod. The implementation is consistent with the existing architecture.

Also applies to: 13-13, 32-32, 41-42

enderio-machines/src/main/java/com/enderio/machines/common/network/FarmStationSoulPacket.java (1)

15-23: Packet implementation looks good

The FarmStationSoulPacket implementation is consistent with other packet types in the mod and follows good practices for network packet design. The use of StreamCodec for serialization is appropriate.

enderio-machines/src/main/java/com/enderio/machines/common/souldata/FarmSoul.java (3)

25-30: Good use of Codec with optional fields.
Using optionalFieldOf is a neat way to handle missing data. This helps keep the SoulData flexible when reading from different resource definitions. Great job!


32-42: Verify that ByteBuf-based streaming is needed.
The STREAM_CODEC is solid but can add overhead if the data rarely changes. Confirm that partial or event-based sync is required, otherwise a standard textual or minimal approach might suffice.


47-50: Event subscription approach looks correct.
AddReloadListenerEvent is handled neatly. Just remember to check that your bus subscription is in a suitable lifecycle for resource reloading.

enderio-machines/src/main/java/com/enderio/machines/common/blocks/farming_station/FarmingStationBlockEntity.java (4)

108-135: Validate range updates and communication
When setActionRange assigns the new range and sets changed flags, ensure that any clients or neighbouring components (e.g. other tile entities) requiring awareness of the range update are notified. The usage of level.sendBlockUpdated(...) is correct but confirm all relevant side effects (e.g. bounding box recalculations) are handled.

Would you like to verify any adjacency checks or additional notifications to confirm the range dimension updates correctly on both client and server?


184-217: Check bounding conditions for your farming task loop
The loop in doFarmTask() processes a subset of positions in each tick, incrementing the index. If stop == positions.size() then the index resets to zero. This logic looks correct, but be cautious with potential off-by-one errors or large ranges.

The logic is understandable and should work well for managing partial iterations, assuming you have tested edge cases like zero or maximum range lengths.


219-234: Validate directional seed slot mapping
The getSeedForPos method bases slot selection on coordinate comparisons with the block’s position. The TODO suggests that the mapping might be reversed or inaccurate. This could place seeds in the wrong slot for certain positions.

Would you like to confirm these direction-based checks align with the intended cardinal directions around the farming station? I can generate a script to track usage of getSeedForPos across the codebase and see if any mismatch arises.


341-353: Verify bonemeal consumption rates
The code randomly consumes bonemeal based on soulData.bonemeal(). This might lead to confusion if the chance is very low (or high). If you intend a near-guaranteed consumption, ensure that the probability isn’t so small that no bonemeal is removed from the slot.

Please confirm that your soulData configurations are tuned for the intended probabilities and that you have tested extremes (0% and 100%).

**Actionable comments posted: 9** <details> <summary>🧹 Nitpick comments (21)</summary><blockquote> <details> <summary>enderio-machines/src/main/java/com/enderio/machines/common/blocks/farming_station/package-info.java (1)</summary><blockquote> `4-5`: **Package Declaration Is Clear** The package declaration clearly reflects the file's location and responsibility within the project structure. For improved maintainability, consider adding package-level documentation to summarise the purpose and functionality of the Farming Station feature. This can be particularly useful for new developers or for future reference. </blockquote></details> <details> <summary>enderio-base/src/main/java/com/enderio/base/api/farm/FarmTask.java (1)</summary><blockquote> `7-7`: **Consider documenting the parameters and return values.** Adding Javadoc would improve understanding of how the interface should be implemented. ```diff +/** + * Interface for farm tasks that can be performed by a farming station. + */ public interface FarmTask { + /** + * Performs a farming operation at the specified soil location. + * + * @param soil The position of the soil block to farm + * @param farmBlockEntity The farming station performing the operation + * @return The result of the farming interaction + */ FarmInteraction farm(BlockPos soil, FarmingStation farmBlockEntity); } ``` </blockquote></details> <details> <summary>enderio-base/src/main/resources/assets/enderio/lang/af_za.json (1)</summary><blockquote> `76-76`: **Consider localizing to actual Afrikaans.** The entry just uses English "Farming Station" while this is the Afrikaans language file. Consider translating it to proper Afrikaans (possibly "Boerdery Stasie"). </blockquote></details> <details> <summary>enderio-machines/src/main/java/com/enderio/machines/common/init/MachineBlocks.java (1)</summary><blockquote> `276-283`: **Consider using the helper method and specifying the type parameter.** While the implementation works, there are two potential improvements: 1. The type parameter for ProgressMachineBlock is not specified, unlike other similar machine blocks that use `ProgressMachineBlock<SpecificBlockEntityType>`. 2. This implementation directly uses the block registry rather than the helper method `progressMachine()` (line 341) that's used by most other machine blocks. Consider refactoring to use the helper method for consistency: ```diff -public static final RegiliteBlock<ProgressMachineBlock> FARMING_STATION = BLOCK_REGISTRY - .registerBlock("farming_station", properties -> new ProgressMachineBlock(MachineBlockEntities.FARMING_STATION, properties), - BlockBehaviour.Properties.of().strength(2.5f, 8)) - .setLootTable(MachinesLootTable::copyComponents) - .addBlockTags(BlockTags.NEEDS_IRON_TOOL, BlockTags.MINEABLE_WITH_PICKAXE) - .setBlockStateProvider((prov, ctx) -> prov.simpleBlock(ctx.get(), - prov.models().getExistingFile(EnderIO.loc("block/" + ctx.getName())))) - .createBlockItem(ITEM_REGISTRY, item -> item.setTab(EIOCreativeTabs.MACHINES)); +public static final RegiliteBlock<ProgressMachineBlock<?>> FARMING_STATION = progressMachine("farming_station", + () -> MachineBlockEntities.FARMING_STATION); ``` </blockquote></details> <details> <summary>enderio-base/src/main/java/com/enderio/base/api/farm/FarmTaskManager.java (3)</summary><blockquote> `10-43`: **Declare constants as final for better code safety** The integer constants PLANT, BONEMEAL, and HARVEST should be declared as final since they represent fixed task priorities and shouldn't be modified. ```diff - public static int PLANT = 1; - public static int BONEMEAL = 3; - public static int HARVEST = 5; + public static final int PLANT = 1; + public static final int BONEMEAL = 3; + public static final int HARVEST = 5; ``` --- `22-30`: **Consider potential race conditions in static initialization** The current implementation of `getTasks()` might cause issues if called concurrently from multiple threads. Consider using thread-safe initialization patterns like an AtomicReference or synchronization. You could use a thread-safe initialization approach: ```diff - private static ImmutableList<FarmTask> TASKS_IMMUTABLE; + private static volatile ImmutableList<FarmTask> TASKS_IMMUTABLE; public static List<FarmTask> getTasks() { if (TASKS_IMMUTABLE == null) { - FarmTaskManager manager = new FarmTaskManager(); - IntegrationManager.forAll(integration -> integration.registerFarmTasks(manager)); - manager.tasks.sort(TaskEntry::compareTo); - TASKS_IMMUTABLE = ImmutableList.copyOf(manager.tasks.stream().map(e -> e.task).toList()); + synchronized (FarmTaskManager.class) { + if (TASKS_IMMUTABLE == null) { + FarmTaskManager manager = new FarmTaskManager(); + IntegrationManager.forAll(integration -> integration.registerFarmTasks(manager)); + manager.tasks.sort(TaskEntry::compareTo); + TASKS_IMMUTABLE = ImmutableList.copyOf(manager.tasks.stream().map(e -> e.task).toList()); + } + } } return TASKS_IMMUTABLE; } ``` --- `36-42`: **Consider a more efficient `compareTo` implementation** The current implementation works correctly but can be improved by using Integer.compare for better readability and to avoid potential integer overflow issues. ```diff @Override public int compareTo(@NotNull FarmTaskManager.TaskEntry o) { - return priority - o.priority; + return Integer.compare(priority, o.priority); } ``` </blockquote></details> <details> <summary>enderio-machines/src/main/java/com/enderio/machines/common/utility/TreeHelper.java (1)</summary><blockquote> `19-40`: **Add a size limit to prevent server performance issues** For very large trees or connected forest structures, the algorithm could potentially process thousands of blocks, causing server lag. Add a maximum size limit to prevent performance issues: ```diff -public static Set<BlockPos> getTree(Level level, BlockPos bottom, Predicate<BlockPos> inRange) { +public static Set<BlockPos> getTree(Level level, BlockPos bottom, Predicate<BlockPos> inRange) { + return getTree(level, bottom, inRange, 1000); // Default max size of 1000 blocks +} + +public static Set<BlockPos> getTree(Level level, BlockPos bottom, Predicate<BlockPos> inRange, int maxSize) { LinkedList<BlockPos> candidates = new LinkedList<>(); HashSet<BlockPos> tree = new HashSet<>(); HashSet<BlockPos> seen = new HashSet<>(); candidates.add(bottom); while(!candidates.isEmpty()) { BlockPos pos = candidates.removeFirst(); BlockState state = level.getBlockState(pos); seen.add(pos); if(isTree(state) && inRange.test(pos)) { tree.add(pos); + // Stop if we've reached the maximum size + if (tree.size() >= maxSize) { + break; + } BlockPos.betweenClosed(pos.offset(1, 1, 1), pos.offset(-1, -1, -1)) .forEach(next -> { if(seen.contains(next)) return; candidates.add(next); }); } } return tree; } ``` </blockquote></details> <details> <summary>enderio-machines/src/main/java/com/enderio/machines/client/gui/screen/FarmingStationScreen.java (2)</summary><blockquote> `10-10`: **Unused import** The import for `NewCapacitorEnergyWidget` on line 10 appears to be unused as the code uses `CapacitorEnergyWidget` on line 34. Consider removing this unused import to keep the code clean. ```diff -import com.enderio.machines.client.gui.widget.NewCapacitorEnergyWidget; ``` --- `55-57`: **Consider adding tooltips for slots** The current implementation handles background rendering but doesn't implement any custom tooltips for the farming station's specialized slots. Consider adding tooltips to improve user experience by explaining the purpose of each specialized slot (axe, hoe, shears, etc.). </blockquote></details> <details> <summary>enderio-machines/src/main/java/com/enderio/machines/common/blocks/farming_station/FarmingStationMenu.java (2)</summary><blockquote> `59-59`: **Consider refactoring duplicated code** The `// noinspection DuplicatedCode` comment suggests there might be duplicated code across different menu classes. Consider refactoring the common code into a shared utility method. ```web What are best practices for handling duplicated code in Java? ``` --- `29-51`: **Consider using constants for slot positions** The slot positions are currently hard-coded with magic numbers. Consider using constants for the base positions and offsets to make the layout more maintainable. ```diff - private void addSlots() { - addCapacitorSlot(12, 63); - - var inventory = getMachineInventory(); - // Tool inputs TODO: Shadow slots to show compatible tools? - addSlot(new MachineSlot(inventory, FarmingStationBlockEntity.AXE, 44, 19)); - addSlot(new MachineSlot(inventory, FarmingStationBlockEntity.HOE, 44 + 18, 19)); - addSlot(new MachineSlot(inventory, FarmingStationBlockEntity.SHEAR, 44 + 18 * 2, 19)); + private static final int TOOL_SLOT_X = 44; + private static final int TOOL_SLOT_Y = 19; + private static final int SLOT_SIZE = 18; + private static final int SEED_SLOT_X = 53; + private static final int SEED_SLOT_Y = 44; + private static final int OUTPUT_SLOT_X = 107; + private static final int OUTPUT_SLOT_Y = 44; + + private void addSlots() { + addCapacitorSlot(12, 63); + + var inventory = getMachineInventory(); + // Tool inputs TODO: Shadow slots to show compatible tools? + addSlot(new MachineSlot(inventory, FarmingStationBlockEntity.AXE, TOOL_SLOT_X, TOOL_SLOT_Y)); + addSlot(new MachineSlot(inventory, FarmingStationBlockEntity.HOE, TOOL_SLOT_X + SLOT_SIZE, TOOL_SLOT_Y)); + addSlot(new MachineSlot(inventory, FarmingStationBlockEntity.SHEAR, TOOL_SLOT_X + SLOT_SIZE * 2, TOOL_SLOT_Y)); ``` </blockquote></details> <details> <summary>enderio-machines/src/main/java/com/enderio/machines/common/network/FarmStationSoulPacket.java (1)</summary><blockquote> `25-31`: **Consider refactoring SoulData construction** The packet is directly constructing a `FarmSoul.SoulData` from the buffer. If the structure of `SoulData` changes, both this code and the codec would need to be updated. Consider adding a static factory method in `FarmSoul.SoulData` to read from a buffer. ```diff - public FarmStationSoulPacket(FriendlyByteBuf buf) { - this( - buf.readMap(FriendlyByteBuf::readResourceLocation, buff -> - new FarmSoul.SoulData(buff.readResourceLocation(), buff.readFloat(), buff.readInt(), buff.readFloat()) - ) - ); - } + public FarmStationSoulPacket(FriendlyByteBuf buf) { + this( + buf.readMap(FriendlyByteBuf::readResourceLocation, FarmSoul.SoulData::fromBuffer) + ); + } ``` And in the FarmSoul class: ```java public static SoulData fromBuffer(FriendlyByteBuf buf) { return new SoulData(buf.readResourceLocation(), buf.readFloat(), buf.readInt(), buf.readFloat()); } ``` </blockquote></details> <details> <summary>enderio-machines/src/main/java/com/enderio/machines/common/souldata/FarmSoul.java (1)</summary><blockquote> `17-22`: **Consider verifying default values for resilience.** The `SoulData` record sets defaults of `1f` for bonemeal and power, and `0` for seeds. If you anticipate future changes or expansions to these fields, ensure these defaults reflect the intended mod behaviour and do not inadvertently unsettle balance. </blockquote></details> <details> <summary>enderio-base/src/main/java/com/enderio/base/api/farm/FarmingStation.java (2)</summary><blockquote> `1-57`: **Please fix Spotless formatting issues.** The pipeline failure indicates you must run `./gradlew :enderio-base:spotlessApply` to satisfy formatting rules. This is critical before merging. If you need help automating this or verifying the fix, I can provide a script – let me know. <details> <summary>🧰 Tools</summary> <details> <summary>🪛 GitHub Actions: Verify Build</summary> [error] 1-6: The following files had format violations: Spotless formatting check failed. Run './gradlew :enderio-base:spotlessApply' to fix these violations. </details> </details> --- `49-55`: **Check concurrency usage of FakePlayer.** `useStack` might be called concurrently if multiple tasks run in parallel. Ensure there's no concurrent access to the same `FakePlayer` instance to avoid item or world interaction conflicts. </blockquote></details> <details> <summary>enderio-machines/src/main/java/com/enderio/machines/common/blocks/base/task/MachineFarmingTasks.java (2)</summary><blockquote> `180-180`: **TODO reference: "no general 2 block crop?"** This comment suggests partial or unimplemented two-block crop logic. If you foresee future expansions (like tall crops), clarifying or implementing a standard approach to multi-block crops would be ideal. --- `34-354`: **Overall code organisation is solid, but be mindful of complexity.** Having many static tasks in a single file is convenient but can become unwieldy. Consider grouping tasks by theme (plant vs. harvest) or splitting them into sub-classes to aid maintenance. </blockquote></details> <details> <summary>enderio-machines/src/main/java/com/enderio/machines/common/blocks/farming_station/FarmingStationBlockEntity.java (3)</summary><blockquote> `90-93`: **Clarify usage of a shared fake player across machines** There is a TODO remark suggesting a single fake player might be used for all farming stations. A shared fake player may lead to concurrency and player-state issues if multiple stations operate simultaneously (e.g. concurrent item usage or partial item states). If you expect multiple stations to perform tasks concurrently, consider provisioning a separate fake player per machine or carefully synchronising all interactions to avoid unexpected behaviour. --- `163-173`: **Discuss the global static `reload` flag** The logic at lines 163–167 depends on a static `reload` boolean to refresh soul data once. If multiple block entities exist or if the server reload state changes unpredictably, this might fail or update unexpectedly. Consider a more local mechanism or an event-based callback to reinitialise internal caches. This avoids potential confusion from having a single reload variable affecting multiple entities. --- `417-419`: **Reassess the onReload toggling approach** The event listener simply flips `reload` using `reload = !reload;`. This might cause confusion if reloaded multiple times in quick succession (e.g. repeated data pack reloads). Consider storing a reload counter or a timestamp rather than toggling a boolean. This way, you can reliably detect changes without having to guess the “true–false” cycle. </blockquote></details> </blockquote></details> <details> <summary>📜 Review details</summary> **Configuration used: CodeRabbit UI** **Review profile: CHILL** **Plan: Pro** <details> <summary>📥 Commits</summary> Reviewing files that changed from the base of the PR and between 9ea99e81e12c284166894154ea8bbe8c375428d5 and 06698810f23912d2fb2ec44ad86d4d0e79b9c81e. </details> <details> <summary>⛔ Files ignored due to path filters (17)</summary> * `enderio-base/src/generated/resources/assets/enderio/blockstates/farming_station.json` is excluded by `!**/generated/**` * `enderio-base/src/generated/resources/assets/enderio/models/block/farming_station_active_combined.json` is excluded by `!**/generated/**` * `enderio-base/src/generated/resources/assets/enderio/models/block/farming_station_combined.json` is excluded by `!**/generated/**` * `enderio-base/src/generated/resources/assets/enderio/models/item/farming_station.json` is excluded by `!**/generated/**` * `enderio-base/src/generated/resources/data/enderio/loot_table/blocks/farming_station.json` is excluded by `!**/generated/**` * `enderio-base/src/generated/resources/data/minecraft/tags/block/mineable/pickaxe.json` is excluded by `!**/generated/**` * `enderio-machines/src/generated/resources/assets/enderio/blockstates/farming_station.json` is excluded by `!**/generated/**` * `enderio-machines/src/generated/resources/assets/enderio/lang/en_us.json` is excluded by `!**/generated/**` * `enderio-machines/src/generated/resources/assets/enderio/models/item/farming_station.json` is excluded by `!**/generated/**` * `enderio-machines/src/generated/resources/data/enderio/eio_soul/farm/minecraft_bee.json` is excluded by `!**/generated/**` * `enderio-machines/src/generated/resources/data/enderio/eio_soul/farm/minecraft_sniffer.json` is excluded by `!**/generated/**` * `enderio-machines/src/generated/resources/data/enderio/eio_soul/farm/minecraft_villager.json` is excluded by `!**/generated/**` * `enderio-machines/src/generated/resources/data/enderio/loot_table/blocks/farming_station.json` is excluded by `!**/generated/**` * `enderio-machines/src/generated/resources/data/enderio/recipe/soulbinding/farming_station.json` is excluded by `!**/generated/**` * `enderio-machines/src/generated/resources/data/minecraft/tags/block/mineable/pickaxe.json` is excluded by `!**/generated/**` * `enderio-machines/src/generated/resources/data/minecraft/tags/block/needs_iron_tool.json` is excluded by `!**/generated/**` * `enderio-machines/src/main/resources/assets/enderio/textures/block/farming_station_side.png` is excluded by `!**/*.png` </details> <details> <summary>📒 Files selected for processing (25)</summary> * `enderio-base/src/main/java/com/enderio/base/api/farm/FarmInteraction.java` (1 hunks) * `enderio-base/src/main/java/com/enderio/base/api/farm/FarmTask.java` (1 hunks) * `enderio-base/src/main/java/com/enderio/base/api/farm/FarmTaskManager.java` (1 hunks) * `enderio-base/src/main/java/com/enderio/base/api/farm/FarmingStation.java` (1 hunks) * `enderio-base/src/main/java/com/enderio/base/api/integration/Integration.java` (2 hunks) * `enderio-base/src/main/java/com/enderio/base/common/tag/EIOTags.java` (1 hunks) * `enderio-base/src/main/resources/assets/enderio/lang/af_za.json` (1 hunks) * `enderio-machines/src/main/java/com/enderio/machines/client/gui/screen/FarmingStationScreen.java` (1 hunks) * `enderio-machines/src/main/java/com/enderio/machines/common/blocks/base/task/MachineFarmingTasks.java` (1 hunks) * `enderio-machines/src/main/java/com/enderio/machines/common/blocks/farming_station/FarmingStationBlockEntity.java` (1 hunks) * `enderio-machines/src/main/java/com/enderio/machines/common/blocks/farming_station/FarmingStationMenu.java` (1 hunks) * `enderio-machines/src/main/java/com/enderio/machines/common/blocks/farming_station/package-info.java` (1 hunks) * `enderio-machines/src/main/java/com/enderio/machines/common/config/common/EnergyConfig.java` (2 hunks) * `enderio-machines/src/main/java/com/enderio/machines/common/init/MachineBlockEntities.java` (2 hunks) * `enderio-machines/src/main/java/com/enderio/machines/common/init/MachineBlocks.java` (1 hunks) * `enderio-machines/src/main/java/com/enderio/machines/common/init/MachineMenus.java` (3 hunks) * `enderio-machines/src/main/java/com/enderio/machines/common/init/MachineNetwork.java` (4 hunks) * `enderio-machines/src/main/java/com/enderio/machines/common/integrations/EnderIOMachinesSelfIntegration.java` (2 hunks) * `enderio-machines/src/main/java/com/enderio/machines/common/network/FarmStationSoulPacket.java` (1 hunks) * `enderio-machines/src/main/java/com/enderio/machines/common/network/MachinePayloadHandler.java` (2 hunks) * `enderio-machines/src/main/java/com/enderio/machines/common/souldata/FarmSoul.java` (1 hunks) * `enderio-machines/src/main/java/com/enderio/machines/common/utility/TreeHelper.java` (1 hunks) * `enderio-machines/src/main/java/com/enderio/machines/data/recipes/SoulBindingRecipeProvider.java` (2 hunks) * `enderio-machines/src/main/java/com/enderio/machines/data/souldata/SoulDataProvider.java` (3 hunks) * `enderio-machines/src/main/resources/assets/enderio/models/block/farming_station.json` (1 hunks) </details> <details> <summary>🧰 Additional context used</summary> <details> <summary>🪛 GitHub Actions: Verify Build</summary> <details> <summary>enderio-base/src/main/java/com/enderio/base/api/farm/FarmInteraction.java</summary> [error] 1-5: The following files had format violations: Spotless formatting check failed. Run './gradlew :enderio-base:spotlessApply' to fix these violations. </details> <details> <summary>enderio-base/src/main/java/com/enderio/base/api/integration/Integration.java</summary> [error] 1-1: Spotless Java check failed: Format violations detected. Please run './gradlew :enderio-base:spotlessApply' to fix. </details> <details> <summary>enderio-base/src/main/java/com/enderio/base/api/farm/FarmTaskManager.java</summary> [error] 2-10: The following files had format violations: Spotless formatting check failed. Run './gradlew :enderio-base:spotlessApply' to fix these violations. </details> <details> <summary>enderio-base/src/main/java/com/enderio/base/api/farm/FarmingStation.java</summary> [error] 1-6: The following files had format violations: Spotless formatting check failed. Run './gradlew :enderio-base:spotlessApply' to fix these violations. </details> </details> </details> <details> <summary>🔇 Additional comments (32)</summary><blockquote> <details> <summary>enderio-machines/src/main/java/com/enderio/machines/common/blocks/farming_station/package-info.java (1)</summary> `1-2`: **Null Safety Annotations Are Correctly Applied** The utilisation of `@javax.annotation.ParametersAreNonnullByDefault` along with `@net.minecraft.MethodsReturnNonnullByDefault` ensures that all methods and parameters in this package are treated as non-null by default. This approach enhances the reliability of the code by reducing potential null pointer issues. </details> <details> <summary>enderio-base/src/main/java/com/enderio/base/api/farm/FarmTask.java (1)</summary> `5-7`: **Well-designed task interface.** The interface is concise and follows the single responsibility principle. It provides a clear contract for implementing farming tasks. </details> <details> <summary>enderio-base/src/main/resources/assets/enderio/lang/af_za.json (1)</summary> `76-76`: **Good localization addition.** The localization entry for the farming station is properly added and follows the same format as existing entries. </details> <details> <summary>enderio-machines/src/main/resources/assets/enderio/models/block/farming_station.json (2)</summary> `1-12`: **Well-structured block model.** The JSON model is properly formatted and includes all necessary faces and particle texture definitions. --- `3-11`: <details> <summary>✅ Verification successful</summary> **Verify texture resources exist.** Ensure that all referenced textures exist in the resource paths: - `enderio:block/soul_machine_bottom` - `enderio:block/farming_station_side` - `enderio:block/soul_machine_top` This will prevent resource loading errors at runtime. --- 🏁 Script executed: ```shell #!/bin/bash # Check if the referenced textures exist in the resource paths echo "Checking for referenced textures..." textures=( "soul_machine_bottom" "farming_station_side" "soul_machine_top" ) for texture in "${textures[@]}"; do echo "Looking for $texture..." found=$(fd "$texture.png" enderio-machines/src/main/resources/assets/enderio/textures/block) if [ -z "$found" ]; then echo "WARNING: Texture $texture.png not found!" else echo "Found: $found" fi done ``` Length of output: 1982 --- </details> **Verified: All texture resources exist as expected.** The textures for: - `enderio:block/soul_machine_bottom` - `enderio:block/farming_station_side` - `enderio:block/soul_machine_top` have been confirmed to exist in the corresponding resource directories. There are no changes required in the JSON file. </details> <details> <summary>enderio-base/src/main/java/com/enderio/base/common/tag/EIOTags.java (1)</summary> `123-124`: **Addition of fertilizer tag looks good.** The introduction of the `FERTILIZERS` tag fits well with the existing tag structure and will be useful for the farming station feature to identify valid fertilizer items. </details> <details> <summary>enderio-base/src/main/java/com/enderio/base/api/integration/Integration.java (1)</summary> `3-3`: **Import addition is appropriate.** This import is necessary for the new method parameter. </details> <details> <summary>enderio-machines/src/main/java/com/enderio/machines/data/recipes/SoulBindingRecipeProvider.java (2)</summary> `12-12`: **Import addition is appropriate.** This import is necessary for accessing the FarmSoul.NAME constant in the new recipe. --- `49-49`: **Soul binding recipe for farming station follows established pattern.** The recipe parameters match other similar machine recipes, using appropriate energy and experience values. This will enable players to create farming stations with soul binding mechanics. </details> <details> <summary>enderio-machines/src/main/java/com/enderio/machines/common/integrations/EnderIOMachinesSelfIntegration.java (2)</summary> `4-5`: **Required imports for farm task functionality.** These imports are necessary for implementing the farm task registration method. --- `18-32`: **Comprehensive implementation of farm task registration.** The implementation properly registers various planting, fertilizing, and harvesting tasks with appropriate priorities. The method follows a consistent pattern for task registration using the priority constants from FarmTaskManager. These tasks provide the farming station with capabilities to handle different crops, trees, and plant types, making it a versatile farming solution. </details> <details> <summary>enderio-machines/src/main/java/com/enderio/machines/common/init/MachineBlockEntities.java (2)</summary> `12-12`: **Appropriate import for the new farming station block entity.** The import for the FarmingStationBlockEntity follows the package structure conventions of the codebase. --- `202-205`: **Good implementation of the farming station block entity registration.** The registration follows the established pattern in the codebase: 1. Properly named using the same convention as other block entities 2. Correctly applies both the powered machine capabilities and fluid handler capability 3. Associates with the appropriate block from MachineBlocks This implementation ensures the farming station will function with energy and fluid capabilities like other similar machines. </details> <details> <summary>enderio-machines/src/main/java/com/enderio/machines/common/init/MachineMenus.java (3)</summary> `10-10`: **Appropriate import for the FarmingStationScreen.** The import follows the existing pattern for GUI screen imports. --- `53-53`: **Appropriate import for the FarmingStationMenu.** The import follows the established pattern of menu imports in the file. --- `104-105`: **Good implementation of the farming station menu registration.** The menu registration correctly: 1. Uses a consistent naming scheme 2. Links the appropriate menu and screen classes 3. Follows the same pattern as other menu registrations This ensures that the farming station GUI will be properly accessible in the game. </details> <details> <summary>enderio-machines/src/main/java/com/enderio/machines/common/network/MachinePayloadHandler.java (2)</summary> `6-6`: **Appropriate import for the FarmSoul class.** The import follows the established pattern for soul data imports. --- `28-30`: **Well-implemented handler for farming station soul packets.** The implementation follows the pattern established by the other soul data handlers: 1. Uses context.enqueueWork() to safely handle the packet processing 2. Updates the appropriate soul data map 3. Maintains a consistent naming and method signature pattern This ensures that farming station soul data can be properly synchronized between client and server. </details> <details> <summary>enderio-machines/src/main/java/com/enderio/machines/data/souldata/SoulDataProvider.java (2)</summary> `145-147`: **Well-structured farm data configuration for entities** The implementation correctly adds farm data for bees, villagers, and sniffers with appropriate parameters tailored to each entity type. This is a good approach for entity-specific farming characteristics. --- `199-203`: **Good implementation of the farm data helper method** The `addFarmData` method follows the same pattern as other data addition methods in this class, ensuring consistency with the existing codebase. </details> <details> <summary>enderio-machines/src/main/java/com/enderio/machines/common/config/common/EnergyConfig.java (1)</summary> `45-46`: **Configuration additions for farming station** The energy configuration for the farming station follows the same pattern as other machines, with appropriate capacity and usage parameters. Have you considered whether the default energy usage of 10 uI/t is sufficient for farming operations? This seems quite low compared to other machines like the SAG Mill (20), Crafter (80), or Painting Machine (30). Consider reviewing the balance of energy consumption for the farming station compared to other machines in the mod. The current value (10 uI/t) is on the low end. Also applies to: 150-153 </details> <details> <summary>enderio-machines/src/main/java/com/enderio/machines/common/utility/TreeHelper.java (1)</summary> `15-17`: **Simple and effective tree detection** Using the vanilla block tags `LOGS` and `LEAVES` is a good approach for compatibility with modded tree variants. </details> <details> <summary>enderio-machines/src/main/java/com/enderio/machines/client/gui/screen/FarmingStationScreen.java (1)</summary> `17-54`: **Screen implementation looks good** The FarmingStationScreen implementation follows the pattern used in other machine screens in the mod, with good separation of concerns. All necessary components are properly added and positioned. </details> <details> <summary>enderio-machines/src/main/java/com/enderio/machines/common/init/MachineNetwork.java (1)</summary> `4-4`: **Soul packet registration looks correct** The FarmStationSoulPacket and FarmSoul integration follows the established pattern used for other soul types in the mod. The implementation is consistent with the existing architecture. Also applies to: 13-13, 32-32, 41-42 </details> <details> <summary>enderio-machines/src/main/java/com/enderio/machines/common/network/FarmStationSoulPacket.java (1)</summary> `15-23`: **Packet implementation looks good** The FarmStationSoulPacket implementation is consistent with other packet types in the mod and follows good practices for network packet design. The use of StreamCodec for serialization is appropriate. </details> <details> <summary>enderio-machines/src/main/java/com/enderio/machines/common/souldata/FarmSoul.java (3)</summary> `25-30`: **Good use of Codec with optional fields.** Using `optionalFieldOf` is a neat way to handle missing data. This helps keep the `SoulData` flexible when reading from different resource definitions. Great job! --- `32-42`: **Verify that ByteBuf-based streaming is needed.** The `STREAM_CODEC` is solid but can add overhead if the data rarely changes. Confirm that partial or event-based sync is required, otherwise a standard textual or minimal approach might suffice. --- `47-50`: **Event subscription approach looks correct.** `AddReloadListenerEvent` is handled neatly. Just remember to check that your bus subscription is in a suitable lifecycle for resource reloading. </details> <details> <summary>enderio-machines/src/main/java/com/enderio/machines/common/blocks/farming_station/FarmingStationBlockEntity.java (4)</summary> `108-135`: **Validate range updates and communication** When `setActionRange` assigns the new range and sets changed flags, ensure that any clients or neighbouring components (e.g. other tile entities) requiring awareness of the range update are notified. The usage of `level.sendBlockUpdated(...)` is correct but confirm all relevant side effects (e.g. bounding box recalculations) are handled. Would you like to verify any adjacency checks or additional notifications to confirm the range dimension updates correctly on both client and server? --- `184-217`: **Check bounding conditions for your farming task loop** The loop in `doFarmTask()` processes a subset of positions in each tick, incrementing the index. If `stop == positions.size()` then the index resets to zero. This logic looks correct, but be cautious with potential off-by-one errors or large ranges. The logic is understandable and should work well for managing partial iterations, assuming you have tested edge cases like zero or maximum range lengths. --- `219-234`: **Validate directional seed slot mapping** The `getSeedForPos` method bases slot selection on coordinate comparisons with the block’s position. The TODO suggests that the mapping might be reversed or inaccurate. This could place seeds in the wrong slot for certain positions. Would you like to confirm these direction-based checks align with the intended cardinal directions around the farming station? I can generate a script to track usage of `getSeedForPos` across the codebase and see if any mismatch arises. --- `341-353`: **Verify bonemeal consumption rates** The code randomly consumes bonemeal based on `soulData.bonemeal()`. This might lead to confusion if the chance is very low (or high). If you intend a near-guaranteed consumption, ensure that the probability isn’t so small that no bonemeal is removed from the slot. Please confirm that your `soulData` configurations are tuned for the intended probabilities and that you have tested extremes (0% and 100%). </details> </blockquote></details> </details> <!-- This is an auto-generated comment by CodeRabbit for review status -->
@ -0,0 +5,4 @@
POWERED,
BLOCKED,
IGNORED;
}
coderabbitai[bot] (Migrated from github.com) commented 2025-03-16 20:29:27 +00:00

⚠️ Potential issue

Good enum design with clear status values.

The enum provides a clean way to represent different farming operation outcomes. The status values are self-explanatory and well-chosen.

Fix formatting to pass CI pipeline.

The pipeline failure indicates formatting issues. Run the suggested command to fix:

./gradlew :enderio-base:spotlessApply
🧰 Tools
🪛 GitHub Actions: Verify Build

[error] 1-5: The following files had format violations: Spotless formatting check failed. Run './gradlew :enderio-base:spotlessApply' to fix these violations.

_⚠️ Potential issue_ **Good enum design with clear status values.** The enum provides a clean way to represent different farming operation outcomes. The status values are self-explanatory and well-chosen. **Fix formatting to pass CI pipeline.** The pipeline failure indicates formatting issues. Run the suggested command to fix: ```shell ./gradlew :enderio-base:spotlessApply ``` <details> <summary>🧰 Tools</summary> <details> <summary>🪛 GitHub Actions: Verify Build</summary> [error] 1-5: The following files had format violations: Spotless formatting check failed. Run './gradlew :enderio-base:spotlessApply' to fix these violations. </details> </details> <!-- This is an auto-generated comment by CodeRabbit -->
@ -0,0 +4,4 @@
public interface FarmTask {
FarmInteraction farm(BlockPos soil, FarmingStation farmBlockEntity);
coderabbitai[bot] (Migrated from github.com) commented 2025-03-16 20:29:27 +00:00

⚠️ Potential issue

Import for FarmingStation is missing.

The interface references FarmingStation but doesn't import it. Add the appropriate import statement.

 package com.enderio.base.api.farm;

 import net.minecraft.core.BlockPos;
+import com.enderio.machines.common.blocks.farming_station.FarmingStation;
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

package com.enderio.base.api.farm;

import net.minecraft.core.BlockPos;
import com.enderio.machines.common.blocks.farming_station.FarmingStation;

public interface FarmTask {

    FarmInteraction farm(BlockPos soil, FarmingStation farmBlockEntity);
_⚠️ Potential issue_ **Import for FarmingStation is missing.** The interface references `FarmingStation` but doesn't import it. Add the appropriate import statement. ```diff package com.enderio.base.api.farm; import net.minecraft.core.BlockPos; +import com.enderio.machines.common.blocks.farming_station.FarmingStation; ``` <!-- suggestion_start --> <details> <summary>📝 Committable suggestion</summary> > ‼️ **IMPORTANT** > Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements. `````suggestion package com.enderio.base.api.farm; import net.minecraft.core.BlockPos; import com.enderio.machines.common.blocks.farming_station.FarmingStation; public interface FarmTask { FarmInteraction farm(BlockPos soil, FarmingStation farmBlockEntity); ````` </details> <!-- suggestion_end --> <!-- This is an auto-generated comment by CodeRabbit -->
@ -0,0 +40,4 @@
return priority - o.priority;
}
}
}
coderabbitai[bot] (Migrated from github.com) commented 2025-03-16 20:29:28 +00:00

⚠️ Potential issue

Fix formatting issues flagged by Spotless

The pipeline failure indicates that this file has formatting violations. Please run ./gradlew :enderio-base:spotlessApply to fix these issues before merging.

#!/bin/bash
# Show the exact formatting violations for this file
./gradlew :enderio-base:spotlessCheck --debug | grep -A 10 "FarmTaskManager.java"
🧰 Tools
🪛 GitHub Actions: Verify Build

[error] 2-10: The following files had format violations: Spotless formatting check failed. Run './gradlew :enderio-base:spotlessApply' to fix these violations.

_⚠️ Potential issue_ **Fix formatting issues flagged by Spotless** The pipeline failure indicates that this file has formatting violations. Please run `./gradlew :enderio-base:spotlessApply` to fix these issues before merging. ```shell #!/bin/bash # Show the exact formatting violations for this file ./gradlew :enderio-base:spotlessCheck --debug | grep -A 10 "FarmTaskManager.java" ``` <details> <summary>🧰 Tools</summary> <details> <summary>🪛 GitHub Actions: Verify Build</summary> [error] 2-10: The following files had format violations: Spotless formatting check failed. Run './gradlew :enderio-base:spotlessApply' to fix these violations. </details> </details> <!-- This is an auto-generated comment by CodeRabbit -->
coderabbitai[bot] (Migrated from github.com) commented 2025-03-16 20:29:27 +00:00

⚠️ Potential issue

New method properly follows interface design patterns.

The default empty implementation allows integrations to optionally override this method only when needed, maintaining backward compatibility.

Please run Spotless to fix formatting issues as indicated by the pipeline failure:

./gradlew :enderio-base:spotlessApply
_⚠️ Potential issue_ **New method properly follows interface design patterns.** The default empty implementation allows integrations to optionally override this method only when needed, maintaining backward compatibility. Please run Spotless to fix formatting issues as indicated by the pipeline failure: ``` ./gradlew :enderio-base:spotlessApply ``` <!-- This is an auto-generated comment by CodeRabbit -->
@ -0,0 +48,4 @@
return FarmInteraction.FINISHED;
}
farmBlockEntity.addConsumedPower(farmBlockEntity.consumeEnergy(40 - farmBlockEntity.getConsumedPower(), false));
return FarmInteraction.POWERED;
coderabbitai[bot] (Migrated from github.com) commented 2025-03-16 20:29:28 +00:00

🛠️ Refactor suggestion

Magic number "40" repeated throughout.
Hardcoding the cost of 40 energy in multiple places risks bugs when future changes adjust the cost. Consider extracting this into a constant (e.g., HARVEST_COST) or reading from a config value for easier balancing.

Also applies to: 62-67, 88-93, 107-112, 126-131, 157-174, 188-204, 215-233, 242-260, 271-292, 303-329, 340-349

_🛠️ Refactor suggestion_ **Magic number "40" repeated throughout.** Hardcoding the cost of 40 energy in multiple places risks bugs when future changes adjust the cost. Consider extracting this into a constant (e.g., `HARVEST_COST`) or reading from a config value for easier balancing. Also applies to: 62-67, 88-93, 107-112, 126-131, 157-174, 188-204, 215-233, 242-260, 271-292, 303-329, 340-349 <!-- This is an auto-generated comment by CodeRabbit -->
@ -0,0 +75,4 @@
return FarmInteraction.FINISHED;
}
return FarmInteraction.IGNORED;
};
coderabbitai[bot] (Migrated from github.com) commented 2025-03-16 20:29:28 +00:00

🛠️ Refactor suggestion

Consider extracting repeated plant-then-hoe logic into a helper.
Each planting task attempts to plant, then tries a hoe, then tries to plant again. This repeated approach is good but could benefit from a small helper method (or a shared routine) to keep code DRY.

_🛠️ Refactor suggestion_ **Consider extracting repeated plant-then-hoe logic into a helper.** Each planting task attempts to plant, then tries a hoe, then tries to plant again. This repeated approach is good but could benefit from a small helper method (or a shared routine) to keep code DRY. <!-- This is an auto-generated comment by CodeRabbit -->
@ -0,0 +323,4 @@
}
updateMachineState(MachineState.FULL_OUTPUT, !empty);
return empty;
}
coderabbitai[bot] (Migrated from github.com) commented 2025-03-16 20:29:28 +00:00

🛠️ Refactor suggestion

Manage full inventory and handle unusual cases
There is a TODO about handling a full inventory (line 274). If all output slots and seed slots are full, items might be lost, or the station might continue to harvest in an unintended manner.

Consider either blocking the harvesting logic when outputs are full or offering partial usage to avoid dropping or losing items. This prevents potential duplication or item loss and ensures consistent behaviour.

_🛠️ Refactor suggestion_ **Manage full inventory and handle unusual cases** There is a TODO about handling a full inventory (line 274). If all output slots and seed slots are full, items might be lost, or the station might continue to harvest in an unintended manner. Consider either blocking the harvesting logic when outputs are full or offering partial usage to avoid dropping or losing items. This prevents potential duplication or item loss and ensures consistent behaviour. <!-- This is an auto-generated comment by CodeRabbit -->
@ -0,0 +30,4 @@
addCapacitorSlot(12, 63);
var inventory = getMachineInventory();
// Tool inputs TODO: Shadow slots to show compatible tools?
coderabbitai[bot] (Migrated from github.com) commented 2025-03-16 20:29:28 +00:00

💡 Verification agent

Verification inconclusive

Address TODO or remove the comment

There's a TODO comment about implementing shadow slots to show compatible tools. Either implement this feature, create a separate issue to track it, or remove the comment if it's out of scope for the current PR.


🏁 Script executed:

#!/bin/bash
# Check if there are any issues related to tool compatibility display
gh issue list --search "in:title tool compatibility display" --limit 10

Length of output: 73


Action Required: Resolve TODO for Shadow Slots Implementation

The TODO comment at line 33 in enderio-machines/src/main/java/com/enderio/machines/common/blocks/farming_station/FarmingStationMenu.java still indicates that shadow slots for tool inputs should display compatible tools. Please address this by taking one of the following actions:

  • Implement the shadow slots feature for tool compatibility.
  • Create a dedicated GitHub issue to track the implementation.
  • If this functionality is out of scope for the current PR, remove the comment.

Note: The GH issue search for "tool compatibility display" did not return any results. If you intend to track this feature on GitHub, please manually verify and create a new issue.

_💡 Verification agent_ <details> <summary>❓ Verification inconclusive</summary> **Address TODO or remove the comment** There's a TODO comment about implementing shadow slots to show compatible tools. Either implement this feature, create a separate issue to track it, or remove the comment if it's out of scope for the current PR. --- 🏁 Script executed: ```shell #!/bin/bash # Check if there are any issues related to tool compatibility display gh issue list --search "in:title tool compatibility display" --limit 10 ``` Length of output: 73 --- </details> **Action Required: Resolve TODO for Shadow Slots Implementation** The TODO comment at line 33 in `enderio-machines/src/main/java/com/enderio/machines/common/blocks/farming_station/FarmingStationMenu.java` still indicates that shadow slots for tool inputs should display compatible tools. Please address this by taking one of the following actions: - Implement the shadow slots feature for tool compatibility. - Create a dedicated GitHub issue to track the implementation. - If this functionality is out of scope for the current PR, remove the comment. Note: The GH issue search for "tool compatibility display" did not return any results. If you intend to track this feature on GitHub, please manually verify and create a new issue. <!-- This is an auto-generated comment by CodeRabbit -->
@ -0,0 +37,4 @@
}
}
return tree;
}
coderabbitai[bot] (Migrated from github.com) commented 2025-03-16 20:29:28 +00:00

🛠️ Refactor suggestion

Optimize the tree detection algorithm for performance

The current implementation has several potential performance issues:

  1. It explores blocks in all 26 directions around each position, including diagonals, which is inefficient for typical tree structures.
  2. It adds positions to the candidates list without checking if they're already seen, only filtering them later.
  3. For very large trees, this could cause significant server lag.
public static Set<BlockPos> getTree(Level level, BlockPos bottom, Predicate<BlockPos> inRange) {
    LinkedList<BlockPos> candidates = new LinkedList<>();
    HashSet<BlockPos> tree = new HashSet<>();
    HashSet<BlockPos> seen = new HashSet<>();

    candidates.add(bottom);
+   seen.add(bottom);

    while(!candidates.isEmpty()) {
        BlockPos pos = candidates.removeFirst();
        BlockState state = level.getBlockState(pos);
-       seen.add(pos);
        if(isTree(state) && inRange.test(pos)) {
            tree.add(pos);
-           BlockPos.betweenClosed(pos.offset(1, 1, 1), pos.offset(-1, -1, -1))
-               .forEach(next -> {
-                   if(seen.contains(next)) return;
-                   candidates.add(next);
-               });
+           // Only check adjacent blocks + above (trees grow upward)
+           for(int x = -1; x <= 1; x++) {
+               for(int z = -1; z <= 1; z++) {
+                   for(int y = 0; y <= 1; y++) {
+                       BlockPos next = pos.offset(x, y, z);
+                       if(!seen.contains(next)) {
+                           seen.add(next);
+                           candidates.add(next);
+                       }
+                   }
+               }
+           }
        }
    }
    return tree;
}

This optimization:

  1. Marks positions as seen when adding them to the candidates list
  2. Focuses on adjacent blocks and blocks above (since trees grow upward)
  3. Reduces the number of positions to check
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

    public static Set<BlockPos> getTree(Level level, BlockPos bottom, Predicate<BlockPos> inRange) {
        LinkedList<BlockPos> candidates = new LinkedList<>();
        HashSet<BlockPos> tree = new HashSet<>();
        HashSet<BlockPos> seen = new HashSet<>();

        candidates.add(bottom);
        seen.add(bottom);

        while (!candidates.isEmpty()) {
            BlockPos pos = candidates.removeFirst();
            BlockState state = level.getBlockState(pos);
            if (isTree(state) && inRange.test(pos)) {
                tree.add(pos);
                // Only check adjacent blocks + above (trees grow upward)
                for (int x = -1; x <= 1; x++) {
                    for (int z = -1; z <= 1; z++) {
                        for (int y = 0; y <= 1; y++) {
                            BlockPos next = pos.offset(x, y, z);
                            if (!seen.contains(next)) {
                                seen.add(next);
                                candidates.add(next);
                            }
                        }
                    }
                }
            }
        }
        return tree;
    }
_🛠️ Refactor suggestion_ **Optimize the tree detection algorithm for performance** The current implementation has several potential performance issues: 1. It explores blocks in all 26 directions around each position, including diagonals, which is inefficient for typical tree structures. 2. It adds positions to the candidates list without checking if they're already seen, only filtering them later. 3. For very large trees, this could cause significant server lag. ```diff public static Set<BlockPos> getTree(Level level, BlockPos bottom, Predicate<BlockPos> inRange) { LinkedList<BlockPos> candidates = new LinkedList<>(); HashSet<BlockPos> tree = new HashSet<>(); HashSet<BlockPos> seen = new HashSet<>(); candidates.add(bottom); + seen.add(bottom); while(!candidates.isEmpty()) { BlockPos pos = candidates.removeFirst(); BlockState state = level.getBlockState(pos); - seen.add(pos); if(isTree(state) && inRange.test(pos)) { tree.add(pos); - BlockPos.betweenClosed(pos.offset(1, 1, 1), pos.offset(-1, -1, -1)) - .forEach(next -> { - if(seen.contains(next)) return; - candidates.add(next); - }); + // Only check adjacent blocks + above (trees grow upward) + for(int x = -1; x <= 1; x++) { + for(int z = -1; z <= 1; z++) { + for(int y = 0; y <= 1; y++) { + BlockPos next = pos.offset(x, y, z); + if(!seen.contains(next)) { + seen.add(next); + candidates.add(next); + } + } + } + } } } return tree; } ``` This optimization: 1. Marks positions as seen when adding them to the candidates list 2. Focuses on adjacent blocks and blocks above (since trees grow upward) 3. Reduces the number of positions to check <!-- suggestion_start --> <details> <summary>📝 Committable suggestion</summary> > ‼️ **IMPORTANT** > Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements. `````suggestion public static Set<BlockPos> getTree(Level level, BlockPos bottom, Predicate<BlockPos> inRange) { LinkedList<BlockPos> candidates = new LinkedList<>(); HashSet<BlockPos> tree = new HashSet<>(); HashSet<BlockPos> seen = new HashSet<>(); candidates.add(bottom); seen.add(bottom); while (!candidates.isEmpty()) { BlockPos pos = candidates.removeFirst(); BlockState state = level.getBlockState(pos); if (isTree(state) && inRange.test(pos)) { tree.add(pos); // Only check adjacent blocks + above (trees grow upward) for (int x = -1; x <= 1; x++) { for (int z = -1; z <= 1; z++) { for (int y = 0; y <= 1; y++) { BlockPos next = pos.offset(x, y, z); if (!seen.contains(next)) { seen.add(next); candidates.add(next); } } } } } } return tree; } ````` </details> <!-- suggestion_end --> <!-- This is an auto-generated comment by CodeRabbit -->
Rover656 commented 2025-04-25 21:38:27 +00:00 (Migrated from github.com)

Going to go ahead and merge this into the 7.2 working branch, this PR is massive and is likely at risk of getting conflicted again soon.
I'll put it behind a feature flag (and give it a feature pack) so it can be tested, but it'll remain out of the "main mod" for now.

Going to go ahead and merge this into the 7.2 working branch, this PR is massive and is likely at risk of getting conflicted again soon. I'll put it behind a feature flag (and give it a feature pack) so it can be tested, but it'll remain out of the "main mod" for now.
Sign in to join this conversation.
No reviewers
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference: Team-EnderIO/EnderIO#568
No description provided.