Doubling Unit Upgrade Price for UnitCombat Change

phungus420

Deity
Joined
Mar 1, 2003
Messages
6,296
I'm trying to get the cost of unit upgrades to double if the UnitCombatType changes. I know unitupgrade price is accessislbe through python, but I think it would be just as much work to set this function up (in fact, I think it would be harder), and I'd rather just have this in the SDK. Here is the code I've found that I think is relevant:

Spoiler :
Code:
int CvUnit::upgradePrice(UnitTypes eUnit) const
{
	int iPrice;

	CyArgsList argsList;
	argsList.add(getOwnerINLINE());
	argsList.add(getID());
	argsList.add((int) eUnit);
	long lResult=0;
	gDLL->getPythonIFace()->callFunction(PYGameModule, "getUpgradePriceOverride", argsList.makeFunctionArgs(), &lResult);
	if (lResult >= 0)
	{
		return lResult;
	}

	if (isBarbarian())
	{
		return 0;
	}

	iPrice = GC.getDefineINT("BASE_UNIT_UPGRADE_COST");

	iPrice += (std::max(0, (GET_PLAYER(getOwnerINLINE()).getProductionNeeded(eUnit) - GET_PLAYER(getOwnerINLINE()).getProductionNeeded(getUnitType()))) * GC.getDefineINT("UNIT_UPGRADE_COST_PER_PRODUCTION"));

	if (!isHuman() && !isBarbarian())
	{
		iPrice *= GC.getHandicapInfo(GC.getGameINLINE().getHandicapType()).getAIUnitUpgradePercent();
		iPrice /= 100;

		iPrice *= std::max(0, ((GC.getHandicapInfo(GC.getGameINLINE().getHandicapType()).getAIPerEraModifier() * GET_PLAYER(getOwnerINLINE()).getCurrentEra()) + 100));
		iPrice /= 100;
	}

	iPrice -= (iPrice * getUpgradeDiscount()) / 100;

[B]	//phungus -UnitCombatType UpgradePrice doubles
	if ( GC.getUnitInfo(eUnit).getUnitCombatType() != GC.getUnitInfo(getUnitType()).getUnitCombatType() )
	{
		iPrice *= 2;
	}
	//phungus end[/B]
	
	return iPrice;
}

Bolded my changes. Now it compiles fine, but the unit upgrade price doesn't change. Any ideas?
:dunno:



Edit: Nevermind Python is overridding.
 
OK, so since Leonardo's was overriding this due to python, I decided it's time to move the Leonardo's Workshop code to the Dll. In the process of building a new gamecore with right now, just after I've added the code to CvInfos. This takes forever...

Anyway, once I make sure I've done all that right, I'm wondering what's the best way to go about this functionally. I've set up the tag iUnitUpgradePriceModifier, I'm thinking the best way to do this is to load the information from CvInfos to CvTeam. Is this correct? Any direction on this here (Xieno's tutorial only covers booleans so far), I think I can figure it out, but any places that those familiar with coding know I'm likely to get tripped up on, please let me know.

Assuming loading this into CvTeam works, I'm sure I'll have more questions about how to get this info into CvUnit to actually get the functional code working. Guess I'll cross that bridge when I get there.

Edit: I've looked at the few integer type Wonder values in the XML, and all these track back to CvPlayer, instead of CvTeam. Actually, that makes things alot easier for when I implement the code to change Unit Upgrade costs. I initially thought this would have to be done through CvTeam, since Wonder effects apply to the whole team, and not just the player. Question: How does the game know to apply these values to the team instead of the player, if they are set up in CvPlayer? I can't track back any references to CvTeam, or really anything that shows them applying to the team, granted I'm only using Notepad++'s search in files function, for any reference to the XML tag, and whatever it creates (ie, if iXMLeffect, gets used to set some function like getXMLeffect I search the getXMLeffect and see if that creates anything and then search for that). But still I can't see how the game is coded to apply these effects to the team, it looks like they should just be applied to the player.
 
OK, so after getting the price doubling to work, I'm now trying to move the Leonardo's workshop code from Tstentom1 over to the SDK.

First set up the tag as an integer for iUnitUpgradePriceModifier. That all works, at least no crash or anything, and seems pretty straightforward in terms of CvInfos. My problem I think at least is getting it to function. I tried sort of copying what similar functions did, and came up with this:

In CvPlayer.h
Code:
...
	//phungus Leonardos Workshop
	int getUnitUpgradePriceModifier() const;																																		// Exposed to Python
	void changeUnitUpgradePriceModifier(int iChange);
	//phungus end
...

	int m_iUnitUpgradePriceModifier;	//phungus Leonardos Workshop
From CvPlayer.cpp
Code:
...
	m_iUnitUpgradePriceModifier = 0;	//phungus Leonardos Workshop
...
	changeUnitUpgradePriceModifier(GC.getBuildingInfo(eBuilding).getUnitUpgradePriceModifier() * iChange); //phungus Leonardos Workshop
...
//phungus Leonardos Workshop
int CvPlayer::getUnitUpgradePriceModifier() const
{
	return m_iUnitUpgradePriceModifier;
}

void CvPlayer::changeUnitUpgradePriceModifier(int iChange)
{
	m_iUnitUpgradePriceModifier = (m_iUnitUpgradePriceModifier + iChange);
}
//phungus end
...
	pStream->Read(&m_iUnitUpgradePriceModifier);	//phungus Leonardos Workshop
...
	pStream->Write(m_iUnitUpgradePriceModifier);	//phungus Leonardos Workshop
And finally in CvUnit
Code:
	//phungus -Leonardos Workshop
	iPrice += ( GET_PLAYER(getOwnerINLINE()).getUnitUpgradePriceModifier() ) / 100;
	//phungus end

It compiles fine but doesn't read the value.
...
 
Is the second line in the second code block (the call to changeUnitUpgradePriceModifer) in processBuilding()? If not, where is that?

Also, your application of the effect is incorrect. You need to add 100 to the modifier and then multiply that by the price, finally dividing by 100:

Code:
iPrice = iPrice * (100 + GET_PLAYER(getOwnerINLINE()).getUnitUpgradePriceModifier()) / 100;
 
Wow, I'm an idiot. That was a very dumb math mistake. Thanks EF, using the correct math fixed it.

Also Xienwolf, good call on setting up GameTextManager first, will do that next time. I see now it's a good way to make sure you have loaded your XML into CvInfos properly before you start tweaking the functionality. Didn't matter here, but it might in the future, I'll keep that in mind.
 
Hm I'm wondering if we can do this by python without the use of sdk? Have to try it out. ;)
 
easy....

PHP:
## phungus UnitCombatType UpgradePrice doubles
		pPlayer = gc.getPlayer(iPlayer)
		pUnit = pPlayer.getUnit(iUnitID)
		if gc.getUnitInfo(iUnitTypeUpgrade).getUnitCombatType() != pUnit.getUnitCombatType():
			iPrice = (iPrice * 2)
## phungus end

works. :) why do you use sdk when you are using python override already?
 
Seeing as today is Calculate-and-Set Operator Appreciation Day in the U.S. you might want to change

Code:
iPrice = (iPrice * 2)

to the much cooler form

Code:
iPrice *= 2
 
thanks. next project will be extra cost for a iCombat difference (or aircombat) difference of minimum X. :)
 
Top Bottom