bool CvCity::doGrowth()
{
int iDiff, iI, iJ, iK;
CvWString szBuffer;
CvWString szName;
CvPlot* pPlot = plot();
CvCity* pNewCity = NULL;
/*************************************************************************************************/
/** SPEEDTWEAK (Block Python) Sephi **/
/** If you want to allow modmodders to enable this Callback, see CvCity::cancreate for example **/
/*************************************************************************************************/
/**
CyCity* pyCity = new CyCity(this);
CyArgsList argsList;
argsList.add(gDLL->getPythonIFace()->makePythonObject(pyCity)); // pass in city class
long lResult=0;
gDLL->getPythonIFace()->callFunction(PYGameModule, "doGrowth", argsList.makeFunctionArgs(), &lResult);
delete pyCity; // python fxn must not hold on to this pointer
if (lResult == 1)
{
return false;
}
/*************************************************************************************************/
/** END **/
/*************************************************************************************************/
iDiff = foodDifference();
changeFood(iDiff);
changeFoodKept(iDiff);
setFoodKept(range(getFoodKept(), 0, ((growthThreshold() * getMaxFoodKeptPercent()) / 100)));
if (getFood() >= growthThreshold())
{
if (AI_isEmphasizeAvoidGrowth())
{
setFood(growthThreshold());
}
else
{
changeFood(-(std::max(0, (growthThreshold() - getFoodKept()))));
changePopulation(1);
// ONEVENT - City growth
CvEventReporter::getInstance().cityGrowth(this, getOwnerINLINE());
}
}
else if (getFood() < 0)
{
changeFood(-(getFood()));
if (getPopulation() > 1 && !(isOccupation()) && !(isBarbarian()) && GET_PLAYER(getOwnerINLINE()).getNumCities() > 1 && !GET_PLAYER(getOwnerINLINE()).isDomai())
{
if (GET_PLAYER(getOwnerINLINE()).isBiodomed())
{
return false;
}
if (GC.getGameINLINE().getSorenRandNum(10, "Revolt #1") < getRevoltTestProbability()) // test for units which reduce revolt chance
{
CLLNode<IDInfo>* pUnitNode;
CvUnit* pLoopUnit;
int iGarrisonModifier = std::max(1, cultureGarrison(NO_PLAYER)/8);
if (-iDiff > GC.getGameINLINE().getSorenRandNum(30 * iGarrisonModifier, "Revolt #2"))
{
CLinkList<IDInfo> oldUnits;
pUnitNode = plot()->headUnitNode();
while (pUnitNode != NULL)
{
oldUnits.insertAtEnd(pUnitNode->m_data);
pUnitNode = plot()->nextUnitNode(pUnitNode);
}
pUnitNode = oldUnits.head();
while (pUnitNode != NULL)
{
pLoopUnit = ::getUnit(pUnitNode->m_data);
pUnitNode = plot()->nextUnitNode(pUnitNode);
if (pLoopUnit)
{
if (pLoopUnit->canDefend())
{
pLoopUnit->changeDamage((pLoopUnit->currHitPoints() / 2), NO_PLAYER);
}
}
}
if (getNumRevolts(BARBARIAN_PLAYER) >= GC.getDefineINT("NUM_WARNING_REVOLTS"))
{
szBuffer = gDLL->getText("TXT_KEY_MISC_CITY_REVOLTED_JOINED_REBELS", getNameKey());
gDLL->getInterfaceIFace()->addMessage(getOwnerINLINE(), false, GC.getEVENT_MESSAGE_TIME(), szBuffer, "AS2D_CULTUREFLIP", MESSAGE_TYPE_MAJOR_EVENT, ARTFILEMGR.getInterfaceArtInfo("WORLDBUILDER_CITY_EDIT")->getPath(), (ColorTypes)GC.getInfoTypeForString("COLOR_RED"), getX_INLINE(), getY_INLINE(), true, true);
gDLL->getInterfaceIFace()->addMessage(BARBARIAN_PLAYER, false, GC.getEVENT_MESSAGE_TIME(), szBuffer, "AS2D_CULTUREFLIP", MESSAGE_TYPE_MAJOR_EVENT, ARTFILEMGR.getInterfaceArtInfo("WORLDBUILDER_CITY_EDIT")->getPath(), (ColorTypes)GC.getInfoTypeForString("COLOR_GREEN"), getX_INLINE(), getY_INLINE(), true, true);
szBuffer = gDLL->getText("TXT_KEY_MISC_CITY_REVOLTS_JOINS_REBELS", getNameKey());
GC.getGameINLINE().addReplayMessage(REPLAY_MESSAGE_MAJOR_EVENT, getOwnerINLINE(), szBuffer, getX_INLINE(), getY_INLINE(), (ColorTypes)GC.getInfoTypeForString("COLOR_ALT_HIGHLIGHT_TEXT"));
szName.Format(L"%s (%s)", getName().GetCString(), GET_PLAYER(getOwnerINLINE()).getName());
for (iI = 0; iI < MAX_PLAYERS; iI++)
{
if (GET_PLAYER((PlayerTypes)iI).isAlive())
{
if (iI != getOwnerINLINE())
{
if (isRevealed(GET_PLAYER((PlayerTypes)iI).getTeam(), false))
{
szBuffer = gDLL->getText("TXT_KEY_MISC_CITY_REVOLTED_JOINED_REBELS", szName.GetCString());
gDLL->getInterfaceIFace()->addMessage(((PlayerTypes)iI), false, GC.getEVENT_MESSAGE_TIME(), szBuffer, "AS2D_CITYCAPTURED", MESSAGE_TYPE_MAJOR_EVENT, ARTFILEMGR.getInterfaceArtInfo("WORLDBUILDER_CITY_EDIT")->getPath(), (ColorTypes)GC.getInfoTypeForString("COLOR_RED"), getX_INLINE(), getY_INLINE(), true, true);
}
}
}
}
GET_PLAYER(BARBARIAN_PLAYER).acquireCity(this, false, false, true);
pNewCity = pPlot->getPlotCity();
if (pNewCity != NULL)
{
pNewCity->changeOccupationTimer(GC.getDefineINT("BASE_OCCUPATION_TURNS") + ((pNewCity->getPopulation() * GC.getDefineINT("OCCUPATION_TURNS_POPULATION_PERCENT")) / 100));
}
GC.getMapINLINE().verifyUnitValidPlot();
int iFreeUnits = std::max(1, GC.getGameINLINE().getSorenRandNum((3 * iGarrisonModifier) / 2, "Free Units"));
for (int iI = 0; iI < iFreeUnits; ++iI)
{
GET_PLAYER(BARBARIAN_PLAYER).initUnit((UnitTypes)GC.getInfoTypeForString(GC.getDefineSTRING("UNIT_PARTISAN")), pPlot->getX_INLINE(), pPlot->getY_INLINE(), UNITAI_CITY_DEFENSE);
}
return true;
}
else
{
changeNumRevolts(BARBARIAN_PLAYER, 1);
changeOccupationTimer(GC.getDefineINT("BASE_REVOLT_OCCUPATION_TURNS") + GC.getGameINLINE().getSorenRandNum(-(foodDifference() / 4), "Revolt Turns"));
// XXX announce for all seen cities?
szBuffer = gDLL->getText("TXT_KEY_MISC_REVOLT_IN_CITY", GET_PLAYER(BARBARIAN_PLAYER).getCivilizationAdjective(), getNameKey());
gDLL->getInterfaceIFace()->addMessage(getOwnerINLINE(), false, GC.getEVENT_MESSAGE_TIME(), szBuffer, "AS2D_CPU_DRONE_RIOTS", MESSAGE_TYPE_MINOR_EVENT, ARTFILEMGR.getInterfaceArtInfo("INTERFACE_RESISTANCE")->getPath(), (ColorTypes)GC.getInfoTypeForString("COLOR_RED"), getX_INLINE(), getY_INLINE(), true, true);
}
}
}
}
}
if (!(isOccupation()) && isBarbarian() && getNumRealBuilding((BuildingTypes)GC.getInfoTypeForString(GC.getDefineSTRING("BUILDING_REBEL_STRONGHOLD"))) > 0)
{
for (iI = 0; iI < MAX_PLAYERS; iI++)
{
if (GET_PLAYER((PlayerTypes)iI).isAlive())
{
CvPlayer& pPlayer = GET_PLAYER((PlayerTypes)iI);
if (pPlayer.isDomai())
{
szBuffer = gDLL->getText("TXT_KEY_MISC_CITY_REVOLTED_JOINED", getNameKey(), pPlayer.getCivilizationDescriptionKey());
gDLL->getInterfaceIFace()->addMessage((PlayerTypes)iI, false, GC.getEVENT_MESSAGE_TIME(), szBuffer, "AS2D_CULTUREFLIP", MESSAGE_TYPE_MAJOR_EVENT, ARTFILEMGR.getInterfaceArtInfo("WORLDBUILDER_CITY_EDIT")->getPath(), (ColorTypes)GC.getInfoTypeForString("COLOR_GREEN"), getX_INLINE(), getY_INLINE(), true, true);
szBuffer = gDLL->getText("TXT_KEY_MISC_CITY_REVOLTS_JOINS", getNameKey(), pPlayer.getCivilizationDescriptionKey());
GC.getGameINLINE().addReplayMessage(REPLAY_MESSAGE_MAJOR_EVENT, getOwnerINLINE(), szBuffer, getX_INLINE(), getY_INLINE(), (ColorTypes)GC.getInfoTypeForString("COLOR_ALT_HIGHLIGHT_TEXT"));
szName.Format(L"%s (%s)", getName().GetCString(), GET_PLAYER(getOwnerINLINE()).getName());
for (iJ = 0; iJ < MAX_PLAYERS; iJ++)
{
if (GET_PLAYER((PlayerTypes)iJ).isAlive())
{
if (iJ != getOwnerINLINE())
{
if (isRevealed(GET_PLAYER((PlayerTypes)iJ).getTeam(), false))
{
szBuffer = gDLL->getText("TXT_KEY_MISC_CITY_CAPTURED_BY", szName.GetCString(), GET_PLAYER((PlayerTypes)iI).getCivilizationDescriptionKey());
gDLL->getInterfaceIFace()->addMessage(((PlayerTypes)iJ), false, GC.getEVENT_MESSAGE_TIME(), szBuffer, "AS2D_CITYCAPTURED", MESSAGE_TYPE_MAJOR_EVENT, ARTFILEMGR.getInterfaceArtInfo("WORLDBUILDER_CITY_EDIT")->getPath(), (ColorTypes)GC.getInfoTypeForString("COLOR_RED"), getX_INLINE(), getY_INLINE(), true, true);
}
}
}
}
if (getPreviousOwner() != NO_PLAYER )
{
int* piShuffle = shuffle(GC.getNumTechInfos(), GC.getGameINLINE().getSorenRand());
for (iJ = 0; iJ < GC.getNumTechInfos(); iJ++)
{
if (GET_TEAM(GET_PLAYER(getPreviousOwner()).getTeam()).isHasTech((TechTypes)piShuffle[iJ]) && !GET_TEAM(pPlayer.getTeam()).isHasTech((TechTypes)piShuffle[iJ]))
{
GET_TEAM(pPlayer.getTeam()).setHasTech(((TechTypes)piShuffle[iJ]), true, NO_PLAYER, false, true);
break;
}
}
SAFE_DELETE_ARRAY(piShuffle);
}
pPlayer.acquireCity(this, false, false, true);
for (int iDX = -2; iDX <= 2; iDX++)
{
for (int iDY = -2; iDY <= 2; iDY++)
{
CvPlot* pLoopPlot = plotXY(pPlot->getX_INLINE(), pPlot->getY_INLINE(), iDX, iDY);
if (NULL != pLoopPlot)
{
if (pLoopPlot->isUnit())
{
CLLNode<IDInfo>* pUnitNode = pLoopPlot->headUnitNode();
while (pUnitNode != NULL)
{
CvUnit* pLoopUnit = ::getUnit(pUnitNode->m_data);
pUnitNode = pLoopPlot->nextUnitNode(pUnitNode);
if (pLoopUnit->getOwnerINLINE() == BARBARIAN_PLAYER && pLoopUnit->isPsi() && !pLoopUnit->isAnimal())
{
CvUnit* pNewUnit = pPlayer.initUnit(pLoopUnit->getUnitType(), pLoopPlot->getX_INLINE(), pLoopPlot->getY_INLINE(), pLoopUnit->AI_getUnitAIType());
pNewUnit->convert(pLoopUnit);
}
}
}
}
}
}
if (pPlayer.getNumCities() == 1)
{
for (iJ = 0; iJ < GC.getNumTechInfos(); iJ++)
{
int iCount = 0;
for (iK = 0; iK < MAX_CIV_TEAMS; iK++)
{
if (GET_TEAM((TeamTypes)iK).isAlive())
{
if (GET_TEAM((TeamTypes)iK).isHasTech((TechTypes)iJ))
{
iCount++;
if (iCount > 1)
{
GET_TEAM(pPlayer.getTeam()).setHasTech(((TechTypes)iJ), true, NO_PLAYER, false, false);
if (GC.getGameINLINE().isOption(GAMEOPTION_NO_TECH_BROKERING))
{
GET_TEAM(pPlayer.getTeam()).setNoTradeTech((TechTypes)iJ, true);
}
break;
}
}
}
}
}
}
return true;
}
}
}
}
return false;
}