Making "taxes" visible

phungus420

Deity
Joined
Mar 1, 2003
Messages
6,296
I need to make the RevIdx of taxes visible. Or at least get something on screen so that I can see what my code calculates.

How can I do this? I've been told to throw in a print statement, but I don't know what that is. I'm trying to adjust the taxes model, but I can't begin to experiment with it, if I can't see the numbers that get churned out by the code.

See here for what I mean:
http://forums.civfanatics.com/showpost.php?p=7887106&postcount=39

from revolutions.py
Code:
        # Finances
        finIdx = 0
        finIdx2 = 0
        taxesIdx = 0

        goldPerc = pPlayer.getCommercePercent( CommerceTypes.COMMERCE_GOLD )
        #I need a print statement to tell me what goldPerc is being calculated as here.
        #This is where I need to see the numbers.  How can I do this?  
        #Once I figure out how to get a print statement working where will the value be displayed?
        sciPerc = pPlayer.getCommercePercent( CommerceTypes.COMMERCE_RESEARCH )
        cultPerc = pPlayer.getCommercePercent( CommerceTypes.COMMERCE_CULTURE )

Alternatively, I'd be just as happy (in fact happier) with getting this to actually show in the RevIdx bar. Currently nothing is displayed, but the TXT calls do in deed exist in the Revolutions text file, so I don't know why they are broken:
Spoiler :
Code:
        if( pTeam.getAtWarCount(True) == 0 ) :
            if( goldPerc > 50 ) :
                # At peace, stronger penalties for taxes and financial trouble
                iGold = pPlayer.getGold()
                goldRate = pPlayer.calculateGoldRate()

                # Taxes
                taxesIdx -= (goldPerc - 50)/3
                if( goldRate > 10*pPlayer.getCurrentEra() ) :
                    taxesIdx /=2
                if( bIsRevWatch ) : negList.append( (taxesIdx, localText.getText("TXT_KEY_REV_WATCH_TAXES",())) )

                # Finances
                if( iGold < 50 + 12*pPlayer.getCurrentEra() and goldRate < 1 + pPlayer.getCurrentEra() ) :
                    if( self.LOG_DEBUG and bVerbose) : CvUtil.pyPrint("  Revolt - The %s is in serious financial trouble, gold: %d, rate: %d, gold perc: %.2f"%(pPlayer.getCivilizationDescription(0), iGold, goldRate,goldPerc))
                    finIdx += (2*(goldPerc - 50)) + 15
                    revIdxHistEvents += 15

                    finIdx2 -= (goldPerc - 50)/2 + 5 - max([goldRate,-5])
                    if( bIsRevWatch ) : negList.append( (finIdx2, localText.getText("TXT_KEY_REV_WATCH_SERIOUS_FINANCIAL",())) )

                elif( iGold < 80 + 20*pPlayer.getCurrentEra() and goldRate < 5 + pPlayer.getCurrentEra() ) :
                    if( self.LOG_DEBUG and bVerbose ) : CvUtil.pyPrint("  Revolt - The %s is in financial trouble, gold: %d, rate: %d, gold perc: %.2f"%(pPlayer.getCivilizationDescription(0), iGold, goldRate,goldPerc))
                    finIdx += (goldPerc - 50) + 5
                    revIdxHistEvents += 8

                    finIdx2 -= (goldPerc - 50)/2 - max([min([goldRate,8]),-5])/2
                    if( bIsRevWatch ) : negList.append( (finIdx2, localText.getText("TXT_KEY_REV_WATCH_FINANCIAL",())) )

                else :
                    if( self.LOG_DEBUG and bVerbose ) : CvUtil.pyPrint("  Revolt - The %s are at peace and have very high taxes, gold: %d, rate: %d, gold perc: %.2f"%(pPlayer.getCivilizationDescription(0),iGold, goldRate,goldPerc))
                    finIdx += 2*(goldPerc - 50)/3
                    if( goldRate > 10*pPlayer.getCurrentEra() ) :
                        finIdx /= 2

            elif( sciPerc + (3*cultPerc)/2 > 60 ) :
                taxesIdx += min([(sciPerc + (3*cultPerc)/2 - 60)/4,10])
                if( bIsRevWatch ) : posList.append( (taxesIdx, localText.getText("TXT_KEY_REV_WATCH_LOW_TAXES",())) )


        else :
            if( goldPerc > 70 ) :
                iGold = pPlayer.getGold()
                goldRate = pPlayer.calculateGoldRate()

                # Taxes
                taxesIdx -= (2*(goldPerc - 70))/3
                if( goldRate > 3 + 4*pPlayer.getCurrentEra() ) :
                    taxesIdx /= 2
                if( bIsRevWatch ) : negList.append( (taxesIdx, localText.getText("TXT_KEY_REV_WATCH_TAXES",())) )

                # Finances
                if( iGold < 80 + 25*pPlayer.getCurrentEra() and goldRate < 6 + pPlayer.getCurrentEra() ) :
                    if( self.LOG_DEBUG and bVerbose ) : CvUtil.pyPrint("  Revolt - The %s is in serious financial trouble, gold: %d, rate: %d, gold perc: %.2f"%(pPlayer.getCivilizationDescription(0), iGold, goldRate,goldPerc))
                    finIdx += (goldPerc - 50) + 10
                    revIdxHistEvents += 8

                    finIdx2 -= (goldPerc - 50)/2 + 5
                    if( bIsRevWatch ) : negList.append( (finIdx2, localText.getText("TXT_KEY_REV_WATCH_SERIOUS_FINANCIAL",())) )
                elif( iGold < 100 + 40*pPlayer.getCurrentEra() and goldRate < 4 + pPlayer.getCurrentEra() ) :
                    if( self.LOG_DEBUG and bVerbose ) : CvUtil.pyPrint("  Revolt - The %s is in financial trouble, gold: %d, rate: %d, gold perc: %.2f"%(pPlayer.getCivilizationDescription(0), iGold, goldRate,goldPerc))
                    finIdx += (goldPerc - 50)/2 + 5

                    finIdx2 -= (goldPerc - 50)/3
                    if( bIsRevWatch ) : negList.append( (finIdx2, localText.getText("TXT_KEY_REV_WATCH_FINANCIAL",())) )
                else :
                    if( self.LOG_DEBUG and bVerbose) : CvUtil.pyPrint("  Revolt - The %s are at war and have very high taxes, gold: %d, rate: %d, gold perc: %.2f"%(pPlayer.getCivilizationDescription(0), iGold, goldRate,goldPerc))
                    finIdx += goldPerc - 70
                    if( goldRate > 3 + 3*pPlayer.getCurrentEra() ) :
                        finIdx /= 2

            elif( sciPerc + (3*cultPerc)/2 > 50 ) :
                taxesIdx += min([(sciPerc + (3*cultPerc)/2 - 50)/5,10])
                if( bIsRevWatch ) : posList.append( (taxesIdx, localText.getText("TXT_KEY_REV_WATCH_LOW_TAXES",())) )

The reason I was able to code a city distance calculation that I am happy with, is because I could see and tweak the numbers. Also this let me know if I was breaking things, ie I had debugging feedback. Currently all this information is stealth. This means I can't begin to takle the problem, because I'd just be shooting blind with everything I try.
 
I've removed the negative penalty from taxes completely. Certainly better, but that's only half the equation. I need to add back in an economic revolution index.

Here is the plan:
(Total Waste (maintenance costs, upkeep costs, imports) / Total GDP (all commerce yields-all types earned in all cities) + total exports *) 100
I will then take this number and pop it into all the references to players gold spending in the existant revolutions code.

What this will do is allow novel strategies such as SEs with 0% research rates and such, but still penalize high expendature bloated empires (siphoning out economic wealth from the government). The only way to combat this will be to reduce government spending, or increase culture rate, which the culture rate I believe is a more true measure of low taxes.

Anyway I really want to try this new aproach.

But I can't, becuase I can't see what I am doing because everything is hidden.

So please tell me how to get this rev idx information displayed.
 
@Phungus
Here is one way to get any variable you want to display in game. You add it to an advisor screen, in this case the RevolutionWatchAdvisor.py. Search for the text:
#Extra variable for Phungus
There is a data source that is linked to a data function inside the py file. You can return whatever you want from that data function or add as many data functions as you want. It will update on a turn by turn basis too within the advisor screen, just leave it up while you autoplay. The data source has to be dragged in the RevolutionWatchAdvisor by modifying it as you would do for any customisation of the screen. In this case there is a PhungusVar you need to add to the screen in game.
Cheers.

EDIT: File attached after network problems...
 
Hey thanks glider. I used the print function, and have a working model, I'm tweaking now.
 
It refuses to upload my code???
 
This is tiny, but still, don't make it disapear>...
 
Refuses to upload it, OK, I'll pagage it with the dll the...

OK, finally uploaded it, it din't like it being small, so I packaged it with the gamecore...

Don't know why that's nessaxry, but OK...

Traits, comment them out, there is a trait Enlightened, that doesn't exist outside my game, so just comment it out...

Otheriwise this works well, except my old city distnace code was better, so use that... But for taxes this is good, it'll print though it's numbers, you'll see when you look at the code, it's half commented out, cause I got the first part working perfect. Wasn't totally happy with the last part, so it still prints,

Peace then...
 
Oh, and I'm drunk as . .. .. .. . now too, though that whole uploading fiasco is unrealtead, for some reason, it don't except small things, had to package it with a full .dll gamecore, don't know why, jsut discard it, or actually use it, unless you have built a new one, this 0.5ACO build is probably better anyway...
 
OK, so sober now. From the code above I'll use these two snippets:

Code:
                # Taxes
                taxesIdx -= (taxBurden - 15)/3
                if( bIsRevWatch ) :
                   [B] if(taxesIdx < 0):
                        abs(taxesIdx)
                        negList.append( (taxesIdx, localText.getText("TXT_KEY_REV_WATCH_TAXES",())) )
                    else :
                        taxesIdx = 0 - taxesIdx
                        posList.append( (taxesIdx, localText.getText("TXT_KEY_REV_WATCH_TAXES",())) )
                taxesIdx = 0 - (taxBurden - 15)/3[/B]

And this for finIdx & finIdx2:
Code:
                finIdx += (taxBurden - 15)/1.5
                if( igoldRate > 2 + 5*pPlayer.getCurrentEra() ) :
                    finIdx /=2
                if( iGold > 100 + 100*pPlayer.getCurrentEra() ) :
                    finIdx /=2
                [B]if(finIdx > 0):
                    if( bIsRevWatch ) :
                        negList.append( (finIdx, localText.getText("TXT_KEY_REV_WATCH_FINANCIAL",())) )[/B]
               [B] else:
                    if( bIsRevWatch ) :
                        posList.append( (finIdx, localText.getText("TXT_KEY_REV_WATCH_FINANCIAL",())) )[/B]
                finIdx2 -= finIdx
                revIdxHistEvents += finIdx


If you're interested in seeing the retooling of the taxes code I've written, check it out in the attachement above, and just search for "phungus taxes". Anyway, that's not really important right now, I think I have everything working, and tweaked to give good values.

This little snippet though, is apparently the reference to the Revolutions Text, and I was expecting it to post "Taxes" and the calcaluted coresponding value of taxesIdx in the RevIdx bar. But it's not. Still not displaying anything. Why is that? If I change similar text references, such as city distance it works, I can change the text via the XML, or get it to not appear, simply and easily. So why isn't this code working, Ie why isn't it showing up in the RevIdx city bar? How can I get it to show up there?

In my oppinion hiding causes of the Rev index from the player does nothing but cause frustration. If stuff is hidden, there should be a good reason for it. I see non for hiding the TaxIdx value from the player. So I consider getting this to show up an imperative part of my upcoming BST mod. I need to get this working before I feel comfortable to release a beta build. In fact this is the main thing holding me up right now. I have some more stuff to work on, but I know how to implement everything else, this I'm at a loss as to how to fix. And since it's embedded in the Revolutions code, I can't just ask in the Python/SDK forum for help. I need specific support from you guys: glider or jdog, before I can begin to solve this.

Edit: I hope this post doesn't come off sounding prickish. I just really need to know how to do this, and I've been working really hard, and teaching myself how to code basically, in order to get certain aspects of revolutions to work in a way that doesn't hinder gameplay. The original tax code, and city distance code forced out novel strategies. I like the idea of having an economic, or tax based penalty, but I needed to make it flexible, so that a SE economy was just as viable as a CE, so I've done that. But now, I just really need to get it to show up, because It just bothers the bejezus out of me having stealth modifiers that are such a huge part of the revolutions effect.
 
I hope this post doesn't come off sounding prickish.
Absolutely not Phungus. What is "prickish" is when people have good ideas but keep it to themselves and do not share. So thanks. Will ponder your technical "issues". At this point "TXT_KEY_REV_WATCH_TAXES" should display "Financial Trouble" according to RevolutionText_CIV4GameText.xml. Sometimes it's not bad to seperate out a problem piece of code into a test piece of python or simplify it right down so that you can find the bugger bug. Will think on these problems.
Cheers.
 
OK, simpler question. How can I get anything to appear in the RevIdx bar? If I know how to get something, anything to appear, I'm pretty sure I can use that technique to display a stored variable.

Please respond, I really want to unstealthify things!!!!
 
Hey Phungus
Well done. You can unstealth any variable using the technique in the Phungusvar.zip upload above. Make whatever you want visible in the revolution watch advisor. Have a relook at post #3 and tell me what I didn't explain correctly or what you don't like about it. The thing is it is much more flexible approach than modifying the rev bar.
Cheers.
 
The thing is though, I want the #s to show up in the rev bar. How can I go about doing this?

To clarify, the reason for this is 2 fold. First, and most importantly, is so that I can use the information to properly tweak the modifiers and analyze the rev affects. To do this, I must be able to seperate the effects on different players, and how these pan out in specific cities. Secondarily, but also important, is to improve the UI, ie make the information more readily available to the player.

To accomplish these goals, I need that info displayed in the RevIdx city bar.

So how would I just print "Hello World" into the city bar? If I can do this, I'm positive i can get a variable's value to print there.
 
Added rational behind the request above.
 
Hey Phungus
Ok, after line 6112 in CvMainInterface.py, add this code:
Code:
						cityString = safe
					
					#Phungus help
					cityString += "Hello World"
					
					szBuffer = u"%s: %s"%(localText.getText("TXT_KEY_REV_STATUS", ()),cityString)
cheers.
 
Hmmm, OK. Thanks, this is a start.

Is it possible to store variables from Revolution.py that can be called later in CvMainInterface.py?

Also what would happen, if I were to add in this code to Revolution.py
Code:
#some function
   cityString = 0
   cityString += "Some Text"
   cityString += iVariable
   
   szBuffer = u"%s: %s"%(localText.getText("TXT_KEY_REV_NEWTEXT", ()),cityString)
Would this then print: Some Text (iVaraible value) in the RevIdx bar (assuming I define TXT_KEY_REV_NEWTEXT in the RevText.xml)? Or do I have to do this in CvMainInterface.py? If so, how do I tell python to store a variable to be used later by another python file?
 
Eh Phungus
(sorry, internet connection hideously slow today on wireless).
Q:
Is it possible to store variables from Revolution.py that can be called later in CvMainInterface.py?
A: yes. The import statements at the start of CvMainInterface allow this.
Q:
Also what would happen, if I were to add in this code to Revolution.py
A: it would crash because there is no reference to those variables in Revolution.py
Q:
Would this then print: Some Text (iVaraible value) in the RevIdx bar (assuming I define TXT_KEY_REV_NEWTEXT in the RevText.xml)? Or do I have to do this in CvMainInterface.py?
A: you have to do it in CvMainInterface because you are presenting information to the user which is the job of the interface, not Revolution.py (the Revolution engine).
Q:
how do I tell python to store a variable to be used later by another python file
A: the import statement is exactly what this is for. CvMainInterface can use Revolution variables because of the import statements (there are a few).
Cheers.
 
Thanks glider, that makes sense. You've probably given me enough information to get to work, but I'm unable to fool around with the code right now, and wol't be able to for a few hours yet. So I figure I'll ask now, since it'll certainly speed up the process, rather then having me bumble along through trial and error. (Remember I'm a complete noob when it comes to code). Also to clarify, when I say the RevIdx bar I mean the pop up window that appears when you hover over the RevIdx bar (The one that shows Good and Bad rev effects), not the bar itself. This prints "Hello World" in the hover pop up right? If it prints in the bar, that would just be really ugly, and not really useable, as there are too many effects, to list them all will be bigger then the bar.

Could you show a couple code snippets on how to import a variable? For a specific Variable, let's say use CityDistModifier in Revolution.py How would I import this variable to CvMainInterface.py?

Thanks for the help glider, cheers.
 
Ok I'm caffenated so here goes:
Could you show a couple code snippets on how to import a variable? let's say use CityDistModifier in Revolution.py How would I import this variable into CvMainInterface.py?
Ok here are the steps:
1) In order to keep it simple, I will use a Revolution variable that is already exposed to the outside world. The CityDistModifier variable is not exposed to the outside world unless it is made so by coding that in.
2) The variable I will use is "revInstigatorThreshold". You will notice that it is exposed to the world outside of the revolution engine, because it is attached to the "self" object as is defined in the Revolution class initialisation function "init", roughly at line 99 of Revolution.py. The code there is:
Code:
self.revInstigatorThreshold = RevDefs.revInstigatorThreshold
3) Now the variable can be accessed anywhere externally, by referring to the Revolution instance. An "instance" is when the Revolution class definition for the revolution code, is transformed into a living and working "object" that holds real data for the length of it's duration, typically the life of the session. The reference to the Revolution instance is done in CvMainInterface, by this code:
Code:
RevInstances.RevolutionInst.revInstigatorThreshold
This line does a number of things. It get's the RevInstances python object which holds all the instances of all Revolutions related entities. The revolution engine instance itself is stored in RevolutionInst. Once that is referenced, bingo, you can get a hold of revInstigatorThrehold.

If you do a search for this last variable in both Revolution.py and CvMainInterface, you will see how it shares a common existence. The underlying theory of coding is that Python is an object oriented language. The structure of this then is:

1) A class is nothing but a template for a future "object" that will be instantanciated and "live" in memory during the session. In Revolution.py, there is the Revolution "class" but this is not the actual revolution object, it is just the definition for the object.

2) The actual revolution object as it exists and operates is referenced via "RevInstances.RevolutionInst". Because Revolutions is an object that is defined by a class definition, no variables inside revolutions has any existence outside of the object unless it is either attached to the "self" object or has it's own "get" function that other code can call in order to get access to these internal variables.

3) The "self" object is the most confusing of all. The variable holds a reference to the ultimate object variable that makes up the class. In this way, it becomes a global way that the Revolutions code can access variables inside itself for it's own purposes. Without a "self" object attachment, variables are only locally accessible, within the context of a specific function, or within a local execution loop.

4) Because in our case the variable of interest is connected to "self", any external code that can get a hold of the Revolution object and then get a hold of the "self" object, will get access to any variables inside Revolutions that have been attached to "self".

This is an informal system that is prone to various problems and is not formal object oriented design. However it is simpler and very flexible. In your case, you want the CityDistModifier variable, but at this point it has no external existence to the Revolutions object because it is neither attached to "self" or does not have it's own "get" function for external use. You would have to replicate exactly the same process as the instigator variable, defining a new "variable" attached to self that can be used externally, and then update in the Revolutions code so that it's "state" is kept accurate and up to date.

For example, you could declare "self.phungusCityDist" in the Revolution class initialisation function, and then reference it externally by "RevInstances.RevolutionInst.phungusCityDist". However the variable will be empty because it is not being updated in the revolution code. You would have to add some lines to the Revolution code, to ensure that your phungus version variable is kept up to date with the real citydistmodifier variable.

The other approach is to make the citydistmodifier externally visible. To do that you would declare citydistmodifier in the initialisation function of the revolution class, to be attached to self by saying "self.citydistmodifier" (make sure you get all the capitals matched up! They are totally important). Then in all references to the citydistmodifier variable in the revolutions code, would then have to have a "self." put in front of it. If you forget even one, there will be a distinction programmatically between self.citydistmodifier and citydistmodifier, two completely seperate variables.

The latter approach as you can see, is prone to error if you are not totally vigilant. If you make your own variable, the only thing that will go wrong is the state of your own variable, not the entire revolution engine code for city distance calculations.

Cheers.
 
Ultimately, what you are trying to get to is:
Code:
#some function
   cityString += "This is the rev instigator variable state"   
   szBuffer = u"%s: %s: %d"%(localText.getText("TXT_KEY_REV_NEWTEXT", ()),cityString, RevInstances.RevolutionInst.revInstigatorThreshold)

I understand that you do not want it in the rev bar but the hover over, but for now keep it simple.
cheers.
 
Top Bottom