Androrc the Orc
Emperor
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
CvInfos.cpp
CvInfos.h
CvPlot.cpp
Some changes to the XML were also done:
CIV4ProfessionInfos.xml
CIV4TerrainSchema.xml
CIV4YieldInfos.xml
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).
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).