void CvPlot::doConsumeSupply()
{
if (getPlotCity() != NULL)
{
return; //Units in cities do not require supply
}
//Construct the needed entities...
int iConIt; //Or Construct Iterator, if you perfer.
typedef std::vector<int > intVector;
intVector* paiFoodUnits[MAX_CIV_PLAYERS];
for (iConIt = 0; iConIt < MAX_CIV_PLAYERS; iConIt++)
{
paiFoodUnits[iConIt] = new intVector;
}
intVector* paiMechUnits[MAX_CIV_PLAYERS];
for (iConIt = 0; iConIt < MAX_CIV_PLAYERS; iConIt++)
{
paiMechUnits[iConIt] = new intVector;
}
int iI;
//Organize Data
CvUnit* pUnit;
for(iI = 0; iI < getNumUnits(); iI++)
{
pUnit = getUnitByIndex(iI);
if (pUnit->getUnitInfo().getUnitCombatType() == -1)
{
continue;
}
if (pUnit->getUnitInfo().isNoSupply())
{
continue;
}
if (pUnit->getDomainType() == DOMAIN_SEA)
{
continue;
}
if (pUnit->getUnitInfo().isMechUnit())
{
paiMechUnits[(int)pUnit->getOwnerINLINE()]->push_back(iI);
}
else
{
paiFoodUnits[(int)pUnit->getOwnerINLINE()]->push_back(iI);
}
}
//Data Organized! Now for the supply!
for (iI = 0; iI < MAX_CIV_PLAYERS; iI++)
{
if ((paiMechUnits[iI]->size() == 0) && (paiFoodUnits[iI]->size() == 0))
{
continue;
}
int iJ;
std::vector<int> apBonusFoodVector; //This is a vector of the ammount of food each bonus produces when spent, ordered according to the order in the XML
std::vector<int> apBonusVector; //This a vector of the BonusType value of each CvBonusInfo sorted by the ammount of food they produce
for (iJ = 0; iJ < GC.getNumBonusInfos(); iJ++)
{
if (GC.getBonusInfo((BonusTypes)iJ).getSpendYieldProduced() != YIELD_FOOD)
{
apBonusFoodVector.push_back(0);
continue;
}
apBonusFoodVector.push_back(GC.getBonusInfo((BonusTypes)iJ).getAmmountProduced());
}
for (iJ = 0; iJ < GC.getNumBonusInfos(); iJ++)
{
apBonusVector.push_back(GC.getVectorHighestVal(&apBonusFoodVector));
apBonusFoodVector[GC.getVectorHighestVal(&apBonusFoodVector)] = 0;
}
int iCounter = 0;
int iFoodNeeded = paiFoodUnits[iI]->size();
int iFood = 0; //The ammount of food you accumulate
int iBonusFoodProduced;
for (iJ = 0; iJ < GC.getNumBonusInfos(); iJ++)//In this loop, iJ != BonusTypes!!!! Use apBonusVector[iJ] instead.
{
if (GC.getBonusInfo((BonusTypes)iJ).getSpendYieldProduced() != YIELD_FOOD)
{
break; //No point in bothering to continue because all the ones after this will also produce 0 food
}
int iBonusFoodProduced = GC.getBonusInfo((BonusTypes)apBonusVector[iJ]).getAmmountProduced();
int iResourceTemp = 0;
//Increase the ammount of the resource you're going to consume untill it's at the max it can be.
for(int iK = 0; iK < getNumResourceOnTileByPlayer((BonusTypes)apBonusVector.at(iJ), (PlayerTypes)iI); iK++) //iK = the ammount of the food resource that the units can consume
{
if ((iK * iBonusFoodProduced + (iFoodNeeded-iFood) <= iFoodNeeded) && ((iK+1 * iBonusFoodProduced + (iFoodNeeded-iFood) <= iFoodNeeded) || (iK+1 == getNumResourceOnTileByPlayer((BonusTypes)apBonusVector.at(iJ), (PlayerTypes)iI)) || (iK == getNumResourceOnTileByPlayer((BonusTypes)apBonusVector.at(iJ), (PlayerTypes)iI))))
{
for (int iL = 0; iL < getNumUnits(); iL++)
{
if (getUnitByIndex(iL)->getOwnerINLINE() == PlayerTypes(iI))
{
if (iK - iResourceTemp > getUnitByIndex(iL)->getNumResourcesCarried(apBonusVector[iJ]))
{
iResourceTemp += getUnitByIndex(iL)->getNumResourcesCarried(apBonusVector[iJ]);
getUnitByIndex(iL)->setNumResourcesCarried(apBonusVector.at(iJ), 0);
}
else
{
getUnitByIndex(iL)->changeNumResourcesCarried(apBonusVector[iJ], (iResourceTemp - iK));
iResourceTemp = iK;
}
}
}
iFood += iK * iBonusFoodProduced;
}
}
if (iFood == iFoodNeeded) //If we have enough food
{
break;
}
}
if (iFood < iFoodNeeded)
{
for (iJ = iFood; iJ < paiFoodUnits[iI]->size(); iJ++)//Start at the first unit that was not fed
{
getUnitByIndex(paiFoodUnits[iI]->at(iJ))->changeMorale(NOSUPPLY_MORALE_LOSS);
}
}
//Now, if you wish, we will do the same thing for mech units
if (paiMechUnits[iI]->size() > 0)
{
int iFuelBonus = GC.getInfoTypeForString(GC.getDefineSTRING("FUEL_RESOURCE")); //Unless someone has changed it, this will be oil.
int iAccumulated = 0;
if (getNumResourceOnTileByPlayer((BonusTypes)iFuelBonus, (PlayerTypes)iI) >= paiMechUnits[iI]->size())
{
//paiMechUnits already does not include units such as catapults that do not need supply
for (int iJ = 0; iJ < getNumUnits(); iJ++)
{
if (getUnitByIndex(iI)->getOwner() == (PlayerTypes)iI)
{
if (getUnitByIndex(iJ)->getNumResourcesCarried(iFuelBonus) <= (paiMechUnits[iI]->size() - iAccumulated))
{
iAccumulated += getUnitByIndex(iJ)->getNumResourcesCarried(iFuelBonus);
getUnitByIndex(iJ)->setNumResourcesCarried(iFuelBonus, 0);
}
else
{
getUnitByIndex(iJ)->changeNumResourcesCarried(iFuelBonus, iAccumulated - paiMechUnits[iI]->size());
iAccumulated = paiMechUnits[iI]->size();
}
}
}
for (int iK = iAccumulated; iK < paiMechUnits[iI]->size(); iK++)
{
getUnitByIndex(paiMechUnits[iI]->at(iK))->setMoves(0); //Vehicles without fuel cannot move
}
}
}
}
}