[SDK MODCOMP] Vicinity Bonus

Mmm... I've tried merging the code myself, but to no avail. I had no problems compiling the SDK, no problems loading the game with it either. I've created a new units schema and tried to make Warriors require Copper in the city vicinity but it just didn't work - at all. The civilopedia shows no reference to it, and I can build warriors willy-nilly. I must be missing something. It'd be great to see this updated to 3.17

EDIT: OK, I think I've got it to work. I've been able to restrict a unit to be built only if Fish is in the vicinity and part of the trade network. The only problem is that the TXT_KEY isn't showing up correctly in the civiliopedia or the unit mouse-over, i.e. instead of saying "Requires Fish in City Vicinity" it just says "TXT_KEY_REQUIRES_VICINITY_BONUS". I'm really not sure if this is an XML problem or an issue with CvGameTextMgr in the SDK. Anyone have any ideas?

Here is my GameText xml file that deals with this:

Code:
	<TEXT>
		<Tag>TXT_KEY_REQUIRES_VICINITY_BONUS</Tag>
		<English>[COLOR_WARNING_TEXT]Requires %s1_Text in City Vicinity[COLOR_REVERT]</English>
		<French>[COLOR_WARNING_TEXT]Requiert : %s1_Text in City Vicinity[COLOR_REVERT]</French>
		<German>[COLOR_WARNING_TEXT]Erfordert: %s1_Text in City Vicinity[COLOR_REVERT]</German>
		<Italian>[COLOR_WARNING_TEXT]Richiede %s1_Text in City Vicinity[COLOR_REVERT]</Italian>
		<Spanish>[COLOR_WARNING_TEXT]Requiere %s1_Text in City Vicinity[COLOR_REVERT]</Spanish>
	</TEXT>
	<TEXT>
		<Tag>TXT_KEY_REQUIRES_IN_CITY_VICINITY</Tag>
		<English>[COLOR_WARNING_TEXT]Requires in City Vicinity:[SPACE]</English>
		<French>[COLOR_WARNING_TEXT]N&#233;cessite in City Vicinity:[SPACE]:[SPACE]</French>
		<German>[COLOR_WARNING_TEXT]Erfordert: in City Vicinity:[SPACE]</German>
		<Italian>[COLOR_WARNING_TEXT]Richiede in City Vicinity:[SPACE]</Italian>
		<Spanish>[COLOR_WARNING_TEXT]Requiere in City Vicinity:[SPACE]</Spanish>
	</TEXT>
 
OK, as it turns out, it was an XML problem and was related to my mod being modular. I moved the GameText xml file into the main mod folder and the game now reads it no problem. So, to sum up: this mod can be adapted to 3.17 simply by copying Shqype's additions from the source code to the equivalent spot in the SDK. You can't use Shqype's mod directly, but you can adapt the source code really quite easily.

My next question is this: does anyone know how to tweak this mod so that the bonus only has to be within the city vicinity, without it having to be improved or connected to the trade network?
 
My next question is this: does anyone know how to tweak this mod so that the bonus only has to be within the city vicinity, without it having to be improved or connected to the trade network?
I don't know if you care anymore, but that is easy to do. Go to CvPlot.cpp, and the section that has this should be changed
Code:
	if (GET_TEAM(getTeam()).isHasTech((TechTypes)(GC.getBonusInfo((BonusTypes)m_eBonusType).getTechReveal())))
	{
        if (GC.getImprovementInfo(getImprovementType()).isImprovementBonusMakesValid(getBonusType()))
		{
			return true;
		}
	}

to

Code:
	if (GET_TEAM(getTeam()).isHasTech((TechTypes)(GC.getBonusInfo((BonusTypes)m_eBonusType).getTechReveal())))
	{
			return true;
	}
 
I'm not sure that the author checks this thread anymore, but I have a major problem with this modcomp. I merged the sources with RevDCM's sources easily enough, and compiled without any problems, but I get a really bad problems in game. In game, every building or unit that used to require a specific resource(s) to be built no longer does. For example, Axeman usually requires your empire to have access to copper to be trained, but after I make the changes the SDK, they no longer require any resources to be built. This applies to buildings too. Looking through the code, I think I isolated the spots where the requirements for units and buildings where changed, but am not good enough at C++ to spot any errors. I included a little of the surrounding code so you can tell where the changes are quickly...

Where I think the Units requirements were changed: (CvCity.cpp)
Spoiler :
Code:
...		if (bRequiresBonus && bNeedsBonus)
		{
			return false;
		}

/*************************************************************************************************/
/** Afforess	Vicinity Bonus Start		 07/29/09                                            */
/**                                                                                              */
/**                                                                                              */
/*************************************************************************************************/
		bRequiresBonus = false;
		bNeedsBonus = true;

		for (iI = 0; iI < GC.getNUM_BUILDING_PREREQ_OR_BONUSES(); iI++)
		{
			if (GC.getBuildingInfo(eBuilding).getPrereqOrVicinityBonuses(iI) != NO_BONUS)
			{
				bRequiresBonus = true;

				for (int iJ = 0; iJ < NUM_CITY_PLOTS; ++iJ)
				{
					CvPlot* pLoopPlot = plotCity(getX_INLINE(), getY_INLINE(), iJ);
					if (pLoopPlot->getBonusType() == GC.getBuildingInfo(eBuilding).getPrereqOrVicinityBonuses(iI))
					{
						CvCity* pCity = GC.getMapINLINE().findCity(getX_INLINE(), getY_INLINE(), getOwnerINLINE(), NO_TEAM, false);
						if (pLoopPlot->isHasValidBonus() && pLoopPlot->isConnectedTo(pCity))
						{
			                bNeedsBonus = false;
							return true;
						}
					}
				}
				bNeedsBonus = true;
			}
		}

		if (bRequiresBonus && bNeedsBonus)
		{
			return false;
		}
/*************************************************************************************************/
/** Afforess	Vicinity Bonus End       END                                                     */
/*************************************************************************************************/
		for (iI = 0; iI < GC.getNumBuildingClassInfos(); iI++)


		{...

Where I think the building requirements were changed: (CvPlot.cpp)

Spoiler :
Code:
		...for (int iI = 0; iI < GC.getNUM_UNIT_PREREQ_OR_BONUSES(); ++iI)
		{
			if (GC.getUnitInfo(eUnit).getPrereqOrBonuses(iI) != NO_BONUS)
			{
				bRequiresBonus = true;

				if (NULL == pCity)
				{
					if (isPlotGroupConnectedBonus(getOwnerINLINE(), (BonusTypes)GC.getUnitInfo(eUnit).getPrereqOrBonuses(iI)))
					{
						bNeedsBonus = false;
						break;
					}
				}
				else
				{
					if (pCity->hasBonus((BonusTypes)GC.getUnitInfo(eUnit).getPrereqOrBonuses(iI)))
					{
						bNeedsBonus = false;
						break;
					}
				}
			}
		}

		if (bRequiresBonus && bNeedsBonus)
		{
			return false;
		}
/*************************************************************************************************/
/** Afforess	Vicinity Bonus Start		 07/29/09                                            */
/**                                                                                              */
/**                                                                                              */
/*************************************************************************************************/
		if (GC.getUnitInfo(eUnit).getPrereqVicinityBonus() != NO_BONUS)
		{
			if (NULL == pCity)
			{
				if (!isHasValidBonus())
				//if (!isPlotGroupConnectedBonus(getOwnerINLINE(), (BonusTypes)GC.getUnitInfo(eUnit).getPrereqVicinityBonus()))
				{
					return false;
				}
			}
			else
			{
				if (GC.getUnitInfo(eUnit).getPrereqVicinityBonus() != NO_BONUS)
				{
					for (int iI = 0; iI < NUM_CITY_PLOTS; ++iI)
					{
						CvPlot* pLoopPlot = plotCity(getX_INLINE(), getY_INLINE(), iI);
						if (pLoopPlot->getBonusType() == GC.getUnitInfo(eUnit).getPrereqVicinityBonus())
						{
							CvCity* pCity = GC.getMapINLINE().findCity(getX_INLINE(), getY_INLINE(), getOwnerINLINE(), NO_TEAM, false);
							if (pLoopPlot->isHasValidBonus() && pLoopPlot->isConnectedTo(pCity))
							{
								return true;
							}
						}
					}
					return false;
				}
			}
		}
		
		bRequiresBonus = false;
		bNeedsBonus = true;

		for (int iI = 0; iI < GC.getNUM_UNIT_PREREQ_OR_BONUSES(); ++iI)
		{
			if (GC.getUnitInfo(eUnit).getPrereqOrVicinityBonuses(iI) != NO_BONUS)
			{
				bRequiresBonus = true;

				if (NULL == pCity)
				{
					if (!isHasValidBonus())
					{
						bNeedsBonus = false;
						break;
					}
				}
				else
				{
					for (int iJ = 0; iJ < NUM_CITY_PLOTS; ++iJ)
					{
						CvPlot* pLoopPlot = plotCity(getX_INLINE(), getY_INLINE(), iJ);
						if (pLoopPlot->getBonusType() == GC.getUnitInfo(eUnit).getPrereqOrVicinityBonuses(iI))
						{
							CvCity* pCity = GC.getMapINLINE().findCity(getX_INLINE(), getY_INLINE(), getOwnerINLINE(), NO_TEAM, false);
							if (pLoopPlot->isHasValidBonus() && pLoopPlot->isConnectedTo(pCity))
							{
								bNeedsBonus = false;
								return true;
							}
						}
					}
					bNeedsBonus = true;
				}
			}
		}

		if (bRequiresBonus && bNeedsBonus)
		{
			return false;
		}
/*************************************************************************************************/
/** Afforess	Vicinity Bonus End       END                                                     */
/*************************************************************************************************/
	}

	return true;
}

int CvPlot::countFriendlyCulture(TeamTypes eTeam) const
{...

Can anyone with more SDK experience tell me what exactly these functions are changing to the requirements, and confirm or deny my suspicions?
 
Did you resolve this, Afforess?

No. The problem still stands. However, If you want it this modcomp, you can always merge it yourself and see if it works okay. It might have been a bad merge on my part, but I never went back and double checked.
 
I have been using this mod in a project of mine, but haven't experienced the problem you describe. So far it's worked exactly as it should. I suspect either something in RevDCM's code or an error in merging is causing it. :dunno:
 
I have been using this mod in a project of mine, but haven't experienced the problem you describe. So far it's worked exactly as it should. I suspect either something in RevDCM's code or an error in merging is causing it. :dunno:

Okay. Well, I will remerge it again. I have a lot more experience now than I did way back when.
 
I second Gaius Octavius. I just finished merging it and everything is fine... Even though some parts seemed weird to me so I rewrote them.
 
I second Gaius Octavius. I just finished merging it and everything is fine... Even though some parts seemed weird to me so I rewrote them.

Could you give me the parts you rewrote, like what seemed weird?
 
Sure...

I don't remember what the original parts were though. For clarity's sake, I will just give you the three parts I know I modified: the two about buildings in CvCity.cpp and the one about units in CvPlot.cpp:

Code:
/*************************************************************************************************/
/** VicinityBonusShqype                 Opera                   18/10/09                        **/
/*************************************************************************************************/
        if (GC.getBuildingInfo(eBuilding).getPrereqVicinityBonus() != NO_BONUS)
        {
            bool bHasVicinityBonus = false;
            for (int iI = 0; iI < NUM_CITY_PLOTS; iI++)
            {
                CvPlot* pLoopPlot = plotCity(getX_INLINE(), getY_INLINE(), iI);
				if (!pLoopPlot == NULL)
				{
					if (pLoopPlot->getBonusType() == GC.getBuildingInfo(eBuilding).getPrereqVicinityBonus())
					{
						if (pLoopPlot->isHasValidBonus() && pLoopPlot->isConnectedTo(this))
						{
							bHasVicinityBonus = true;
						}
					}
				}
            }

            if (!bHasVicinityBonus)
            {
                return false;
            }
        }
/*************************************************************************************************/
/** VicinityBonusShqype                 END                                                     **/
/*************************************************************************************************/

Code:
/*************************************************************************************************/
/** VicinityBonusShqype                 Opera                   18/10/09                        **/
/*************************************************************************************************/
        bool bRequiresVicinityBonus = false;
        bool bNeedsVicinityBonus = true;

        for (iI = 0; iI < GC.getNUM_BUILDING_PREREQ_OR_BONUSES(); iI++)
        {
            if (GC.getBuildingInfo(eBuilding).getPrereqOrVicinityBonuses(iI) != NO_BONUS)
            {
                bRequiresVicinityBonus = true;

                for (int iJ = 0; iJ < NUM_CITY_PLOTS; iJ++)
                {
                    CvPlot* pLoopPlot = plotCity(getX_INLINE(), getY_INLINE(), iJ);
					if (!pLoopPlot == NULL)
					{
						if (pLoopPlot->getBonusType() == GC.getBuildingInfo(eBuilding).getPrereqOrVicinityBonuses(iI))
						{
							if (pLoopPlot->isHasValidBonus() && pLoopPlot->isConnectedTo(this))
							{
								bNeedsVicinityBonus = false;
							}
						}
					}
                }

            }
        }

        if (bRequiresVicinityBonus && bNeedsVicinityBonus)
        {
            return false;
        }
/*************************************************************************************************/
/** VicinityBonusShqype                 END                                                     **/
/*************************************************************************************************/

Code:
/*************************************************************************************************/
/** VicinityBonusShqype                     Opera               18/10/09                        **/
/*************************************************************************************************/
        if (GC.getUnitInfo(eUnit).getPrereqVicinityBonus() != NO_BONUS)
		{
			if (NULL == pCity)
			{
                return false;
			}
			else
			{
				if (GC.getUnitInfo(eUnit).getPrereqVicinityBonus() != NO_BONUS)
				{
				    bool bHasVicinityBonus = false;
					for (int iI = 0; iI < NUM_CITY_PLOTS; ++iI)
					{
						CvPlot* pLoopPlot = plotCity(getX_INLINE(), getY_INLINE(), iI);
						if (!pLoopPlot == NULL)
						{
							if (pLoopPlot->getBonusType(pCity->getTeam()) == GC.getUnitInfo(eUnit).getPrereqVicinityBonus())
							{
								if (/**pLoopPlot->isHasValidBonus() && **/pLoopPlot->isConnectedTo(pCity))
								{
									bHasVicinityBonus = true;
								}
							}
						}
					}

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

		bool bRequiresVicinityBonus = false;
		bool bNeedsVicinityBonus = true;

		for (int iI = 0; iI < GC.getNUM_UNIT_PREREQ_OR_BONUSES(); ++iI)
		{
			if (GC.getUnitInfo(eUnit).getPrereqOrVicinityBonuses(iI) != NO_BONUS)
			{
				bRequiresVicinityBonus = true;

				if (NULL == pCity)
				{
                    return false;
				}
				else
				{
					for (int iJ = 0; iJ < NUM_CITY_PLOTS; iJ++)
					{
					    CvPlot* pLoopPlot = plotCity(getX_INLINE(), getY_INLINE(), iJ);
						if (!pLoopPlot == NULL)
						{
							if (pLoopPlot->getBonusType() == GC.getUnitInfo(eUnit).getPrereqOrVicinityBonuses(iI))
							{
								if (pLoopPlot->isHasValidBonus() && pLoopPlot->isConnectedTo(pCity))
								{
									bNeedsVicinityBonus = false;
								}
							}
						}
					}
				}
			}
		}

		if (bRequiresBonus && bNeedsBonus)
		{
			return false;
		}
/*************************************************************************************************/
/** VicinityBonusShqype                     END                                                 **/
/*************************************************************************************************/

What I did was to remove the 'return true' statements as I was unsure they were a good idea, seeing as the whole functions seemed to work only by returning false if a condition wasn't met.
 
Okay. While I was remerging, I think I saw what I did wrong. I clipped off a bNeedsResource = true; assignment, which could have caused my issues. I'm recompiling, we'll see.
 
I seem to still have that bug. By any chance, is this code in CvCity meant to be merged?
Code:
//Shqype Bonus Vicinity Start
//	if (GC.getUnitInfo(eUnit).getPrereqVicinityBonus() != NO_BONUS)
//	{
//		for (int iI = 0; iI < NUM_CITY_PLOTS; ++iI)
//		{
//			CvPlot* pLoopPlot = plotCity(getX_INLINE(), getY_INLINE(), iI);
			//if (pLoopPlot->getBonusType() == GC.getUnitInfo(eUnit).getPrereqVicinityBonus())
			//{
//			if (pLoopPlot->isHasValidBonus((BonusTypes)GC.getUnitInfo(eUnit).getPrereqVicinityBonus()))
				//if (pLoopPlot->isHasValidBonus())
//			{
//				return true;
//			}
			//}
//		}
//		return false;
//	}
//Shqype Vicinity Bonus End
 
No, you shouldn't merge this one. I got it Shqype first went this road for units but then chose to use CvPlot::canTrain(); he may have forgotten to remove this snippet.
 
No, you shouldn't merge this one. I got it Shqype first went this road for units but then chose to use CvPlot::canTrain(); he may have forgotten to remove this snippet.

Okay, well that doesn't help me any, because I never did merge it. I was just curious if it was needed.
 
Strange... Are you still using DCM components, or did you merge it into a clean BTS SDK? I've been having some odd issues with DCM in 3.19 myself -- every so often in the game, some kind of infinite loop pops up and prevents the end-of-turn AI processes from completing. It's weird because I am using exactly the same code that I used in 3.13 and 3.17, yet the problem never happened then.
 
Strange... Are you still using DCM components, or did you merge it into a clean BTS SDK? I've been having some odd issues with DCM in 3.19 myself -- every so often in the game, some kind of infinite loop pops up and prevents the end-of-turn AI processes from completing. It's weird because I am using exactly the same code that I used in 3.13 and 3.17, yet the problem never happened then.


I fixed it. It turned to be WoC's fault. I looked at what WoC changed with Array's of Arrays, and cloned their changes and got it working.

RevDCM's SDK has always been as as stable as a rock for me. It's just my additions that cause me trouble.
 
Sup guys? Good to see you've been making use of this :)
 
I like this modcomp. However, I would like to see if it is at all possible to lessen checking of vicinity for resources, especially in the fat cross that doesn't have any resources it is looking to expand on in this modcomp. That may speed up turn time a bit.

What I mean is: the computer check the fat cross surrounding the city and see if there is/are resources to expand on in buildings. If not, then the code should stop completely from checking that fat-cross forever in this game. Is that possible?
 
Back
Top Bottom