Unofficial Patch for 3.19

The one issue is that fallout won't be cleared in this case if a city is founded on it.

Is that a common way to clear fallout? :lol: I need to follow more SGs to get tips like this! :p You could always give fallout +25% defense (j/k). I didn't know fallout was a feature--I've only had one game get to nukes being lobbed, and that was a long time ago.

That's a tough call, then. Without special-casing a check for some feature, I don't see a completely non-gameplay-changing way to handle this. Of course, my view is that the UP shouldn't change how flood plains are handled at all, as I posted in the PIG thread, I think, too many threads this weekend. This change seems like a "the game designers should have done this" type of change. :confused:
 
Jdog, I found something that doesn't scale for gamespeed; memory decays. See here in CvPlayerAI:

Spoiler :
Code:
	for (iI = 0; iI < MAX_PLAYERS; iI++)
	{
		if (GET_PLAYER((PlayerTypes)iI).isAlive())
		{
			for (iJ = 0; iJ < NUM_MEMORY_TYPES; iJ++)
			{
				if (AI_getMemoryCount(((PlayerTypes)iI), ((MemoryTypes)iJ)) > 0)
				{
					if (GC.getLeaderHeadInfo(getPersonalityType()).getMemoryDecayRand(iJ) > 0)
					{
						if (GC.getGameINLINE().getSorenRandNum(GC.getLeaderHeadInfo(getPersonalityType()).getMemoryDecayRand(iJ), "Memory Decay") == 0)
						{
							AI_changeMemoryCount(((PlayerTypes)iI), ((MemoryTypes)iJ), -1);
						}
					}
				}
			}
		}
	}

It should really scale, so Marathon leaders are less forgetful.
Not UG; while I agree that this should be fixed, I think it's more suited to BetterAI or RevolutionDCM. In my opinion changes like this do not belong in the UP.
 
Not UG; while I agree that this should be fixed, I think it's more suited to BetterAI or RevolutionDCM. In my opinion changes like this do not belong in the UP.

Wait, what? So in Blitz games, the AI should remember everything? And in Marathon, not? It's an oversight.
 
Jdog, I found something that doesn't scale for gamespeed; memory decays. See here in CvPlayerAI:

Code:
	for (iI = 0; iI < MAX_PLAYERS; iI++)
	{
		if (GET_PLAYER((PlayerTypes)iI).isAlive())
		{
			for (iJ = 0; iJ < NUM_MEMORY_TYPES; iJ++)
			{
				if (AI_getMemoryCount(((PlayerTypes)iI), ((MemoryTypes)iJ)) > 0)
				{
					if (GC.getLeaderHeadInfo(getPersonalityType()).getMemoryDecayRand(iJ) > 0)
					{
						if (GC.getGameINLINE().getSorenRandNum(GC.getLeaderHeadInfo(getPersonalityType()).getMemoryDecayRand(iJ), "Memory Decay") == 0)
						{
							AI_changeMemoryCount(((PlayerTypes)iI), ((MemoryTypes)iJ), -1);
						}
					}
				}
			}
		}
	}

It should really scale, so Marathon leaders are less forgetful.

Yeah, there's a lot of diplomacy related stuff that doesn't scale ... rand calls for trade requests for one. It's kind of a big can of worms to open.

The question is really whether these things should be done based on years or based on turns. With memory I can see the argument going either way ... they attacked me or made a demand X turns ago, so I still remember it. If the AI player was a human, their memory would be more tied to number of turns and completely independent of years or the relative speed of turns.

Not sure there's a clear answer as to what's "right".
 
I think it makes sense to scale it based on total game time (number of turns). I'd go for getting the same number of requests from a single AI no matter the game speed.

As for this being UG, I think there's enough precedent for it. Many things scale in the game, and I suspect the ones that don't are simply lack of time, forethought, or a time vs. payoff analysis: Firaxis could add espionage . . . or make everything scale uniformly.
 
Yeah, there's a lot of diplomacy related stuff that doesn't scale ... rand calls for trade requests for one. It's kind of a big can of worms to open.

The question is really whether these things should be done based on years or based on turns. With memory I can see the argument going either way ... they attacked me or made a demand X turns ago, so I still remember it. If the AI player was a human, their memory would be more tied to number of turns and completely independent of years or the relative speed of turns.

Not sure there's a clear answer as to what's "right".

Yeah, diplomacy is really complicated, I'll give you that. However, it would be nice to have all of those contact rand's scale too. But for the AI_doDiplo(...), wouldn't it be easiest to create a function that scaled the contact rand number, and returned it; instead of writing the code in each place? I mean, AI_doDiplo is already a PITA to mod as it is, no need to exacerbate things.
 
Wait, what? So in Blitz games, the AI should remember everything? And in Marathon, not? It's an oversight.
Actually I think yes, that makes more sense, at least on a roleplaying level.
Oversight or not, I'd really appreciate it if Diplomacy wasn't touched, and if then at least all of it in one single update. And I believe jdog when he says it's a huge can of worms.

One more variable where gamespeed scaling is easy: GLOBAL_WARMING_PROB in doGlobalWarming()


As for floodplains and fallout: Can fallout still be cleared by a worker when a city is built on top of it? If yes there's no problem in my eyes. But I guess the answer is no ..
 
Actually I think yes, that makes more sense, at least on a roleplaying level.

If you are considering role playing, than it's even more of a reason to scale it. I don't want AI remembering things for all 6000 years in Blitz, but just 1000 years in Marathon. It just doesn't make sense.
 
As for floodplains and fallout: Can fallout still be cleared by a worker when a city is built on top of it? If yes there's no problem in my eyes. But I guess the answer is no ..
The awnser is yes and no... not that you will see a lot of fallout below cities ;) Yes, because if you WB fallout under a city you can scrub it, no because settling a city removes fallout :devil: Not that matters much: fallout in city tiles does not remove the city tile contribution to the hammers, food and commerce ( that is somewhat strange ... )

I do not agree much with what EF said about the reasoning behind cities removing FPs. The base game is coded to only have one overlay per tile ( you can't have forested oasis or FP or forested jungle :D Or to be honest, fallout with any other of the overlays ). I guess the coders simply wanted to make the city tile behave like the overlays ( given that behaving like improvements or terrain types would probably bring even deeper problems ) and never thought of the possible consequences of that ( we have all seen that happening in other parts of the code ... )
 
no because settling a city removes fallout :devil:
I was talking about the change suggested by EF that would make city founding not remove fallout...

I don't see the big issue about FPs, I think can handle it either way but I'm leaning towards keeping it. And keeping fallout too btw, if it really stays scrubbable.
 
I mean, AI_doDiplo is already a PITA to mod as it is, no need to exacerbate things.

Could I suggest my algorithm for it?
I'm making one modcomp for FfH2, and it includes fixation of your pointing problem.

Spoiler :
Code:
	for (iI = 0; iI < MAX_PLAYERS; iI++)
	{
		if (GET_PLAYER((PlayerTypes)iI).isAlive())
		{
			for (iJ = 0; iJ < NUM_MEMORY_TYPES; iJ++)
			{
				if (AI_getMemoryCount(((PlayerTypes)iI), ((MemoryTypes)iJ)) > 0)
				{
					if (GC.getLeaderHeadInfo(getPersonalityType()).getMemoryDecayRand(iJ) > 0)
					{
/*
						[COLOR="Red"]if (GC.getGameINLINE().getSorenRandNum(GC.getLeaderHeadInfo(getPersonalityType()).getMemoryDecayRand(iJ), "Memory Decay") == 0)
						{
							AI_changeMemoryCount(((PlayerTypes)iI), ((MemoryTypes)iJ), -1);
						}[/COLOR]
*/
						[COLOR="Blue"]int iGameSpeedPercent = GC.getGameSpeedInfo(GC.getGame().getGameSpeedType()).getVictoryDelayPercent();
						int iDenominator = iGameSpeedPercent * GC.getLeaderHeadInfo(getPersonalityType()).getMemoryDecayRand(iJ);
						int iNumerator = 100;
						int iOverflowCount = iNumerator / iDenominator;
						iNumerator -= iOverflowCount * iDenominator;

						AI_changeMemoryCount((PlayerTypes)iI, (MemoryTypes)iJ, -1 * iOverflowCount);

						if (GC.getGameINLINE().getSorenRandNum(iDenominator / iNumerator, "Memory Decay") == 0)
						{
							AI_changeMemoryCount((PlayerTypes)iI, (MemoryTypes)iJ, -1);
						}[/COLOR]
					}
				}
			}
		}
	}
I does not make sure that this code is correct yet.
Please review my approach, thanks!
 
Well, I was just trying to avoid making the functions even more unreadable. I was just thinking of creating this function and calling it each time, to eliminate all that code, since it will need to be used ~10 times anyway.

Code:
int CvPlayerAI::scaleForGameSpeed(int iDecayType)
{
	int iGameSpeedPercent = GC.getGameSpeedInfo(GC.getGame().getGameSpeedType()).getVictoryDelayPercent();
	int iDenominator = iGameSpeedPercent * GC.getLeaderHeadInfo(getPersonalityType()).getMemoryDecayRand(iDecayType);
	int iNumerator = 100;
	int iOverflowCount = iNumerator / iDenominator;
	iNumerator -= iOverflowCount * iDenominator;

	return iNumerator / std:max(1, iDenominator);
}
 
Gamespeed scaling:
Diplo: Memory decay scaling is ok I guess. I changed my mind there.

doImprovement:
Yeah, you're right ... this snippet gets called a lot though, I'm just not sure it's worth it. We can make the original code (and your code if you use it) faster by moving the multiplies inside the iOdds > 0 check though.
Yes, for every worked mine it loops over all bonuses for which you have the revealing tech, so what I suggested could only ever be feasable if it was possible to only calculate the real odds once per turn/player and save it somewhere. I don't see how that would easily be possible though.
More importantly, the error introduced by this way of handling it is lower the lower the base chance and game speeds are, and since all mine resources have a discoverRand of 10k, the error must be really small.. I thought, and went ahead and calculated:

chances for one type of resource to be discovered on a worked mine:
[<game speed>: <chance with current implementation> (<correct value>)]
Marathon: 1/30000 (~1/29998,99998)
* error: -0,0033334074111113443237323833734253%
* error after rounding to 29999: -0,003333333333333%
Epic: 1/15000 (~1/14999,75)
* error: -0,0016667129652779209632637655049945%
* error after rounding to 15000: 0
Normal: 1/10000 (1/10000)
* no error possible
Quick: 1/6700 (~1/6700,165)
* error: +0,0024627888779157460147099993370482%
* error after rounding to 6700: 0

On that note, I forgot the math::round() before the typecast even, so the errors I would have introcuded by cutting off the fractions would have been even worse than ones that come from the current not 100% mathematically correct implementation.
 
That's a tough call, then. Without special-casing a check for some feature, I don't see a completely non-gameplay-changing way to handle this.
Actually there is.
Fallout is the only feature that doesn't allow improvements yet still allows settling a city there .. If you can't even build a cottage there, how can a whole city be founded there?
And with this rhetorical question I suggest to either change the xml so that you can't found cities on fallout (evil gameplay change) or to remove the feature when settling if isNoImprovement()
Code:
if (pPlot->getFeatureType() != NO_FEATURE && 
 [B]([/B]GC.getFeatureInfo(pPlot->getFeatureType()).getDefenseModifier() != 0 [B]|| 
  GC.getFeatureInfo(pPlot->getFeatureType()).isNoImprovement())[/B])
 
If we're going to have the UP change this game rule, I suppose that's the best way to handle it.

I still contend that the UP should not be making this change in the first place. :nono:
 
changes from other people that I think are not part of UP yet (or BBAI or BULL for that matter)
but probably should be

Don't get penalities from civs you haven't even met by trading with their Worst Enemies (by Seph)

MongooseSDK 3.3

GreatPersonFix (NEW) (CvCity.cpp, CvCity.h, CyCity.cpp, CyCity.h, CyCityInterface1.cpp, CvGameTextMgr.cpp)

Applies floating point precision to great people points, preventing truncation errors (which could result in a great person taking several turns longer to finish than he should) and allowing overflow points to be calculated correctly when starting a new great person. (Note: the progress bar in the city view will display gibberish without the code in my CvMainInterface.py file which I'm not providing here, but the bar's mouseover popup will be fine since that's handled by the SDK.)

Fixes a significant bug with the application of the Parthenon/Pacifist/etc effect which frequently led to incorrect results.


BarbarianPassiveTechFix (NEW) (CvTeam.cpp)

Fixes a minor bug where the barbs were counting themselves (and any other barbarian players for that matter) in the list of other civs for determining passive tech accumulation rate, making it slightly slower than whatever value the XML global indicates. Also adds an enforced minimum of one research per turn if any other civs have the tech, which is probably not necessary but was missing nonetheless.

AITargetCityValueFix (NEW) (CvPlayerAI.cpp, CvCity.cpp, CvCity.h)

Fixes the AI's calculation of the value of potential target cities: obsolete world wonders are no longer considered under any circumstances (before they were given full weight if at least one active world wonder was present, and ignored otherwise), and multi-holy-cities now count extra as appropriate (before they were valued the same as single-holy-cities). Also greatly increases the weight values for these things, which were set negligibly small.

maybe even this:
EventTileDowngradeMod (NEW) (CvPlot.cpp, CvPlayer.cpp, CvCity.cpp)
Tile improvements that are hit by destruction events (like a Tornado) now behave as if they were pillaged instead; most are still destroyed, but Towns downgrade to Villages instead of being wiped out entirely, for example.
 
One possible issue with Fractional Great People Points is that it would break saved game compatibility. That would mean you'd have to swap out your DLL to open saved games posted to the forum.

I'll probably put it into BULL as another option a la Fractional Trade Routes, but FTR doesn't have the above problem since route values aren't saved.

The other two quoted ones seem reasonable at first skim. I dunno about Event Downgrade, though. If a volcano hits a Town, it's not going to just knock down a few buildings such that it's now only a Village. It's going to wipe it off the face of the planet. I do hate when that happens, though. :mad:
 
One possible issue with Fractional Great People Points is that it would break saved game compatibility. That would mean you'd have to swap out your DLL to open saved games posted to the forum.

Or play tricks with the UI flags and multiply the values. ;)
 
Yeah damn, I didn't think of that savegame issue. So no Fractional GPP. (or can you go around that after all? Storing 0.5 is all it needs to do for stock BTS)
AITargetCityValueFix looks like a good idea for BBAI but likely needs tweaking (double holy city is not really worth twice as much as a single)

But the one from Seph and BarbarianPassiveTechFix are just simple bug fixes in my eyes.
 
Or play tricks with the UI flags and multiply the values. ;)

That only works for a UP-loader. Those without the latest UP won't be able to open saves from those with it.

And yes, the one about trading with WEs before meeting them also sounds good.
 
Top Bottom