Nullkiller AI will now prefer giving its scout heroes faster units to
optimize their movement points on next turns.
Unit selection logic:
- AI prefers to give 'weak' units that won't affect army strength of main
hero. Unit is considered 'weak' if its level below 4 or if its AI value
is below 1% of total army strength. So AI can give high-tier unit to
scout, but only if main hero already has massive army.
- Within weak units, if hero is moving on terrain with penalty, AI will
always prefer units that are native to this terrain. So on snow AI will
always prefer unit from Tower even if its speed is lower than unit from
another faction.
- Within remaining candidates, AI will prefer unit that will give higher
movement points limit. This also means that in case of H3 rules, all
units with 11+ speed will be viewed as equally good
- If there are multiple units with same speed, AI will prefer unit with
lowest AI value
It was happening when all slots were full but no unit even needed disbanding because the unit to be bought is part of the units that are inside of the existing slots.
(This commit contains excessive debugging but I don't want to remove it just yet incase another issue pops up.)
The score for buying army now scales with the cost of that army.
The cost of the units that need to be disbanded in order to hire the new units is subtracted from the army-hiring-score so the AI will prefer hiring armies where the amount of troops to disband is low or non-existent.
Fixed a bug that also disbanded troops when there still were free slots available.
When the AI cannot buy units in a city because all slots are blocked and the units in the slot are cheaper than the units it wants to buy, the AI will now get rid of the units that block that slot in order to be able to buy the better units.
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
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.