CvUnitAI::AI_rangeAttack

It can be overpowered, which is why I made it Random Damage. It could be changed to Random between -50 to 100%, given that below zero would be a miss. Or use something before pushing mission like Random(1-100) < airstrength + 50, if true it hits. That way the "quality" of the sieges is in the calculation aswell.
My initial thought was to add "wear and tear/limited ammo" to the sieges, so for every shot it would loose something like 5% of health. shouldnt be difficult to mod in.
Another idea I had was to make damage nonlinear, so the less health enemy unit have, the less damage it does, sort of "bowling effect" where when you have 10 pins its easy to hit with the ball, but when only 1 left its more difficult.

I like these ideas. I'll think of which one is best and not too difficult to code.

in one of the screenies above there is a target with a finger pointing on the center. I recall I made another one which actually showed a ranged hit and another with a white figure carrying a target on its back.

The one with the guy carrying the target on his back is funny but I don't think that I want to use one of these. I'll rather look for a "medieval castle walls hit by a projectile" for the bombard one. Thank you. :)
 
I found a small thing that needs to be changed imho, and I recall seeing it in the code:
When Bombard, instead of going for 0% it checks odds, and if they are good it stops to bombard. In my current game I have an enemy that have bombard-unit (pre cannon gunpowder siege) and the rest of the units is pregunpowder, so while the AI thinks odds are ok (checking with the gunpowder siege) the defense is actually 20% and therefore quite a boost against non-gunpowder units.
Will look at code when kids are in bed.

edit :
CvUnitAI::AI_bombardCity()
PHP:
		int iAttackOdds = getGroup()->AI_attackOdds(pBombardCity->plot(), /*bPotentialEnemy*/ true);
		if (iAttackOdds > 95)
		{
			return false;
		}
While it only really matters when Bombards are gunpowder and attackunits are pre-guns, I think its an improvement to comment it out. I know that I always bombard to 0%, and since the AI isnt taking THAT many cities, it might as well go for the best solution imho.
 
I want to have the rangestrike area border shown only after when rangestrike button is pressed, but having a bit of trouble syntax'ing it:
I think its something like this: (in CvGameInterface.cpp)
else if ((pHeadSelectedUnit->airRange() > 0) && (GC.getInterfaceModeInfo(InterfaceModeTypes) == INTERFACEMODE_RANGE_ATTACK))//other ranged units

which is obviously wrong. I tried a bunch of other stuff, but there isnt really any precedence, other than perhaps :
PHP:
			if (GC.getInterfaceModeInfo((InterfaceModeTypes)GC.getActionInfo(iAction).getInterfaceModeType()).getSelectAll())
			{
				gDLL->getInterfaceIFace()->selectGroup(pHeadSelectedUnit, false, false, true);
			}
 
added a Ranged Hit check:
If Random(100) > 50% + airstrength + enemy units on plot - enemy unit strength, then it misses : (iDamage becomes 0, and if IDamage is 0, no collateral damage is done either)
So basically the higher Airstrength a unit have, the better it hits. The more enemies on plot, the easier it is to hit something and the stronger the unit, the less chance of hitting it (or should it be movement points of the unit?)

PHP:
	iDamage = rangeCombatDamage(pDefender);
//Vincentz Rangehit check
	if ((GC.getGameINLINE().getSorenRandNum(100, "Random")) > 50 + airBaseCombatStr() + pPlot->getNumUnits() - pDefender->baseCombatStr())	
	{
		iDamage = 0;
		gDLL->getInterfaceIFace()->addMessage(getOwnerINLINE(), true, GC.getEVENT_MESSAGE_TIME(), CvWString::format(L"Ranged attack missed"), "AS2D_COMBAT", MESSAGE_TYPE_INFO, pDefender->getButton(), (ColorTypes)GC.getInfoTypeForString("COLOR_GREEN"), pPlot->getX_INLINE(), pPlot->getY_INLINE());
	}
//Vincentz Rangehit check end	
	iUnitDamage = std::max(pDefender->getDamage(), std::min((pDefender->getDamage() + iDamage), airCombatLimit()));

	szBuffer = gDLL->getText("TXT_KEY_MISC_YOU_ARE_ATTACKED_BY_AIR", pDefender->getNameKey(), getNameKey(), -(((iUnitDamage - pDefender->getDamage()) * 100) / pDefender->maxHitPoints()));
	//red icon over attacking unit
	gDLL->getInterfaceIFace()->addMessage(pDefender->getOwnerINLINE(), false, GC.getEVENT_MESSAGE_TIME(), szBuffer, "AS2D_COMBAT", MESSAGE_TYPE_INFO, getButton(), (ColorTypes)GC.getInfoTypeForString("COLOR_RED"), this->getX_INLINE(), this->getY_INLINE(), true, true);
	//white icon over defending unit
	gDLL->getInterfaceIFace()->addMessage(pDefender->getOwnerINLINE(), false, 0, L"", "AS2D_COMBAT", MESSAGE_TYPE_DISPLAY_ONLY, pDefender->getButton(), (ColorTypes)GC.getInfoTypeForString("COLOR_WHITE"), pDefender->getX_INLINE(), pDefender->getY_INLINE(), true, true);

	szBuffer = gDLL->getText("TXT_KEY_MISC_YOU_ATTACK_BY_AIR", getNameKey(), pDefender->getNameKey(), -(((iUnitDamage - pDefender->getDamage()) * 100) / pDefender->maxHitPoints()));
	gDLL->getInterfaceIFace()->addMessage(getOwnerINLINE(), true, GC.getEVENT_MESSAGE_TIME(), szBuffer, "AS2D_COMBAT", MESSAGE_TYPE_INFO, pDefender->getButton(), (ColorTypes)GC.getInfoTypeForString("COLOR_GREEN"), pPlot->getX_INLINE(), pPlot->getY_INLINE());

//Vincentz Rangehit check
	if (iDamage != 0)
		{
		collateralCombat(pPlot, pDefender);
		}
//Vincentz Rangehit check end	
		
	//set damage but don't update entity damage visibility
	pDefender->setDamage(iUnitDamage, getOwnerINLINE(), false);
 
I added an "Automatic Return Fire (ARF)" if the target (defender) can return rangestrike the original rangestriking unit (attacker).

A little in doubt about whether the defender should be able to do unlimited ARF, or just be able to do it once if it havent attacked anything in the last round. And atm its only if the attacker is rangestriking the defender. F.ex :
1 Frigate and 2 Galleons are being rangestriked by a Frigate. Because it is Frigate vs Frigate the defender will ARF.
1 Catapult rangestrike 3 Longbowmen and a catapult, but because the Catapult hits the longbowmen the defending catapult wont ARF. However if in the defending catapults turn it rangestrikes the lonely catapult, the later will ARF.

Adjustments can (afaik) be made in the unitInfo.xml with a tag already in, but not used in vanilla/WL/BtS :
example :first is for destroyers, so if a submarine is attacking the stack, the destroyers will defend first
second part is for submarines, so if it attacks a stack it will try to hit transportships first. These could be added to rangestrikers, so they are being attacked by other rangestrikers, they will defend their position (ARF)

I guess the first part is the importan one. F.ex. if catapults have it vs catapults the second example above would result in ARF from the catapult instead of damage on the longbowman.

Code:
			<UnitClassDefenders>
				<UnitClassDefender>
					<UnitClassDefenderType>UNITCLASS_SUBMARINE</UnitClassDefenderType>
					<bUnitClassDefender>1</bUnitClassDefender>
				</UnitClassDefender>
				<UnitClassDefender>
					<UnitClassDefenderType>UNITCLASS_ATTACK_SUBMARINE</UnitClassDefenderType>
					<bUnitClassDefender>1</bUnitClassDefender>
				</UnitClassDefender>
			</UnitClassDefenders>

Code:
			<UnitClassTargets>
				<UnitClassTarget>
					<UnitClassTargetType>UNITCLASS_TRANSPORT</UnitClassTargetType>
					<bUnitClassTarget>1</bUnitClassTarget>
				</UnitClassTarget>
				<UnitClassTarget>
					<UnitClassTargetType>UNITCLASS_GALLEON</UnitClassTargetType>
					<bUnitClassTarget>1</bUnitClassTarget>
				</UnitClassTarget>
				<UnitClassTarget>
					<UnitClassTargetType>UNITCLASS_PADDLE_STEAMER</UnitClassTargetType>
					<bUnitClassTarget>1</bUnitClassTarget>
				</UnitClassTarget>
				<UnitClassTarget>
					<UnitClassTargetType>UNITCLASS_COG</UnitClassTargetType>
					<bUnitClassTarget>1</bUnitClassTarget>
				</UnitClassTarget>
			</UnitClassTargets>
 
Removed the land sieges ability to direct combat : CvUnit::canMoveInto
Code:
// Vincentz Rangestrike
	if (bAttack)
	{
		if ((getDomainType() == DOMAIN_LAND) && (canRangeStrike()))
		{
			return false;
		}
	}

still need it to "combat focus" when "show enemy moves" is enabled and "quick combat" is disabled...
tried something around this :
gDLL->getInterfaceIFace()->lookAt(lookAtPoint, (((getOwnerINLINE() != GC.getGameINLINE().getActivePlayer()) || gDLL->getGraphicOption(GRAPHICOPTION_NO_COMBAT_ZOOM)) ? CAMERALOOKAT_BATTLE : CAMERALOOKAT_BATTLE_ZOOM_IN), attackDirection);
and tried to look at "normal" moves when CAMERALOOKAT was in code, but still no luck :(
 
Top Bottom