AI will now also garrison a hero as defender if the town to be defended has troops as long as the hero can merge their own troops with the town.
AI will no longer just dismiss existing troops in a town if a hero trying to garrison there can merge with it.
Final goal (of multiple PR's) is to remove all remaining pointers from
serializeable game state, and replace them with either identifiers or
with shared/unique pointers.
CGTownInstance::town and CGHeroInstance::type members have been removed.
Now this data is computed dynamically using subID member.
VLC entity of a town can now be accessed via following methods:
- getFactionID() returns ID of a faction
- getFaction() returns pointer to a faction
- getTown() returns pointer to a town
VLC entity of a hero can now be accessed via following methods:
- getHeroTypeID() returns ID of a hero
- getHeroClassID() returns ID of a hero class
- getHeroType() returns pointer to a hero
- getHeroClass() returns pointer to a hero class
While it fixed the bug it was supposed to fix it caused another severe bug: AI wasn't generating a thread-map anymore.
Original bug needs to find another fix.
Reduced the amount of circumstances under which the AI dismisses heroes. Among others to prevent a loop through all passes where it repeatedly hires and dismisses heroes.
Removed the usage of BonusModifiers because depending on the case the function was sometimes called with and sometimes without an actual hero as first parameter.
This lead to inconsistencies between planned and performed army-merge and got the AI stuck in a loop where it ordered an army-merge over and over that then would not conclude.
The inclusion of bonuses of the hero for determining which army is better on them is unnecessarily convoluted and just causes issues. It took me like 4 hours to figure out why the AI didn't act.
Even if the hero blocking a town is from the own faction, the town must not become a target if the city has stashed armies because in that case the hero ontop of it won't be able to go into garrison for the TP.
AI is more careful when gathering stuff near enemies.
The wasted movement-points are no longer considered when calculating which own city to fall back to when there's nothing better to do.
Fix an issue that caused AI to take their hero's attributes into consideration twice when calculating how much army they think they'll lose.
Fixed an issue where offensive defending didn't take into consideration whether the hero would actually be strong enough to beat the enemy hero it was trying to dispatch.
A recent fix made it so that towns that weren't supposed to be defended are now no longer defended.
This caused scouts with minimal army to also go after them in addition to the main-hero.
Problem is when two heroes go for the same town it's a massive waste of movement-points. So for the time being only main-heroes will go for faraway captures.
Better solution would be to memorize who was sent to attack what on the same turn and filter out tasks going for the same target.
When attacking non-neutral towns that are far away, the AI now considers whether their attack would arrive in the same week. If it wouldn't, it means there's a high risk that newly bought troops might flip around who is stronger. So they now refrain from sending a hero towards an enemy town that is too far away.
The AI should no longer chase enemy heroes that are not reachable in the same turn, when there's other options as this behavior was quite exploitable.
The AI should now take their overall strength into account when deciding whether to attack or not.
Previously it would attack as long as their assumed army-loss was at most 25%.
Now that is 50% times the ratio of their power compared to the total power of everyone.