Simple Python Things

Is there a difference between i.e.:
Code:
serfdom = gc.getInfoTypeForString( [COLOR="red"]"[/COLOR]CIVIC_SERFDOM[COLOR="red"]"[/COLOR] )
or
Code:
serfdom = gc.getInfoTypeForString( [COLOR="red"]'[/COLOR]CIVIC_SERFDOM[COLOR="Red"]'[/COLOR] )
Modders seem to use both. Which one is correct or are both correct?
 
There's no real difference, both is correct, Python allowes these variants.
Why? No real idea, but it's sometimes convenient that you can use " ' someText ' ", without dealing with special characters.
Civ-wise...just ignore. Use whatever you like better :D.
 
There are three kinds of literals/strings in Python:
' sometext ' -> is a single-quoted literal, only applies on a single line, but you can use " without error
" sometext " -> is a double-quoted literal, applies on a single line, but you can use ' in it without error
''' sometext ''' -> is a triple-quoted literal, also known as multi-line literal, it can be applied on multiple lines, and it allows both ' and ".

EDIT: Also there is a triple-double-quoted one, which I think only works if used as comment. e.g. """ sometext, probably and most likely used to be a comment """ I don't know if this can be supported by strings.
 
Hello, The J!

I decided that this was an interesting little thing that I could have use for in my little personal mod.

Unfortunately it doesn't work the way I thought.

I Did put the CvGameUtils.py in my mod's Assets/Python folder, and the PythonCallbackDefines.xml in my mod's Assets/XML folder. But as I loaded up a previous saved game I could not build obsolete units.

Then I tried to only use it as a stand-alone mod. I exctracted the TrainingObsoleteUnits folder to my BtS/Mods folder. I then had to copy the BUG 4.4 Config folder from my CustomAssets to the TOU/Assets folder in order for BUG to work. And it did. But loading the TOU mod didn't help. I still cannot train obsolete units.

I would like some hints as to where to look for a solution to this. Where must I change things to get it to work?

I looked at the picture, and realized you have made it work. So, is there some reason to believe the PythonCallbackDefines.xml, or the CvGameUtils.py, in this mod is NOT replacing the ones from BtS when I do it the way described above?



Yours Sincerely

Kjotleik of Norway:)
 
mmhh...do i understand you right, that you're using BUG as standard (and in your mod)?
Because the files have to be modified to work with BUG, and i'm pretty sure mods with additional python files are not loaded if BUG is loaded by default.
 
I do use BUG in CustomAssets so that I have it loaded by default. And then I had to copy the Config folder from BUG into my mod to make it work with my mod as well.

If I did not copy the Config-folder from the CustomAssets installation of BUG, I would get this annoying empty Tech-screen starting a game...and the interface with buttons would be gone...so I use BUG as default, and have the Config-folder from BUG inside my mod, in order to make BUG work with my mod as well.

Unfortunately, I'm rather blank on the way to go from here. I don't know how to fix this so that the python file from the TrainingObsoleteUnits actually gets loaded when loading the mod itself (from the Advanced, Load a Mod menu).

Any ideas you, or any other reading this, might have is worth a try. I would really like to have the option to train obsolete units. Of course, I COULD just build a city without connecting it to my trade-network...but that would be a rather extreme sub-optimal tactic in a game like Civilization...I think? And it would probably only help with building Warriors...hmm...


Yours Sincerely


Kjotleik of Norway:)
 
*scratch**scratch* mmhh...okay...that's a small bit of a problem.
Short explanation why:
- The files which you'd have to modify are in BUG, but
- BUG is not in your mod.
-> you'd have to modify files, which would also be loaded without the mod.

How to go around that:
- Install BUG as mod
- Copy the changes you've already done into that mod
- In case your interface is then missing, go the new MOD BUG folder, open the .ini file in that folder, and change
PHP:
; Custom XML and Python from user folder are not loaded
NoCustomAssets = 0

to 1.

We'll talk further after this is done and working :).
 
I did this...

1) Ran BUGMod_4.4.exe as administrator
2) Chose option three - install as multiplayer-available own mod.
3) Copied an ini-file from another mod. Renamed it and made sure Name = BUG Mod 4.4 and NoCustomAssets = 1
4) Started a game to see that the game functioned properly. It did.
-as I have Blue Marble in CustomAssets I saw that it was not loaded. All well.
5) Played on until Bronze Working, and connecting Copper to obsolete Warrior. Saved game.
6) Changed ini-file to NoCustomAssets = 0
7) Re-started and loaded the previously saved game.
-now Blue Marble works as well, and game is still alright.
8) Copied your CvGameUtils.py into BtS/Mods/BUG Mod 4.4/Assets/Python
9) Copied your PythonCallbackDefines.xml into BtS/Mods/BUG Mod 4.4/Assets/XML
10) Re-started and loaded previously saved game. Still no obsolete units available.

And here I stand at this moment in time.

Just want to mention I appreciate your willingness to help me in this matter. I will not be able to make this work without help from more knowledgeable people than me...so thanks...


Yours Sincerely

Kjotleik of Norway:)
 
Okay, fine that this worked so far :).
Currently this doesn't work due to BUG. BUG is not only an awesome interface mod, but also an awesome code architecture. Which means it changes how the stuff from the python files is loaded. Confusing to beginners, but great if you know how to handle it.

-> so the CvGameUtils.py is not loaded by BUG, because it's coded to do this all in another way. So the modcomp has to be changed to do it in that way.
I attached the changed version, you'll have to drop the both files into the respective folders, and add to Assets\config\init.xml the line
PHP:
<load mod="TrainingObsoleteUnits"/>

before the
PHP:
</bug>

at the end.
I hope this will work too, because i can't currently test it, because my gaming machine is roughly 200 kms away, and no idea when i'll be back to it.
 

Attachments

It is close to midnight in Norway, but I just had to share this wonderful news before going to bed:

I downloaded your updated BUG-version of TrainingObsoleteUnits, and...

1) Copied the TrainingObsoleteUnits.xml into BtS/Mods/BUG Mod 4.4/Assets/Config
2) Copied the TrainingObsoleteUnits.py into BtS/Mods/BUG Mod 4.4/Assets/Python/Contrib
3) Copied the PythonCallbackDefines.xml into BtS/Mods/BUG Mod 4.4/Assets/XML
4) Added the line <load mod="TrainingObsoleteUnits"/> to init.xml in the Config folder (just below the other [<load mod...] lines)
5) Started the BUG Mod 4.4 and loaded the savegame...IT WORKS...OH, YES!

...but wait, there's more...

I did repeat the steps 1 through 4 for my own personal mod as well. Remember that I already had the Config folder from my CustomAssets' BUG-version inside my own mod.

Then I started my own mod, loaded an old savegame...and there it was...I COULD TRAIN A WARRIOR...OR A PHALANX...(I played Alexander, as you know by now).

It seems in a mod, if you just copy the CustomAssets' BUG-folder called Config into your own mod's Assets-folder...you don't need the rest of BUG inside your own mod to make it work...I'm so pleased...I'll be dreaming of Civ tonight...sure as I can ever be of that!:D

This was very easy to DO...but close to impossible to KNOW how to do. For me, that is. So, again, a big, megabig, gigabig, superbig, hyperbig...ultrabig...thanks to The_J!!!



Yours Sincerely

Kjotleik of Norway:)
 
Another Python Thing:

I wrote this peace of code in CvEventManager, which should execute if peace is declared. Basically it should remove all 'fanatic' units from the player.
PHP:
	def onChangeWar(self, argsList):
		'War Status Changes'
		bIsWar = argsList[0]
		iTeam = argsList[1]
		iRivalTeam = argsList[2]
		if (not self.__LOG_WARPEACE):
			return
		if (bIsWar):
			strStatus = "declared war"
		else:
			strStatus = "declared peace"
			
## Fanatics START 14/10/2011 ##

			## Peace is made, remove all Fanatics units ##
						
			player = gc.getPlayer(iTeam) ## WILL THIS WORK ?????
			
			iFanaticMedieval = gc.getInfoTypeForString("UNITCLASS_FANATIC_MEDIEVAL")
			iFanaticRenaissance = gc.getInfoTypeForString("UNITCLASS_FANATIC_RENAISSANCE")
			iFanaticIndustrial = gc.getInfoTypeForString("UNITCLASS_FANATIC_INDUSTRIAL")
			iFanaticModern = gc.getInfoTypeForString("UNITCLASS_FANATIC_MODERN")

			## Loop through all units, kill unit if it's a fanatic
			(loopUnit, iter) = player.firstUnit(false)
			while (loopUnit):
				if loopUnit.getUnitClassType() == iFanaticMedieval or loopUnit.getUnitClassType() == iFanaticRenaissance or loopUnit.getUnitClassType() == iFanaticIndustrial or loopUnit.getUnitClassType() == iFanaticModern:
					loopUnit.kill(false, -1)
				(loopUnit, iter) = player.nextUnit(iter, false)
			
## Fanatics END 14/10/2011 ##

		CvUtil.pyPrint('Team %d has %s on Team %d'
			%(iTeam, strStatus, iRivalTeam))

I really doubt if this piece of code will work:
PHP:
			player = gc.getPlayer(iTeam)

Bottomline is how can I get the player from the team??
 
That code part will work, but only if you don't have any alliances (so i'd not rely on that).
And there's no real option to get both players in one team. The only solution here is to loop over all players and collect the IDs of all players which belong to the team. Not really nice, but there's no other way.

And i'd also put the code part before
PHP:
 if (not self.__LOG_WARPEACE):

because the code will stop in that if clause if no logging is enabled (at least that's how i read that).

This was very easy to DO...but close to impossible to KNOW how to do. For me, that is. So, again, a big, megabig, gigabig, superbig, hyperbig...ultrabig...thanks to The_J!!!

Thank you :).
Nice to hear that it works and your questions are welcome.
 
That code part will work, but only if you don't have any alliances (so i'd not rely on that).
And there's no real option to get both players in one team. The only solution here is to loop over all players and collect the IDs of all players which belong to the team. Not really nice, but there's no other way.
That would be fine because it would remove all fanatics belonging to this team. How can I do this?
And i'd also put the code part before
PHP:
 if (not self.__LOG_WARPEACE):
because the code will stop in that if clause if no logging is enabled (at least that's how i read that).
I suppose this code can also be changed to:
PHP:
    def onChangeWar(self, argsList): 
        'War Status Changes' 
        bIsWar = argsList[0] 
        iTeam = argsList[1] 
        iRivalTeam = argsList[2] 
        if (bIsWar): 
            strStatus = "declared war" 
        else: 
            strStatus = "declared peace" 
             
## Fanatics START 14/10/2011 ## 

## code ##

## Fanatics END 14/10/2011 ## 

        if (not self.__LOG_WARPEACE): 
            return
        CvUtil.pyPrint('Team %d has %s on Team %d' 
            %(iTeam, strStatus, iRivalTeam))
Anyway thanks :)
 
:yup: that change will work.

That would be fine because it would remove all fanatics belonging to this team. How can I do this?

You can't, that's the problem :/.
Units belong to players, not to the teams, so you can't access them via a CyTeam object.
You'll have to make a loop over all the players and compare their team IDs to the given team ID. I don't see any other real option :dunno:.
 
Can I have a question (not topic related, but Python related)?
What is the difference between e.g
PHP:
if (variable < anotherOne):
and
PHP:
if variable < anotherOne:

In Java you can only use if statement with brackets, and in Python you can choose. Is there any difference between the bracket one and the non-bracket one?

And another question: Why do we use PHP code fields for Python ones? It would be amazing if the forum would have Python BB Code. :)
 
@brackets: No, there's no real difference in your example.
It will make differences if you have a bit complicated logic in there.
e.g. (X AND Y) OR Z is not the same as X AND (Y OR Z), but for simple comparisons it doesn't make a difference.


@code field: Don't really see a need, and no idea where it would make a difference :dunno:.
And the PHP field is by default in the software, in comparison to a custom field, which would need someone to do it just for this forum here.
-> too much work for too little gain.
 
You can't, that's the problem :/.
Units belong to players, not to the teams, so you can't access them via a CyTeam object.
You'll have to make a loop over all the players and compare their team IDs to the given team ID. I don't see any other real option :dunno:.

OK, thanks :goodjob:
Please take a look at this code I cooked up:
PHP:
	def onChangeWar(self, argsList):  
		'War Status Changes'  
		bIsWar = argsList[0]
		iTeam = argsList[1]
		iRivalTeam = argsList[2]
		if (bIsWar):  
			strStatus = "declared war"
		else:
			strStatus = "declared peace"  

## Fanatics START 14/10/2011 ##  

		## Peace is made, remove all Fanatics units ## 
		player = gc.getPlayer(iTeam)
		rival = gc.getPlayer(iRivalTeam)
		playerTeam = gc.getTeam(iTeam)
		rivalTeam = gc.getTeam(iRivalTeam)

		iFanaticMedieval = gc.getInfoTypeForString("UNITCLASS_FANATIC_MEDIEVAL") 
		iFanaticRenaissance = gc.getInfoTypeForString("UNITCLASS_FANATIC_RENAISSANCE") 
		iFanaticIndustrial = gc.getInfoTypeForString("UNITCLASS_FANATIC_INDUSTRIAL") 
		iFanaticModern = gc.getInfoTypeForString("UNITCLASS_FANATIC_MODERN")

		iLoopPlayer = 0 ## probably not necessary
		for iLoopPlayer in range(gc.getMAX_CIV_PLAYERS()):
			LoopPlayerTeam = gc.getTeam(iLoopPlayer)
			if LoopPlayerTeam == playerTeam or LoopPlayerTeam == rivalTeam: ## kill all fanatics of both teams
 
				## Loop through all units, kill unit if it's a fanatic 
				LoopPlayer = gc.getPlayer(iLoopPlayer)
				(loopUnit, iter) = LoopPlayer.firstUnit(false) 
				while (loopUnit): 
					if loopUnit.getUnitClassType() == iFanaticMedieval or loopUnit.getUnitClassType() == iFanaticRenaissance or loopUnit.getUnitClassType() == iFanaticIndustrial or loopUnit.getUnitClassType() == iFanaticModern: 
						loopUnit.kill(false, -1) 
					(loopUnit, iter) = LoopPlayer.nextUnit(iter, false)

## Fanatics END 14/10/2011 ##  

        if (not self.__LOG_WARPEACE):  
            return 
        CvUtil.pyPrint('Team %d has %s on Team %d'  
            %(iTeam, strStatus, iRivalTeam))
I haven't tested the code yet, would this code work?
 
nevermind
 
Back
Top Bottom