[SDK] Lead from Behind

@UncutDragon: Are the previous versions of your mod available anywhere (they're useful for maintaining mod merges)? If not, can you (or someone else) make them available temporarily? I have versions 1.1 and 1.2, and I assume there was a 1.0 at some point. Was there anything before 1.0?

Excellent mod by the way.
Thanks, and I've put v1.0 and v1.1 up here. There were I think 3 or 4 versions before that, but I don't have a record of them. In any case, v1.0 was (as you might guess from the name) the first version I felt was 'complete', and I don't know that it was merged into anything else prior to that.
 
If you just want to update Better AI, 1.1 is all you need since that should be the version jdog used.
Thanks, and I've put v1.0 and v1.1 up here. There were I think 3 or 4 versions before that, but I don't have a record of them. In any case, v1.0 was (as you might guess from the name) the first version I felt was 'complete', and I don't know that it was merged into anything else prior to that.

Thanks to you both!
 
Just a heads up, there's a bug in how siege units are handled in Lead from Behind. To test out the bug, place a large number of siege units outside an enemy city which has some defenders plus at least one non-defender units (ships, aircraft, workers, GP, etc). Attack with the siege until all defenders are down below the siege combat limit. Then, try attacking with another siege unit, you shouldn't be able to and if there isn't a ship or worker in there then you can't. But if there's one of these non-land combat units, then you can and your siege gets free experience.

More importantly, the fix ... in CvUnit::canMoveInto, change the Lead from Behind code to:

Code:
	// From Lead From Behind by UncutDragon
	// original
	//CvUnit* pDefender = pPlot->getBestDefender(NO_PLAYER, getOwnerINLINE(), this, true);
	//if (NULL != pDefender)
	//{
	//	if (!canAttack(*pDefender))
	//	{
	//		return false;
	//	}
	//}
	// modified
	if( combatLimit() < 100 )
	{
		CvUnit* pDefender = pPlot->getBestDefender(NO_PLAYER, getOwnerINLINE(), this, true);
		if (NULL != pDefender)
		{
			if (!canAttack(*pDefender))
			{
				return false;
			}
		}
	}
	else if (!pPlot->hasDefender(true, NO_PLAYER, getOwnerINLINE(), this, true))
	{
		return false;
	}

Basically, there is a valid "defender" on the plot as the siege unit is allowed to kill a non-combat or sea unit. But since there are (badly damaged) land defenders the siege unit can't actually attack the worker/boat/etc. This fixes that case.
 
The original code should be simply restored.

Code:
else if (!pPlot->hasDefender(true, NO_PLAYER, getOwnerINLINE(), this, true))
				{
					return false;
				}

is not the same as

Code:
//CvUnit* pDefender = pPlot->getBestDefender(NO_PLAYER, getOwnerINLINE(), this, true);
				//if (NULL != pDefender)
				//{
				//	if (!canAttack(*pDefender))
				//	{
				//		return false;
				//	}
				//}

as it leaves out the "if (!canAttack(*pDefender))" check, changing the effect of code from preventing units that can't attack from attacking defended cities, to preventing attacking units from moving into empty cities.
 
Is there anything wrong with just restoring the original code? I'm not sure why it was changed in the first place. Was it just for efficiency or is there a problem with how getBestDefender works?

For example, maybe the strongest defender happens to be a valuable unit (lead by a warlord or something), and although this strong defender should be attackable by the siege unit, getBestDefender actually returns a weaker unit which is not attackable by the siege unit...

I don't know if what I've described can actually happen or not. I'm just speculating as to why the code was changed in the first place. But if I'm right, then jdog's fix just trades the problem that he described for the problem that I described. To fix both problems (assuming that the problem I described actually exists), the original code for this section should be restored and getBestDefender should make sure units that are allowed to be attacked are always better defenders than units that are not.
 
I don't even know for sure what exactly you've seen but maybe this helps ..
If there is a unit with enough health left, an attacker with combat limit will always be able to attack it, ignoring any other defender ranking code.
Code:
[COLOR="Gray"]// Modified version of best defender code (minus the initial boolean tests,
// which we still check in the original method)
bool CvUnit::LFBisBetterDefenderThan(const CvUnit* pDefender, const CvUnit* pAttacker, int* pBestDefenderRank) const
{[/COLOR]
    [COLOR="Green"]//Fuyu: combat limits![/COLOR]
    if ((maxHitPoints() > pAttacker->combatLimit()))
    {
        if (getDamage() >= pAttacker->combatLimit() && pDefender->getDamage() < pAttacker->combatLimit())
            return false;
        else if (pDefender->getDamage() >= pAttacker->combatLimit() && getDamage() < pAttacker->combatLimit())
            return true;
    }

    [COLOR="Gray"]// We adjust ranking based on ratio of our adjusted strength compared to twice that of attacker
    // Effect is if we're over twice as strong as attacker, we increase our ranking
    // (more likely to be picked as defender) - otherwise, we reduce our ranking (less likely)[/COLOR]
 
Thank you for having shared your work, i have included it in the next version of the Total War mod.
 
Top Bottom