• Our friends from AlphaCentauri2.info are in need of technical assistance. If you have experience with the LAMP stack and some hours to spare, please help them out and post here.

Quick Modding Questions Thread

A question to mainly to the native English speakers:

I want to make an ancient era building that requires Cow or Goat and gives +1:food: (milk, cheese, etc).
What would be the right name? Is Dairy a fitting name? I'd like to avoid Dairy farm if possible. Or maybe Homestead?
 
Not a native speaker, but I am familiar with Dairy as a word for the place where milk is processed to e.g. cheese. I am not sure if the word feels anachronistic for an early time period to a native speaker, but my intuition would be that it works.
 
Back in the day, (first half of the 1960's in the UK) dairy refers to
  • place where milk is taken from the animal
  • place it is stored to cool down after collection
  • place it is processed:- pasteurized, turned into butter, or cream or cheese
  • and the place in the shops where it is sold
 
A question to mainly to the native English speakers:

I want to make an ancient era building that requires Cow or Goat and gives +1:food: (milk, cheese, etc).
What would be the right name? Is Dairy a fitting name? I'd like to avoid Dairy farm if possible. Or maybe Homestead?

Dairy would probably be the best. Homestead implies more self-sufficiency. Ranch might work if you want an upgrade but I'd probably want a bonus with Horse there too.
 
Python people: Would there be any obvious reason that passing a value from a list (for example, MyList[7], which is a pointer) into a function doesn't work? I am getting an AttributeError as if the game thinks the thing being passed is a "list" itself, but there is no reason for it to be anything other than a pointer.
 
Python people: Would there be any obvious reason that passing a value from a list (for example, MyList[7], which is a pointer) into a function doesn't work? I am getting an AttributeError as if the game thinks the thing being passed is a "list" itself, but there is no reason for it to be anything other than a pointer.

Can you post the relevant code?
 
CIV 4 BTS 3.19

Does anyone know the difference between MEMORY_STOPPED_TRADING and MEMORY_STOPPED_TRADING_RECENT, as well as between
MEMORY_MADE_DEMAND and MEMORY_MADE_DEMAND_RECENT in CIV4MemoryInfos.xml?

Both pairs can be used in CIV4LeaderHeadInfos.xml to set MemoryDecay and MemoryAttitudePercent values.

What happens if I set both? Will the RECENT-values replace the regular values until a certain number of turns have passed? Will both values be added to each other? Will all RECENT-values disappear even if I don't set a MemoryDecay vaule for a MemoryAttitudePercent?

Thanks in advance.
 
Can you post the relevant code?

Sure, here it is:

First, this is the function I am passing "unitInfo" into (the problem probably isn't here, but, context)
Code:
def getAnimalCategory(self, unitInfo):
        sCategory = "None"
        for sTerrain in self.lColdTerrains:
            if unitInfo.getTerrainNative(gc.getInfoTypeForString(sTerrain)):
                sCategory = "Cold"
                return sCategory
        for sFeature in self.lColdFeatures:
            if unitInfo.getFeatureNative(gc.getInfoTypeForString(sFeature)):
                sCategory = "Cold"
                return sCategory
        for sTerrain in self.lMildTerrains:
            if unitInfo.getTerrainNative(gc.getInfoTypeForString(sTerrain)):
                sCategory = "Mild"
                return sCategory
        for sFeature in self.lMildFeatures:
            if unitInfo.getFeatureNative(gc.getInfoTypeForString(sFeature)):
                sCategory = "Mild"
                return sCategory
        for sTerrain in self.lHotTerrains:
            if unitInfo.getTerrainNative(gc.getInfoTypeForString(sTerrain)):
                sCategory = "Hot"
                return sCategory
        for sFeature in self.lHotFeatures:
            if unitInfo.getFeatureNative(gc.getInfoTypeForString(sFeature)):
                sCategory = "Hot"
                return sCategory

And here is the place I am calling the function from
Code:
lColdPrey = []
        lMildPrey = []
        lHotPrey = []
        if len(lPreyUnits) > 0:
            for i in range(len(lPreyUnits)):
                unit = lPreyUnits[i]
                category = self.getAnimalCategory(unit)
                if category == "Cold":
                    lColdPrey.append(unit)
                elif category == "Mild":
                    lMildPrey.append(unit)
                else:
                    lHotPrey.append(unit)
I do the same thing two other times, replacing "Prey" with "predator" and "plant".

Basically, I have a list of "Prey" unitInfos, and I am trying to figure out whether they should spawn in Hot, Cold, or Mild terrains, by passing each unitInfo into the getAnimalCategory function one at a time.
 
CIV 4 BTS 3.19

Does anyone know the difference between MEMORY_STOPPED_TRADING and MEMORY_STOPPED_TRADING_RECENT, as well as between
MEMORY_MADE_DEMAND and MEMORY_MADE_DEMAND_RECENT in CIV4MemoryInfos.xml?

Both pairs can be used in CIV4LeaderHeadInfos.xml to set MemoryDecay and MemoryAttitudePercent values.

What happens if I set both? Will the RECENT-values replace the regular values until a certain number of turns have passed? Will both values be added to each other? Will all RECENT-values disappear even if I don't set a MemoryDecay vaule for a MemoryAttitudePercent?

Thanks in advance.

Have you tried the SDK mod that reveals hidden attitudes in the diplomacy screen? To me it sounds like one of those is visible to the player, and one is not, so the game can make an AI distrust you for a long time even though it looks like they have forgotten you backstabbed them.
 
@Kjotleik: As far as I remember:
MADE_DEMAND_RECENT memory is increased when a human civ asks an AI civ for a gift or demands tribute.
So long as the AI civ has MADE_DEMAND_RECENT memory about a human civ, it dismisses demands and pleas from that human out of hand.
MADE_DEMAND is only increased when a human civ makes a demand, and results in a permanent relations penalty ("you made an arrogant demand"). The penalty is permanent only because the BtS LeaderHead XML file doesn't have a (positive) MemoryDecay value for MADE_DEMAND.
STOPPED_TRADING_RECENT and STOPPED_TRADING are both increased when a (human or AI) civ agrees to stop trading with an AI civ. So long as an AI civ has STOPPED_TRADING_RECENT memory about another civ, it refuses to talk to that other civ. STOPPED_TRADING memory results in the "you stopped trading with us" relations penalty.
Both pairs can be used in CIV4LeaderHeadInfos.xml to set MemoryDecay and MemoryAttitudePercent values.
Could be done – but the original idea appears to be that the "recent" memory types decay faster and result in special AI behavior, while the non-recent memory types are responsible for the relations penalty. (Although there is unused game text "You recently made an arrogant demand!" and "You recently stopped trading with us!".)
What happens if I set both?
They're treated independently from each other i.e. decay independently and their relations penalties stack. For example (in BtS), as far as I'm aware, the "stopped trading with us" penalty can randomly disappear through decay before the AI becomes willing to talk.
Will all RECENT-values disappear even if I don't set a MemoryDecay vaule for a MemoryAttitudePercent?
No, without a decay value, they should become permanent.

If you need to be certain about these things, you could search the CvGameCoreDLL source code for "_RECENT" to see any special treatment of those memory types and for "NUM_MEMORY_TYPES" to see how memory types are treated in general.
Have you tried the SDK mod that reveals hidden attitudes in the diplomacy screen? [...]
Diplo effects of all AI memory types should be displayed already by BtS.
 
Oh oh I think I have found my problem. For some reason the following code is returning a NoneType instead of a unitInfo object:
Code:
pNewUnit = pBarb.initUnit(i,iX,iY,UnitAITypes.NO_UNITAI, DirectionTypes.NO_DIRECTION)
unitInfo = gc.getUnitInfo(pNewUnit.getID())

Is getID() the right thing to use in gc.getUnitInfo()? Should I use something else?

EDIT: answered my own question. Definitely need to use getUnitType(). getID seems to be something else entirely.
 
Last edited:
You should use pNewUnit.getUnitType() to get the unitType for UnitInfos.

Each unit is given an unique ID upon creation. You can obtain this ID with getID().
 
This seems like it should be obvious...

How do you set a civ to "minor"?
 
AFAIK you either have to set MinorNationStatus of the civ to 1 in a scenario file, or in the DLL call GC.getInitCore().setMinorNationCiv(eID, bMinorNationCiv).
 
AFAIK you either have to set MinorNationStatus of the civ to 1 in a scenario file, or in the DLL call GC.getInitCore().setMinorNationCiv(eID, bMinorNationCiv).

Well that's annoying. Do you know if the civ CIVILIZATION_MINOR in xml naturally spawns as a minor civ if you force it to spawn?
 
Well that's annoying. Do you know if the civ CIVILIZATION_MINOR in xml naturally spawns as a minor civ if you force it to spawn?
setAlive doesn't affect the minor status of civs, so I don't think it would. I can only guess though since the setMinorNationCiv function is hardly used in the DLL, and isn't exposed to Python by default either. Your best bet is to try it yourself.
 
Game options are listed in CvEnums.h.
Game options will never be truly unlimited as you need to define what each option does. If you want to add more options, you’ll need to include them in CvEnums.h.
 
Game options will never be truly unlimited as you need to define what each option does. If you want to add more options, you’ll need to include them in CvEnums.h.
Thanks for the answer. I'm aware that this is how people usually do it, but I'm not sure if that's really the only way.
My question is whether I can replace every occurrence of NUM_GAMEOPTION_TYPES with GC.getNumGameOptions(). The only problem this might cause that I can think of is that the game might access NUM_GAMEOPTION_TYPES before the XML is loaded; in this case GC.getNumGameOptions () wouldn't work.
The main suspect for this is PBGameSetupData::PBGameSetupData(); I have no idea when it is called. Maybe it's related to PitBoss games?
 
Back
Top Bottom