Help with ranged bombard promotions

NotSoGood

Emperor
Joined
Jan 25, 2009
Messages
1,077
Location
Finland
Now I'm trying to add tags to promotions that could change the ranged bombard(range +1, more accuracy). I have followed xienwolf's great tutorial and managed to add proper texts to promotions' civilopedia with DLL, but now I'm out of ideas how would I display it on unit. Right now it looks like this in CvGameTextMgr.cpp void CvGameTextMgr::setUnitHelp(CvWStringBuffer &szString, const CvUnit* pUnit, bool bOneLine, bool bShort)
Code:
...
		// Dale - RB: Field Bombard START
		if (GC.getDCM_RANGE_BOMBARD())
		{
			if (pUnit->getDCMBombRange() > 0 || pUnit->getDCMBombAccuracy() > 0)
			{
				szString.append(NEWLINE);
				szString.append(gDLL->getText("TXT_KEY_IS_DCM_BOMBARD"));
			}
			[COLOR="Red"]if (pUnit->getDCMBombRange() > 0)
			{
				szString.append(NEWLINE);
				szString.append(gDLL->getText("TXT_KEY_IS_RANGE_BOMBARD", pUnit->getDCMBombRange()));
			}[/COLOR]			
			if (pUnit->getDCMBombAccuracy() > 0)
			{
				szString.append(NEWLINE);
				szString.append(gDLL->getText("TXT_KEY_IS_ACCURACY_BOMBARD", pUnit->getDCMBombAccuracy()));
			}
		}		
		if (pUnit->bombardRate() > 0)
		{
			if (bShort)
			{
				szString.append(NEWLINE);
				szString.append(gDLL->getText("TXT_KEY_UNIT_BOMBARD_RATE_SHORT", ((pUnit->bombardRate() * 100) / GC.getMAX_CITY_DEFENSE_DAMAGE())));
			}
			else
			{
				szString.append(NEWLINE);
				szString.append(gDLL->getText("TXT_KEY_UNIT_BOMBARD_RATE", ((pUnit->bombardRate() * 100) / GC.getMAX_CITY_DEFENSE_DAMAGE())));
			}
		}
		// Dale - RB: Field Bombard END
...
The red part adds the range text if the unit has range defined. I don't think it would work if I add my code here. It would just display it right. So after that, I went looking for the pUnit->getDCMBombRange()
Code:
int CvUnit::getDCMBombRange() const
{
	return GC.getUnitInfo(getUnitType()).getDCMBombRange();
}
I thought that this would be the right place to add check if the unit has promotion that changes the range. I'm not totally sure about it or how to check the promotion and what the promotion does.
So if anyone could tell me was I right about how it works and teach me how to check the promotion?
 
Have a look at how other values are stored in the CvUnit class.

What you'd want to change it to is something along these lines...

In the CvUnit class definition:

Code:
private:
    int m_iDCMBombRange;

Your new accessors:

Code:
int CvUnit::getDCMBombRange() const
{
    return m_iDCMBombRange;
}

void CvUnit::setDCMBombRange(int iNewValue)
{
    m_iDCMBombRange = iNewValue;   
}

void CvUnit::changeDCMBombRange(int iChange)
{
    setDCMBombRange(getDCMBombRange() + iChange);
}

In the init() method:

Code:
setDCMBombRange(GC.getUnitInfo(getUnitType()).getDCMBombRange());

Finally, in setHasPromotion():

Code:
changeDCMBombRange(GC.getPromotionInfo(eIndex).getDCMBombRangeChange() * iChange);
 
I tried to do it the way you said (notice word tried) and after few tries I didn't get error messages anymore but the promotion had no effect either. I added the two functions to CvUnit.cpp and CvUnit.h and added the line to setHasPromotion(), but didn't know about the others. I think the first thing is already defined and had no idea where the third should go. Could you explain me little bit more precisely what you meant, I'm still a noob in DLL coding?

EDIT: I think I know now what you you meant, the only thing that's not clear yet is what that "init() method" is?
 
I'm not familiar with programing the SDK, so I can't help you but I would be really interested if you get this working. I have been looking for something like this for quite a while. Have you found a way to give bombard units experience when they successfully bombard a unit? I managed to do so for aircraft using just Python, but I can't find a way to do it for bombard units because doCombat doesn't get called for DCM bombard missions.
 
Ok, I'll se what I can do. It should be easy with SDK.

EDIT: Do you want it to get xp from city or unit bombarding or both?

EDIT2: Ok, I got the experience from bombarding work. Nothing big, added only one line.
 
Both would be nice, but unit bombardment is the important one. Is the dll file that you are creating compatable with version 3.19 and include all of the other DCM stuff? If so that would be awesome.
 
Both would be nice, but unit bombardment is the important one. Is the dll file that you are creating compatable with version 3.19 and include all of the other DCM stuff? If so that would be awesome.

It gives you experience from both now, but it's easy to change. Actually all these changes I have made are for my own mod. It does work with 3.19, but includes only the ranged bombard from DCM.
But does anyone know why the code doesn't give you extra range?
 
Ok, lets list here all I have done to the promotions in the DLL.

1. CvInfos.h, added
Code:
int getDCMBombRangeChange() const;
and
Code:
int m_iDCMBombRangeChange;

2. CvInfos.cpp, added
Code:
m_iDCMBombRangeChange(0),
and
Code:
int CvPromotionInfo::getDCMBombRangeChange() const
{
	return m_iDCMBombRangeChange;
}
and
Code:
stream->Read(&m_iDCMBombRangeChange);
and
Code:
stream->Write(m_iDCMBombRangeChange);
and
Code:
pXML->GetChildXmlValByName(&m_iDCMBombRangeChange, "iDCMBombRangeChange");

3. CvUnit.h, added
Code:
	void setDCMBombRange(int iNewValue);
	void changeDCMBombRange(int iChange);

4. CvUnit.cpp, added
Code:
		changeDCMBombRange((GC.getPromotionInfo(eIndex).getDCMBombRangeChange()) * iChange);
and
Code:
void CvUnit::setDCMBombRange(int iNewValue)
{
    m_iDCMBombRange = iNewValue;   
}

void CvUnit::changeDCMBombRange(int iChange)
{
    setDCMBombRange(getDCMBombRange() + iChange);
}

5. CvGameTextMgr.cpp, added
Code:
	if (GC.getPromotionInfo(ePromotion).getDCMBombRangeChange() != 0)
	{
		szBuffer.append(pcNewline);
		szBuffer.append(gDLL->getText("TXT_KEY_PROMOTION_DCMBOMBRANGECHANGE_TEXT", GC.getPromotionInfo(ePromotion).getDCMBombRangeChange()));
	}

I'm sure I must have missed something, but I just can't get what. Could someone help me?
 
EDIT: I think I know now what you you meant, the only thing that's not clear yet is what that "init() method" is?
CvUnit::init() is a method near the start of CvUnit.cpp. It sets all the default values for a CvUnit object when a new unit is created. In your case, you want to initialise m_iDCMBombRange to the value from the XML for whatever unit type it is.

You need to set the bombard range variable there or else it will be set to some random value (basically whatever that block of memory held before it become part of a CvUnit object). Trying to read a variable before it's been initialised is a big source of bugs in C and C++ precisely because of this behaviour.
 
Yay! :woohoo: It works! Thank you very much of your help. :bowdown::bowdown:
Next I'll try to add the accuracy tag...

EDIT: Got the another promotion work properly too. Thanks for help. I wouldn't have gotten it work without you.
 
This is getting weird, my mod crashes when I try to run it first time after opening my computer. The weird thing is that it works perfectly when I try to run it again after the crash. And if some of the promotions has the tags I have added, the mod won't crash. Not on first or second time. The xml log stops to promotions file when the mod crashes. :eek: :confused: :confused: :crazyeye: Any idea why it does so?
 
The fact that it only crashes the first time may have something to do with file caching. Do you have file caching enabled? If so you could try disabling it and seeing what happens. It won't solve your problem, but it might explain why it's only happening the first time. If you are not familiar with turning file caching on or off, it is controlled in CivilizationIV.ini (use the Civ4Config.ini shortcut in your game folder). There are two seperate lines for caching I usually turn them both off or on when changing things just to be on the safe side.
 
NotSoGood,

Could you please explain what you did in CvUnit.cpp for the accuracy promotion?
 
Okay, but remember that it won't work with just changes to CvUnit.cpp, you need to make changes to other places aswell.

CvUnit::init
Code:
	setDCMBombAccuracy(GC.getUnitInfo(getUnitType()).getDCMBombAccuracy());

CvUnit::setHasPromotion
Code:
		changeDCMBombAccuracy((GC.getPromotionInfo(eIndex).getDCMBombAccuracyChange()) * iChange);

Code:
/**Original code start
int CvUnit::getDCMBombAccuracy() const
{
	return GC.getUnitInfo(getUnitType()).getDCMBombAccuracy();
}
/**Original code end**/
int CvUnit::getDCMBombAccuracy() const
{
	return m_iDCMBombAccuracy;
}

void CvUnit::setDCMBombAccuracy(int iNewValue)
{
    m_iDCMBombAccuracy = iNewValue;   
}

void CvUnit::changeDCMBombAccuracy(int iChange)
{
    setDCMBombAccuracy(getDCMBombAccuracy() + iChange);
}
 
Thank you, and yes, I understand about what else needs to be modified. I've never created a new promotion before, and what confused me was how to change getDCMBombAccuracy to actually include the effect of the promotion.
 
Well, the dll compiles fine. No errors on starting the mod. I can also give the promotion to units, as planned. But I get consistent crashes for some reason. I am building a debug dll to see if that helps me anything.
 
Got everything working now! :) Thanks for helping out.
 
This is getting weird, my mod crashes when I try to run it first time after opening my computer. The weird thing is that it works perfectly when I try to run it again after the crash. And if some of the promotions has the tags I have added, the mod won't crash. Not on first or second time. The xml log stops to promotions file when the mod crashes. :eek: :confused: :confused: :crazyeye: Any idea why it does so?

Did you find a fix for this? I get weird behaviour on my 64 bit Windows 7, with nearly all games crashing within 25 turns. I am able to play on an XP machine without issues. I have a debug dll, that works, but I'm not getting any meaningful information from those crashes yet. Mostly Access Violations. :confused:
 
Did you find a fix for this? I get weird behaviour on my 64 bit Windows 7, with nearly all games crashing within 25 turns. I am able to play on an XP machine without issues. I have a debug dll, that works, but I'm not getting any meaningful information from those crashes yet. Mostly Access Violations. :confused:
So are you having those issues because of these promotions? I think I fixed that crash because the mod, where I added this, has been working for hundreds of turns when playing. And I haven't heard General Tso, whose also using this, to say anything like that. Unfortunately I can't remember anymore how did I fix it. :sad:
 
Top Bottom