Looking into the AI code, there's a lot of stuff that makes a unit want to escape, but especially if it's hurt and sees lots of enemies at once. In a zombie mission, the player generally shoots the closest zombie first (why wouldn't you?) and also generally keeps all the soldiers together (because you don't need to move, they all need support and that's closer to the ammo pile). This results in a situation where the closest zombies are hurt and see many enemies, so likely try to escape. Zombies are also melee and pretty slow, so the further ones probably can't charge this turn they're probably unlikely to try to advanced unless they can get cover.
This result in a situation where the closest zombies retreat when wounded, the ones not too far refuse to advance into exposed positions because they see 4 soldiers (assuming a van) and the presence of other zombies does nothing to influence their decision and make them likely to charge because every alien is considered independently (that's the point of vanilla: Superhuman aliens grown in vat and with no coordination but great weapons VS simple human with crappy weapons but good team play: Humans + team play + good tactics wins and player is happy). But it doesn't work very well for zombies or some other factions in mods.
As for giving the knowledge of where the player is, that's usually not a problem in zombie maps since there are plenty of zombies in sight already (and they see you too). But that would make them deadly in terrain heavy maps where you are more likely to be in charge range and to spread your soldiers as opposed to open maps where you can stick together and there's no hiding for zombies. A good fix should make a zombie horde charge you in open terrain and try to overwhelm you with numbers, not make scattered zombies in terrain suddenly psychic things that know exactly when to leap out to get you.
For this, I can only see cranking up aggression to insane levels to lower escape odds as much as possible but in the following code:
https:// take our aggression into consideration
switch (_unit->getAggression())
{
case 0:
escapeOdds *= 1.4;
combatOdds *= 0.7;
break;
case 1:
ambushOdds *= 1.1;
break;
case 2:
combatOdds *= 1.4;
escapeOdds *= 0.7;
break;
default:
combatOdds *= std::max(0.1, std::min(2.0, 1.2 + (_unit->getAggression() / 10)));
escapeOdds *= std::min(2.0, std::max(0.1, 0.9 - (_unit->getAggression() / 10)));
break;
}
It looks as if values other than 0-1-2 get handled by a default that caps useable values for aggression at 8. Changing this min/max to a formula that can be extended beyond 8 could enable modders to set aggression to 200 and pretty much get a unit that always goes for the charge?