Hi everyone, in the last post I showed you our nice new archery camp where you could train your archer guards to be better.
But since a colony does not only have archers but also knights we decided to create a combat academy for the knights as well!
As always, the first thing to consider is the block.
Then adding it to the ModBlocks class,
and then registering the custom renderer (for the block).
The next step of a hut is to create the building class.
And afterwards setting up the block-building mapping.
As always we then create the job (which defines the behavior) and register the mapping as well.
Now, while testing the guards I noticed that they were quite ugly handling their shields and bows.
First of all, the shield wasn't recognized as a tool which was an easy fix.
The bigger problem was, that neither shield nor bow were rendered in action. Fortunately, I found some code hiddin in the mincraft source code taking care of that which I was able to adapt for the citizen.
This way it would check for the stack in the main hand, then check if the item is in use and check for the action.
If there was a specific action it would define the armPose in that manner.
The same thing it would do for the offhand (minecraft allows items in the right and in the left hand).
And following that we would then set the armpose of the citizen to the one we setup earlier (if found).
Which makes our guard hold their shields like below in the screenshot.
The building would serve for the knights to train fighting so we setup some fields which define the fighting statues and training pairs.
Every building has a nice "registerBlockPosition" method which gets called for every block in the building progress.
In our case it specifically checks for a pumpkin block with a hay block below it.
To get a random partner for a citizen we would get the citizen data of the caller (to get the citizen id) and then go through all the citizens which work in the building which are not the citizen itself and are neither as a key nor as a value (don't have a partner yet) in the map.
If one was found we would get the citizenEntity to the caller.
Getting the partner would again check if the data of the citizen is null and if not check in the map as a key or value of the citizen for its partner. If none was found it would return null.
To check if a citizen has a partner we would check the getCombatParner call for null.
And to reset the partner it would remove the citizen from the map if key or if value.
For the AI I first abstracted a bunch of the methods from the archer AI class into a abstract class.
You might ask why I didn't do this in the first place and the answer is simple. I strongly believe in feature driven iterative programming. I was not sure if there would be any issues with the way the archer AI was structured. So, I decided to first have the code in the archer AI and a few weeks later after noticing it works nice I'd abstract it and add another class using it to it. This methodology saved me from headache a few times already.
The tasks would be quite similar to the archer, he would wander around in the building and at a certain random moment would decide to start fighting with either the dummy or with a collegue (without taking damage of course).
The most interesting method is the attack method.
He would first check if he has a training partner and check if the partner is close. Else he would try to path to him.
Then he would run into the attack delay check (to make sure they don't spam the attacks).
On a random chance they would decide to block or to attack.
If blocking it would find the shield slot, equip the shield, play the block sound and face their target.
On attack they'd swing the arm, play the swing sound and attack their target with 0 damage.
Then they'd run away from their target again and check if they attacked often enough. If so they reset, else they will start all this all over again.