Is it possible to make Unit-Producing buildings?

jlocke

Cold Warrior
Joined
Feb 8, 2006
Messages
221
Location
University of Chicago
If anyone knows how to make small wonders or buildings which produce units I would really be interested in hearing how to do that.
Also, is there an unbuildable tag that you can put in the XML so that the only way units can be produced is with a building?

thanks for any help offered.
 
jlocke said:
If anyone knows how to make small wonders or buildings which produce units I would really be interested in hearing how to do that.
Also, is there an unbuildable tag that you can put in the XML so that the only way units can be produced is with a building?

thanks for any help offered.

I'm not sure what you mean. Do you mean only when that building is in the city that specific unit can be produced? I think the XML tag BuildingPrereq does this.

If you mean wonders kinda like the Terra Cotta Army from Rise of Nations that every 3 minutes or something pumps out a free unit, then you could probably just make a normal wonder. Edit the CvEventManager.py file, and edit onBeginPlayerTurn to check for the existance of the Terra Cotta Army. If so, you keep track of the last time a unit was popped out either using the CyVariableSystem or some other mod that keeps track of mod data.

Hope this helps.
 
Gerikes said:
I'm not sure what you mean. Do you mean only when that building is in the city that specific unit can be produced? I think the XML tag BuildingPrereq does this.

If you mean wonders kinda like the Terra Cotta Army from Rise of Nations that every 3 minutes or something pumps out a free unit, then you could probably just make a normal wonder. Edit the CvEventManager.py file, and edit onBeginPlayerTurn to check for the existance of the Terra Cotta Army. If so, you keep track of the last time a unit was popped out either using the CyVariableSystem or some other mod that keeps track of mod data.

Hope this helps.
He means that a particular unit can NEVER be built, it can only be "popped out" by a building/wonder, and he wants to know how to do this.

Right now, Python is the answer (until an XML value can be added by the SDK that allows for exactly what you're trying to do). The CyVariableSystem is new to me, I haven't heard it mentioned as a possible solution before, nor have I looked through it. Although, in attempting to do something similar, Belizan and others mentioned that keeping track of the turn the current turn and subtracting the turn the building was built would give you a number which you could "mod" by x (let's say 5). Whenever the result was 0 you could then write a line to create the unit on that spot. For example, let's say the current turn was 25, and you built the building on turn 19: 25-19=6; 6 mod 5 is 1, so for this turn the unit would not be created. But, last turn it was created since 5 mod 5 is 0.

As for making a unit unbuildable in XML, I believe setting the cost to -1 will do the trick.
 
Shqype said:
He means that a particular unit can NEVER be built, it can only be "popped out" by a building/wonder, and he wants to know how to do this.

Ah.... gotcha.

Right now, Python is the answer (until an XML value can be added by the SDK that allows for exactly what you're trying to do). The CyVariableSystem is new to me, I haven't heard it mentioned as a possible solution before, nor have I looked through it. Although, in attempting to do something similar, Belizan and others mentioned that keeping track of the turn the current turn and subtracting the turn the building was built would give you a number which you could "mod" by x (let's say 5). Whenever the result was 0 you could then write a line to create the unit on that spot. For example, let's say the current turn was 25, and you built the building on turn 19: 25-19=6; 6 mod 5 is 1, so for this turn the unit would not be created. But, last turn it was created since 5 mod 5 is 0.

So you'd still need to find some way to keep track of the variable. CyVariableSystem should work.

When the wonder builds...

CyVariableSystem().setValueInt("TERRA_COTTA_BUILT", currentTurn)

Then, every turn...

Code:
turnBuilt = CyVariableSystem().getValueInt("TERRA_COTTA_BUILT")
if ((currentTurn - turnBuilt) % 5 == 0):
   makeUnitAppear()

The only thing I don't know about the CyVariableSystem is if the values lasts after saving, leaving the game, then reloading, but I would think it does. Probably should test first.
 
Terra Cota Army here we Come!
 
Gerikes said:
Ah.... gotcha.



So you'd still need to find some way to keep track of the variable. CyVariableSystem should work.

When the wonder builds...

CyVariableSystem().setValueInt("TERRA_COTTA_BUILT", currentTurn)

Then, every turn...

Code:
turnBuilt = CyVariableSystem().getValueInt("TERRA_COTTA_BUILT")
if ((currentTurn - turnBuilt) % 5 == 0):
   makeUnitAppear()

The only thing I don't know about the CyVariableSystem is if the values lasts after saving, leaving the game, then reloading, but I would think it does. Probably should test first.
Now I have a question for you: what if you had multiple instances of a building (or an improvement for that matter)? Let's say instead of a "Terra Cotta" wonder you wanted each Barracks to produce a soldier every 5 turns. Then how would you keep track of every one of them to produce the unit at the correct time?
 
This is basically how great people work now. They can't be built and are popped out by buildings after x amount of turns.
 
True Kael, but it's random; I believe jlocke wanted something concrete; a constant like 5, not a value that increases with each GP increasing the threshold.
 
Yes each City has an array of all the Units called "UnitProgress" I belive this is how the City always "remembers" previous work on a Unit after you change to something else. Great People use that same Array for figuring out the % probabilites of each type spawning.

What could be done is to add a few new XML tags to Buildings,

<FreeUnitProductions> top nest element holding any number of <FreeUnitProduction>

<FreeUnitProduction> each instance contains <FreeUnitType> and <iFreeProductionQuantiy>

<FreeUnitType> specifies the type of unit
<iFreeProductionQuantity> specifies the number of Hammers added for free each turn, you will have to do the math to figure out effective rate.

The game would simply add the specified production to the Array each turn possibly adding a check for canbuild() and obsolecence so your Building can change with the times (assuming you specify the later game units) and isn't spiting out Spearman forever. Any Building could do a TerraCota Army effect and you could configure it all in XML. Another neat thing is that you could combine the Cities normal task with this Free Production to get units made even faster!

I'll put this on my TODO list.

EDIT: Oh I could also include a <bAlwaysBuildable> that could be used to skip the canbuild() check, this would remove all tech, building or resorce requirement and alow a unit that is normaly unbuildable to be produced (I hope).
 
Cool Impaler[WRG]!

How about instead adding a tag <iTurnsCreated> that will specify how many turns it will take before the unit is created again?
 
I guess that might work by dividing the units cost by the turn count and adding that value, the effect might not be totaly reliable if the 2 numbers dont divide evenly. If you want it perfect am not going to need to create some complex function that moduluses the buildings creation date and sets the Progress equal to the units cost (aka done). But this could step on any regualar progrees if the user is also building that unit at the time so some kind of save and restore needs to be done which adds more complexity. My TODO list is rather long already so dont expect any work on this in the imediate future.
 
Impaler[WrG] said:
I guess that might work by dividing the units cost by the turn count and adding that value, the effect might not be totaly reliable if the 2 numbers dont divide evenly. If you want it perfect am not going to need to create some complex function that moduluses the buildings creation date and sets the Progress equal to the units cost (aka done). But this could step on any regualar progrees if the user is also building that unit at the time so some kind of save and restore needs to be done which adds more complexity. My TODO list is rather long already so dont expect any work on this in the imediate future.

Unless you would add to the CvCity class a variable (like m_iFreeUnitCounter) that gets incremented every turn and either calls a python script that the user can edit or just calls initUnit right there, spitting out whatever unit you want when it's counter hits whatever the value for iTurnsCreated.

The problem with this is what if you want two structures in the same city ("Terra Cotta Army" and "Terra Cotta Army 2: The Revenge!") that both need to use the same variables. To cover that case, instead of one integer, you'd need an integer array that has a counter for each building in numBuildingInfos().



And Shqype, just for fun; if doing it in python a quick fix might be like this...


Spoiler Python Quick Implementation :

There would be a few variables... (TCA being short for "Terra Cotta Army")

TCA_TOTAL (Total number of TCA's on the map)
TCA_(NUM)_X
TCA_(NUM)_Y
TCA_(NUM)_TURN_CREATED

NUM = An individual ID for each TCA.

So, when I get the first one, I would check how many TCA's there are ( 0 ) and make the variable "TCA_0_X" and "TCA_0_Y", and set those variables to the X and Y plot values. Then, set the variable TCA_0_TURN_CREATED to the current turn, and increment TCA_TOTAL.

Then, it works just like before when checking for units, only rather than just check one variable, I have a loop that checks all those in TCA_TOTAL.

Now, this is just a quick fix. Some problems are...

A.) You can't have more than one TCA on a plot. This is fine if it's just a building or an improvement, since by default you can only have one of those anyway.

B.) If a TCA gets destroyed, you need to check that it no longer is getting checked to pump out units. This can be done by setting the turn created some sentinal value like -1, and run an if statement on each pass.

C.) For the sticklers out there, it might be important to not have a ton of these things, and thus letting TCA_TOTAL run high while having a ton of the buildings under it get destroyed would make this script run long (although since it only runs at the beginning or end of a turn, it's not that much of a problem). I think there is a mod somewhere for custom mod data to be stored, and I would hope that it has a linked list option. So, I'd replace all of this and use a linked list to store all this data.

 
Back
Top Bottom