REQUEST: Modifying SDK

werewabbit

Chieftain
Joined
Oct 24, 2007
Messages
13
I would like a prod in the right direction with modifying the SDK to allow a player to "grant independance" to any city, regardless of culture, ethnicity, whatever. This means if it's on the same continent, you can do it, if it's your capital, you could do it, if you got an ethnicity of 100% whatever the hell you are- you can do it.

I've already tried asking in a seperate thread and I admit I'm impatient.
 
Do you mean liberate (give city to next highest foreign culture) or release as a colony?

You wouldn't be able to liberate the city under your model as you're allowing for any culture settings in any location. Thus a core city with 100% your culture cannot be liberated.

Can't see why you can't colonise it though. I think you'd just need to turn off the continent check in colonise.
 
Yay a post!

Well, in this case I mean specifically releasing as a colony. I think liberating I can leave as it is, I am inquiring however in this case to simply releasing a colony. I suppose you could think of it as "randomly" releasing a colony (though not random by any means you get to pick).

I basically want to turn off all the checks that would determine what's "eligable" for a colony and what isn't (meaning that I could potentially release any city I wanted into becoming a colony, regardless of culture, position, whatever), make it so I could build a colony anywhere (on any continent) and to make it so that when creating a colony it doesn't absorb every single city on the continent it was granted independence upon (because, well that'd ruin the game >_>).
 
Well, for the first part just find the section of code to check on release of a city (I don't have the code in front of me so can't tell you) and remove the checks regarding continents. That'll allow you to release core cities.

For part two it's a bit harder. You can make it simple by ONLY allowing one city releases, but if you want multiple city releases you'll have to setup routines to check cities in a radius from primary release target and assess if they too will join the released city based on your criteria. Just loop till desired number of cities.
 
Yeah I just want one city releases, I can do all the liberating manually if I want to.

Okay so I checked around the CvDLLButtonPopUp, CvCity and CvPlayer and I (lamentably) don't understand it all completely (my programming knowledge is minimal). If you got time, do you mind sifting through and pointing out where I gotta change stuff (and even what, would be even better)?

I understand if this is tedious and I appologize. I'm not really sure where it begins that check (if it's a bool I'm sure I could figure it out but >_>).

Thanks!
 
This is very quick & dirty but i can colonize single cities with it.


CvPlayer.cpp:

in canSplitEmpire()

Colonize-button shows up in Domestic advisor:

line 19095

Code:
    CivLeaderArray aLeaders;
	if (!getSplitEmpireLeaders(aLeaders))
	{
		return false;
	}
// Human can always split empire if they have more then 1 city
    if (isHuman() && (getNumCities () > 1))
        return true;


	bool bFoundArea = false;


splitEmpire() now don't get the area but the City id.



line 19226
Code:
            // human -> pArea = cityid
            // very quick & dirty
bool CvPlayer::splitEmpire(int iAreaId)
{
	PROFILE_FUNC();

    int iCity = iAreaId;;

    if (isHuman())
    {

        int iLoop;


        for (CvCity* pLoopCity = firstCity(&iLoop); pLoopCity != NULL; pLoopCity = nextCity(&iLoop))
            if (pLoopCity->getID() == iCity)
                iAreaId = pLoopCity->getArea();
    }

	if (!canSplitEmpire())
	{
		return false;
	}

	if (!canSplitArea(iAreaId)&&(!isHuman()))
	{
		return false;
	}

	CvArea* pArea = GC.getMapINLINE().getArea(iAreaId);
	if (NULL == pArea)
	{
		return false;
	}

	PlayerTypes eNewPlayer = getSplitEmpirePlayer(iAreaId);
	if (eNewPlayer == NO_PLAYER)
	{
		return false;
	}

	bool bPlayerExists = GET_PLAYER(eNewPlayer).isAlive();
	FAssert(!bPlayerExists);
	if (!bPlayerExists)
	{
		int iBestValue = -1;
		LeaderHeadTypes eBestLeader = NO_LEADER;
		CivilizationTypes eBestCiv = NO_CIVILIZATION;

		CivLeaderArray aLeaders;
		if (getSplitEmpireLeaders(aLeaders))
		{
			CivLeaderArray::iterator it;
			for (it = aLeaders.begin(); it != aLeaders.end(); ++it)
			{
				int iValue = (1 + GC.getGameINLINE().getSorenRandNum(100, "Choosing Split Personality"));

				if (GC.getCivilizationInfo(getCivilizationType()).getDerivativeCiv() == it->first)
				{
					iValue += 1000;
				}

				if (iValue > iBestValue)
				{
					iBestValue = iValue;
					eBestLeader = it->second;
					eBestCiv = it->first;
				}
			}
		}

		if (eBestLeader == NO_LEADER || eBestCiv == NO_CIVILIZATION)
		{
			return false;
		}

		CvWString szMessage = gDLL->getText("TXT_KEY_MISC_EMPIRE_SPLIT", getNameKey(), GC.getCivilizationInfo(eBestCiv).getShortDescriptionKey(), GC.getLeaderHeadInfo(eBestLeader).getTextKeyWide());
		for (int i = 0; i < MAX_CIV_PLAYERS; ++i)
		{
			if (GET_PLAYER((PlayerTypes)i).isAlive())
			{
				if (i == getID() || i == eNewPlayer || GET_TEAM(GET_PLAYER((PlayerTypes)i).getTeam()).isHasMet(GET_PLAYER((PlayerTypes)getID()).getTeam()))
				{
					gDLL->getInterfaceIFace()->addMessage((PlayerTypes)i, false, GC.getEVENT_MESSAGE_TIME(), szMessage, "AS2D_REVOLTEND", MESSAGE_TYPE_MAJOR_EVENT, ARTFILEMGR.getInterfaceArtInfo("INTERFACE_CITY_BAR_CAPITAL_TEXTURE")->getPath());
				}
			}
		}
		GC.getGameINLINE().addReplayMessage(REPLAY_MESSAGE_MAJOR_EVENT, getID(), szMessage, -1, -1, (ColorTypes)GC.getInfoTypeForString("COLOR_HIGHLIGHT_TEXT"));

		GC.getGameINLINE().addPlayer(eNewPlayer, eBestLeader, eBestCiv);
		GET_PLAYER(eNewPlayer).setParent(getID());

		CvTeam& kNewTeam = GET_TEAM(GET_PLAYER(eNewPlayer).getTeam());
		for (int i = 0; i < GC.getNumTechInfos(); ++i)
		{
			kNewTeam.setHasTech((TechTypes)i, GET_TEAM(getTeam()).isHasTech((TechTypes)i), eNewPlayer, false, false);
		}

		for (int iTeam = 0; iTeam < MAX_TEAMS; ++iTeam)
		{
			CvTeam& kLoopTeam = GET_TEAM((TeamTypes)iTeam);

			if (kLoopTeam.isAlive())
			{
				kNewTeam.setEspionagePointsAgainstTeam((TeamTypes)iTeam, GET_TEAM(getTeam()).getEspionagePointsAgainstTeam((TeamTypes)iTeam));
				kLoopTeam.setEspionagePointsAgainstTeam(GET_PLAYER(eNewPlayer).getTeam(), kLoopTeam.getEspionagePointsAgainstTeam(getTeam()));
			}
		}
		kNewTeam.setEspionagePointsEver(GET_TEAM(getTeam()).getEspionagePointsEver());

		GET_TEAM(getTeam()).assignVassal(GET_PLAYER(eNewPlayer).getTeam(), false);

		AI_updateBonusValue();
	}

	std::vector< std::pair<int, int> > aCultures;
	for (int iPlot = 0; iPlot < GC.getMapINLINE().numPlotsINLINE(); ++iPlot)
	{
		CvPlot* pLoopPlot = GC.getMapINLINE().plotByIndexINLINE(iPlot);

		bool bTranferPlot = false;

		if (!bTranferPlot && pLoopPlot->area() == pArea)
		{
			bTranferPlot = true;
		}

		if (!bTranferPlot)
		{
			CvCity* pWorkingCity = pLoopPlot->getWorkingCity();
			if (NULL != pWorkingCity && pWorkingCity->getOwnerINLINE() == getID() && pWorkingCity->area() == pArea)
			{
				bTranferPlot = true;
			}
		}

		if (!bTranferPlot && pLoopPlot->isWater() && pLoopPlot->isAdjacentToArea(pArea))
		{
			bTranferPlot = true;
		}

		if (bTranferPlot)
		{
			int iCulture = pLoopPlot->getCulture(getID());

			if (bPlayerExists)
			{
				iCulture = std::max(iCulture, pLoopPlot->getCulture(eNewPlayer));
			}

			aCultures.push_back(std::make_pair(iPlot, iCulture));
		}
	}

	int iLoop;


	for (CvCity* pLoopCity = firstCity(&iLoop); pLoopCity != NULL; pLoopCity = nextCity(&iLoop))
	{
	    	// human only split 1 city

		if ((!isHuman()&&(pLoopCity->area() == pArea))||(isHuman()&&(pLoopCity->getID() == iCity)))
		{
			int iCulture = pLoopCity->getCultureTimes100(getID());
			CvPlot* pPlot = pLoopCity->plot();

			GET_PLAYER(eNewPlayer).acquireCity(pLoopCity, false, true, false);

			if (NULL != pPlot)
			{
				CvCity* pCity = pPlot->getPlotCity();
				if (NULL != pCity)
				{
					pCity->setCultureTimes100(eNewPlayer, iCulture, false, false);
				}

				for (int i = 0; i < GC.getDefineINT("COLONY_NUM_FREE_DEFENDERS"); ++i)
				{
					pCity->initConscriptedUnit();
				}
			}
		}
	}

    for (uint i = 0; i < aCultures.size(); ++i)
	{
		CvPlot* pPlot = GC.getMapINLINE().plotByIndexINLINE(aCultures[i].first);
		pPlot->setCulture(eNewPlayer, aCultures[i].second, true, false);
		if (!isHuman())pPlot->setCulture(getID(), 0, true, false);

		for (int iTeam = 0; iTeam < MAX_TEAMS; ++iTeam)
		{
			if (pPlot->getRevealedOwner((TeamTypes)iTeam, false) == getID())
			{
				if (!isHuman()) pPlot->setRevealedOwner((TeamTypes)iTeam, eNewPlayer);
			}
		}
	}


	GC.getGameINLINE().updatePlotGroups();

	return true;
}


CvDLLButtonPopup

in launchFreeColonyPopup() every city can become a colony. pass the cityid not the area.

line 2428:
Code:
	gDLL->getInterfaceIFace()->popupSetBodyString(pPopup, gDLL->getText("TXT_KEY_FREE_COLONY"));

	if (GET_PLAYER(ePlayer).canSplitEmpire())
	{
//		for(CvArea* pLoopArea = GC.getMapINLINE().firstArea(&iLoop); pLoopArea != NULL; pLoopArea = GC.getMapINLINE().nextArea(&iLoop))
		{
//			if (GET_PLAYER(ePlayer).canSplitArea(pLoopArea->getID()))
			{
				CvWString szCityList;
				int iCityLoop;
				int iNumCities = 0;
				for (CvCity* pLoopCity = GET_PLAYER(ePlayer).firstCity(&iCityLoop); pLoopCity != NULL; pLoopCity = GET_PLAYER(ePlayer).nextCity(&iCityLoop))
				{
					//if (pLoopCity->area()->getID() == pLoopArea->getID())
					//{
					//	if (!szCityList.empty())
					//	{
					//		szCityList += L", ";
					//	}
					//	++iNumCities;
                    //
					 szCityList = pLoopCity->getName();
					//}


                    CvWString szBuffer = gDLL->getText("TXT_KEY_SPLIT_EMPIRE", szCityList.GetCString());
                    gDLL->getInterfaceIFace()->popupAddGenericButton(pPopup, szBuffer, ARTFILEMGR.getInterfaceArtInfo("INTERFACE_BUTTONS_CITYSELECTION")->getPath(), pLoopCity->getID(), WIDGET_GENERAL);
				}
			}
		}
	}
 
Man this looks fantastic I really appreciate this.

As a follow-up to my noob question ; ) will I have to compile the dll. to get this thing to work? My ultimate goal is to try and compile this with the Revolutions Modpack- but I admit I have no clue how to do a compile (I checked out the tutorial by Kael and it's a little more then confusing).

If I will need to merge this it may prove a bit tricky. I may be pushing my luck, but is there anyway you or, someone else could compile a .dll with the Revolutions Modpack (reading up on it he said it has no SDK changes or something so maybe you don't even have to >_>)?

If not I completely understand, I guess I'll keep hammering away at it.

Thanks a ton for the code Osaft I really appreciate it. =]
 
Hey man, thank you so much this'll be great XD.

I tried playing it though I wasn't able to make any colonies. Was there any prereqs or anything? I just tried playing custom a game and just, built a few cities and I wasn't able to grant independence to any. Think it's my problem? XD

I really appreciate you making this though thanks man =D
 
Colonies become your vassals automatically, IIRC. So it may be you need the tech that enables vassalage (can't remeber what that is due to too much FfH playing).
 
@werewabbit:Hm, are you sure you put the dll into the right place? And start the revolution mod? You only need 2 Cities. It works for me.

@falc: you can make colonies from the start.
 
Yeah I dunno what's up. I've modified the source files just like you said, I put that .dll in my Revolution's assets file and I double and triple checked it all. Obviously something's up but I dunno what.

You say it works for you when you test it? Maybe you could zip your whole revolutions folder and send it over XD man I'm totally bumming everything off you ;)

*I've checked quite a few times since and I still can't get it working, I really dunno what's wrong. I stuck the lines of code in where you said =/ obviously something's up though.
 
I incorporated this into the FfH dll (the latest version released uncompiled, which is a little outdated), and it doesn't seem to work. I couldn't liberate any colonies at all.
 
this looks cool
just finished compiling. works o.k. so far.
I had a bit of trouble but then realised I had some duplicate code in there (just me being sloppy with pasting)
will give it a try.
 
awesome, just tried it with bts 3.17
the line numbers are slightly different so i had to search for the right places for the code but it wasn't that hard.
Now I just have to get hold of the source files for the bts 3.17 TAM CvGameCoreDLL so I can integrate it into that.
 
awesome, just tried it with bts 3.17
the line numbers are slightly different so i had to search for the right places for the code but it wasn't that hard.
Now I just have to get hold of the source files for the bts 3.17 TAM CvGameCoreDLL so I can integrate it into that.

you ever do it?
 
A project for the future would be allowing AI players to use this and then (the tricky part) getting the AI to use it intelligently.
Working on other AI mods at the moment but I might look at doing this soon
 
Top Bottom