1. Firaxis celebrates the "Asian American and Pacific Islander Heritage Month", and offers a give-away of a Civ6 anthology copy (5 in total)! For all the details, please check the thread here. .
    Dismiss Notice

Python: How to call the function at the end of a turn

Discussion in 'Civ4 - Modding Tutorials & Reference' started by Olleus, Mar 19, 2006.

  1. Olleus

    Olleus Deity

    Oct 30, 2005
    Beyond the Veil
    In civ4 python their is no function which is called at the end of a turn. onEndPlayerTurn is actualy called before you move any unit, and onEndGameTurn is called once every player has moved. I have made a scipt which i called at the begining of a players turn and returns the index of the previous player. Using this you can fool the computer into calling a script at the end of a players turn.

    	def onBeginPlayerTurn(self, argsList):
    		'Called at the beginning of a players turn'
    		iGameTurn, iPlayer = argsList
    		if iPlayer == 0:
    			iRealPlayer = 18
    		elif iPlayer == 18:
    			iRealPlayer = gc.getGame().countCivPlayersEverAlive() - 1
    			while gc.getPlayer(iRealPlayer).isAlive() == False:
    				iRealPlayer -= 1
    			iRealPlayer = iPlayer - 1
    			while gc.getPlayer(iRealPlayer).isAlive() == False:
    				iRealPlayer -= 1
                    # iRealplayer is the index of the previous player
    A far as I can see it always works.
  2. Kael

    Kael Deity

    May 6, 2002
    Thanks for writing this, Im checking it into FfH now.
  3. jdog5000

    jdog5000 Revolutionary

    Nov 25, 2003
    Excellent idea. One minor point, where ever you have an 18, you should replace it with gc.getBARBARIAN_PLAYER() to support dll hacks allowing more than 18 civs ...

    EDIT: To cover a corner case where player 0 is dead (wouldn't usually occur in normal game, as player 0 is human and if they're dead the game is over), I used:

    def onBeginPlayerTurn( self, argsList ) :
        iGameTurn, iPlayer = argsList
        # Stuff at end of previous players turn
        iPrevPlayer = iPlayer - 1
        while( iPrevPlayer >= 0 and not gc.getPlayer(iPrevPlayer).isAlive() ) :
                iPrevPlayer -= 1
        if( iPrevPlayer < 0 ) :
            iPrevPlayer = gc.getBARBARIAN_PLAYER()
  4. MatzeHH

    MatzeHH Warlord

    Jan 8, 2006
    That is what I was thinking before I tried to use a mod in a scenario.
    In scenarios, the human player is not always player 0.

  5. Gerikes

    Gerikes User of Run-on Sentences.

    Jul 26, 2005
    Same with Multiplayer. Especially in a simultaneous game.

    Simultaneous games make all the players active at the start. When a player becomes "active", in a simultaneous game their turn (doTurn())is run automatically (unlike a SP game where the turn is run at the end of the turn, when they become inactive). In order to make sure that player 0 won't always have their turn run first, thus whenever there's a tie in who built a wonder/researched a tech first, player 0 won't always get the win, the players start their turn in a random order every turn.

    Of course, you don't have to worry about doing something at the "start" of a turn anyway in simultaneous games, since I believe that all changes happen at the beginning of a player's turn in simultaneous mode anyway.

    While theres probably no real problem in doing it this way, just realize that if at the end of these statements you have some function "doBeginTurn()", that the actual order that the players turns are being run for a simultaneous game are going to be different than the order of the doBeginTurn() runs. In many cases, this won't matter, but if somehow it's critical that the turns are run in the correct order, you'll have problems in a simultaneous game.

    If you do have this problem, I would recommend going into the CvPlayer::setTurnActive() function, go into the code block where it says:

    [b]// Insert your begin-turn code here[/b]
    and put a function call (or python function call) to do what you want. This would be where a turn actually starts.

Share This Page