Unofficial Patch for 3.19

I had a weird issue when choosing what to research: when I tried to research machinery or some such, it researched pottery instead, even though I'm certain I should have been able to research it. No matter what I did, it tried to research some earlier thing instead.

Machinery requires Metal Casting which requires Pottery.

You may have been certain you should have been able to research it, but you were wrong.
 
Machinery requires Metal Casting which requires Pottery.

You may have been certain you should have been able to research it, but you were wrong.

Fortunately, you are right. I played after a long period of not playing, and didn't remember some tech requirements were shown in the upper right corner of the tech icon.
 
As you've fixed all the major stuff, which is much appreciated, I'm not really sure how much you think a new patch is needed, but out of curiosity, do you have any further ones in the pipeline?, Or are you now trying to fix Civ V ( :) )?
 
Hi all. I've come back to Civ4 after a long absence, and I've been playing a PBEM game with a friend. We're using the unofficial 3.19 patch as well as the BAT and BUG mods (I've crossposted this to that thread also).

Hovering over my flag shows:
BUG Mod 4.4 [Build 2220]
BULL 1.3 [Build 216]
Unofficial 3.19 patch v1.50

I've just got Liberalism, but when I try to select my free tech, I get in red "You have already chosen your free tech(s)". Googling this phrase brings up this page:
http://code.google.com/p/planetfall...ssets/XML/Text/TextBULL.xml?spec=svn888&r=888, which lists that phrase as a text resource under "<!-- Free Tech Popup Fix -->" with the tag "<Tag>TXT_KEY_CHEATERS_NEVER_PROSPER</Tag>"


I am certainly not cheating - but it looks like the game thinks I am!

My guess is that something in either the unofficial patch or the BAT/BUG mods is causing this. Has anyone else experienced this? Any suggestions on how to fix it?

Any advice gratefully received.
 
That is a fix to an exploit that allows you to choose as many free techs as you like. I haven't tested it with PBEM games, but I'm surprised that would cause any issues. Can you please answer the following?

  1. When did it ask you to choose a tech? As soon as you loaded the game or after you hit End Turn?
  2. What player # are you (if you started the game, probably 0)?
  3. Does it ask you to pick again?
  4. Are you blocked from continuing the game, even without your free tech?
  5. How many human players total?
  6. How many non-humans excluding barbs?
  7. Running as a mod or in CustomAssets?
  8. Other things asked on the Troubleshooting page in my sig.
I am really sorry this happened to you. Unfortunately, I can't think of a way to fix it in your current game. Any fix would require changing the DLL (where the problem occurs) which would invalidate the saved game AFAIK. I assume you've tried reloading the game?
 
Hi, thanks for the quick response!

That is a fix to an exploit that allows you to choose as many free techs as you like. I haven't tested it with PBEM games, but I'm surprised that would cause any issues. Can you please answer the following?

  1. When did it ask you to choose a tech? As soon as you loaded the game or after you hit End Turn?
  2. What player # are you (if you started the game, probably 0)?
  3. Does it ask you to pick again?
  4. Are you blocked from continuing the game, even without your free tech?
  5. How many human players total?
  6. How many non-humans excluding barbs?
  7. Running as a mod or in CustomAssets?
  8. Other things asked on the Troubleshooting page in my sig.

1 - IIRC, the first thing to happen on loading the turn was the tech page for liberalism popping up, and immediately after it prompted me to choose a tech. This was the normal Lib dialog box - "Choose your free tech", with turns to research all zero. When I clicked one (rifling, in this case, but I've reloaded and tried others with the same effect), I get the red "You have already chosen your free tech(s)" message at the top of the screen.
2 - I am the second of two human players, so player 1 if it's zero based. My friend started the game, and would be player zero.
3 - After picking the free tech and getting the error, I get the "Would you like to adopt free religion?" popup, then a normal "choose your next research" dialog, with Rifling showing as 10 turns. Selecting that allows me to go on with the turn, just with no benefit from Liberalism.
4 - See 3.
5 - Two humans.
6 - Five AIs I believe.
7 - I *believe* we installed the unofficial patch in CustomAssets, and BAT/BUG as a mod. Is there an easy way to check? (This is the first mod we've used).
8 - XP SP3. Now I know from your page how to enable logging, I have a bunch of logs in my logs directory - what should I be looking for?
I am really sorry this happened to you. Unfortunately, I can't think of a way to fix it in your current game. Any fix would require changing the DLL (where the problem occurs) which would invalidate the saved game AFAIK. I assume you've tried reloading the game?
Well, it's not the end of the world. To be honest, I'm so dominant in the game that it's probably a good thing :) But if there's an underlying problem, it would be nice to fix before it crops up again.

I've tried reloading several times, which results in exactly the same sequence of events. I've now backed up a turn (waiting on my friend to play his), hoping to bypass the problem. (I still have a copy of the affected turn backed up though).

I really have to hit the sack now - it's *very* late here - but I'd be more than happy to provide you with any further info you need in the morning. Thanks again for your help!

EDIT: I've now tried a clean install on another machine (Civ->Warlords->BtS->official 3.19->unofficial 3.19->BAT), with exactly the same result. So it's not a problem with my machine or installation.
 
No, I doubt it's a problem with the configuration. The way I block people from "enhancing" the Liberalism benefit is to keep track in the player of how many free techs they have remaining. It's been a long while since I wrote the code, but it's entirely possible that the code won't work if the game is saved in between.

I am hoping the solution is simply ignoring the issue when a PBEM game is involved and let the players enforce it themselves. Could you send me the save game from the turn before to my name at gmail.com? I'll see if I can do a quick test.
 
I am hoping the solution is simply ignoring the issue when a PBEM game is involved and let the players enforce it themselves. Could you send me the save game from the turn before to my name at gmail.com? I'll see if I can do a quick test.
Sure, sent.
 
I've been editing the AI's civic evaluation function for my mod, and I've just realised that one of the 'bug fixes' from the unofficial patch is actually a regression. ie. it creates a bug rather than fixes one.

I'll try to explain what I'm talking about. It's a bit subtle, and the original code certainly _looks_ wrong, but it actually worked correctly.

The changes I'm referring to are all the ones that look like this:
Code:
/************************************************************************************************/
/* UNOFFICIAL_PATCH                       10/21/09                                jdog5000      */
/*                                                                                              */
/* Bugfix                                                                                       */
/************************************************************************************************/
/* orginal bts code
		iValue += (getNumCities() * 6 * AI_getHealthWeight(isCivic(eCivic) ? -kCivic.getExtraHealth() : kCivic.getExtraHealth(), 1)) / 100;
*/
		iValue += (iCities * 6 * AI_getHealthWeight(kCivic.getExtraHealth(), 1)) / 100;
/************************************************************************************************/
/* UNOFFICIAL_PATCH                        END                                                  */
/************************************************************************************************/
There are a bunch of changes like this, for happiness and healthiness. This looks like the original code would subtract the value of the bonus if we were already in that civic - which would make the civic significantly less desired... clearly a bug.

However, things are not what they seem, because in the AI_getHealthWeight function, there is a second 'bug fix'.

Code:
/************************************************************************************************/
/* UNOFFICIAL_PATCH                       10/21/09                                jdog5000      */
/*                                                                                              */
/* Bugfix                                                                                       */
/************************************************************************************************/
/* orginal bts code
			iValue += std::max(0, -iTempValue);
*/
			// Negative health changes should produce a negative value, not the same value as positive
			iValue += std::min(0, iTempValue);
/************************************************************************************************/
/* UNOFFICIAL_PATCH                        END                                                  */
/************************************************************************************************/
Here, the original bts code essentially would return the absolute value. Therefore, AI_getHealthWeight(-kCivic.getExtraHealth()) would return a positive number after all, so it actually wasn't devaluing the civic.

Alright, so it might look like these two changes just put us back where we started, except that we are now able to correctly evaluate civics which have negative effects (which wouldn't have worked correctly under the original code). That's true, and it's important, but there's a problem.

Consider this: a happiness bonus is worth more if you don't have much happiness. For example, if I have a city with 1 anger citizen and I'm considering a civic which gives +1 happiness, I'd probably think "that's just what I need". However, if I switch to that civic I would then have 0 anger citizens, and so when I re-evaluate the civic I would probably think "I don't need an extra happiness point, so this civic is not valuable" – so I switch out of the civic, lose the happiness, then decide that I need it again! ... etc.

The original code
Code:
AI_getHealthWeight(isCivic(eCivic) ? -kCivic.getExtraHealth() : kCivic.getExtraHealth(), 1)
deals with this issue. If you are already using that civic, it tells you the cost of losing the bonus. If you are not using the civic, it tells you the value of gaining the bonus.

So the original code worked correctly (for positive bonuses) and the patched code does not work correctly.

For negative bonuses, the original code is completely wrong. So... my recommendation is to keep the change which allows AI_getHealthWeight and AI_getHappyWeight to return negative value; but to change the other part to something like this:
Code:
iValue += (getNumCities() * (isCivic(eCivic)?-6:6) * AI_getHealthWeight(isCivic(eCivic) ? -kCivic.getExtraHealth() : kCivic.getExtraHealth(), 1)) / 100;

(I don't actually expect that there will be a new version of the Unofficial Patch; otherwise I would have been reporting the other bugs I've found. The only reason I'm reporting this is because I think it's a regression.)
 
Hi. I found a problem in
PHP:
void CvTeam::setHasTech(TechTypes eIndex, bool bNewValue, PlayerTypes ePlayer, bool bFirst, bool bAnnounce)

Here the code part I'm talking about:
PHP:
			for (iI = 0; iI < GC.getMapINLINE().numPlotsINLINE(); iI++)
			{
				pLoopPlot = GC.getMapINLINE().plotByIndexINLINE(iI);

				if (pLoopPlot->getBonusType() != NO_BONUS)
				{
					if (pLoopPlot->getTeam() == getID())
					{
						if ((GC.getBonusInfo(pLoopPlot->getBonusType()).getTechReveal() == eIndex) ||
							  (GC.getBonusInfo(pLoopPlot->getBonusType()).getTechCityTrade() == eIndex) ||
								(GC.getBonusInfo(pLoopPlot->getBonusType()).getTechObsolete() == eIndex))
						{
							pLoopPlot->updatePlotGroupBonus(false);
						}
					}
				}
			}

			m_pabHasTech[eIndex] = bNewValue;

			for (iI = 0; iI < GC.getMapINLINE().numPlotsINLINE(); iI++)
			{
				pLoopPlot = GC.getMapINLINE().plotByIndexINLINE(iI);

				if (pLoopPlot->getBonusType() != NO_BONUS)
				{
					if (pLoopPlot->getTeam() == getID())
					{
						if ((GC.getBonusInfo(pLoopPlot->getBonusType()).getTechReveal() == eIndex) ||
							  (GC.getBonusInfo(pLoopPlot->getBonusType()).getTechCityTrade() == eIndex) ||
							  (GC.getBonusInfo(pLoopPlot->getBonusType()).getTechObsolete() == eIndex))
						{
							pLoopPlot->updatePlotGroupBonus(true);
						}
					}
				}
			}

The problem:
The function only updates the bonuses if there is a plot with a bonus that becomes obsolete. But that's a problem! What about cities with free bonuses that become obsolete? Maybe free bonuses from a building of the city.

The code should look like this:
PHP:
			for (iI = 0; iI < GC.getMapINLINE().numPlotsINLINE(); iI++)
			{
				pLoopPlot = GC.getMapINLINE().plotByIndexINLINE(iI);

				// Thomas SG - Bugfix
				if (pLoopPlot->isCity(false,getID()))
				{
					pLoopPlot->updatePlotGroupBonus(false);
				}
				else if (pLoopPlot->getBonusType() != NO_BONUS)
				{
					if (pLoopPlot->getTeam() == getID())
					{
						if ((GC.getBonusInfo(pLoopPlot->getBonusType()).getTechReveal() == eIndex) ||
							  (GC.getBonusInfo(pLoopPlot->getBonusType()).getTechCityTrade() == eIndex) ||
								(GC.getBonusInfo(pLoopPlot->getBonusType()).getTechObsolete() == eIndex))
						{
							pLoopPlot->updatePlotGroupBonus(false);
						}
					}
				}
			}

			m_pabHasTech[eIndex] = bNewValue;

			for (iI = 0; iI < GC.getMapINLINE().numPlotsINLINE(); iI++)
			{
				pLoopPlot = GC.getMapINLINE().plotByIndexINLINE(iI);


				// Thomas SG - Bugfix
				if (pLoopPlot->isCity(false,getID()))
				{
					pLoopPlot->updatePlotGroupBonus(true);
				}
				else if (pLoopPlot->getBonusType() != NO_BONUS)
				{
					if (pLoopPlot->getTeam() == getID())
					{
						if ((GC.getBonusInfo(pLoopPlot->getBonusType()).getTechReveal() == eIndex) ||
							  (GC.getBonusInfo(pLoopPlot->getBonusType()).getTechCityTrade() == eIndex) ||
							  (GC.getBonusInfo(pLoopPlot->getBonusType()).getTechObsolete() == eIndex))
						{
							pLoopPlot->updatePlotGroupBonus(true);
						}
					}
				}
			}
 
I have a (basic) question - if I install this as a MOD and place scenarios under it (privateMaps) will it work correctly or will it use the official BTS patch?
 
I've just got Liberalism, but when I try to select my free tech, I get in red "You have already chosen your free tech(s)". Googling this phrase brings up this page:
http://code.google.com/p/planetfall...ssets/XML/Text/TextBULL.xml?spec=svn888&r=888, which lists that phrase as a text resource under "<!-- Free Tech Popup Fix -->" with the tag "<Tag>TXT_KEY_CHEATERS_NEVER_PROSPER</Tag>"


I am certainly not cheating - but it looks like the game thinks I am!
I've noticed this as well. The problem is that the unofficial patch does not save the variable "m_bChoosingFreeTech" in the save files. This means that if you reload the save game on the same turn that you get a free tech, it will assume you are not meant to be choosing a free tech, and thus will call you a cheater. Unfortunately, in PBEM games, every turn reloads the save... so it always triggers the bug.

This bug is fixed in K-Mod. (the commit for the fix is here, but unfortunately, that same commit also changes a stack of other K-Mod things. So it isn't easy to see exactly which bits are for this bug. Suffice to say it's just a matter of including m_bChoosingFreeTech in the save files.)
 
Unfortunately, for the Unofficial Patch breaking saved game compatibility wasn't an option. You can try loading the autosave immediately before the turn where you acquired Liberalism. Did you by chance reload the autosave of the turn where you just acquired it? Otherwise it shouldn't happen.
 
Unfortunately, for the Unofficial Patch breaking saved game compatibility wasn't an option. You can try loading the autosave immediately before the turn where you acquired Liberalism. Did you by chance reload the autosave of the turn where you just acquired it? Otherwise it shouldn't happen.
Yes, it only happens on the autosave on the exact turn of getting the free tech. So it isn't really a big deal for normal games. But the big problem is that in play-by-email games, every turn is essentially loading an autosave. So this bug can not be avoided - you always miss the free tech. (At least, that's how I understand it. I've never actually played a PBEM game.)

In my view, this is a pretty serious flaw - and probably one worth changing the save format for. But perhaps there is some other way to solve the original problem without the m_bChoosingFreeTech thing. (I don't actually know what the original problem was, so I don't have any advice for that.)
 
It's been a long while since I made the fix, but as I recall the problem is that the "open the free tech popup" command is issued at the end of the previous turn but of course doesn't appear until the beginning of the next turn. This is just how Civ4 turns work:

  1. Player makes moves
  2. Player hits end turn
  3. Game performs automoves
  4. Game acquires techs
  5. Other players make their moves
  6. Player starts their move
  7. Game displays popups/diplomacy created during 4 and 5
That's abridged, but it illustrates the problem. What I did was add a field to the CvPlayer that tracks how many free techs they have available which gets decremented when they select a tech in the popup. The exploit would allow them to select a tech, get it, and have the popup reappear immediately.

The bug is caused because when you load a game you are starting at step 6, but all the popups opened between hitting the end turn button and starting your next turn are saved. Because I don't save the "how many free techs do you have coming to you" value, when the popup appears I see zero for that value (in memory) and determine you must be cheating.

If there were a way to determine that the game was just loaded, I could assume you have one free tech coming to fix it, but I don't know if that's possible. It may be. Actually, maybe I can set that value when the popup is loaded from the saved game. Hmm, that would solve it without breaking save compatibility.

If any SDK modders are keeping track of this thread, could you see if the code that loads the queued popups is available in the SDK? If they are, it should be a simple matter of detecting the free tech popup and assigning one free tech to the player.
 
EmperorFool, without the unofficial patch, what does one actually have to do in order to get extra free techs? I see that the actual free tech comes on the turn after the event that grants the free tech - but I'm not really sure what the exploit is that the unofficial patch corrects.

Actually, the real reason I'm posting is to ask about this code in CvSelectionGroup::continueMission :
Code:
/************************************************************************************************/
/* UNOFFICIAL_PATCH                       08/04/09                                jdog5000      */
/*                                                                                              */
/* Player interface                                                                             */
/************************************************************************************************/
/* original bts code
				deleteMissionQueueNode(headMissionQueueNode());
*/
				if (!isHuman() || (headMissionQueueNode()->m_data.eMissionType != MISSION_MOVE_TO))
				{
					deleteMissionQueueNode(headMissionQueueNode());
				}
				else
				{
					if (canAllMove() || (nextMissionQueueNode(headMissionQueueNode()) == NULL))
					{
						deleteMissionQueueNode(headMissionQueueNode());
					}
				}
/************************************************************************************************/
/* UNOFFICIAL_PATCH                        END                                                  */
/************************************************************************************************/
I'd like to know what this change is meant to fix. The change is causing a minor problem with my "rapid unit cycling" feature, and although I could work around the problem easily enough, I'm tempted to just delete all of those unofficial patch conditions because I don't see why they are there in the first place. But presumably there is some purpose for the conditions... Does anyone know what that purpose is?
 
IIRC you need to hit both left- and right-mouse buttons together. I worked the timing out at the time, and it's probably that you must let go of right-click last, but I don't remember precisely. What happens is that you trigger both "yes, this is the tech I want for free" and "show me the Civilopedia entry for this tech" actions, and this causes the game to give you the free tech but neglect to decrement your free tech counter.

The other way is to choose your free tech, save, reload, and repeat forever. At least, I think that worked as well. This was over two years ago mind you that I worked out a solution . . . :)
 
Top Bottom