Simple Python Things

Good to hear! :goodjob:
 
is it possible to created unit promotion that only useable by specific cilization and for all unit not just UU?
 
At least there seems to be no way to do this in Python. Unless you wanna attach that promotion automatically to all units of that Civ. Then it would be an easy Python job.
 
No SDK or even Python required.

Create a 'dummy' promotion with the <unitcombats> tag as <UnitCombats/>, which will mean it cannot be given to any unit in game. The civilization that you want to have the signature promotion needs to have a trait which gives this dummy promotion to all UnitCombats. Then, create the signature promotion with the dummy one as a prereq, plus any others you want. For bonus points set the <button> tag to <Button/> so that it just shows a blank space.
 
Actually another way to do this is to make a tech that's available only to that civ, and have that promotion require that tech. And if you don't know how to do a tech that's available only to that civ, you can also do that without python or SDK, although it'd require a lot of reundant XML work - basically, in the CivilizationInfos.xml, there is a tag, <DisableTechs/> that the game doesn't use. However, it works similarly to the FreeTechs tag, except that it disables a civ from being able to research a tech. So, basically, you'll just have to disable all the other civs (and the barbarians) from being able to research that promotion-giving trait.

Yes, it's a bit of a hassle, but the plus side is that no SDK or python is required!

-----

@The J:

Concerning the pop-up message modcomp (the one that adds one to the beginning of the game), is there any way to have the message be civ-specific? Is there also a way to have an image appear with the pop-up message? I'm assuming that these are pretty easy to do, but I just wanted to check with you first, if you wanted to add these features to a second version or something.
 
@The J:

Concerning the pop-up message modcomp (the one that adds one to the beginning of the game), is there any way to have the message be civ-specific? Is there also a way to have an image appear with the pop-up message? I'm assuming that these are pretty easy to do, but I just wanted to check with you first, if you wanted to add these features to a second version or something.
I'm sure that the author will confirm this, but it should be easy enough to make these additions to the mod. Or you could just use stand-alone code for the pop-ups you need for your mod.

If The_J doesn't have the time, I might be able to add these requested features myself. Do you have a download link?
 
Hello TJ,

I need some code for a simple eventtrigger which checks if there's a road or railroad on a plot? If so the trigger shouldn't fire (return false). Here's part of the trigger:

PHP:
######## STUCK IN THE SWAMP ############

def canTriggerStuckInSwamp(argsList):
	kTriggeredData = argsList[0]

	## if road or railroad on plot then return false (unit not stuck)

	return true
 
@The J: Yes, that would be very helpful if you can do it. This is not anything immediately needed, as always, but I mean if you think you can do it sometime then I won't mind.
 
Okay, i'll then try it at the weekend.
If i forget it, then i'll need a reminder please.

Hello TJ,

I need some code for a simple eventtrigger which checks if there's a road or railroad on a plot? If so the trigger shouldn't fire (return false). Here's part of the trigger:

PHP:
######## STUCK IN THE SWAMP ############

def canTriggerStuckInSwamp(argsList):
	kTriggeredData = argsList[0]

	## if road or railroad on plot then return false (unit not stuck)

	return true

mmmhh...just looking...in the EventTriggerInfo.xml, the value iNumPlotsRequired has to be set to 1 (at least that's what i can see from another event), then you have to add:
PHP:
	pPlot = gc.getMap().plot(kTriggeredData.iPlotX, kTriggeredData.iPlotY)
	if pPlot.isRoute (): return False

That should be everything what is needed.
 
Thank you :)
Here is a gift to this thread, using the 'Swamptrigger'. I haven't tested the event yet.
Trigger in CIV4EventTriggerInfos.xml:
PHP:
<!-- STUCK IN SWAMP -->

		<EventTriggerInfo>
			<Type>EVENTTRIGGER_STUCK_IN_SWAMP</Type>
			<WorldNewsTexts>
				<Text>TXT_KEY_EVENTTRIGGER_STUCK_IN_SWAMP_1</Text>
			</WorldNewsTexts>
			<TriggerTexts>
				<TriggerText>
					<Text>TXT_KEY_EVENT_TRIGGER_STUCK_IN_SWAMP_1</Text>
					<Era>NONE</Era>
				</TriggerText>
			</TriggerTexts>
			<!-- <EventArt>Art/EventImages/StuckInSwampEvent.dds</EventArt> -->
			<bSinglePlayer>0</bSinglePlayer>
			<iPercentGamesActive>100</iPercentGamesActive>
			<iWeight>100</iWeight>
			<bProbabilityUnitMultiply>0</bProbabilityUnitMultiply>
			<bProbabilityBuildingMultiply>0</bProbabilityBuildingMultiply>
			<Civic>NONE</Civic>
			<iMinTreasury>0</iMinTreasury>
			<iMinPopulation>0</iMinPopulation>
			<iMaxPopulation>0</iMaxPopulation>
			<iMinMapLandmass>0</iMinMapLandmass>
			<iMinOurLandmass>0</iMinOurLandmass>
			<iMaxOurLandmass>-1</iMaxOurLandmass>
			<MinDifficulty>NONE</MinDifficulty>
			<iAngry>0</iAngry>
			<iUnhealthy>0</iUnhealthy>
			<UnitsRequired>
				<UnitClass>UNITCLASS_WARRIOR</UnitClass>
				<UnitClass>UNITCLASS_AXEMAN</UnitClass>
				<UnitClass>UNITCLASS_ARCHER</UnitClass>
				<UnitClass>UNITCLASS_SWORDSMAN</UnitClass>
			</UnitsRequired>
			<iNumUnits>1</iNumUnits>
			<iNumUnitsGlobal>0</iNumUnitsGlobal>
			<iUnitDamagedWeight>0</iUnitDamagedWeight>
			<iUnitDistanceWeight>-1</iUnitDistanceWeight>
			<iUnitExperienceWeight>0</iUnitExperienceWeight>
			<bUnitsOnPlot>1</bUnitsOnPlot>
			<BuildingsRequired></BuildingsRequired>
			<iNumBuildings>0</iNumBuildings>
			<iNumBuildingsGlobal>0</iNumBuildingsGlobal>
			<iNumPlotsRequired>1</iNumPlotsRequired>
			<bOwnPlot>0</bOwnPlot>
			<iPlotType>-1</iPlotType>
			<FeaturesRequired>
				<FeatureType>FEATURE_FLOOD_PLAINS</FeatureType>
			</FeaturesRequired>
			<TerrainsRequired></TerrainsRequired>
			<ImprovementsRequired/>
			<BonusesRequired></BonusesRequired>
			<RoutesRequired></RoutesRequired>
			<ReligionsRequired/>
			<iNumReligions>0</iNumReligions>
			<CorporationsRequired/>
			<iNumCorporations>0</iNumCorporations>
			<bPickReligion>0</bPickReligion>
			<bStateReligion>0</bStateReligion>
			<bHolyCity>0</bHolyCity>
			<bPickCorporation>0</bPickCorporation>
			<bHeadquarters>0</bHeadquarters>
			<Events>
				<Event>EVENT_STUCK_IN_SWAMP_1</Event>
			</Events>
			<PrereqEvents/>
			<bPrereqEventPlot>0</bPrereqEventPlot>
			<OrPreReqs></OrPreReqs>
			<AndPreReqs></AndPreReqs>
			<ObsoleteTechs></ObsoleteTechs>
			<bRecurring>1</bRecurring>
			<bTeam>0</bTeam>
			<bGlobal>0</bGlobal>
			<bPickPlayer>0</bPickPlayer>
			<bOtherPlayerWar>0</bOtherPlayerWar>
			<bOtherPlayerHasReligion>0</bOtherPlayerHasReligion>
			<bOtherPlayerHasOtherReligion>0</bOtherPlayerHasOtherReligion>
			<bOtherPlayerAI>0</bOtherPlayerAI>
			<iOtherPlayerShareBorders>0</iOtherPlayerShareBorders>
			<OtherPlayerHasTech>NONE</OtherPlayerHasTech>
			<bPickCity>0</bPickCity>
			<bPickOtherPlayerCity>0</bPickOtherPlayerCity>
			<bShowPlot>1</bShowPlot>
			<iCityFoodWeight>0</iCityFoodWeight>
			<PythonCanDo>canTriggerStuckInSwamp</PythonCanDo>
			<PythonCanDoCity></PythonCanDoCity>
			<PythonCanDoUnit/>
			<PythonCallback/>
		</EventTriggerInfo>
Event in CIV4EventInfos.xml:
PHP:
<!-- STUCK IN SWAMP -->

		<EventInfo>
			<Type>EVENT_STUCK_IN_SWAMP_1</Type>
			<Description>TXT_KEY_EVENT_STUCK_IN_SWAMP_1</Description>
			<LocalInfoText/>
			<WorldNewsTexts/>
			<OtherPlayerPopup/>
			<QuestFailText/>
			<bQuest>0</bQuest>
			<bGlobal>0</bGlobal>
			<bTeam>0</bTeam>
			<bPickCity>0</bPickCity>
			<bPickOtherPlayerCity>0</bPickOtherPlayerCity>
			<bDeclareWar>0</bDeclareWar>
			<iGold>0</iGold>
			<bGoldToPlayer>0</bGoldToPlayer>
			<iRandomGold>0</iRandomGold>
			<iCulture>0</iCulture>
			<iEspionagePoints>0</iEspionagePoints>
			<bGoldenAge>0</bGoldenAge>
			<iFreeUnitSupport>0</iFreeUnitSupport>
			<iInflationMod>0</iInflationMod>
			<iSpaceProductionMod>0</iSpaceProductionMod>
			<Tech>NONE</Tech>
			<TechFlavors/>
			<iTechPercent>0</iTechPercent>
			<iTechCostPercent>0</iTechCostPercent>
			<iTechMinTurnsLeft>0</iTechMinTurnsLeft>
			<PrereqTech>NONE</PrereqTech>
			<UnitClass>NONE</UnitClass>
			<iNumFreeUnits>0</iNumFreeUnits>
			<bDisbandUnit>0</bDisbandUnit>
			<iUnitExperience>0</iUnitExperience>
			<iUnitImmobileTurns>1</iUnitImmobileTurns>
			<UnitPromotion/>
			<UnitName></UnitName>
			<UnitCombatPromotions></UnitCombatPromotions>
			<UnitClassPromotions></UnitClassPromotions>
			<BuildingClass>NONE</BuildingClass>
			<iBuildingChange>0</iBuildingChange>
			<BuildingExtraYields/>
			<BuildingExtraCommerces/>
			<BuildingExtraHappies/>
			<BuildingExtraHealths/>
			<iHappy>0</iHappy>
			<iHealth>0</iHealth>
			<iHurryAnger>0</iHurryAnger>
			<iHappyTurns>0</iHappyTurns>
			<iRevoltTurns>0</iRevoltTurns>
			<iMinPillage>0</iMinPillage>
			<iMaxPillage>0</iMaxPillage>
			<iFood>0</iFood>
			<iFoodPercent>0</iFoodPercent>
			<FreeSpecialistCounts/>
			<FeatureType>NONE</FeatureType>
			<iFeatureChange>0</iFeatureChange>
			<ImprovementType>NONE</ImprovementType>
			<iImprovementChange>0</iImprovementChange>
			<BonusType>NONE</BonusType>
			<iBonusChange>0</iBonusChange>
			<RouteType>NONE</RouteType>
			<iRouteChange>0</iRouteChange>
			<BonusRevealed>NONE</BonusRevealed>
			<BonusGift>NONE</BonusGift>
			<PlotExtraYields/>
			<iConvertOwnCities>0</iConvertOwnCities>
			<iConvertOtherCities>0</iConvertOtherCities>
			<iMaxNumReligions>-1</iMaxNumReligions>
			<iOurAttitudeModifier>0</iOurAttitudeModifier>
			<iAttitudeModifier>0</iAttitudeModifier>
			<iTheirEnemyAttitudeModifier>0</iTheirEnemyAttitudeModifier>
			<iPopulationChange>0</iPopulationChange>
			<AdditionalEvents/>
			<EventTimes/>
			<ClearEvents/>
			<PythonCallback/>
			<PythonExpireCheck/>
			<PythonCanDo/>
			<PythonHelp/>
			<Button>,Art/Interface/Buttons/Process/Blank.dds,Art/Interface/Buttons/Beyond_the_Sword_Atlas.dds,8,5</Button>
			<iAIValue>1000</iAIValue>
		</EventInfo>
Some text:
PHP:
<!-- STUCK IN SWAMP -->

	<TEXT>
		<Tag>TXT_KEY_EVENTTRIGGER_STUCK_IN_SWAMP_1</Tag>
		<English>A foolish unit of the %s1_civ_adjective empire got lost in vast swamplands. Its gonna take some time for them to recover.</English>
	</TEXT>
	<TEXT>
		<Tag>TXT_KEY_EVENT_TRIGGER_STUCK_IN_SWAMP_1</Tag>
		<English>One of our units got lost in the swamps. The fools...</English>
	</TEXT>
	<TEXT>
		<Tag>TXT_KEY_EVENT_STUCK_IN_SWAMP_1</Tag>
		<English>Eventually they will find their way out...</English>
	</TEXT>

and the Pythoncode from TJ in CvRandomEventInterface.py:
PHP:
######## STUCK IN SWAMP ############

def canTriggerStuckInSwamp(argsList):
	kTriggeredData = argsList[0]

	pPlot = gc.getMap().plot(kTriggeredData.iPlotX, kTriggeredData.iPlotY) 
	if pPlot.isRoute (): return False  

	return true

Maybe someone finds a use for this little event ;)
 
I made this code in CvGameUtils.py:

Code:
	def cannotConstruct(self,argsList):
		pCity = argsList[0]
		eBuilding = argsList[1]
		bContinue = argsList[2]
		bTestVisible = argsList[3]
		bIgnoreCost = argsList[4]

                ### Lots of other code ###
		
                ### Particle Accelerator begins ###
		###########################################################################################

		if ( eBuilding == gc.getInfoTypeForString("BUILDING_PARTICLE_ACCELARETOR") ):

			### check if city has power ###
			##pPlayer = gc.getPlayer(pCity.plot().getOwner())
			##iPID = pPlayer.getID()
			##iTID = pPlayer.getTeam()
			power = pCity.isPower()

			if ( power == true ):
				return true

			return false

		###########################################################################################
		### Particle Accelerator ends ###
		
		return False

The purpose of this code is to check if a city has access to power, and if so, allow to build the Particle Accelarator. Somehow it doesn't work.
USE_CANNOT_CONSTRUCT_CALLBACK is set to 1.
What's wrong?
 
I don't remember if this can modify anything, but isn't "true" and "false" MUST be capitalized? I mean they're "True" and "False" I can only think of this, as the code seems to be good. :confused:

In Python, lowercase and uppercase characters differs, and AFAIK this applies on boolean values too.
 
Good idea, and a valid one. But that is not a problem here, because the Civ4 developers took already care of that and defined somewhere in the code True = true, etc ;).

The problem is that the used callback is wrong.
The cannotConstruct callback forbids you to build things, which you normally could
The canConstruct callback allows you to build things, which you normally could not.
-> move the code over to canConstruct, then it should work.


----------------
Like requested, i uploaded another version of the starting popup here.
There's only one change in the CvEventManager.py, and one XML for example text.
It should not be hard to use, adding new civ specific text doesn't require anyone to deal with the python. Just add TXT_KEY_MOD_HEADER_CIVILIZATION_XY and TXT_KEY_MOD_TEXT_CIVILIZATION_XY to the XML, and the civ of question will get that specific text. There are 2 small nonsense examples included, with TXT_KEY_MOD_HEADER_CIVILIZATION_ENGLAND / TXT_KEY_MOD_TEXT_CIVILIZATION_ENGLAND and TXT_KEY_MOD_HEADER_CIVILIZATION_AMERICA / TXT_KEY_MOD_TEXT_CIVILIZATION_AMERICA, so both civs will get a specific popup. Every civ else will get a standard text instead (can also easily be modified that there's no popup for other civs than the defined).

Image
Spoiler :
startingpopup_english_w97.jpg
 
The problem is that the used callback is wrong.
The cannotConstruct callback forbids you to build things, which you normally could
The canConstruct callback allows you to build things, which you normally could not.
-> move the code over to canConstruct, then it should work.

Now that's odd. Would this work:
Code:
	def cannotConstruct(self,argsList):
		pCity = argsList[0]
		eBuilding = argsList[1]
		bContinue = argsList[2]
		bTestVisible = argsList[3]
		bIgnoreCost = argsList[4]

                ### Lots of other code ###
		
                ### Particle Accelerator begins ###
		###########################################################################################

		if ( eBuilding == gc.getInfoTypeForString("BUILDING_PARTICLE_ACCELARETOR") ):

			### check if city has power ###
			##pPlayer = gc.getPlayer(pCity.plot().getOwner())
			##iPID = pPlayer.getID()
			##iTID = pPlayer.getTeam()
			power = pCity.isPower()

			if ( power == [COLOR="Red"]true[/COLOR] ):
				return [COLOR="red"]false[/COLOR]

			return [COLOR="red"]true[/COLOR]

		###########################################################################################
		### Particle Accelerator ends ###
		
		return False

The cannotConstruct callback is false which should allow the building?
 
Sadly not always, but hopefully often enough :).

Now that's odd. Would this work:
[...]

The cannotConstruct callback is false which should allow the building?

No, would not, it's still the wrong callback ;) Just move it over to canConstruct, that should not be a problem in any way.
Edit: Before here was nonsense :mischief:.
If these callbacks return "False", they just will not have any effect.
In the case here, it returns True in the case a city does not have power, so cities without power can not construct it.

2. edit: this all depends on how you put the building in the XML.
If you can normally build it, then you're right here, then use the cannot construct to restrict it only to certain cities.
If you could normally not build it (due to whatever restrictions, because it's attached to future tech, whatever), then you would have to use the canConstruct callback to allow it for certain cities.
 
Back
Top Bottom