Help with some code modifying in cvunit.cpp

Lib.Spi't

Overlord of the Wasteland
Joined
Feb 12, 2009
Messages
3,708
Location
UK
Hi guys, so I have managed to sort of break something that one of my play testers kindly pointed out, and I need some help in fixing the code to make it do what it is supposed and also to not explode in everyones face!

This is the code:
Spoiler :

Code:
// Dale - SA: Opp Fire START
void CvUnit::doOpportunityFire()
{
	int iI, iUnitDamage;
	int iOurStrength;
	int iTheirStrength;
	CvPlot* pPlot;
	CvPlot* pLoopPlot;
	CvPlot* pAttackPlot = NULL;
	CvUnit* pDefender = NULL;
	CvWString szBuffer;
	if (!GC.isDCM_OPP_FIRE())
	{
		return;
	}

	if (getFortifyTurns() > 0)
	{
		for (iI = 0; iI < NUM_DIRECTION_TYPES; iI++)
		{
			pLoopPlot = plotDirection(plot()->getX_INLINE(), plot()->getY_INLINE(), ((DirectionTypes)iI));
			if (pLoopPlot != NULL)
			{
				if (pLoopPlot->getNumUnits() > 0)
				{
					pDefender = pLoopPlot->getBestDefender(NO_PLAYER, getOwnerINLINE(), this, true);
					if (pDefender != NULL)
					{
						pPlot = pDefender->plot();

						iOurStrength = airCurrCombatStr(pDefender);
						FAssertMsg(iOurStrength > 0, "Combat strength is expected to be greater than zero");
						iTheirStrength = pDefender->maxCombatStr(pPlot, this);
						iUnitDamage = std::max(1, ((GC.getDefineINT("RANGE_COMBAT_DAMAGE")) * (iOurStrength) / (iTheirStrength)));
						pDefender->changeDamage(iUnitDamage, getOwner());
						szBuffer = gDLL->getText("TXT_KEY_MISC_YOU_OPP_FIRE", getNameKey(), pDefender->getNameKey());
						gDLL->getInterfaceIFace()->addMessage(getOwnerINLINE(), true, GC.getEVENT_MESSAGE_TIME(), szBuffer, "AS2D_OUR_WITHDRAWL", MESSAGE_TYPE_INFO, getButton(), (ColorTypes)GC.getInfoTypeForString("COLOR_GREEN"), plot()->getX_INLINE(), plot()->getY_INLINE(), true, true);
						szBuffer = gDLL->getText("TXT_KEY_MISC_ENEMY_OPP_FIRE", getNameKey(), pDefender->getNameKey());
						gDLL->getInterfaceIFace()->addMessage(pDefender->getOwnerINLINE(), true, GC.getEVENT_MESSAGE_TIME(), szBuffer, "AS2D_THEIR_WITHDRAWL", MESSAGE_TYPE_INFO, getButton(), (ColorTypes)GC.getInfoTypeForString("COLOR_RED"), plot()->getX_INLINE(), plot()->getY_INLINE(), true, true);
						if (pLoopPlot->isActiveVisible(false))
						{
							// Bombard entity mission
							CvMissionDefinition kDefiniton;
							kDefiniton.setMissionTime(GC.getMissionInfo(MISSION_BOMBARD).getTime() * gDLL->getSecsPerTurn());
							kDefiniton.setMissionType(MISSION_BOMBARD);
							kDefiniton.setPlot(pLoopPlot);
							kDefiniton.setUnit(BATTLE_UNIT_ATTACKER, this);
							kDefiniton.setUnit(BATTLE_UNIT_DEFENDER, pDefender);
							gDLL->getEntityIFace()->AddMission(&kDefiniton);
						}
					}
				}
			}
		}
	}
}
// Dale - SA: Opp Fire END

This is what is going wrong.

First of all the code is running even if a units RANGE_COMBAT_DAMAGE is 0, so I need a bit of code that will say if RANGE_COMBAT_DAMAGE = 0 then skip OR something like if RANGE_COMBAT_DAMAGE is greater than 0 run the code.

Second issue is that the iTheirStrength seems to be referencing the defender iaircombat value rather than their icombat value. which is not what I want, so i need to figure out why it is looking up that value and not the icombat value for the defender.

I THINK those are the only issues...

As always help is much appreciated and please be gentle with my poor useless brain :)

Any other info or any files that would be of help, just ask and I shall do my best to supply you with whatever is needed :)
 
Looks like you're using the code a bit differently than it was written.

First off, this code is looking for a fixed number for RANGE_COMBAT_DAMAGE. Did you add a tag to UnitInfos to specify this by unit instead?

iOurStrength is the one looking at the air combat value. Just change it to maxCombatStr instead.
 
Looks like you're using the code a bit differently than it was written.

First off, this code is looking for a fixed number for RANGE_COMBAT_DAMAGE. Did you add a tag to UnitInfos to specify this by unit instead?

iOurStrength is the one looking at the air combat value. Just change it to maxCombatStr instead.

IF memory serve me correct, we actually modified the RCD to include the iaircombat value...

The iourstrength is right to look up the iaircombat, as I want the attacker to use his (ranged strength)

Someone commented that the defender seemed to be using their iaircombat value instead of their icombat value to defend themselves, maybe they read the code wrong..

It may be that I need to have a different code entirely, we basically hacked away at this code till we got it working with our range system, which uses iaircombat instead of the realism invictus system.

basically what I need the code to do is to check if a unit has an iaircombat or iairrange greater than 0.

if this is true then it attacks the enemy.

iaircombat(oppfire) vs icombat (enemy)
 
This is the only other bit of code I could find that contained RANGE_COMBAT_DAMAGE

It has been so long since we messed with this code I can't remember much about it...


Spoiler :
Code:
int CvUnit::rangeCombatDamage(const CvUnit* pDefender) const
{
	CvPlot* pPlot;
	int iOurStrength;
	int iTheirStrength;
	int iStrengthFactor;
	int iDamage;

	pPlot = pDefender->plot();

	iOurStrength = airCurrCombatStr(pDefender);
	FAssertMsg(iOurStrength > 0, "Combat strength is expected to be greater than zero");
	iTheirStrength = pDefender->maxCombatStr(pPlot, this);

	iStrengthFactor = ((iOurStrength + iTheirStrength + 1) / 2);

	iDamage = std::max(1, ((GC.getDefineINT("RANGE_COMBAT_DAMAGE")) * (iOurStrength) / (iTheirStrength)));

	return iDamage;
}
 
OK. So you need to call the rangeCombatDamage() function. You can see that the code there is similar to the damage code within the doOpportunityFire() function.

Try replacing this section in doOpportunityFire()...
Code:
pPlot = pDefender->plot();

iOurStrength = airCurrCombatStr(pDefender);
FAssertMsg(iOurStrength > 0, "Combat strength is expected to be greater than zero");
iTheirStrength = pDefender->maxCombatStr(pPlot, this);
iUnitDamage = std::max(1, ((GC.getDefineINT("RANGE_COMBAT_DAMAGE")) * (iOurStrength) / (iTheirStrength)));

with this...

Code:
iUnitDamage = rangeCombatDamage(pDefender);

And then you can check..
Code:
if (iUnitDamage == 0)
{
     return;
}
 
Top Bottom