Deon
Lt. of Mordor
Greetings! I am a newbie to SDK coding but I would like to address the following issue. In MOO2Civ mod barbarians spawn units which are "NONE" in their profile in Civ4CivilizationInfos.xml. I thought it's hardcoded in SDK so despite that fact that I've never tried to look into it I opened it and quite quickly found this:
As I see, it selects eBestUnit from eLoopUnit, and this line looks like it governs where it picks units from:
I don't have an idea yet how to address it to ignore units which are disabled in XML.
Any tips how to block certain unit types from spawning?
Spoiler Wall of code :
Code:
void CvGame::createBarbarianUnits()
{
CvUnit* pLoopUnit;
CvArea* pLoopArea;
CvPlot* pPlot;
UnitAITypes eBarbUnitAI;
UnitTypes eBestUnit;
UnitTypes eLoopUnit;
bool bAnimals;
long lResult;
int iNeededBarbs;
int iDivisor;
int iValue;
int iBestValue;
int iLoop;
int iI, iJ;
if (isOption(GAMEOPTION_NO_BARBARIANS))
{
return;
}
lResult = 0;
gDLL->getPythonIFace()->callFunction(PYGameModule, "createBarbarianUnits", NULL, &lResult);
if (lResult == 1)
{
return;
}
bAnimals = false;
if (GC.getEraInfo(getCurrentEra()).isNoBarbUnits())
{
bAnimals = true;
}
if (getNumCivCities() < ((countCivPlayersAlive() * 3) / 2) && !isOption(GAMEOPTION_ONE_CITY_CHALLENGE))
{
bAnimals = true;
}
if (getElapsedGameTurns() < ((GC.getHandicapInfo(getHandicapType()).getBarbarianCreationTurnsElapsed() * GC.getGameSpeedInfo(getGameSpeedType()).getBarbPercent()) / 100))
{
bAnimals = true;
}
if (bAnimals)
{
createAnimals();
}
else
{
for(pLoopArea = GC.getMapINLINE().firstArea(&iLoop); pLoopArea != NULL; pLoopArea = GC.getMapINLINE().nextArea(&iLoop))
{
if (pLoopArea->isWater())
{
eBarbUnitAI = UNITAI_ATTACK_SEA;
iDivisor = GC.getHandicapInfo(getHandicapType()).getUnownedWaterTilesPerBarbarianUnit();
}
else
{
eBarbUnitAI = UNITAI_ATTACK;
iDivisor = GC.getHandicapInfo(getHandicapType()).getUnownedTilesPerBarbarianUnit();
}
if (isOption(GAMEOPTION_RAGING_BARBARIANS))
{
iDivisor = std::max(1, (iDivisor / 2));
}
if (iDivisor > 0)
{
iNeededBarbs = ((pLoopArea->getNumUnownedTiles() / iDivisor) - pLoopArea->getUnitsPerPlayer(BARBARIAN_PLAYER)); // XXX eventually need to measure how many barbs of eBarbUnitAI we have in this area...
if (iNeededBarbs > 0)
{
iNeededBarbs = ((iNeededBarbs / 4) + 1);
for (iI = 0; iI < iNeededBarbs; iI++)
{
pPlot = GC.getMapINLINE().syncRandPlot((RANDPLOT_NOT_VISIBLE_TO_CIV | RANDPLOT_ADJACENT_LAND | RANDPLOT_PASSIBLE), pLoopArea->getID(), GC.getDefineINT("MIN_BARBARIAN_STARTING_DISTANCE"));
if (pPlot != NULL)
{
eBestUnit = NO_UNIT;
iBestValue = 0;
for (iJ = 0; iJ < GC.getNumUnitClassInfos(); iJ++)
{
bool bValid = false;
eLoopUnit = ((UnitTypes)(GC.getCivilizationInfo(GET_PLAYER(BARBARIAN_PLAYER).getCivilizationType()).getCivilizationUnits(iJ)));
if (eLoopUnit != NO_UNIT)
{
CvUnitInfo& kUnit = GC.getUnitInfo(eLoopUnit);
bValid = (kUnit.getCombat() > 0 && !kUnit.isOnlyDefensive());
if (bValid)
{
if (pLoopArea->isWater() && kUnit.getDomainType() != DOMAIN_SEA)
{
bValid = false;
}
else if (!pLoopArea->isWater() && kUnit.getDomainType() != DOMAIN_LAND)
{
bValid = false;
}
}
if (bValid)
{
if (!GET_PLAYER(BARBARIAN_PLAYER).canTrain(eLoopUnit))
{
bValid = false;
}
}
if (bValid)
{
if (NO_BONUS != kUnit.getPrereqAndBonus())
{
if (!GET_TEAM(BARBARIAN_TEAM).isHasTech((TechTypes)GC.getBonusInfo((BonusTypes)kUnit.getPrereqAndBonus()).getTechCityTrade()))
{
bValid = false;
}
}
}
if (bValid)
{
bool bFound = false;
bool bRequires = false;
for (int i = 0; i < GC.getNUM_UNIT_PREREQ_OR_BONUSES(); ++i)
{
if (NO_BONUS != kUnit.getPrereqOrBonuses(i))
{
TechTypes eTech = (TechTypes)GC.getBonusInfo((BonusTypes)kUnit.getPrereqOrBonuses(i)).getTechCityTrade();
if (NO_TECH != eTech)
{
bRequires = true;
if (GET_TEAM(BARBARIAN_TEAM).isHasTech(eTech))
{
bFound = true;
break;
}
}
}
}
if (bRequires && !bFound)
{
bValid = false;
}
}
if (bValid)
{
iValue = (1 + getSorenRandNum(1000, "Barb Unit Selection"));
if (kUnit.getUnitAIType(eBarbUnitAI))
{
iValue += 200;
}
if (iValue > iBestValue)
{
eBestUnit = eLoopUnit;
iBestValue = iValue;
}
}
}
}
if (eBestUnit != NO_UNIT)
{
GET_PLAYER(BARBARIAN_PLAYER).initUnit(eBestUnit, pPlot->getX_INLINE(), pPlot->getY_INLINE(), eBarbUnitAI);
}
}
}
}
}
}
for (pLoopUnit = GET_PLAYER(BARBARIAN_PLAYER).firstUnit(&iLoop); pLoopUnit != NULL; pLoopUnit = GET_PLAYER(BARBARIAN_PLAYER).nextUnit(&iLoop))
{
if (pLoopUnit->isAnimal())
{
pLoopUnit->kill(false);
break;
}
}
}
}
As I see, it selects eBestUnit from eLoopUnit, and this line looks like it governs where it picks units from:
Code:
GC.getCivilizationInfo(GET_PLAYER(BARBARIAN_PLAYER).getCivilizationType()).getCivilizationUnits(iJ))
I don't have an idea yet how to address it to ignore units which are disabled in XML.
Any tips how to block certain unit types from spawning?