RevolutionDCM for BTS

I can try the former (is AIAutoplay good enough?), and for the latter does it matter if the killer is human or AI?

Both critical bugs happened for me using AIAutoplay. AI killed the civ I switched to, and that was a reproducable crash for me previously (had to switch into a newly spawned civ, then switched out and when AI killed that civ it crashed, got alot of asserts about civ indexes being out of bounds though, so that might have been fixed already, haven't checked that since you started helping). I'm still confused how I get a key error that throws alot of python asserts and you don't though, but I'll deal with that later. If change player works for you, that's good, may just be an issue with my comp.
 
As I said, error logs / screenshots could still help. If there is a keyError, there must be dictionary without an entry for the requested key..
 
After almost 150 turns of autoply, all I got was one assert message from AI_doWar() (CvTeamAI::AI_doTurnPost())
FAssert(!AI_shareWar((TeamTypes)iI));
Which as far as I can see only means a team was considering to start a war against the enemy of an enemy, which is not smart but no problem either.
 
I think I finally found something.
CvUnitAI::AI_pickupStranded, line 20771
if( pPickupPlot != NULL && iPathTurns <= iMaxPath )
gave me a "variable iPathTurns is used without being initialized" error/warning.
edit: the message says "Run-Time Check Failure #3: The variable 'iPathTurns' is being used without being defined"
- (and I just hope that defined means initialized here ..)
I believe that doesn't crash XP but it does for newer windows.

Spoiler :
fix:
Code:
			if( 1000*iCount > iBestValue )
			{
				pPickupPlot = NULL;
[B]				if( atPlot(pLoopPlot) )
				{
					pPickupPlot = pLoopPlot;
					iPathTurns = 0;
				}
				else if( AI_plotValid(pLoopPlot) && generatePath(pLoopPlot, 0, true, &iPathTurns) )[/B]
				{
					pPickupPlot = pLoopPlot;
				}
				else
				{
					[B]for (iI = 0; iI < NUM_DIRECTION_TYPES; iI++)
					{
						pAdjacentPlot = plotDirection(pLoopPlot->getX_INLINE(), pLoopPlot->getY_INLINE(), ((DirectionTypes)iI));

						if (pAdjacentPlot != NULL && atPlot(pLoopPlot))
						{
							pPickupPlot = pAdjacentPlot;
							iPathTurns = 0;
							break;
						}
					}
					
					if (pPickupPlot == NULL)[/B]
					[B]{[/B]
						for (iI = 0; iI < NUM_DIRECTION_TYPES; iI++)
						{
							pAdjacentPlot = plotDirection(pLoopPlot->getX_INLINE(), pLoopPlot->getY_INLINE(), ((DirectionTypes)iI));

							if (pAdjacentPlot != NULL && AI_plotValid(pAdjacentPlot))
							{
								if( generatePath(pAdjacentPlot, 0, true, &iPathTurns) )
								{
									pPickupPlot = pAdjacentPlot;
									break;
								}
							}
						}
					[B]}[/B]
				}
 
I tried to recreate the switching to a player, switching out and watching that player get killed a few turns later. No error either.

I don't compile with /D_MOD_SHAM_SPOILER since that is cheating and I suggest you turn it off in the RevDCM makefile too. I'm not sure if that could cause any differences when it comes to what bugs pop up, I doubt it though so this is just a sidenote.
 
OK, think I'll go post in the bug forums and see if EF has any ideas, since it seems really strange I get an error, and you don't.

Edit:
Ah, the error doesn't occur if you save and reload after the civ is created. You must switch into a newly created civ that was spawned in that play session, if you save and reload you can switch into them without issue.
 
Oh, not just soon-to-be-dead but spawned before load .. ok, then I did not yet recreate that situation right.
 
Yeah, didn't realize that until I loaded that save and also didn't get an error, so I hit AIAuotplay and ran forward for another 100 turns, the Germans spawned sometime in there, and when AIAutoplay stopped I switched to them, and got the key error again. Here are my python error logs.
 
Sorry, I don't think I can fix that.
The theory is easy: you just have to call _reset for Civ4lerts WorstEnemy and RefusesToTalk classes whenever after a formerly human player gets turned into an AI player, which happens at the end of CvGame::changeHumanPlayer -
GET_PLAYER(eCurHuman).setIsHuman(false);

However since I have no clue about python I don't really know how to do it, especially not how to do it the right way.
 
That's cool, I'll post in the BUG forums and see if EF can't help out with this.
 
It should work, reloading has the same curing _reset effect. But EF seems pretty busy atm .. maybe call Afforess to the rescue again?
 
It should work, reloading has the same curing _reset effect. But EF seems pretty busy atm .. maybe call Afforess to the rescue again?

He's busy until Monday.
 
Sorry, I don't think I can fix that.
The theory is easy: you just have to call _reset for Civ4lerts WorstEnemy and RefusesToTalk classes whenever after a formerly human player gets turned into an AI player, which happens at the end of CvGame::changeHumanPlayer -
GET_PLAYER(eCurHuman).setIsHuman(false);

However since I have no clue about python I don't really know how to do it, especially not how to do it the right way.

So if I'm understanding correctly, a way to do this would be to add an event through CvEventManager (actually add it modularly through the BUG system) that fires when CvGame::changeHumanPlayer. Basically I should take a look at onGameStart and how that gets python to fire this event at the start of a game, and copy this so that a new event is fired for python when CvGame::changeHumanPlayer happens, then add in a reset in Civ4lerts when this occurs. If this is what you're saying, I think I can code that.
 
maybe call Afforess to the rescue again?

I talked with EF about it weeks ago - but he seems to have given up Civ modding.


Anyway, Phungus's idea of adding a new event in the SDK for when the active player changes is a good one. I've added an event before (for when a player changes teams... actually, I need to port it over to RevDCM for Dynamic Civ Names eventually. :p ), it isn't too hard.

Once the new event is working, it needs to call the reset functions on any of the Civ Alerts modules that sorts lists based on the active player.

He's busy until Monday.

Found an internet connection. CFC is like my constant high... that sounds bad. :lol:
 
Well I tried to shortcut it, gc.getGame().changeHumanPlayer is actually called in RevUtils (and no where else in Python), when changePlayer is executed. So I tried this in RevUtils:

Code:
def changeHuman( newHumanIdx, oldHumanIdx ) :
##********************************
##   LEMMY 101 FIX
##********************************
	[B]import Civ4lerts[/B]
	game.changeHumanPlayer( oldHumanIdx, newHumanIdx )
	[B]Civ4lerts._reset()[/B]
##********************************
##   LEMMY 101 FIX
##********************************

Code fires correctly, and from what I understand this should reset Civ4lerts right after this function is fired. Unfortunately it does not fix this bug.
 
Civ4lerts._reset() does nothing. (the code simply says "Pass). You'll need to find the individual portions of code and call resets for each of them.
 
Civ4lerts._reset() does nothing. (the code simply says "Pass). You'll need to find the individual portions of code and call resets for each of them.

I tried resseting the specific classes as well, but no dice:

Civ4lerts.WorstEnemy._reset()
Civ4lerts.RefusesToTalk._reset()

I'm a little confused then with specifics. If I go through and add a python event for when CvGame::changeHumanPlayer is executed, what specifically would I need this event to do? It seems like adding that code into RevUtils is basically running the reset function after changeHumanPlayer runs now, so it's the same effect as adding an event, unless I'm missing something.

This is what's in the Python error log:
Code:
Traceback (most recent call last):
  File "BugEventManager", line 361, in _handleDefaultEvent
  File "Civ4lerts", line 829, in onBeginActivePlayerTurn
  File "Civ4lerts", line 866, in check
KeyError: 7
Traceback (most recent call last):
  File "BugEventManager", line 361, in _handleDefaultEvent
  File "Civ4lerts", line 905, in onBeginActivePlayerTurn
  File "Civ4lerts", line 944, in check
KeyError: 7

Which corresponds to this code in Civ4lerts:
Code:
	def check(self):
		if (not Civ4lertsOpt.isShowRefusesToTalkAlert()):
			return
		eActivePlayer, activePlayer = PlayerUtil.getActivePlayerAndID()
		refusals = self.refusals[eActivePlayer]
		[B]newRefusals = set()[/B]
...
And:
Code:
	def check(self):
		if (not Civ4lertsOpt.isShowWorstEnemyAlert()):
			return
		eActivePlayer = PlayerUtil.getActivePlayerID()
		eActiveTeam, activeTeam = PlayerUtil.getActiveTeamAndID()
		enemies = self.enemies[eActivePlayer]
		newEnemies = AttitudeUtil.getWorstEnemyTeams()
		[B]delayedMessages = {}[/B]

I'm not exactly sure what needs to be fixed here (was hoping just running that reset function after CvGame::changeHumanPlayer is called would work, but guess not). Not really sure where to go from here, and I don't want to write the code for creating a new python event if I'm not sure how I'm supposed to use it to fix this bug.
 
I tried resseting the specific classes as well, but no dice:

Civ4lerts.WorstEnemy._reset()
Civ4lerts.RefusesToTalk._reset()

I'm a little confused then with specifics. If I go through and add a python event for when CvGame::changeHumanPlayer is executed, what specifically would I need this event to do? It seems like adding that code into RevUtils is basically running the reset function after changeHumanPlayer runs now, so it's the same effect as adding an event, unless I'm missing something.

I agree, it should be the same thing as adding a new event.

I'm not at a computer that has Civ - so my question to you is what value is eActivePlayer, from the line above the first error? I'm suspecting -1...
 
Actually screw what I said before, Civ4lerts just has to keep track of players that are human or dead too by simply storing that NO_TEAM is their worst enemy. Once it does that, there will be no missing keys when one of those formerly dead civs changes its worst enemy or refusal state.
 
Back
Top Bottom