[BTS] having problems with adding victory condition

KeeperOT7Keys

did nothing wrong
Joined
Jul 10, 2013
Messages
384
Location
Mugla, Turkey
I am having a couple of problems with adding a new victory condition to an existing mod (history rewritten but I don't think this part is very important).
I want to add some kind of a double score victory, like if you are in digital age and your score is more than x2 of your closest opponent you win, or if you have x8 score in the ancient age.

but somehow my win condition triggers when everybody has the same score at turn 10~. I don't get what triggers the bug, here's my XML and python code:

XML:
<VictoryInfo>
            <Type>QUICK_DOMINATION</Type>
            <Description>TXT_KEY_VICTORY_QUICK_DOMINATION</Description>
            <Civilopedia>TXT_KEY_VICTORY_QUICK_DOMINATION_PEDIA</Civilopedia>
            <bTargetScore>0</bTargetScore>
            <bEndScore>0</bEndScore>
            <bConquest>0</bConquest>
            <bDiploVote>0</bDiploVote>
            <bPermanent>1</bPermanent>
            <iPopulationPercentLead>0</iPopulationPercentLead>
            <iLandPercent>0</iLandPercent>
            <iMinLandPercent>0</iMinLandPercent>
            <iReligionPercent>0</iReligionPercent>
            <CityCulture>NONE</CityCulture>
            <iNumCultureCities>0</iNumCultureCities>
            <iTotalCultureRatio>0</iTotalCultureRatio>
            <iVictoryDelayTurns>0</iVictoryDelayTurns>
            <VictoryMovie>ART_DEF_MOVIE_VICTORY_DOMINATION</VictoryMovie>
        </VictoryInfo>


def onEndGameTurn(self, argsList): ... if CyGame().isVictoryValid(gc.getInfoTypeForString('VICTORY_QUICK_DOMINATION')): iPlayerHighestScore = -1 secondHighestScore = -1 highestScore = -1 for iPlayer in xrange(gc.getMAX_PLAYERS()): pPlayer = gc.getPlayer(iPlayer) if pPlayer.isAlive(): # this is how scores in board is calculated iPopulationScore = CvUtil.getScoreComponent(pPlayer.getPopScore(), gc.getGame().getInitPopulation(), gc.getGame().getMaxPopulation(), gc.getDefineINT("SCORE_POPULATION_FACTOR"), True, False, False) iLandScore = CvUtil.getScoreComponent(pPlayer.getLandScore(), gc.getGame().getInitLand(), gc.getGame().getMaxLand(), gc.getDefineINT("SCORE_LAND_FACTOR"), True, False, False) iTechScore = CvUtil.getScoreComponent(pPlayer.getTechScore(), gc.getGame().getInitTech(), gc.getGame().getMaxTech(), gc.getDefineINT("SCORE_TECH_FACTOR"), True, False, False) iWondersScore = CvUtil.getScoreComponent(pPlayer.getWondersScore(), gc.getGame().getInitWonders(), gc.getGame().getMaxWonders(), gc.getDefineINT("SCORE_WONDER_FACTOR"), False, False, False) playerScore = iPopulationScore + iLandScore + iWondersScore + iTechScore # compare scores if playerScore > highestScore: secondHighestScore = highestScore highestScore = playerScore iPlayerHighestScore = iPlayer elif playerScore > secondHighestScore: secondHighestScore = playerScore era = gc.getPlayer(iPlayerHighestScore).getCurrentEra() iFinalEra = CvUtil.findInfoTypeNum(gc.getEraInfo,gc.getNumEraInfos(),'ERA_DIGITAL') if highestScore > (secondHighestScore * (iFinalEra-era+2)): gc.getGame().setWinner(iPlayerHighestScore, 8)

another bigger problem is, somehow debug codes I have aren't working either, I have all logging and exception stuff open, but neither "interface.addmessage" nor plain "print" produce any output in the game or in the logs. any ideas what might be the cause?
 
plain "print" produce any output in the game or in the logs
Check the ini file to see if logging is enabled. I have had problems where the ini file has reset to hide logs, python exceptions etc.

PHP:
gDLL->ChangeINIKeyValue("CONFIG", "HidePythonExceptions", "0");
I added this line to CvXMLLoadUtility::LoadPlayerOptions (yeah DLL) to ensure bug reports related to python errors will always be useful. It also fights the issue of ini file killing the python exceptions.

As for why there is a victory at turn 10, I have no idea. The code looks valid so it would make sense to add print (playerID, score) pairs, but I guess you already knew that.

I wonder about the hassle of setting up iFinalEra. Why not simply relying on gc.getNumEraInfos()? Either approach should work through. However since there is a problem with triggering incorrectly, I would simplify the last if statement and make variables prior to it. Make it do multiple lines with just a single math operation on each and then the if statement is A > B, where each is a variable, no math in that line. On top of making it easier to read, it will also allow print/log to be done at each step.

There is one bug through. CyGame::setWinner takes TeamTypes as argument, not PlayerTypes. In most cases those two are the same, but not always. If you are to do this technically correct, then you should loop teams and then add up the scores for all players on each team and then declare the winner to be the team with the highest score.
 
thanks for the suggestion, I found the cause of the bugs. Apparently there were two bugs happening at once which prevented me from understanding what was going on:
I had copied one of the existing victory conditions' xml to create mine, but for some unknown reason the game was triggering it as some other condition, like it was thinking I had a second domination condition while I didn't intend that. I fixed this by making mine based on timer victory.
second bug was just an xml mismatch, I was using quick_domination in my xml and victory_quick_domination in my python code, that's why my body wasn't executed.

I also added team thing and I realized there's actually one liner for score calculation, which helped me to simplify code:
Code:
CyGame().getTeamScore(iTeam)
 
Top Bottom