Sample SDK Code (basic)

Kael

Deity
Joined
May 6, 2002
Messages
17,401
Location
Ohio
This thread is to post simple working SDK changes to help begining programmers get an idea of how they can use the SDK without having to get into deep in depth programming.

Please don't use this thread to ask questions on things that aren't working or post non-working code. Start new threads in the creation and customization forum for that.

1. So that the promotion prereq’s are AND reqs instead of OR reqs

CvUnit.cpp CvUnit::canAcquirePromotion:

Original:

Code:
	if (GC.getPromotionInfo(ePromotion).getPrereqOrPromotion1() != NO_PROMOTION)
	{
		if (!isHasPromotion((PromotionTypes)(GC.getPromotionInfo(ePromotion).getPrereqOrPromotion1())))
		{
			if ((GC.getPromotionInfo(ePromotion).getPrereqOrPromotion2() == NO_PROMOTION) || !isHasPromotion((PromotionTypes)(GC.getPromotionInfo(ePromotion).getPrereqOrPromotion2())))
			{
				return false;
			}
		}
	}

Changed to:

Code:
	if (GC.getPromotionInfo(ePromotion).getPrereqOrPromotion1() != NO_PROMOTION)
	{
		if (!isHasPromotion((PromotionTypes)(GC.getPromotionInfo(ePromotion).getPrereqOrPromotion1())))
		{
		    return false;
		}
	}

	if (GC.getPromotionInfo(ePromotion).getPrereqOrPromotion2() != NO_PROMOTION)
	{
		if (!isHasPromotion((PromotionTypes)(GC.getPromotionInfo(ePromotion).getPrereqOrPromotion2())))
		{
		    return false;
		}
	}


2. So that player owned animals act like normal units

CvUnit.cpp CvUnit::canMoveInto():

Origional:

Code:
	if (isAnimal())
	{
		if (pPlot->isOwned())
		{
			return false;
		}

Changed to:

Code:
	if (isAnimal() && isBarbarian())
	{
		if (pPlot->isOwned())
		{
			return false;
		}


3. So that animals don’t disappear when barbarians appear

CvGame.cpp CvGame::createBarbarianUnits():

Commented out the following lines:

Code:
//	CvUnit* pLoopUnit;

//		for (pLoopUnit = GET_PLAYER(BARBARIAN_PLAYER).firstUnit(&iLoop); pLoopUnit != NULL; pLoopUnit = GET_PLAYER(BARBARIAN_PLAYER).nextUnit(&iLoop))
//		{
//			if (pLoopUnit->isAnimal())
//			{
//				pLoopUnit->kill(false);
//				break;
//			}
//		}

4. So that civs with the Scorched Earth trait auto-raze cities

CvPlayer.cpp CvPlayer::acquireCity()

Original:

Code:
	if (bConquest)
	{
		if (((pOldCity->getHighestPopulation() == 1) && !(GC.getGameINLINE().isOption(GAMEOPTION_NO_CITY_RAZING))) ||
			  ((GC.getGameINLINE().getMaxCityElimination() > 0) && !(GC.getGameINLINE().isOption(GAMEOPTION_NO_CITY_RAZING))) ||
			  (GC.getGameINLINE().isOption(GAMEOPTION_ONE_CITY_CHALLENGE) && isHuman()))
		{

Changed to:

Code:
	if (bConquest)
	{
		if (((pOldCity->getHighestPopulation() == 1) && !(GC.getGameINLINE().isOption(GAMEOPTION_NO_CITY_RAZING))) ||
			  ((GC.getGameINLINE().getMaxCityElimination() > 0) && !(GC.getGameINLINE().isOption(GAMEOPTION_NO_CITY_RAZING))) ||
			  (GC.getGameINLINE().isOption(GAMEOPTION_ONE_CITY_CHALLENGE) && isHuman()) ||
			  (hasTrait((TraitTypes)GC.getInfoTypeForString("TRAIT_SCORCHED_EARTH"))))
		{


5. So that civs with the Agnostic trait can’t adopt a state religion

CvPlayer.cpp CvPlayer::canConvert()

Added:

Code:
	if (hasTrait((TraitTypes)GC.getInfoTypeForString("TRAIT_AGNOSTIC")))
	{
	    return false;
	}
 
hun... what language SDK use??? (I not downloading yet..) this codes remember Java...
 
HP_Ganesha said:
hun... what language SDK use??? (I not downloading yet..) this codes remember Java...

It uses C++
 
Thanks! I'm trying a compile right now. Is there any documentation or references for this stuff? I know most of the variables are fairly easy to follow but it would be nice to have a reference doc describing what is done in each file. Otherwise I guess it'll be a lot of trial and error.
Now if there was an EASY way (and free!) to change the graphics and animations...
 
Thorn said:
Thanks! I'm trying a compile right now. Is there any documentation or references for this stuff? I know most of the variables are fairly easy to follow but it would be nice to have a reference doc describing what is done in each file. Otherwise I guess it'll be a lot of trial and error.

Yeah, I would love to see someone as detailed as Locotus go through an detail the files and the functions with their purposes.

Now if there was an EASY way (and free!) to change the graphics and animations...

No doubt.
 
My dlls are generally around 4800 kb.
 
@Thorn/talchas, are you using codeblocks, or VS2003? I'm using VS2003 and my dll is compiling to 3752Kb. That's slightly larger than standard, but my dll's got lots of extra stuff in it ;). If I turn off VS2003's linker optimization it comes out at 4956Kb.
 
I'm using codeblocks. My compiler switches that could make a difference seem to be /O2 /GR /EHsc and for the linker switches, /debug /INCREMENTAL:NO

The compiler is just the 2003 compiler, so the difference should only be due to different switches.
 
I should start by saying that I am NO programmer, just someone who fiddles around the edges-as it were-so forgive my ignorance. Kael, you said the Code is written in C++ (and I do believe you), but then why does it read so much like Python?

Dumb question, but one I need to ask!

Aussie_Lurker.
 
Aussie_Lurker said:
I should start by saying that I am NO programmer, just someone who fiddles around the edges-as it were-so forgive my ignorance. Kael, you said the Code is written in C++ (and I do believe you), but then why does it read so much like Python?

Dumb question, but one I need to ask!

Aussie_Lurker.


Modern programming languages often Copy syntax from C/C++. *I think* that C or C++ was the first object-oriented language aswell, which another reason its copied. The first being its probably one of the most popular programming languages.
 
It's not really the syntax, it's more the way Boost Python has been used to expose the underlying C++ functions.

For example, there is a C++ method declared in CvPlayer.h:

Code:
DllExport bool isHuman();	// Exposed to Python

This is 'wrapped ' in CyPlayer, the Python wrapper class for CvPlayer:

Code:
bool CyPlayer::isHuman()
{
	return m_pPlayer ? m_pPlayer->isHuman() : false;
}

(IIRC, this 'wrapping' is an error protection technique.) Next, this method is exposed to Python in CyPlayerInterface1.cpp:

Code:
 void CyPlayerPythonInterface1(python::class_<CyPlayer>& x)
{
...
	.def("isHuman", &CyPlayer::isHuman, "bool ()")

Now when you call "isHuman" in a Python script it goes through this &CyPlayer::isHuman to ultimately call CvPlayer::isHuman().

That's how so much of the stuff that you see in Python is actually defined in CvGameCoreDLL.
 
Grey Fox said:
Modern programming languages often Copy syntax from C/C++. *I think* that C or C++ was the first object-oriented language aswell, which another reason its copied. The first being its probably one of the most popular programming languages.
No. C is not object oriented at all (well, you have structs, so you can program OO if you like to), but it is immensely popular.
C++ is not the first OO language either (that'd be Smalltalk) but it is(was) totally compatible with C, thus became very popular. ObjectiveC was a C dialect that was OO too but it didn't get as popular as C++. Looking at C code, C++ and Obejctive C, C++ looks like C the most, thus I think it won because of its greater familiarity and compatibility with C.
Apart from that, indeed, the functions are mostly the same between C++ and python apis, thus they look somewhat similar. But count the lines to do the same stuff in C++ and in python, and you will see the difference...
 
LDiCesare said:
No. C is not object oriented at all (well, you have structs, so you can program OO if you like to), but it is immensely popular.
C++ is not the first OO language either (that'd be Smalltalk) but it is(was) totally compatible with C, thus became very popular. ObjectiveC was a C dialect that was OO too but it didn't get as popular as C++. Looking at C code, C++ and Obejctive C, C++ looks like C the most, thus I think it won because of its greater familiarity and compatibility with C.
Apart from that, indeed, the functions are mostly the same between C++ and python apis, thus they look somewhat similar. But count the lines to do the same stuff in C++ and in python, and you will see the difference...

Kinda knew C wasnt OO. And thanks for correcting my *I think* part. Wasnt sure about that. :goodjob:
 
Just a simple example of a change that can be made in CvUnit::maxCombatStr(). This applies a combat modifier based on the existence of the "Elf" promotion on the defender and the "Elf Slaying" promotion on the attacker. maxCombatStr is called from the perspective of the defender and I have the 2 checks in so that the bonus is applied on attack and defense.

Changes are in bold.

CvUnit::maxCombatStr()

Code:
		if (getUnitCombatType() != NO_UNITCOMBAT)
		{
			iModifier -= pAttacker->unitCombatModifier(getUnitCombatType());
			if (pCombatDetails != NULL)
			{
				pCombatDetails->iCombatModifierT = -(pAttacker->unitCombatModifier(getUnitCombatType()));
			}
		}

[b]		if (isHasPromotion((PromotionTypes)GC.getInfoTypeForString("PROMOTION_ELF")))
		{
		    if (pAttacker->isHasPromotion((PromotionTypes)GC.getInfoTypeForString("PROMOTION_ELF_SLAYING")))
		    {
		        iModifier = iModifier - 40;
		    }
		}
		if (isHasPromotion((PromotionTypes)GC.getInfoTypeForString("PROMOTION_ELF_SLAYING")))
		{
		    if (pAttacker->isHasPromotion((PromotionTypes)GC.getInfoTypeForString("PROMOTION_ELF")))
		    {
		        iModifier = iModifier + 40;
		    }
		}[/b]

		iModifier += domainModifier(pAttacker->getDomainType());
		if (pCombatDetails != NULL)
		{
			pCombatDetails->iDomainModifierA = domainModifier(pAttacker->getDomainType());
		}

Why use this? It provides the ability to specify anti-unit combat bonuses without having to make new unit combats or declare specific unitclasses. Also since its easy to add and remove promotions as you play it can allow you to create pretty dynamic bonuses.

Outside of that just being familiar with the effect of changing maxCombatStr can be very helpful to anyone who wants to effect the combat odds. Changes made here are reflect both in the actual combat odds as well as the display.
 
Top Bottom