A New Dawn Beta Builds

@Afforess

I think it's a great idea. You don't even have to make it dependent on AND's installer if you don't want to; nothing stops you from self-distributing it too.

Awesome! However I would still like it to stay as an option in AND rather than self distributing since AND was ment to be a RoM community mod.

Anywho which mods of yours can I combine into my "uber mod"? So far I have ...

- Misc Mod
- Water Mod
- Military Mod
- Health Mod
- Domestic Animals Mod
- Science Mod
- Transportation Mod
- Garbage Mod
- disabled buildings from Early Buildings
- disabled Buildings from Civic Buildings
- Towers and Walls Mod

I would like to add the following ...

- Firestorm Mod
- Zoological Buildings Mod
- Farming Mod
- Education Mod (Gladiator School, Drama School, Music School, etc)
- Public Pool (from the Sports Mod)
- Misc Mod (Cryogenic Prison, Saloon, etc)
- NIMBY Mod
- GeneralStaff's Vacation Mod (National Parks, Cruse Ship Port, etc)
- All of Early Buildings (or at least some key buildings like the weaver, tailor, apiary, candlemaker, etc)

In short which can I use of these?

Once combined you can take them out of the installation, thus making far fewer choice for custom installation.
 
@Afforess



Awesome! However I would still like it to stay as an option in AND rather than self distributing since AND was ment to be a RoM community mod.

Anywho which mods of yours can I combine into my "uber mod"? So far I have ...

- Misc Mod
- Water Mod
- Military Mod
- Health Mod
- Domestic Animals Mod
- Science Mod
- Transportation Mod
- Garbage Mod
- disabled buildings from Early Buildings
- disabled Buildings from Civic Buildings
- Towers and Walls Mod

I would like to add the following ...

- Firestorm Mod
- Zoological Buildings Mod
- Farming Mod
- Education Mod (Gladiator School, Drama School, Music School, etc)
- Public Pool (from the Sports Mod)
- Misc Mod (Cryogenic Prison, Saloon, etc)
- NIMBY Mod
- GeneralStaff's Vacation Mod (National Parks, Cruse Ship Port, etc)
- All of Early Buildings (or at least some key buildings like the weaver, tailor, apiary, candlemaker, etc)

In short which can I use of these?

Once combined you can take them out of the installation, thus making far fewer choice for custom installation.

All of them. You have permission to modify and take over over all of those you listed. To be specific, you can have:

- Firestorm Mod
- Zoological Buildings Mod
- Farming Mod
- Education Mod
- Public Pool
- Misc Mod
- NIMBY Mod
- GeneralStaff's Vacation Mod
- The Buildings I cut from the Early Buildings.

By the way, I never delete perfectly good buildings. You will find I just commented out the buildings, so you should find it easy to turn them back on.
 
All of them. You have permission to modify and take over over all of those you listed. To be specific, you can have:

- Firestorm Mod
- Zoological Buildings Mod
- Farming Mod
- Education Mod
- Public Pool
- Misc Mod
- NIMBY Mod
- GeneralStaff's Vacation Mod
- The Buildings I cut from the Early Buildings.

By the way, I never delete perfectly good buildings. You will find I just commented out the buildings, so you should find it easy to turn them back on.

1. Thank you. I shall add all of the ones you approved then.

2. Aw darn I was hoping for some more of the early buildings (like the apiary, weaver's hut, wheelwright and stonemaker's hut. Sure you don't want to disable some more?

3. That's what i mean when i say "disabled". Not that you deleted them.

4. So once I get is all combined into one and uploaded you are going to take out the other mods that are completely combined right?
 
2. Aw darn I was hoping for some more of the early buildings (like the apiary, weaver's hut, wheelwright and stonemaker's hut. Sure you don't want to disable some more?

Nothing stops you from using the bForceOverwrite tag, and re-creating the building the way you see fit. :mischief:

4. So once I get is all combined into one and uploaded you are going to take out the other mods that are completely combined right?

Yes. Unless you have something else in mind.
 
Nothing stops you from using the bForceOverwrite tag, and re-creating the building the way you see fit. :mischief:

Yes. Unless you have something else in mind.

1. Yeah I know. Just was trying to keep things simpler. For instance I wanted the wheelwright so I would not have to have overriding code for it to fit into the transportation mod. Its too bad I did not learn how to mod sooner or I could have made those ideas myself rather than you or generalstaff making them for me.

2. Nope. Just wanted to make sure we were on the same page.
 
About the bug of stoneworker's hut, I found the problem, but I'm sorry for that it's hard to fix by me.

The building's extra yields bonus is calculated by the vicinity resourece in the city's plots.

Code:
>	CvGameCoreDLL.dll!CvCity::hasVicinityBonus(BonusTypes eBonus=8)  行18993	C++
 	CvGameCoreDLL.dll!CvCity::changeNumBonuses(BonusTypes eIndex=8, int iChange=-2)  行12112 + 0xc 字节	C++
 	CvGameCoreDLL.dll!CvPlot::setPlotGroup(PlayerTypes ePlayer=0, CvPlotGroup * pNewValue=0x00000000)  行7691	C++
 	CvGameCoreDLL.dll!CvPlotGroup::recalculatePlots()  行164	C++
 	CvGameCoreDLL.dll!CvPlayer::updatePlotGroups()  行4581	C++
 	CvGameCoreDLL.dll!CvGame::updatePlotGroups()  行2431	C++

This function is called by the game's plots updating every turn. Then it will call processBonus() (red text) to calculate the city's yield of all buildings. The real problem is here, in the hasVicinityBonus() function. (blue text). It can not determine whether or not there is vicinity resources in the city's plots.
Code:
void CvCity::changeNumBonuses(BonusTypes eIndex, int iChange)
{
	FAssertMsg(eIndex >= 0, "eIndex expected to be >= 0");
	FAssertMsg(eIndex < GC.getNumBonusInfos(), "eIndex expected to be < GC.getNumBonusInfos()");

	if (iChange != 0)
	{
		bool bOldHasBonus = hasBonus(eIndex);
/************************************************************************************************/
/* Afforess	                  Start		 04/23/10                                               */
/*                                                                                              */
/*                                                                                              */
/************************************************************************************************/
		bool bHadVicinityBonus = hasVicinityBonus(eIndex);
/************************************************************************************************/
/* Afforess	                     END                                                            */
/************************************************************************************************/
		m_paiNumBonuses[eIndex] += iChange;
/************************************************************************************************/
/* Afforess	                  Start		 04/23/10                                               */
/*                                                                                              */
/*                                                                                              */
/************************************************************************************************/
		[COLOR="Blue"]bool bHasVicinityBonus = hasVicinityBonus(eIndex);[/COLOR]
		
		if (bOldHasBonus != hasBonus(eIndex))
		{
			if (hasBonus(eIndex))
			{
				[COLOR="red"]processBonus(eIndex, 1, bHadVicinityBonus != bHasVicinityBonus);[/COLOR]
			}
			else
			{
				[COLOR="Red"]processBonus(eIndex, -1, bHadVicinityBonus != bHasVicinityBonus);[/COLOR]
			}
		}
/************************************************************************************************/
/* Afforess	                     END                                                            */
/************************************************************************************************/
		if (isCorporationBonus(eIndex))
		{
			updateCorporation();
		}


	}
}

Then in the function CvCity::processBonus() Line start from 4677, it will subtract city's yield by the count bonus from vicinity resource, in every turn. (red text)
Code:
/************************************************************************************************/
/* Afforess	                  Start		 12/7/09                                                */
/*                                                                                              */
/*                                                                                              */
/************************************************************************************************/
	for (iI = 0; iI < NUM_COMMERCE_TYPES; iI++)
	{
		changeBonusCommerceRateModifier(((CommerceTypes)iI), (getBonusCommerceRateModifier(((CommerceTypes)iI), eBonus) * iChange));
	}
	for (iI = 0; iI < GC.getNumBuildingInfos(); iI++)
	{
		if (getNumActiveBuilding((BuildingTypes)iI) > 0)
		{
			for (int iJ = 0; iJ < NUM_YIELD_TYPES; iJ++)
			{
 				updateYieldRate((BuildingTypes)iI, (YieldTypes)iJ, ((getBuildingYieldChange((BuildingClassTypes)(GC.getBuildingInfo((BuildingTypes)iI).getBuildingClassType()), (YieldTypes)iJ)) + (GC.getBuildingInfo((BuildingTypes)iI).getBonusYieldChanges(eBonus, iJ) * getNumActiveBuilding((BuildingTypes)iI) * iChange)));

				if (bLostVicinityBonus)
				{
					[COLOR="Red"]updateYieldRate((BuildingTypes)iI, (YieldTypes)iJ, ((getBuildingYieldChange((BuildingClassTypes)(GC.getBuildingInfo((BuildingTypes)iI).getBuildingClassType()), (YieldTypes)iJ)) + (GC.getBuildingInfo((BuildingTypes)iI).getVicinityBonusYieldChanges(eBonus, iJ) * iChange)));[/COLOR]
				}
			}
		}
	}
/************************************************************************************************/
/* Afforess	                     END                                                            */
/************************************************************************************************/	
}

Maybe you will ask me why? Just read the code in these functions:
Code:
bool CvCity::hasVicinityBonus(BonusTypes eBonus) const
{
	//No sense in checking...
	if (!hasBonus(eBonus))
	{
		return false;
	}
	
	bool bHasVicinityBonus = false;
	for (int iI = 0; iI < [COLOR="red"]getNumCityPlots(); [/COLOR]iI++)
	{
		CvPlot* pLoopPlot = plotCity(getX_INLINE(), getY_INLINE(), iI);
		if (pLoopPlot != NULL)
		{
			if (pLoopPlot->getBonusType() == eBonus)
			{
				if (pLoopPlot->getOwnerINLINE() == getOwnerINLINE())
				{
					if (pLoopPlot->isHasValidBonus() && pLoopPlot->isConnectedTo(this))
					{
						bHasVicinityBonus = true;
						break;
					}
				}
			}
		}
	}

	if (!bHasVicinityBonus)
	{
		return false;
	}
	
	return true;
}

Code:
int CvCity::getNumCityPlots() const
{
	int iRadius;
	int var_city_plots;
	if (getCultureLevel() == -1)
	{
	    return NUM_CITY_PLOTS_1;
	}
    iRadius = GC.getCultureLevelInfo(getCultureLevel()).getCityRadius();
    switch (iRadius)
    {
    case 3:
        var_city_plots = NUM_CITY_PLOTS;
        break;
    case 2:
        var_city_plots = NUM_CITY_PLOTS_2;
        break;
    case 1:
        var_city_plots = NUM_CITY_PLOTS_1;
        break;
    default:
        var_city_plots = NUM_CITY_PLOTS_2;
        break;
    }
	return (var_city_plots);
}

Do you remember that you changed the calculation method of city's culture radius? I guess this old way will not get the city's real working plots. To avoid this bug without modify many codes, I suggest you simply disable this feature temporarily.
 
There is my save for debugging, and some helpful informations to debug it. Wish this can help you. ( the first turn after end the current turn will construct the stoneworker's hut. the second turn and next, the bug comes. )

x 32 y 31 The plot of stone resource.

x 31 y 33 city plot.

"BUILDING_STONEWORKER" BuildingTypes 378 BuildingClassTypes 339

Stone Resource eBonus == 8

source revision 133.

A New Dawn.log:
Spoiler :

Installed Components:
{Required Files} {Military Civics} {Beautification Project} {Castle Improvements} {Ice Breaker} {Ideology Civics} Meteorology {Realistic Diplomacy} {Seafaring } {War Prizes} Arctic {Larger Cities} {Espionage Process} Forestation {Sea Tunnels} Terraforming {Lead From Behind} {Event Images} Sports {Civic Buildings} {Early Buildings} ANM {Historical Wonders} {Better RoM} Withdraw Guilds {Modern Corporations} {Improved Artwork} {Civic Diplomacy} {Trading Posts} {Spy Satellites}

Install Type:
Custom

Version:
1.73beta3

Install Directory:
F:\Sid Meier's Civilization 4\Beyond the Sword\Mods\Rise of Mankind

Windows Version:
Vista


P.S. A little advice: Do not call other functions in a function, and use their returned values as parameters. That's will be hard to read or debug. Define some variables and pass them instead.
 
Unless I'm missing something, I'm not sure that is the problem. CvCity::hasVicinityBonus() does check that you own the plot's:

Code:
bool CvCity::hasVicinityBonus(BonusTypes eBonus) const
{
	//No sense in checking...
	if (!hasBonus(eBonus))
	{
		return false;
	}
	
	bool bHasVicinityBonus = false;
	for (int iI = 0; iI < [COLOR="red"]getNumCityPlots(); [/COLOR]iI++)
	{
		CvPlot* pLoopPlot = plotCity(getX_INLINE(), getY_INLINE(), iI);
		if (pLoopPlot != NULL)
		{
			if (pLoopPlot->getBonusType() == eBonus)
			{
				[COLOR="Blue"]if (pLoopPlot->getOwnerINLINE() == getOwnerINLINE())[/COLOR]
				{
					if (pLoopPlot->isHasValidBonus() && pLoopPlot->isConnectedTo(this))
					{
						bHasVicinityBonus = true;
						break;
					}
				}
			}
		}
	}

	if (!bHasVicinityBonus)
	{
		return false;
	}
	
	return true;
}
 
Do you remember that you changed the calculation method of city's culture radius? I guess this old way will not get the city's real working plots. To avoid this bug without modify many codes, I suggest you simply disable this feature temporarily.

Wouldn't it be easiest to change the count for worked tiles to a city resource count? Sure, it would include resources outside of the city radius, but at least it would work.
 
Unless I'm missing something, I'm not sure that is the problem. CvCity::hasVicinityBonus() does check that you own the plot's:

Code:
bool CvCity::hasVicinityBonus(BonusTypes eBonus) const
{
	//No sense in checking...
	if (!hasBonus(eBonus))
	{
		return false;
	}
	
	bool bHasVicinityBonus = false;
	for (int iI = 0; iI < [COLOR="red"]getNumCityPlots(); [/COLOR]iI++)
	{
		CvPlot* pLoopPlot = plotCity(getX_INLINE(), getY_INLINE(), iI);
		if (pLoopPlot != NULL)
		{
			if (pLoopPlot->getBonusType() == eBonus)
			{
				[COLOR="Blue"]if (pLoopPlot->getOwnerINLINE() == getOwnerINLINE())[/COLOR]
				{
					if (pLoopPlot->isHasValidBonus() && pLoopPlot->isConnectedTo(this))
					{
						bHasVicinityBonus = true;
						break;
					}
				}
			}
		}
	}

	if (!bHasVicinityBonus)
	{
		return false;
	}
	
	return true;
}

Yes, you're right. I checked the count of plots owned by my city, it's 17. And the getNumCityPlots() returns 21. So the resource plot must be checked. I just think that is it any chance of this function returns a plots count which less than actual count?

And for the reason of losing bonus resource, I found this:
Spoiler :


The game updates the plot groups of player every turn.
Code:
 	CvGameCoreDLL.dll!CvCity::hasVicinityBonus(BonusTypes eBonus=8)  &#34892;19018	C++
 	CvGameCoreDLL.dll!CvCity::changeNumBonuses(BonusTypes eIndex=8, int iChange=1)  &#34892;12122 + 0xc &#23383;&#33410;	C++
 	CvGameCoreDLL.dll!CvPlotGroup::changeNumBonuses(BonusTypes eBonus=8, int iChange=1)  &#34892;248	C++
 	[COLOR="red"]CvGameCoreDLL.dll!CvPlot::updatePlotGroupBonus(bool bAdd=true)  &#34892;1269[/COLOR]	C++
 	CvGameCoreDLL.dll!CvPlot::setPlotGroup(PlayerTypes ePlayer=0, CvPlotGroup * pNewValue=0x58e6aa68)  &#34892;7724	C++
 	CvGameCoreDLL.dll!CvPlotGroup::addPlot(CvPlot * pPlot=0x4f6624a4)  &#34892;86	C++
 	CvGameCoreDLL.dll!CvMap::combinePlotGroups(PlayerTypes ePlayer=0, CvPlotGroup * pPlotGroup1=0x5c534988, CvPlotGroup * pPlotGroup2=0x58e6aa68)  &#34892;564	C++
 	CvGameCoreDLL.dll!CvPlot::updatePlotGroup(PlayerTypes ePlayer=0, bool bRecalculate=true)  &#34892;7830	C++
>	[COLOR="red"]CvGameCoreDLL.dll!CvPlotGroup::recalculatePlots()  &#34892;179	C++[/COLOR] 	CvGameCoreDLL.dll!CvPlayer::updatePlotGroups()  &#34892;4581	C++
 	CvGameCoreDLL.dll!CvGame::updatePlotGroups()  &#34892;2431	C++

When calling function pPlot->setPlotGroup(eOwner, NULL); , the vicinity resource will be removed. (red text).
Code:
void CvPlotGroup::recalculatePlots()
{
	PROFILE_FUNC();

	CLLNode<XYCoords>* pPlotNode;
	CvPlot* pPlot;
	CLinkList<XYCoords> oldPlotGroup;
	XYCoords xy;
	PlayerTypes eOwner;
	int iCount;

	eOwner = getOwnerINLINE();

	pPlotNode = headPlotsNode();

	if (pPlotNode != NULL)
	{
		pPlot = GC.getMapINLINE().plotSorenINLINE(pPlotNode->m_data.iX, pPlotNode->m_data.iY);

		iCount = 0;

		gDLL->getFAStarIFace()->SetData(&GC.getPlotGroupFinder(), &iCount);
		gDLL->getFAStarIFace()->GeneratePath(&GC.getPlotGroupFinder(), pPlot->getX_INLINE(), pPlot->getY_INLINE(), -1, -1, false, eOwner);

		if (iCount == getLengthPlots())
		{
			return;
		}
	}

	{
		PROFILE("CvPlotGroup::recalculatePlots update");

		oldPlotGroup.clear();

		pPlotNode = headPlotsNode();

		while (pPlotNode != NULL)
		{
			PROFILE("CvPlotGroup::recalculatePlots update 1");

			pPlot = GC.getMapINLINE().plotSorenINLINE(pPlotNode->m_data.iX, pPlotNode->m_data.iY);

			FAssertMsg(pPlot != NULL, "Plot is not assigned a valid value");

			xy.iX = pPlot->getX_INLINE();
			xy.iY = pPlot->getY_INLINE();

			oldPlotGroup.insertAtEnd(xy);

			[COLOR="red"]pPlot->setPlotGroup(eOwner, NULL);[/COLOR]

			pPlotNode = deletePlotsNode(pPlotNode); // will delete this PlotGroup...
		}

		pPlotNode = oldPlotGroup.head();

		while (pPlotNode != NULL)
		{
			PROFILE("CvPlotGroup::recalculatePlots update 2");

			pPlot = GC.getMapINLINE().plotSorenINLINE(pPlotNode->m_data.iX, pPlotNode->m_data.iY);

			FAssertMsg(pPlot != NULL, "Plot is not assigned a valid value");

			[COLOR="red"]pPlot->updatePlotGroup(eOwner, true);[/COLOR]
			pPlotNode = oldPlotGroup.deleteNode(pPlotNode);
		}
	}
}

Code:
void CvPlot::setPlotGroup(PlayerTypes ePlayer, CvPlotGroup* pNewValue)
{
	int iI;

	CvPlotGroup* pOldPlotGroup = getPlotGroup(ePlayer);

	if (pOldPlotGroup != pNewValue)
	{
		if (NULL ==  m_aiPlotGroup)
		{
			m_aiPlotGroup = new int[MAX_PLAYERS];
			for (int iI = 0; iI < MAX_PLAYERS; ++iI)
			{
				m_aiPlotGroup[iI] = FFreeList::INVALID_INDEX;
			}
		}

		CvCity* pCity = getPlotCity();

		if (ePlayer == getOwnerINLINE())
		{
			updatePlotGroupBonus(false);
		}

		if (pOldPlotGroup != NULL)
		{
			if (pCity != NULL)
			{
				if (pCity->getOwnerINLINE() == ePlayer)
				{
					FAssertMsg((0 < GC.getNumBonusInfos()), "GC.getNumBonusInfos() is not greater than zero but an array is being allocated in CvPlot::setPlotGroup");
					for (iI = 0; iI < GC.getNumBonusInfos(); ++iI)
					{
						[COLOR="red"]pCity->changeNumBonuses(((BonusTypes)iI), -(pOldPlotGroup->getNumBonuses((BonusTypes)iI)));[/COLOR]					}
				}
			}
		}

		if (pNewValue == NULL)
		{
			m_aiPlotGroup[ePlayer] = FFreeList::INVALID_INDEX;
		}
		else
		{
			m_aiPlotGroup[ePlayer] = pNewValue->getID();
		}

		if (getPlotGroup(ePlayer) != NULL)
		{
			if (pCity != NULL)
			{
				if (pCity->getOwnerINLINE() == ePlayer)
				{
					FAssertMsg((0 < GC.getNumBonusInfos()), "GC.getNumBonusInfos() is not greater than zero but an array is being allocated in CvPlot::setPlotGroup");
					for (iI = 0; iI < GC.getNumBonusInfos(); ++iI)
					{
						pCity->changeNumBonuses(((BonusTypes)iI), getPlotGroup(ePlayer)->getNumBonuses((BonusTypes)iI));
					}
				}
			}
		}
		if (ePlayer == getOwnerINLINE())
		{
			updatePlotGroupBonus(true);
		}
	}
}

Then it will be added back in the function pPlot->updatePlotGroup(eOwner, true); --> CvPlot::updatePlotGroupBonus.
Code:
void CvPlot::updatePlotGroupBonus(bool bAdd)
{
	PROFILE_FUNC();

	CvCity* pPlotCity;
	CvPlotGroup* pPlotGroup;
	BonusTypes eNonObsoleteBonus;
	int iI;

	if (!isOwned())
	{
		return;
	}

	pPlotGroup = getPlotGroup(getOwnerINLINE());

	if (pPlotGroup != NULL)
	{
		pPlotCity = getPlotCity();

		if (pPlotCity != NULL)
		{
			for (iI = 0; iI < GC.getNumBonusInfos(); ++iI)
			{
				if (!GET_TEAM(getTeam()).isBonusObsolete((BonusTypes)iI))
				{
					pPlotGroup->changeNumBonuses(((BonusTypes)iI), (pPlotCity->getFreeBonus((BonusTypes)iI) * ((bAdd) ? 1 : -1)));
				}
			}

			if (pPlotCity->isCapital())
			{
				for (iI = 0; iI < GC.getNumBonusInfos(); ++iI)
				{
					pPlotGroup->changeNumBonuses(((BonusTypes)iI), (GET_PLAYER(getOwnerINLINE()).getBonusExport((BonusTypes)iI) * ((bAdd) ? -1 : 1)));
					pPlotGroup->changeNumBonuses(((BonusTypes)iI), (GET_PLAYER(getOwnerINLINE()).getBonusImport((BonusTypes)iI) * ((bAdd) ? 1 : -1)));
				}
			}
		}

		eNonObsoleteBonus = getNonObsoleteBonusType(getTeam());

		if (eNonObsoleteBonus != NO_BONUS)
		{
			if (GET_TEAM(getTeam()).isHasTech((TechTypes)(GC.getBonusInfo(eNonObsoleteBonus).getTechCityTrade())))
			{
				if (isCity(true, getTeam()) ||
					((getImprovementType() != NO_IMPROVEMENT) && GC.getImprovementInfo(getImprovementType()).isImprovementBonusTrade(eNonObsoleteBonus)))
				{
					if ((pPlotGroup != NULL) && isBonusNetwork(getTeam()))
					{
						[COLOR="red"]pPlotGroup->changeNumBonuses(eNonObsoleteBonus, ((bAdd) ? 1 : -1));[/COLOR]
					}
				}
			}
		}
	}
}

When this function was called by the code above, bool bHadVicinityBonus == false, but the bool bHasVicinityBonus == true. Then the city yield will not be added back by function processBonus( eIndex, false ).
Code:
void CvCity::changeNumBonuses(BonusTypes eIndex, int iChange)
{
	FAssertMsg(eIndex >= 0, "eIndex expected to be >= 0");
	FAssertMsg(eIndex < GC.getNumBonusInfos(), "eIndex expected to be < GC.getNumBonusInfos()");

	if (iChange != 0)
	{
		bool bOldHasBonus = hasBonus(eIndex);
/************************************************************************************************/
/* Afforess	                  Start		 04/23/10                                               */
/*                                                                                              */
/*                                                                                              */
/************************************************************************************************/
		[COLOR="red"]bool bHadVicinityBonus = hasVicinityBonus(eIndex);[/COLOR]
/************************************************************************************************/
/* Afforess	                     END                                                            */
/************************************************************************************************/
		m_paiNumBonuses[eIndex] += iChange;
/************************************************************************************************/
/* Afforess	                  Start		 04/23/10                                               */
/*                                                                                              */
/*                                                                                              */
/************************************************************************************************/
		[COLOR="red"]bool bHasVicinityBonus = hasVicinityBonus(eIndex);[/COLOR]		
		if (bOldHasBonus != hasBonus(eIndex))
		{
			if (hasBonus(eIndex))
			{
				[COLOR="red"]processBonus(eIndex, 1, bHadVicinityBonus != bHasVicinityBonus);[/COLOR]			}
			else
			{
				processBonus(eIndex, -1, bHadVicinityBonus != bHasVicinityBonus);
			}
		}
/************************************************************************************************/
/* Afforess	                     END                                                            */
/************************************************************************************************/
		if (isCorporationBonus(eIndex))
		{
			updateCorporation();
		}


	}
}

What happend in this function? I found that the pLoopPlot->isConnectedTo(this) returns false.
Code:
bool CvCity::hasVicinityBonus(BonusTypes eBonus) const
{
	//No sense in checking...
	if (!hasBonus(eBonus))
	{
		return false;
	}
	
	bool bHasVicinityBonus = false;
	for (int iI = 0; iI < getNumCityPlots(); iI++)
	{
		CvPlot* pLoopPlot = plotCity(getX_INLINE(), getY_INLINE(), iI);
		if (pLoopPlot != NULL)
		{
			if (pLoopPlot->getBonusType() == eBonus)
			{
				if (pLoopPlot->getOwnerINLINE() == getOwnerINLINE())
				{
					[COLOR="red"]if (pLoopPlot->isHasValidBonus() && pLoopPlot->isConnectedTo(this))[/COLOR]
					{
						bHasVicinityBonus = true;
						break;
					}
				}
			}
		}
	}

	if (!bHasVicinityBonus)
	{
		return false;
	}
	
	return true;
}

Because of that getPlotGroup(getOwnerINLINE()) returns NULL.
Code:
bool CvPlot::isConnectedTo(const CvCity* pCity) const
{
	FAssert(isOwned());
	return (([COLOR="red"]getPlotGroup(getOwnerINLINE()[/COLOR]) == pCity->plotGroup(getOwnerINLINE())) || (getPlotGroup(pCity->getOwnerINLINE()) == pCity->plotGroup(pCity->getOwnerINLINE())));
}

So the yield from vicinity bonus never added back.

I can only trace this bug till here for now, I will keep working on it. Wish these informations may help you.

 
I found a new clue about this bug: when the function recalculatePlots() is called, it refreshes all plot groups of the player. And for every plots in a group, its owner will be set to null and restored by function CvPlot::setPlotGroup(PlayerTypes ePlayer, CvPlotGroup* pNewValue).

When set the owner plot group of the city's plot ( x 31 y 33 in my save ) to null, the group pointer of the plot which has bonus resource is valid, so it knows there is vicinity bonus.

But after all plots of this group was removed from its group ( set to null ), and then the owner group of vicinity bonus plot ( x 32 y 31 in my save ) was restored by the CvPlot::setPlotGroup function, the plot instance use its m_plotCity member to find the city which need to restore the yields. But, unfortunately, the value of the m_plotCity member always is -1, even before the plot was removed from its group.

They are the code details below:
Spoiler :


Removing plot's group.
Code:
[COLOR="red"]( the bonus' plot )CvGameCoreDLL.dll!CvPlot::isConnectedTo(const CvCity * pCity=0x5f47a060)  &#34892;1137 + 0x11 &#23383;&#33410;	C++ [/COLOR]
CvGameCoreDLL.dll!CvCity::hasVicinityBonus(BonusTypes eBonus=8)  &#34892;19010 + 0x1b &#23383;&#33410;	C++
CvGameCoreDLL.dll!CvCity::changeNumBonuses(BonusTypes eIndex=8, int iChange=-2)  &#34892;12112 + 0xc &#23383;&#33410;	C++
[COLOR="Red"]( the city's plot )CvGameCoreDLL.dll!CvPlot::setPlotGroup(PlayerTypes ePlayer=0, CvPlotGroup * pNewValue=0x00000000)  &#34892;7691	C++ [/COLOR]
CvGameCoreDLL.dll!CvPlotGroup::recalculatePlots()  &#34892;164	C++
CvGameCoreDLL.dll!CvPlayer::updatePlotGroups()  &#34892;4581	C++
CvGameCoreDLL.dll!CvGame::updatePlotGroups()  &#34892;2431	C++

Restoring plot's group.
Code:
[COLOR="red"]( bonus' plot )CvGameCoreDLL.dll!CvPlot::setPlotGroup(PlayerTypes ePlayer=0, CvPlotGroup * pNewValue=0x66454720)  &#34892;7663	C++ [/COLOR]
CvGameCoreDLL.dll!CvPlotGroup::addPlot(CvPlot * pPlot=0x4f623a64)  &#34892;86	C++
CvGameCoreDLL.dll!CvPlot::updatePlotGroup(PlayerTypes ePlayer=0, bool bRecalculate=true)  &#34892;7823	C++
CvGameCoreDLL.dll!CvPlotGroup::recalculatePlots()  &#34892;179	C++
CvGameCoreDLL.dll!CvPlayer::updatePlotGroups()  &#34892;4581	C++
CvGameCoreDLL.dll!CvGame::updatePlotGroups()  &#34892;2431	C++

Code:
void CvPlot::setPlotGroup(PlayerTypes ePlayer, CvPlotGroup* pNewValue)
{
	int iI;

	CvPlotGroup* pOldPlotGroup = getPlotGroup(ePlayer);

	if (pOldPlotGroup != pNewValue)
	{
		if (NULL ==  m_aiPlotGroup)
		{
			m_aiPlotGroup = new int[MAX_PLAYERS];
			for (int iI = 0; iI < MAX_PLAYERS; ++iI)
			{
				m_aiPlotGroup[iI] = FFreeList::INVALID_INDEX;
			}
		}

		[COLOR="red"]CvCity* pCity = getPlotCity();[/COLOR]

		if (ePlayer == getOwnerINLINE())
		{
			updatePlotGroupBonus(false);
		}

		if (pOldPlotGroup != NULL)
		{
			if (pCity != NULL)
			{
				if (pCity->getOwnerINLINE() == ePlayer)
				{
					FAssertMsg((0 < GC.getNumBonusInfos()), "GC.getNumBonusInfos() is not greater than zero but an array is being allocated in CvPlot::setPlotGroup");
					for (iI = 0; iI < GC.getNumBonusInfos(); ++iI)
					{
						pCity->changeNumBonuses(((BonusTypes)iI), -(pOldPlotGroup->getNumBonuses((BonusTypes)iI)));
					}
				}
			}
		}

		if (pNewValue == NULL)
		{
			m_aiPlotGroup[ePlayer] = FFreeList::INVALID_INDEX;
		}
		else
		{
			m_aiPlotGroup[ePlayer] = pNewValue->getID();
		}

		if (getPlotGroup(ePlayer) != NULL)
		{
			if (pCity != NULL)
			{
				if (pCity->getOwnerINLINE() == ePlayer)
				{
					FAssertMsg((0 < GC.getNumBonusInfos()), "GC.getNumBonusInfos() is not greater than zero but an array is being allocated in CvPlot::setPlotGroup");
					for (iI = 0; iI < GC.getNumBonusInfos(); ++iI)
					{
						pCity->changeNumBonuses(((BonusTypes)iI), getPlotGroup(ePlayer)->getNumBonuses((BonusTypes)iI));
					}
				}
			}
		}
		if (ePlayer == getOwnerINLINE())
		{
			updatePlotGroupBonus(true);
		}
	}
}


I guess there are some bugs of calculating the city's plots.

Edited:

Interesting, I missed the updatePlotGroupBonus(true); function call at the end of setPlotGroup() function. This function iterate all plots in the group, it will change the city's bonus by the city's plot. Though the bonus' plot has the right group value this time, but the bonus of the city already has been added, so the processBonus(eIndex, 1, bHadVicinityBonus != bHasVicinityBonus); function will be ignored.
 
Hi Afforess,

Found a small bug (especially compared to the problem you're talking over with lichen) in ver.133. Put it on sourceforge, but not sure if you saw it. Has to do with Great Commanders not receiving any xp. Improved XP on/off doesn't change it.
 
Not to sure wether its a bug or on my side, but yeah was running a clean version of a New Dawn, and in the diplomacy screen, for vote for me in the U.N. when i click on it i get no response or no reaction in the diplomacy screen from the AI player, tried most of them. Any idea?
 
Not to sure wether its a bug or on my side, but yeah was running a clean version of a New Dawn, and in the diplomacy screen, for vote for me in the U.N. when i click on it i get no response or no reaction in the diplomacy screen from the AI player, tried most of them. Any idea?

I've noticed this with the Apostolic Palace. You ask them to vote for you - it's either available or not. They don't ask for anything for voting for you.
 
I've noticed this with the Apostolic Palace. You ask them to vote for you - it's either available or not. They don't ask for anything for voting for you.

Its the same for the UN as well. Except if you ask what a civ wants for its vote, it will be happy trading it for nothing. If you ask 2 or 3 more civs and repeat the process, the game crashes
 
Yeah, I am going to disable those until I have time to fix them. Thanks for the reminder.
 
Just a teaser: this is what I have been working on the last day; A new Civilopedia tab, "Building Upgrades"

Spoiler :
Building%20Upgrades.png


Useful for people who want to see the big picture. :p
 
Back
Top Bottom