Help forcing a players turn to end immediately

DasGuntLord01

Chieftain
Joined
Feb 11, 2010
Messages
80
I'm trying to make a simple mod that will let one player watch a duel between two others: a spectator mod!

One of the things that is annoying for both spectator and player is that the spectator still needs to end turn manually. Since the "wait until end of turn" option doesn't actually work properly, I thought a solution might lie in python: at the beginning of the spectators turn, can I force the turn to end immediately?

The "Defense" mod that comes with BTS uses CyMessageControl().sendTurnComplete(), which works like a charm in that mod. But it doesn't work for me in mine. Here is my code.

CvEventManager.py
Code:
def onBeginPlayerTurn(self, argsList):
		'Called at the beginning of a players turn'
		iGameTurn, iPlayer = argsList
		forceTurn.checkForceTurn(iPlayer)

my forceTurn.py:
Code:
from CvPythonExtensions import *
from PyHelpers import *
from Popup import PyPopup
import time

gc = CyGlobalContext()
cyGame = CyGame()
cyMap = CyMap()
pyGame = PyGame()
eng = CyEngine()

def checkForceTurn(player):
	
	cyPlayer = gc.getPlayer(player);
		
	iCivType = cyPlayer.getCivilizationType();
	
	if iCivType >= 36: ##civs 36+ are spectator civs
		modPopup = PyPopup()
		modPopup.setHeaderString("New Turn")
		modPopup.setBodyString("Attempting to force end of turn. %i" % (iCivType))
		modPopup.launch()
		
		CyMessageControl().sendTurnComplete()

This throws no errors, but does NOT end the players turn.

Does anyone have any advice? Thanks in advance.

EDIT: As part of the mod, I have added in extra civ ("Spectator 1") that IS civ 36, and the use of the popup in the above code verifies this.
With God-Emperors suggestion (below) I removed the popup code, and this did not solve the problem.
 
I would guess that the popup requires clicking on a button to exit it. After that it ought to end the turn.

If it doesn't, perhaps the civ you are using doesn't actually have a type >= 36. BtS only has 34 regular civ types (and Minor and Barbarian).
 
I would guess that the popup requires clicking on a button to exit it. After that it ought to end the turn.

If it doesn't, perhaps the civ you are using doesn't actually have a type >= 36. BtS only has 34 regular civ types (and Minor and Barbarian).

Perhaps I should have been more clear in the OP. I added an extra civ, called "Spectator 1", that IS civ #36. The popup code was added to confirm that this was the case. The popup does appear only once at the beginning of the spectator's turn.

I can also verify that removing the popup code does not solve the problem. The turn still doesn't end.

I'm making a guess that there is extra "stuff" happening as part of the beginning of the players turn that explicitly or implicitly prevents the function from ending the turn. My next experiment is going to be and see if I can find a way for check for the appropriate condition, and THEN force the end of the turn. Further examination of the defense mod will probably help.
 
The answer is because it is done onBeginPlayerTurn, which is misleading.

onBPT actually triggers at the end of the player turn rather than at the start if I am not wrong.
You can do a simple test, by printing out the iGameTurn, or simply do a loop through all units and set them to finishMoves()

You will realise that iGameTurn is actually the turn before, and all units will still be able to move.

Thus, you are simply ending the previous turn.

Code:
	def onBeginPlayerTurn(self, argsList):
		'Called at the beginning of a players turn'
		iGameTurn, iPlayer = argsList
		CyInterface().addMessage(iPlayer,True,15,str(iGameTurn),'',0, '', -1, -1, -1, True,True)
		pPlayer = gc.getPlayer(iPlayer)
		(loopUnit, iter) = pPlayer.firstUnit(False)
		while(loopUnit):
			loopUnit.finishMoves()
			(loopUnit, iter) = pPlayer.nextUnit(iter, False)
 
I think platyping is right.

I seem to recall that the onBeginPlayerTurn event handler is run right after you click on the end-turn button. It is not the beginning of the part of your turn where you move things, it is the beginning of the part of the turn where it does its calculations to process the results of your turn like adding production to things being built in your cities (if you have 1 turn left showing for the time to build a unit, that unit will be completed and sitting in the city when the next player's turn starts and therefore it can defend your city if they are attacking you).

OK, I just checked the DLL and that is evidently the case.

I just checked the Defense mod and the reason it works there is that it is in the CvMainInterface::updateScreen function, which is called about 4 times per second to update information on the screen.
 
Well, that's frustrating, but thanks for the info. :)

EDIT

So, i guess I CAN use onGameUpdate ("sample generic event, called on each game turn slice"), and end a spectator players turn from there?

EDIT2: That seems to have done the trick! TYVM for the help!!:D
 
Back
Top Bottom