[Religion and Revolution]: Horses Produced on Plots

The basic implementation of the horse production per plot with percentage is done. If there are no horses in the city, the rancher will take another profession.

For reference, these are the code changes for the horse plot percentage production (in red):

CvCity.cpp

Code:
void CvCity::setYieldStored(YieldTypes eYield, int iValue)
{
	FAssertMsg(eYield >= 0, "eYield expected to be >= 0");
	FAssertMsg(eYield < NUM_YIELD_TYPES	, "eYield expected to be < NUM_YIELD_TYPES");
	FAssert(iValue >= 0 || eYield == YIELD_FOOD);

	int iChange = iValue - getYieldStored(eYield);
	if (iChange != 0)
	{
//VET NewCapacity - begin 3/9
		if ((eYield != YIELD_FOOD) && GC.getYieldInfo(eYield).isCargo())
			{changeTotalYieldStored(iChange);}
//VET NewCapacity - end 3/9
		m_aiYieldStored[eYield] = iValue;

		if (!AI_isWorkforceHack())
		{
			checkCompletedBuilds(eYield, iChange);
		}

		GET_PLAYER(getOwnerINLINE()).changePower(GC.getYieldInfo(eYield).getPowerValue() * iChange);
		GET_PLAYER(getOwnerINLINE()).changeAssets(GC.getYieldInfo(eYield).getAssetValue() * iChange);
		area()->changePower(getOwnerINLINE(), GC.getYieldInfo(eYield).getPowerValue() * iChange);

		if (getTeam() == GC.getGameINLINE().getActiveTeam())
		{
			setBillboardDirty(true);

			if (getOwnerINLINE() == GC.getGameINLINE().getActivePlayer())
			{
				gDLL->getInterfaceIFace()->setDirty(ResourceTable_DIRTY_BIT, true);
				gDLL->getInterfaceIFace()->setDirty(CitizenButtons_DIRTY_BIT, true);
				gDLL->getInterfaceIFace()->setDirty(CityScreen_DIRTY_BIT, true);
			}
		}
[COLOR="Red"]		//R&R
		//Androrc Livestock Breeding
		if (GC.getYieldInfo(eYield).isLivestock())
		{
			for (int iI = 0; iI < NUM_CITY_PLOTS; iI++)
			{
				CvPlot* pLoopPlot = getCityIndexPlot(iI);

				if (pLoopPlot != NULL)
				{
					if (pLoopPlot->getWorkingCity() == this)
					{
						pLoopPlot->updateYield(true);
						if (getYieldStored(eYield) <= 0 && getUnitWorkingPlot(pLoopPlot) != NULL && eYield == GC.getProfessionInfo(getUnitWorkingPlot(pLoopPlot)->getProfession()).getYieldProduced())
						{
							getUnitWorkingPlot(pLoopPlot)->setColonistLocked(false);
							clearUnitWorkingPlot(pLoopPlot);
						}
					}
				}
			}
		}
		//Androrc End
		//R&R End[/COLOR]
	}
}

CvInfos.cpp

Code:
CvYieldInfo::CvYieldInfo() :
m_iChar(0),
m_iBuyPriceLow(0),
m_iBuyPriceHigh(0),
// TAC - Price Limits - Ray - START
m_iBuyPriceMin(0),
// TAC - Price Limits - Ray - END
m_iSellPriceDifference(0),
m_iPriceChangeThreshold(0),
m_iPriceCorrectionPercent(0),
m_iNativeBuyPrice(0),
m_iNativeSellPrice(0),
m_iNativeConsumptionPercent(0),
m_iNativeHappy(0),
m_iHillsChange(0),
m_iPeakChange(0),
m_iLakeChange(0),
m_iCityChange(0),
m_iMinCity(0),
m_iAIWeightPercent(0),
m_iAIBaseValue(0),
m_iNativeBaseValue(0),
m_iColorType(NO_COLOR),
m_iUnitClass(NO_UNITCLASS),
m_iTextureIndex(-1),
m_iWaterTextureIndex(-1),
m_iPowerValue(0),
m_iAssetValue(0),
//R&R
[COLOR="Red"]//Androrc Livestock Breeding
//m_bCargo(false)
m_bCargo(false),
m_bLivestock(false)
//Androrc End
[/COLOR]//R&R End
{
}

Code:
[COLOR="Red"]//R&R
//Androrc Livestock Breeding
bool CvYieldInfo::isLivestock() const
{
	return m_bLivestock;
}
//Androrc End
//R&R End
[/COLOR]

Code:
bool CvYieldInfo::read(CvXMLLoadUtility* pXML)
{
	CvString szTextVal;
	if (!CvInfoBase::read(pXML))
	{
		return false;
	}
	pXML->GetChildXmlValByName(&m_iBuyPriceLow, "iBuyPriceLow");
	pXML->GetChildXmlValByName(&m_iBuyPriceHigh, "iBuyPriceHigh");
	// TAC - Price Limits - Ray - START
	pXML->GetChildXmlValByName(&m_iBuyPriceMin, "iBuyPriceMin");
	// TAC - Price Limits - Ray - END
	pXML->GetChildXmlValByName(&m_iSellPriceDifference, "iSellPriceDifference");
	pXML->GetChildXmlValByName(&m_iPriceChangeThreshold, "iPriceChangeThreshold");
	pXML->GetChildXmlValByName(&m_iPriceCorrectionPercent, "iPriceCorrectionPercent");
	pXML->GetChildXmlValByName(&m_iNativeBuyPrice, "iNativeBuyPrice");
	pXML->GetChildXmlValByName(&m_iNativeSellPrice, "iNativeSellPrice");
	pXML->GetChildXmlValByName(&m_iNativeConsumptionPercent, "iNativeConsumptionPercent");
	pXML->GetChildXmlValByName(&m_iNativeHappy, "iNativeHappy");
	pXML->GetChildXmlValByName(&m_iHillsChange, "iHillsChange");
	pXML->GetChildXmlValByName(&m_iPeakChange, "iPeakChange");
	pXML->GetChildXmlValByName(&m_iLakeChange, "iLakeChange");
	pXML->GetChildXmlValByName(&m_iCityChange, "iCityChange");
	pXML->GetChildXmlValByName(&m_iMinCity, "iMinCity");
	pXML->GetChildXmlValByName(&m_iAIWeightPercent, "iAIWeightPercent");
	pXML->GetChildXmlValByName(&m_iAIBaseValue, "iAIBaseValue");
	pXML->GetChildXmlValByName(&m_iNativeBaseValue, "iNativeBaseValue");
	pXML->GetChildXmlValByName(szTextVal, "ColorType");
	m_iColorType = pXML->FindInInfoClass(szTextVal);
	pXML->GetChildXmlValByName(szTextVal, "UnitClass");
	m_iUnitClass = pXML->FindInInfoClass(szTextVal);
	pXML->GetChildXmlValByName(&m_iTextureIndex, "iTextureIndex");
	pXML->GetChildXmlValByName(&m_iWaterTextureIndex, "iWaterTextureIndex");
	pXML->GetChildXmlValByName(&m_iPowerValue, "iPower");
	pXML->GetChildXmlValByName(&m_iAssetValue, "iAsset");
	pXML->GetChildXmlValByName(&m_bCargo, "bCargo");
[COLOR="Red"]	//R&R
	//Androrc Livestock Breeding
	pXML->GetChildXmlValByName(&m_bLivestock, "bLivestock", false);
	//Androrc End
	//R&R End
[/COLOR]	pXML->GetChildXmlValByName(m_szIcon, "Icon");
	// KJ Jansson addon for Multiple Professions per Building modcomp by Androrc the Orc START
	pXML->GetChildXmlValByName(m_szCombiIcon, "CombiIcon");
	// KJ Jansson addon for Multiple Professions per Building modcomp by Androrc the Orc END
	pXML->GetChildXmlValByName(m_szHightlightIcon, "HightlightIcon");

	return true;
}

CvInfos.h

Code:
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
//
//  class : CvYieldInfo
//
//  DESC:
//
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
class CvYieldInfo :
	public CvInfoBase
{
	//---------------------------------------PUBLIC INTERFACE---------------------------------
public:
	DllExport CvYieldInfo();
	DllExport virtual ~CvYieldInfo();
	DllExport int getChar() const;
	DllExport void setChar(int i);
	DllExport const char* getIcon() const;
// KJ Jansson addon for Multiple Professions per Building modcomp by Androrc the Orc START
	DllExport const char* getCombiIcon() const;
// KJ Jansson addon for Multiple Professions per Building modcomp by Androrc the Orc END
	DllExport const char* getHighlightIcon() const;
	DllExport int getBuyPriceLow() const;
	DllExport int getBuyPriceHigh() const;
	// TAC - Price Limits - Ray - START
	DllExport int getMinimumBuyPrice() const;
	// TAC - Price Limits - Ray - END
	DllExport int getSellPriceDifference() const;
	DllExport int getPriceChangeThreshold() const;
	DllExport int getPriceCorrectionPercent() const;
	DllExport int getNativeBuyPrice() const;
	DllExport int getNativeSellPrice() const;
	DllExport int getNativeConsumptionPercent() const;
	DllExport int getNativeHappy() const;
	DllExport int getHillsChange() const;
	DllExport int getPeakChange() const;
	DllExport int getLakeChange() const;
	DllExport int getCityChange() const;
	DllExport int getMinCity() const;
	DllExport int getAIWeightPercent() const;
	DllExport int getAIBaseValue() const;
	DllExport int getNativeBaseValue() const;
	DllExport int getColorType() const;
	DllExport int getUnitClass() const;
	DllExport int getTextureIndex() const;
	DllExport int getWaterTextureIndex() const;
	DllExport int getPowerValue() const;
	DllExport int getAssetValue() const;

	DllExport bool isCargo() const;
	//R&R
[COLOR="Red"]	//Androrc Livestock Breeding
	DllExport bool isLivestock() const;
	//Androrc End
[/COLOR]	//R&R End

	DllExport bool read(CvXMLLoadUtility* pXML);
	//---------------------------------------PROTECTED MEMBER VARIABLES---------------------------------
protected:
	int m_iChar;
	CvString m_szIcon;
// KJ Jansson addon for Multiple Professions per Building modcomp by Androrc the Orc START
	CvString m_szCombiIcon;
// KJ Jansson addon for Multiple Professions per Building modcomp by Androrc the Orc END
	CvString m_szHightlightIcon;
	int m_iBuyPriceLow;
	int m_iBuyPriceHigh;
	// TAC - Price Limits - Ray - START
	int m_iBuyPriceMin;
	// TAC - Price Limits - Ray - END
	int m_iSellPriceDifference;
	int m_iPriceChangeThreshold;
	int m_iPriceCorrectionPercent;
	int m_iNativeBuyPrice;
	int m_iNativeSellPrice;
	int m_iNativeConsumptionPercent;
	int m_iNativeHappy;
	int m_iHillsChange;
	int m_iPeakChange;
	int m_iLakeChange;
	int m_iCityChange;
	int m_iMinCity;
	int m_iAIWeightPercent;
	int m_iAIBaseValue;
	int m_iNativeBaseValue;
	int m_iColorType;
	int m_iUnitClass;
	int m_iTextureIndex;
	int m_iWaterTextureIndex;
	int m_iPowerValue;
	int m_iAssetValue;

	bool m_bCargo;
	//R&R
[COLOR="Red"]	//Androrc Livestock Breeding
	bool m_bLivestock;
	//Androrc End
[/COLOR]	//R&R End
};

CvPlot.cpp

Code:
int CvPlot::calculatePotentialYield(YieldTypes eYield, PlayerTypes ePlayer, ImprovementTypes eImprovement, bool bIgnoreFeature, RouteTypes eRoute, UnitTypes eUnit, bool bDisplay) const
{
	TeamTypes eTeam = ((ePlayer != NO_PLAYER) ? GET_PLAYER(ePlayer).getTeam() : NO_TEAM);

	if (getTerrainType() == NO_TERRAIN)
	{
		return 0;
	}

	//TAC Whaling, ray
	/*if (!isPotentialCityWork())
	{
		return 0;
	}*/

	int iYield = calculateNatureYield(eYield, eTeam, bIgnoreFeature);

	if (eImprovement != NO_IMPROVEMENT)
	{
		iYield += calculateImprovementYieldChange(eImprovement, eYield, ePlayer);
	}

	if (eRoute != NO_ROUTE)
	{
		if(iYield > 0)
		{
			iYield += GC.getRouteInfo(eRoute).getYieldChange(eYield);
		}
	}

	if (ePlayer != NO_PLAYER)
	{
		if (isWater())
		{
			if (!isImpassable())
			{
				iYield += GET_PLAYER(ePlayer).getSeaPlotYield(eYield);

				CvCity* pWorkingCity = getWorkingCity();
				if (pWorkingCity != NULL)
				{
					if (!bDisplay || pWorkingCity->isRevealed(eTeam, false))
					{
						iYield += pWorkingCity->getSeaPlotYield(eYield);
					}
				}
			}
		}

		if (isRiver())
		{
			if (!isImpassable())
			{
				CvCity* pWorkingCity = getWorkingCity();
				if (NULL != pWorkingCity)
				{
					if (!bDisplay || pWorkingCity->isRevealed(eTeam, false))
					{
						iYield += pWorkingCity->getRiverPlotYield(eYield);
					}
				}
			}
		}

		CvCity* pCity = getPlotCity();
		if (pCity != NULL)
		{
			if (!bDisplay || pCity->isRevealed(eTeam, false))
			{
				//city plot extra
				if (iYield > 0 || !GC.getYieldInfo(eYield).isCargo())
				{
					iYield += GC.getYieldInfo(eYield).getCityChange();
					iYield += GET_PLAYER(pCity->getOwnerINLINE()).getCityExtraYield(eYield);
				}

				if (eYield != YIELD_FOOD && GC.getYieldInfo(eYield).isCargo())
				{
					//cities get food and one other yield
					YieldTypes bestYield = NO_YIELD;
					int bestOutput = 0;
					for (int i = 0; i < NUM_YIELD_TYPES; i++)
					{
						//ignore food and lumber
						if ((i != YIELD_FOOD) && (i != YIELD_LUMBER))
						{
							int natureYield = calculateNatureYield((YieldTypes) i, pCity->getTeam(), false);
							if (natureYield > bestOutput)
							{
								bestYield = (YieldTypes) i;
								bestOutput = natureYield;
							}
						}
					}

					if (eYield != bestYield)
					{
						iYield = 0;
					}
				}

				iYield = std::max(iYield, GC.getYieldInfo(eYield).getMinCity());
			}
		}
	}

	if (eUnit != NO_UNIT)
	{
		if (iYield > 0)
		{
			if (isValidYieldChanges(eUnit))
			{
				iYield += GC.getUnitInfo(eUnit).getYieldChange(eYield);

				if (getBonusType() != NO_BONUS)
				{
					if (GC.getBonusInfo(getBonusType()).getYieldChange(eYield) > 0)
					{
						iYield += GC.getUnitInfo(eUnit).getBonusYieldChange(eYield);
					}
				}
			}
		}
	}

[COLOR="Red"]	//R&R
	//Androrc Livestock Breeding
	CvCity* pWorkingCity = getWorkingCity();
	if (pWorkingCity != NULL)
	{
		if (GC.getYieldInfo(eYield).isLivestock())
		{
			if (iYield > 0 && pWorkingCity->getYieldStored(eYield) > 0)
			{
				iYield = std::min(iYield, pWorkingCity->getYieldStored(eYield) * iYield / 100);
				if (iYield < 1)
				{
					iYield = 1;
				}
			}
			else
			{
				iYield = 0;
			}
		}
	}
	//Androrc End
	//R&R End
[/COLOR]
	iYield += GC.getGameINLINE().getPlotExtraYield(m_iX, m_iY, eYield);

	if (ePlayer != NO_PLAYER)
	{
		if (GET_PLAYER(ePlayer).getExtraYieldThreshold(eYield) > 0)
		{
			if (iYield >= GET_PLAYER(ePlayer).getExtraYieldThreshold(eYield))
			{
				iYield += GC.getDefineINT("EXTRA_YIELD");
			}
		}
	}

	int iModifier = 100;
	if (eUnit != NO_UNIT)
	{
		iModifier += GC.getUnitInfo(eUnit).getYieldModifier(eYield);
	}

	return std::max(0, (iYield * iModifier) / 100);
}

Some changes to the XML were also done:

CIV4ProfessionInfos.xml

Code:
		<ProfessionInfo>
			<Type>PROFESSION_RANCHER</Type>
			<Description>TXT_KEY_PROFESSION_RANCHER</Description>
			<Civilopedia>TXT_KEY_UNIT_RANCHER_PEDIA</Civilopedia>
			<Strategy>TXT_KEY_PROFESSION_RANCHER_STRATEGY</Strategy>
			<Help/>
			<Combat>NONE</Combat>
			<DefaultUnitAI>NONE</DefaultUnitAI>
			<YieldProduced>YIELD_HORSES</YieldProduced>
[COLOR="Red"]			<YieldConsumed>NONE</YieldConsumed>
			<SpecialBuilding>NONE</SpecialBuilding>
			<bWorkPlot>1</bWorkPlot>
[/COLOR]			<bCitizen>1</bCitizen>
			<bWater>0</bWater>
			<bScout>0</bScout>
			<bCityDefender>0</bCityDefender>
			<bCanFound>0</bCanFound>
			<bUnarmed>0</bUnarmed>
			<bNoDefensiveBonus>0</bNoDefensiveBonus>
			<iCombatChange>0</iCombatChange>
			<iMovesChange>0</iMovesChange>
			<iWorkRate>0</iWorkRate>
			<iMissionaryRate>0</iMissionaryRate>
			<iPower>0</iPower>
			<iAsset>0</iAsset>
			<YieldEquipedNums/>
			<FreePromotions/>
			<Button>,Art/Interface/Buttons/Civilizations/Colonization_Civilizations_Leaders.dds,1,9</Button>
			<bUseLbD>1</bUseLbD>
			<ExpertUnit>UNITCLASS_RANCHER</ExpertUnit>
			<iLbDLearnLevel>1</iLbDLearnLevel>
		</ProfessionInfo>

CIV4TerrainSchema.xml

Code:
	<ElementType name="bLivestock" content="textOnly" dt:type="boolean"/>

Code:
	<ElementType name="YieldInfo" content="eltOnly">
		<element type="Type"/>
		<element type="Description"/>
		<element type="Civilopedia"/>
		<element type="bCargo"/>
[COLOR="Red"]		<element type="bLivestock" minOccurs="0"/>
[/COLOR]		<element type="iBuyPriceLow"/>
		<element type="iBuyPriceHigh"/>
		<element type="iBuyPriceMin"/>
		<element type="iSellPriceDifference"/>
		<element type="iPriceChangeThreshold"/>
		<element type="iPriceCorrectionPercent"/>
		<element type="iNativeBuyPrice"/>
		<element type="iNativeSellPrice"/>
		<element type="iNativeConsumptionPercent"/>
		<element type="iNativeHappy"/>
		<element type="iHillsChange"/>
		<element type="iPeakChange"/>
		<element type="iLakeChange"/>
		<element type="iCityChange"/>
		<element type="iMinCity"/>
		<element type="iAIWeightPercent"/>
		<element type="iAIBaseValue"/>
		<element type="iNativeBaseValue"/>
		<element type="iPower"/>
		<element type="iAsset"/>
		<element type="ColorType"/>
		<element type="UnitClass"/>
		<element type="iTextureIndex"/>
		<element type="iWaterTextureIndex"/>
		<element type="Icon"/>
		<element type="CombiIcon" minOccurs="0"/>
		<element type="HighlightIcon"/>
		<element type="Button"/>
	</ElementType>

CIV4YieldInfos.xml

Code:
  <YieldInfo>
   <Type>YIELD_HORSES</Type>
   <Description>TXT_KEY_YIELD_HORSES</Description>
   <Civilopedia>TXT_KEY_YIELD_HORSES_PEDIA</Civilopedia>
   <bCargo>1</bCargo>
[COLOR="Red"]   <bLivestock>1</bLivestock>
[/COLOR]   <iBuyPriceLow>4</iBuyPriceLow>
   <iBuyPriceHigh>6</iBuyPriceHigh>
   <iBuyPriceMin>1</iBuyPriceMin>
   <iSellPriceDifference>2</iSellPriceDifference>
   <iPriceChangeThreshold>600</iPriceChangeThreshold>
   <iPriceCorrectionPercent>1</iPriceCorrectionPercent>
   <iNativeBuyPrice>10</iNativeBuyPrice>
   <iNativeSellPrice>30</iNativeSellPrice>
   <iNativeConsumptionPercent>100</iNativeConsumptionPercent>
   <iNativeHappy>5</iNativeHappy>
   <iHillsChange>0</iHillsChange>
   <iPeakChange>0</iPeakChange>
   <iLakeChange>0</iLakeChange>
   <iCityChange>0</iCityChange>
   <iMinCity>0</iMinCity>
   <iAIWeightPercent>100</iAIWeightPercent>
   <iAIBaseValue>3</iAIBaseValue>
   <iNativeBaseValue>0</iNativeBaseValue>
   <iPower>1</iPower>
   <iAsset>1</iAsset>
   <ColorType>COLOR_YIELD_FOOD</ColorType>
   <UnitClass>UNITCLASS_HORSES</UnitClass>
[COLOR="Red"]   <iTextureIndex>33</iTextureIndex>
[/COLOR]   <iWaterTextureIndex>-1</iWaterTextureIndex>
   <Icon>,Art/Interface/Buttons/Unit_Resource_Colonization_Atlas.dds,7,15</Icon>
   <HighlightIcon>,Art/Interface/Screens/City_Management/Colonization_Yield_Highlight_Icon_Atlas.dds.dds,7,2</HighlightIcon>
   <Button>,Art/Interface/Buttons/Unit_Resource_Colonization_Atlas.dds,7,2</Button>
  </YieldInfo>

The changed files can be gotten here:

http://dl.dropbox.com/u/1732902/Colonization/Religion and Revolution/CvCity.cpp
http://dl.dropbox.com/u/1732902/Colonization/Religion and Revolution/CvInfos.cpp
http://dl.dropbox.com/u/1732902/Colonization/Religion and Revolution/CvInfos.h
http://dl.dropbox.com/u/1732902/Colonization/Religion and Revolution/CvPlot.cpp
http://dl.dropbox.com/u/1732902/Colonization/Religion and Revolution/CIV4ProfessionInfos.xml
http://dl.dropbox.com/u/1732902/Colonization/Religion and Revolution/CIV4TerrainSchema.xml
http://dl.dropbox.com/u/1732902/Colonization/Religion and Revolution/CIV4YieldInfos.xml

The percentage production for yields can be turned on and off for a particular yield through the bLivestock field on CIV4YieldInfos.xml (this field isn't necessary for every yield entry - when it is absent in the xml, it is automatically interpreted by the game to be false).

CIV4TerrainInfos.xml also needs to be modified. Just set the amount for YIELD_HORSES in <Yields> for the correct terrains and it will become the percentage of the production. This is the formula for the percentage:

Plot Yield + River Increase + Improvement Increase + Unit Type Bonus

Then, it is applied to the amount of horses stored in the city. If there are any horses stored in the city, at least 1 horse will be produced by the rancher. The maximum horse production is the percentage number itself; a rancher with a percentage of 3% will as such produce at maximum 3 horses (in other words, after you get 100 horses stored in your city, you don't get any additional horse production from having more of them stored).
 
@Androrc:

I have a few questions. :)

1. Did you create a second profession ?
(Because we still need the old one for Natives.)

2. We said, there is not Plot-Base-Yield without the Improvement.
Will this be the case ?

3. Did you consider the Bonus-Ressource Horses ?

4. Could you create a fully functional Preview (without AI of course) and upload it so we can take a look ?
(If you can't use SVN you could do it somewhere else, but please send the link as private message then. :thumbsup:)
 
@Androrc:

I have a few questions. :)

1. Did you create a second profession ?
(Because we still need the old one for Natives.)

I forgot about that :p

2. We said, there is not Plot-Base-Yield without the Improvement.
Will this be the case ?

Yes, if in the xml you make the improvement give out horses but terrains don't give out any.

3. Did you consider the Bonus-Ressource Horses ?

Yes. A horse bonus resource if added would increase the % of production and therefore the maximum production as well.

4. Could you create a fully functional Preview (without AI of course) and upload it so we can take a look ?
(If you can't use SVN you could do it somewhere else, but please send the link as private message then. :thumbsup:)

I'm not exactly sure I understand. By compiling the SDK files I put there and using the xml (and adding an entry for the horse ranch improvement, and make it produce horses) would make it testable. Do you want me to send you my already-compiled DLL with this feature, or...?
 
I'm not exactly sure I understand. By compiling the SDK files I put there and using the xml (and adding an entry for the horse ranch improvement, and make it produce horses) would make it testable. Do you want me to send you my already-compiled DLL with this feature, or...?

I thought you already created a fully fucntional version to test it and could upload that.
(I simply would have liked to do some basic test first. Especially because of Yields display on Map.)

But is ok. :)
I will integrate all of your changes in XML, add the rest and create the base feature.
(At the weekend.)

Then I will upload it to SVN and we can start discussing / working on AI. :goodjob:
 
I thought you already created a fully fucntional version to test it and could upload that.
(I simply would have liked to do some basic test first. Especially because of Yields display on Map.)

That would mean uploading the whole Religion and Revolution along with it, it would be easier to apply the SDK and XML changes to R&R.

But is ok. :)
I will integrate all of your changes in XML, add the rest and create the base feature.
(At the weekend.)

Then I will upload it to SVN and we can start discussing / working on AI. :goodjob:

Great :)
 
I have implemented base version of this feature using Androrc's code and the graphics from KJ.

@both: :goodjob:

However I have made changes to the last concept:
(Because of AI.)

1. Yield Horses is only available on Bonus Horses.

2. Improvement Horse Pasture can only be built on Bonus Horses.

3. Bonus Horses is relatively common, so it should be no problem to get reasonable horse production.
(I balanced that in XML.)

4. Natives use "percentual breeding" just like Europeans and Kings.

5. The buildings "Stable" and "Large Stable" have not been removed.
(Since Natives cannot use Improvements, their equivalent of Stable works a little better.)

However you cannot have colonists working in them.
They simply give a percentual bonus on horse breeding.
(Explanation: Stables grant protection to your horses during long cold winters and a secured environment for your horses to give birth.)

The rest is still the same:

Profession Rancher is a "Plot"-Profession requiring horses to be stored in City.

Breeding of horses on plot will be calculated by percent of existing horses with min and max values.

Specialist "Experienced Rancher" and all other units stay as they are.
(Considering Boni and Mail on Horse Production.)

Bonus Horses will give increase (100%) on horse production.
It will be generated on Plains, Grassland and Savannah (only flatlands).

River will give another percentual increase (50%).

All important factors can be balanced in XML.

Thus the following is granted:

1. AI (Europeans, Kings) should know how to handle the new Improvement.
2. Sufficient horse production can be achieved.
3. Natives cannot produce horses before actually having acquired some from Europeans.
4. Once Natives have acquired horses, they can produce them.
5. Natives, Europeans and Kings basically use the same mechanism.

This still needs to be done:

We need to teach AI, to keep sufficient amounts of horses in towns that could use them for horse production.
(But only in these, it would not make sense to have horses in AI cities, that cannot use them.)

We need to check, if AI builds the improvement properly or if it gets confused by the percent calculation.
(AI should build Improvement Horse pasture on Bonus Horses, even if it currently does not have horses in city.)

After we have done that, the feature should be fully implemented. :thumbsup:

With the changed concept, we should drastically have lowered implementation efforts and risks.

Feedback ?
(Is everybody ok with the changes I did ?)
 
Very good :)

I really like the changes to the natives.

About the AI changes, I imagine the particular code we need to change is in CvUnitAI (for AI ships and wagons to decide which goods to load or not, and for units to choose which profession they prefer).

The Horse bonus I think would be more intuitive if it were named "Prime Pasture", with the improvement being called "Horse Ranch". That way it would be clearer that the bonus means a very good place for breeding horses, rather than horses actually being there.
 
Very good :)

Great. :)

----------------------

Should we then start working on improving AI then ?

These are the 2 points I believe we should work on:

We need to teach AI, to keep sufficient amounts of horses in towns that could use them for horse production.
(But only in these, it would not make sense to have horses in AI cities, that cannot use them. Meaning not having Bonus on surrounding plot.)

We need to check, if AI builds the improvement properly or if it gets confused by the percent calculation.
(AI should build Improvement Horse pasture on Bonus Horses, even if it currently does not have horses in city.)

Would it be possible if you take a look at both aspects ?
(Thus I could continue working on "New Native Nations" or other open topics.)

----------------------

About the AI changes, I imagine the particular code we need to change is in CvUnitAI (for AI ships and wagons to decide which goods to load or not, and for units to choose which profession they prefer).

Yes I think so, too. :thumbsup:
Both aspects "enough horses stored" and "building proper improvement" should be in CvUnitAI.

The Horse bonus I think would be more intuitive if it were named "Prime Pasture", with the improvement being called "Horse Ranch". That way it would be clearer that the bonus means a very good place for breeding horses, rather than horses actually being there.

Ok to me. :)
(I will wait a little with renaming, because maybe colonialfan - as Native English speaker - has another suggestion.)
 
Technically this feature should be fully implemented now. :)

Eventually we could improve some texts however.
 
Actually I don't like this (sorry).

First a history of horse production:

#Col Vanilla - horses were too cheap in Europe, everyone bought them as needed and resold them to natives for a profit. People created a mega ranch late in the game to produce horses for WOI and transported them in wagons to the battle zones.

#Col Vanilla + patch - horses more expensive in Europe, players had to set up own ranch earlier in the game, but usually expanded this during the game to mega level, still transporting horses to where they were needed.

#TAC2 - horses still expensive in Europe (maybe moreso?), but players need more horses throughout the game for wagons, plus horses need to be produced in more locations because transport was made more difficult. But still some of these ranches are upscaled to mega level late in the game for warhorses.

#RAR1:
- move to percentage breeding (this isn't really an issue, providing warehouse / transport operation is suitable),
- can only create horses on horse bonus tiles (now the map chooses where player can create horses, whereas previously this had been completely at discretion of player - and noting that Europeans had all knowledge needed to breed horses, and in fact the horses would do it themselves, the only real issues are to provide food and make sure the horses don't run away),
- maximum production per turn is capped at 16 horses per turn (bonus tile + expert rancher + big ranch + 50% from rebel sentiment), and I think this only needs about 150 horses in warehouse, the extra ones don't give you any benefit.

OK, my issues:
- I want to produce horses in more locations / from more tiles. I usually end up with more expert ranchers than I have horse bonus tiles. And I think this is more than balance (i.e. making horse bonus tiles more frequent), I think the concept of only being able to create horses from bonus tiles isn't good. Elsewhere in the game bonus resources mean extra, not only.
- For example if I have the bonus tile and a ranch / rancher, why shouldn't I also be able to create horse pasture on another tile at that settlement to take advantage of the transport system I have already in place.
- And why shouldn't I be able to produce at least some horses at a settlement that doesn't have a horse bonus tile at all?

- I want to produce more horses per turn, particularly late in the game. I have spare expert ranchers, more horses in the warehouse than 150, and more flat food producing tiles than I need, but I can't do anything except buy more horses from europe or go to war with a neighbour for one of their horse bonus tiles.

I think this is more restrictive than the previous versions of the game, but for what purpose? I don't recall anyone having an objective of wanting to make horses less available when we started talking about this.

Suggestions / Questions:
- Is it really a problem to create horse pasture on tiles that don't have horse bonus?
- If there is a problem is it a coding issue, or is it just that we think the AI can't manage it?
- Can we do something else to increase max production at a settlement - e.g. maybe the max percentage cap increases if you are willing to give up 5 food units per turn at that settlement (i.e. enabling you to get benefit from more than 150 horses).
 
Actually I don't like this (sorry).

Nothing to be sorry for. :)

- I want to produce horses in more locations / from more tiles. I usually end up with more expert ranchers than I have horse bonus tiles. And I think this is more than balance (i.e. making horse bonus tiles more frequent), I think the concept of only being able to create horses from bonus tiles isn't good. Elsewhere in the game bonus resources mean extra, not only.
- For example if I have the bonus tile and a ranch / rancher, why shouldn't I also be able to create horse pasture on another tile at that settlement to take advantage of the transport system I have already in place.
- And why shouldn't I be able to produce at least some horses at a settlement that doesn't have a horse bonus tile at all?
- I want to produce more horses per turn, particularly late in the game. I have spare expert ranchers, more horses in the warehouse than 150, and more flat food producing tiles than I need, but I can't do anything except buy more horses from europe or go to war with a neighbour for one of their horse bonus tiles.

Thanks for the feedback. :thumbsup:
It really is valuable.

Suggestions / Questions:
- Is it really a problem to create horse pasture on tiles that don't have horse bonus?
- If there is a problem is it a coding issue, or is it just that we think the AI can't manage it?

As I said, AI needs to be able to handle this feature.
The biggest problem in coding new complex features really is AI.
We can not implement an important feature that human players understand well and AI does not understand.

However I think I might have a solution. :)
(Give me some time to think about it and maybe even do a test implementation, before I present.)
 
As I said, AI needs to be able to handle this feature.
The biggest problem in coding new complex features really is AI.
We can not implement an important feature that human players understand well and AI does not understand.
I agree that its most important to have a simple and straightforwardly implemented feature the AI and players can easily understand. Its best to try to avoid a whole new AI system that is specific to new details about Horses, even if we think it works at first it will probably encounter lots of unpredictable situations where it breaks down.

Percentage breeding doesnt matter to me much, and may not add tons of new interest to the game compared to the risk the AI can't understand it completely in most situations. If horses breed within several years, then once you have access to a reasonable number of horses to breed with, realistically their long term breeding was not limited by the specific horse population you had currently, but limited by the amount of pasture available .

So as was mentioned earlier, maybe it's best to let Horses be a regular yield that can be produced by the Rancher profession, and a unit working in the Rancher profession requires Horses (50 or so) to breed with.
 
So as was mentioned earlier, maybe it's best to let Horses be a regular yield that can be produced by the Rancher profession, and a unit working in the Rancher profession requires Horses (50 or so) to breed with.

But I can tell you:
If we implement this (and spend lots of effort into AI) and some team member will say later on
"Oh, I think I have changed my mind and would like the old system back.",
I will go crazy. :trouble: ;)

Hmmm ...
I really would not like to remove "percentual breeding" now, after Androrc and myself have put so much time into this. :(
However, if this continues to cause us problems, it might really be the best solution ...

Give me some time (until the weekend) to do a test implementation of the new solution I have in mind. :)
(If it is working, I will present my idea. :thumbsup:)

Edit:

The current challenges I see are the following:

Spoiler :

1. With "percentual breeding" you only have / see yield horses on a plot, if you also have horses stored in the city.
Currently precondition for building improvement pasture is "bonus horses exists", which is not problematic.
If we change precondition for building improvement pasture to "yield horses on plot",
you can only build the improvement pasture, if you have horses in the city.
(This might be pretty hard for players to understand ...)

Spoiler :

Eventually precondition for building improvement pasture is "2 yield food on plot" will solve this problem.
But I have to check side effects for logic here, too.


2. On the contrary if horses were available on every (flat) plot and not only on "bonus horses",
then AI might build way too many improvements "pasture" instead of others (like "plantations"), since horses are of relative "high value" for AI.
Thus AI might damage its economy.
(But that is one of the things I will test again.)

--> These 2 aspects were the main reasons, why currently horses can only be produced on bonus horses.
(Including pasture only being allowed on bonus horses.)


As I said, give me some time to figure out a few things ... :)
 
Originally Posted by raystuttgart View Post
But I can tell you:
If we implement this (and spend lots of effort into AI) and some team member will say later on
"Oh, I think I have changed my mind and would like the old system back.",
I will go crazy.
Ah you predicted it all too correctly! :crazyeye:;) Well anything that will create less work & complication for the future is fine with me.

1. With "percentual breeding" you only have / see yield horses on a plot, if you also have horses stored in the city.
Currently precondition for building improvement pasture is "bonus horses exists", which is not problematic.
If we change precondition for building improvement pasture to "yield horses on plot",
you can only build the improvement pasture, if you have horses in the city.
(This might be pretty hard for players to understand ...)
Eventually precondition for building improvement pasture is "2 yield food on plot" will solve this problem.
But I have to check side effects for logic here, too.
Hmm.. If you only have / see yield horses on a plot if you also have horses stored in the city; will the AI know to plan to import horses to a particular settlement so it can enable seeing the plot yield?

2. On the contrary if horses were available on every (flat) plot and not only on "bonus horses",
then AI might build way too many improvements "pasture" instead of others (like "plantations"), since horses are of relative "high value" for AI.
Thus AI might damage its economy.
(But that is one of the things I will test again.)
--> These 2 aspects were the main reasons, why currently horses can only be produced on bonus horses.
(Including pasture only being allowed on bonus horses.)
Maybe one solution could be that only a special unit or profession that requires horses can build pasture improvement; but I'm not sure that would solve the problems.
Thinking ahead, if we are adding a lot more yields in the future, could there be other situations where the AI would have a hard time planning improvements or professions correctly? Maybe we will need some more general algorithm to help with the planning, not only specific to Horses.
 
Update:

Hi guys, I have almost solved the problem. :)

But as expected, AI is currently building way too many "Horse Pastures" ...
I will need to do a little coding to get AI (incl. Automization) on track again.

If the team will still not be happy with the solution,
I will probably be so frustrated, that I will totally remove the complete feature.
Spoiler :

Just kidding ... ;)


@agaro:

I guess, you will be happy again, because building pastures will be allowed without bonus needed.

@orlanth:

Don't worry AI will be able to handle this feature. :thumbsup:
(Also, Natives will only be able to breed horses if they have acquired some.)

But yes, as expected, we have invested massive amounts of time and efforts compared to a simple solution.
 
@team:

I have rebuilt the "Rebuild Horses". :)
(It is uploaded to SVN.)

Summary:
Spoiler :

Horses are available on flat tiles without Bonus, too.
(Improvement "Pasture" can also be built there.)

AI will build improvement "Pasture" in a reasonable manor.

AI should thus fully be able to handle this feature.
(And of course, Natives will still only be able to produce horses, once they have acquired.)


@agaro:

Would you please test and tell me if it is ok for you now ? :)
 
Yes this is much better, well done.

It is worth taking a bit of time to explain why.

Previously there were 2 related problems, I couldn't produce enough horses, particularly late in the game, and I couldn't produce horses in enough locations. These are related - if I could produce huge numbers of horses then I would be able to transport the excess to remote locations. But as it is the remote locations are the ones that miss out.

This first post shows a small remote Island. This is a 13 turn round trip from my main settlements, but I need the island because my main settlements only have two mines and no silver. It is basically a quarry producing ore, silver, fur and lumber shipped back to my main settlements.

However, to do that the island needs a few wagons, and the wagons need horses. There are no horse bonus tiles on the island, and only 3 tiles that aren't tundra. Under the previous horse system my only option was to ship scarce horses to the island whenever I needed another wagon (13 turn round trip).

But after Ray's changes this rocky island can now be self-sufficient in horses for wagons (see Eskimo settlement image). By moving 60 horses into the warehouse this activates the potential to produce just 1 horse per turn, but this is enough to keep the island in wagons.
 
Oops forgot the images ...
 

Attachments

  • RockyIsland0000.JPG
    RockyIsland0000.JPG
    184.6 KB · Views: 133
  • trickle breeding0000.JPG
    trickle breeding0000.JPG
    175.6 KB · Views: 173
Top Bottom