September 17th, 2020, 12:49
Posts: 5,323
Threads: 22
Joined: Feb 2012
(September 6th, 2020, 23:00)T-hawk Wrote: That is correct, a Golden Age uses the eligible GP nearest to the capital. Selecting GP beyond the first has no effect on what GP are consumed. I investigated this in the code once.
Selecting multiple GP causes a start-golden-age order for each of them, and each of those orders looks nearest the capital for the GP it will consume. You get what you asked for, you ordered each of those GP to start a golden age if possible, same as each of a stack of catapults will bombard if possible.
Civ 4 issues an order to each unit individually, it has no concept of issuing one order to a group of units, even if it looks like that in the UI. The start-golden-age order is unique in that it's the only order where the ordered unit needs some other unit to do something. The CvUnit code that executes the order doesn't look back at the Python interface code to see if that some-other-unit might be a selected one.
I just did a test where I had a GP in the cap and 2 in a tile near the cap and a 4th elsewhere. they were all different. I started a GA with the 4th one and then I selected both the GP in the same tile and started a 2nd GA. Those two GP were used, not the one in the cap.
Are you sure about your findings?
Completed: PBEM 34g (W), 36 , 35 , 5o, 34s, 5p, 42, 48 and PB 9, 18, 27, 57
Current: PB 52. Boudicca of Maya
September 17th, 2020, 13:20
Posts: 7,602
Threads: 75
Joined: Jan 2018
Ha, I'm just about to write my investigation about that just now.
September 17th, 2020, 13:38
Posts: 7,602
Threads: 75
Joined: Jan 2018
Which units are used to start a golden age
We start our journey in CvUnit.cpp and in there in the method killGoldenAgeUnits:
We start with some simple setup stuff. How many units are needed, which is the unit triggering the golden age etc. Then we get to the meat of the method:
Code: for (iI = 0; iI < iUnitsRequired; iI++)
{
iBestValue = 0;
pBestUnit = NULL;
for(pLoopUnit = firstUnit(&iLoop); pLoopUnit != NULL; pLoopUnit = nextUnit(&iLoop))
{
if (pLoopUnit->isGoldenAge())
{
if (!(pabUnitUsed[pLoopUnit->getUnitClassType()]))
{
iValue = 10000;
iValue /= (plotDistance(pLoopUnit->getX_INLINE(), pLoopUnit->getY_INLINE(), pUnitAlive->getX_INLINE(), pUnitAlive->getY_INLINE()) + 1);
if (iValue > iBestValue)
{
iBestValue = iValue;
pBestUnit = pLoopUnit;
}
}
}
}
...boring stuff, the actual killing and setting up everything for the next
}
We begin with something fairly simple, just a for loop that is called as often as we need it. Note that at this point iUnitsRequired is already reduced by 1 because we already know the first unit to be killed aka the unit that triggered the golden age. Then we get to the first important part
Code: for(pLoopUnit = firstUnit(&iLoop); pLoopUnit != NULL; pLoopUnit = nextUnit(&iLoop))
Here we iterate over all the units that the player owns in order of creation. The next steps are fairly simple again: Checking that the unit can trigger golden ages and the unit type wasn't used for this golden age before (only one type of GP for every golden age). Then we arrive at the most important stuff.
Code: iValue = 10000;
iValue /= (plotDistance(pLoopUnit->getX_INLINE(), pLoopUnit->getY_INLINE(), pUnitAlive->getX_INLINE(), pUnitAlive->getY_INLINE()) + 1);
if (iValue > iBestValue)
{
iBestValue = iValue;
pBestUnit = pLoopUnit;
}
We start with a base value and then we calculate the distance of the current unit to the unit that triggered the golden age ( pUnitAlive). The unit closest to the triggering unit will be the next unit to be used for the golden age.
We finish up the method with the boring part of killing the best unit and setting up everything for the next.
Summary
The game will use the unit closest to the triggering unit. If units are on the same tile, then the oldest unit will be used meaning the unit that was created first.
September 17th, 2020, 13:53
(This post was last modified: September 18th, 2020, 00:26 by Charriu.)
Posts: 7,602
Threads: 75
Joined: Jan 2018
How exactly is the 'We love the King day' triggered?
Our story begins in CvCity.cpp and in there in the method doTurn:
There right at the end we find the code that triggers the WLTKD
Code: if (isOccupation() || (angryPopulation() > 0) || (healthRate() < 0))
{
setWeLoveTheKingDay(false);
}
else if ((getPopulation() >= GC.getDefineINT("WE_LOVE_THE_KING_POPULATION_MIN_POPULATION")) && (GC.getGameINLINE().getSorenRandNum(GC.getDefineINT("WE_LOVE_THE_KING_RAND"), "Do We Love The King?") < getPopulation()))
{
setWeLoveTheKingDay(true);
}
else
{
setWeLoveTheKingDay(false);
}
We start simple with the first statement:
if (isOccupation() || (angryPopulation() > 0) || (healthRate() < 0))
As long as our city is under occupation, has angry population or is loosing food from being unhealthy we never get a WLTKD. The next statement is the actual trigger:
else if ((getPopulation() >= GC.getDefineINT("WE_LOVE_THE_KING_POPULATION_MIN_POPULATION")) && (GC.getGameINLINE().getSorenRandNum(GC.getDefineINT("WE_LOVE_THE_KING_RAND"), "Do We Love The King?") < getPopulation()))
Let's break this down:
1. We check that the population is higher or equal to WE_LOVE_THE_KING_POPULATION_MIN_POPULATION, which is defined in the GlobalDefines.xml to 8
2. We role a random number from 0 to WE_LOVE_THE_KING_RAND (GlobalDeinges.xml, value is 1000), 1000 not included
4. If that number is smaller then the current cities population, we get a WLTKD this turn.
The last statement just guarantees that the WLTKD ends if all other conditions do not apply.
Summary
You only get a WLTKD if:
- Your city is not under occupation
- No angry citizens
- No food loss due to unhealthiness
- Population >= 8
- A random number between 0 and 999 is smaller then the cities population
September 17th, 2020, 14:04
Posts: 1,948
Threads: 19
Joined: Apr 2019
(September 17th, 2020, 13:53)Charriu Wrote: A random number between 0 and 1000 is smaller then the cities population
This is the kicker.
"I know that Kilpatrick is a hell of a damned fool, but I want just that sort of man to command my cavalry on this expedition."
- William Tecumseh Sherman
September 17th, 2020, 14:12
Posts: 7,602
Threads: 75
Joined: Jan 2018
Yes that seems unlikely to ever happen for you, but remember that you are rolling random numbers for almost every city at every turn, which makes it a lot more likely to happen over the course of the game.
September 17th, 2020, 14:19
Posts: 2,941
Threads: 12
Joined: Apr 2015
Good to know the actual probabilities involved. While ~1% per city per turn adds up to a decent chance of seeing WLT_D every so often, you can't plan a strategy around consistently having it.
September 17th, 2020, 14:58
Posts: 6,687
Threads: 131
Joined: Mar 2004
(September 17th, 2020, 13:38)Charriu Wrote: The game will use the unit closest to the triggering unit.
Ah ok, that's the part I misremembered when I said closest to the capital.
I knew the foolproof method is to put only the GPs you want to use and no others in the capital, and that's 100% reliable, but went the wrong way from there.
September 17th, 2020, 15:40
Posts: 13,214
Threads: 25
Joined: Oct 2010
Why have you turned orange?
So it's 0.1% increased chance for WLTKD every turn per citizen, starting with 0.8% at the minimum required size.
September 17th, 2020, 15:44
Posts: 7,602
Threads: 75
Joined: Jan 2018
(September 17th, 2020, 15:40)NobleHelium Wrote: Why have you turned orange?
It's his final form.
|