[PYTHON] Help adding Attribute

Louis the XIV

Sun King
Joined
Jun 23, 2020
Messages
839
Location
Court of Versailles
I'm trying to add the plague in civ 4 bts by creating a modcomp.
But whenever I right the following code I get an error in which it tells me that I need an attribute.
Here is the original code I wrote under the city built [argslist]:
Code:
        city = argsList[0]
        ##--------PLAGUE END: spreading to founded cities
        pUnit = gc.getInfoTypeForString("UNIT_SETTLER")
        if pUnit.isHasPromotion(gc.getInfoTypeForString("PROMOTION_PLAGUE")):
            city.setHasRealBuilding(iPlague, True)
        ##--------PLAGUE END: spreading to founded cities
        if (city.getOwner() == gc.getGame().getActivePlayer()):
And here is the error it gave me:
Civ4ScreenShot0004.JPG


Then I tried giving it an attribute like this:

Code:
            'vassalState'            : self.onVassalState,
            'changeWar'                : self.onChangeWar,
            'setPlayerAlive'        : self.onSetPlayerAlive,
            'playerChangeStateReligion'        : self.onPlayerChangeStateReligion,
            'playerGoldTrade'        : self.onPlayerGoldTrade,
            'windowActivation'        : self.onWindowActivation,
            'gameUpdate'            : self.onGameUpdate,          #sample generic event
            ### PLAGUE START        ### PLAGUE START
            'isHasPromotion'        : self.onisHasPromotion,               
        }    ### PLAGUE END            ### PLAGUE END
But then when I load up the game, the game gives me a python error in which it says that it has no attribute and it still doesn't work.

If anyone knows how to add an attribute I really really really really really really really need help!
 
pUnit = gc.getInfoTypeForString("UNIT_SETTLER")
This will NOT give you a pointer to the unit. Instead it will give you the UnitTypes ID for UNIT_SETTLER. Python will see this as an int and then you call
pUnit.isHasPromotion, which will fail because that's a function in CyUnit, not int. How to get the real pUnit depends on code, which you didn't include here.
 
as @Nightinggale said

getInfoTypeForString only returns the UnitType (an ID).
It generally just an int, it is not an object.

If you want to make method calls, you first need to get an object.
To do so you can try something like:

pUnitInfoObject = gc.getUnitInfo(pUnit)

pUnitInfoObject will now allow you to call methods on it.
(I am just explicitly calling it "...Object" to make it a bit more obvious.)

So this code:
Code:
       pUnit = gc.getInfoTypeForString("UNIT_SETTLER")
       if pUnit.isHasPromotion(gc.getInfoTypeForString("PROMOTION_PLAGUE")):

Will probalby become:
Code:
       pUnit = gc.getInfoTypeForString("UNIT_SETTLER")
       pUnitInfoObject = gc.getUnitInfo(pUnit)
       if pUnitInfoObject.isHasPromotion(gc.getInfoTypeForString("PROMOTION_PLAGUE")):
 
Last edited:
If you are trying to trigger the logic for the specific Unit that triggers the event the code would look totally different.

The specific UnitObject (not the UnitInfoObject) would be in the args[] of the event.
So you would need to get it from there.

Your code is currently confusing me a bit. :dunno:
(I do not know how your "plague feature" is set up.)
 
So you mean I have to move the code inside the brackets of the args list?
No. :nope:

I am trying to say the you might get the Object you need from one of the args[].
But which one (args[1], args[2], ...) or if you get it at all, heavily depends on your XML setup of your EventTrigger.

But no matter what, you will always need an object because only objects have methods that can be called.
 
Your code is currently confusing me a bit. :dunno:
(I do not know how your "plague feature" is set up.)

It's a bit complicated to explain how the plague feature works but for know I need the settlers that have the plague "promotion" (that means they were build in a city that has the plague) to get the plague in their founded city, so if they found a city that city starts with the plague "building"

EDIT: Think of the Plague as a promotion and if a settler has that promotion and founds a city the city starts with a building called the plague
 
It is probably much easier if you completely code this in DLL logic - in CvUnit.cpp
There you can directly hook into the logic of "founding a City" (and you already have the specific Unit).
 
I think that's not an option for me. I have never edited c++ or h, and I also have no idea how to recompile the dll back.
But I think it would be much easier in python, isn't there a way to make settlers that have a promotion and found a city that city starts with a building?
I mean platy did it in settler promotions.

And also it's not just that, I have no idea what files have to be edited in the dll to achieve this.
There are at least 30 files there and I have no idea which one has to be edited and where.
 
Oh, this is not an event. It's just python no xml.
Oh, ok.

I was thinking about coding a feature "Small Pox" myself for our Civ4Col mod (We the People).
And it would have used the PythonEventSystem. (Because it can nicely trigger stuff on specific events and display text popups - with really low effort.)

But I would have used DLL (for base functions), Python (for additional trigger checks) and XML (for trigger / event config and text popup messages).
There are advantages of all of these.
 
I think that's not an option for me.
Well, there are lots of possible solutions. :)
What is easier for you, depends on your pre-experience. :thumbsup:

Just in general:
Learning DLL modding (C++) is really worth it. It is extremely powerful.
And it will make it easier to write Civ4 Python Code as well.
(Because Python calls DLL functions. Thus it is always important to understand these DLL functions.)
 
This is how I am trying to make the plague mechanic work:
An event pops up with a 70% chance of happening, that states the plague has broken out.
Then you get a free building aka the plague in half of your cities.
Units build in cities that have the plague get the plague "promotion" that means that they can't heal and have a -20 combat penaly.
Plague also spreads in new cities that where founded by a settler that has the plague.
To stop the plague you have to build a reaserch institute with a Great Doctor.
When the reaserch institute is built an event triggers that gives you the following options:
1.Lose 300 gold but have a 75% chance to stop the plague. (all plague buildings removed from your cities)
2.Lose 150 gold but have a 50% chance to stop the plague.
3This is of no concern to me. (3:mad: in every city that has the plague)
 
An event pops up with a 70% chance of happening, that states the plague has broken out.
Now you confuse me, because you said you do not use events. :confused:
 
Back
Top Bottom