Hi everyone, Minecolonies updates are here and I'm here with a new building type: The Archery.
Previously players were quite unhappy since their guards were dying quite regularly at early levels and there was no good way to level them up.
That's why we created the Archery.
What does it do:
It is a building which levels up your archers without any risk of them dying. Then they can be employed to the job as an archer guard.
What I had to prepare:
To get started I had to make sure that the levels and experience the archers get at the archery will be stored.
This way, the previously double experience field and int level field got into a map of their job description to a tuple of the level and experience.
To guarantee backward compatibility I had to load this correctly from NBT.
If the new system would be in place, I would load the whole list, else I would load the old field and put it in the list.
Writing was easier since I only had to write the new data then.
The getters and setters I then changed to job-specific getters and setters.
Where I would in all cases query the list entry, change it and then put it back in.
To make sure that the query always returns a value for a job key I used the computeIfAbsent map method which was quite handy for that.
The advantage of this was that I was able to remove all the code which previously handled losing the experience when changing the job.
I also created the getExperienceTag method to jobs.
Which a job can override if it wants to level up a different job.
The new Hut:
To create the new Hut a few things had to be taken care of.
Creating the block.
Adding it to our modblock registry.
Add a mapping in our building registry from the block to the building.
Create the building:
The building itself would store a position to shoot from and a position to shoot at for the archers to train.
To find this in the world there is the registerBlockPosition method which is called by the builder when building.
There we would check for a hay block with a fence under it as a target and glowstone as the standing position.
Then, I had to write and read this from NBT (omitted here because boring) and two methods to get one of the position by random.
To actually make them work I had to create the job class (which stores job-related info for the worker) and override the getExperienceTag method to level up the archer.
And not forget to register that.
Finally, I was able to start coding the AI itself.
The AI descriptions always get a bit more complex.
We naturally map different states to different method calls.
Initially, we map IDLE to decide and then from there we go to different states.
Decide would, in this case, make sure it has a bow, equip it and then decide on random if it should wander or find a shooting stand position.
Wandering would then get a random target and try to walk to it.
When it reaches the random position it would then decide again.
The shooting stand selection would get the random position from the building and then transfer to the walk to it state.
Which, itself, when reaching it would switch to the select target state.
There it will check if he is finished shooting and, if not, select a shooting target and go to the shoot job.
Shooting would check if he is in the progress of shooting (if hand is active)
and then to all the preparations to try to hit the target.
If not it would reduce the attack delay and eventually set the hand active.
After shooting it would then check out the result.
Depending on how successful it was it will earn some experience and then go to target selection again.