This is of course a constant, and you define it at the top of the module. Since you wanted the amount of XP to be 1 (one), then you should define it as 1. I believe that I already pointed this out earlier.
The nice thing about this approach is of course that you will be able to find the setting easily the day you wanna try another value. Simply go (if you wanna raise the amount to 3):
right ok... once again I tried the ERE code (btw the xp code works perfectly now!!!) and once again it spawned advanced swordsmen??? I attacked with axes and my max tech level was ironworking... Of course it's not a problem as by the time they appear the world would be at that level but im a little concerned about the other rebellions?
If you get the eNum definitions matching the actual XML entries you have, then it should work as intended. But I guess you need to figure out your own XML first!
As I described in my earlier post: I debugged the function that is fetching the unit type and it always returned advanced swordmen. The reason was that the tech-to-unit data is evaluated from bottom and up, so the most advanced tech/unit is checked first. Apparently, the method used for checking whether or not a team has a tech handles a -1 ("no tech") as a pass. So because the eAdvancedIronWorking constant was pointing to the value -1, then the condition passed. Every time, without exception.
The point is still that the constant isn't correctly defined. It would be easy enough to just put integer values into the tRebelUnits data, but then the eNum would be defined in vain.
Just take another look at the XML tags and figure it out. As long as they match it should work.
edit: As I thought, this is what the actual Advanced Iron Working XML tag looks like:
Code:
<Type>TECH_IRON_WORKING_II</Type>
In hindsight the introduction of the getIndex() function was a bad idea. I simply didn't predict that you'd opt for irregular XML tag names. getInfoTypeForString() is the method used to fetch the values anyway (look at the getInfo() definition) so the helper isn't helping, its actually hurting your mod.
Anything can of course be done in any order imaginable, but I was thinking about you and the fact that you need to be able to alter any mod settings on your own. So a reversed order would probably just have confused you. Or so I thought. (Also, I realized that the way to get the appropriate unit type was to check in reverse only after I had already prompted you for the design aspect of it. Again, no reason to confuse you more than necessary.)
But this (reverse or not) has of course no bearing what so ever on the fact the the function won't work unless the eNums are defined correctly. (I'm just gonna assume that its working now.)
edit: This is your mod and if you have an idea of your own on how the get the the unit type, then by all means, try it! You'd learn something even if you idea turns out to be flawed.
and the print-out was the value 71. So this is the value we need. It would be as simple as doing this:
Code:
eAdvanceIronWorking = 71
(I just noticed that the constant was actually misspelled, but there is no exception because it matches exactly in the Rebellion module.)
But it would be possible to define the constant with the XML tag - it looks better and is also more robust in case you change around the order of Tech - or add/remove Techs - in the future. Plus you'll be able to keep the constant intact in any sequel your planing. But the assignment above is equally valid - as the XML stands today.
So I propose we get the eNums module in order, even if it entails only using getInfoTypeForString() all the way.
Yeah, that seems about right. This is the default way of doing this, so you should know about it, even if you were to prefer the getIndex() function for future projects.
Also, this setup would have prevented all the confusion about the unit XML tags from the beginning. Because you could have simply copy-pasted the correct tags - no matter what they are. In fact, you can still do this to the unit type eNums.
On a side note, assigning constants from the XML tags (no matter what method you're using) only works because of the import humbug I made up in the event manager. As I explained earlier, if the import statements are at module level (typically top of the module) they will automatically execute the modules concerned at initialization. And this will happen before the XML is even parsed and read, so all the eNums will get default -1 values. And the whole things breaks down.
edit: You might as well correct the eAdvanceIronWorking typo while you're at it. Just make sure to correct it in the Rebellion module also!
The only way to know for sure is to test it, and I don't understand why you haven't already. There can always be other issues, but this should at least take care of the one that I discovered by debugging the function. Namely that the code is checking whether or not Rome has a none-type Tech - and it turns out that they do. :crazyeyes: The condition should of course check the Techs you are defining in the tuple - in reverse order - and nothing else.
If you like, we could dissect the function in great detail and you'd be able to understand the logic behind the whole procedure. Because you might wanna be able to do something similar yourself - and I don't think copy-pasting someone else's code and trying to change some name counts as programming. (It probably wouldn't work either, and you wouldn't be able to understand why.)
def getTechUnitType(pTeam):
for i in xrange(len(tRebelUnits) - 1, -1, -1):
eTechType = tRebelUnits[i][0]
if pTeam.isHasTech(eTechType):
return tRebelUnits[i][1]
return eDefaultUnit
Firstly we can establish that the function takes a CyTeam instance as a argument and returns a integer - corresponding to a enumerated UnitType. There are however two return statements in this function and the function will always exit through either of these. The last line is the default return value and it returns the integer value assigned to the eDefaultUnit constant.
Secondly, the function is referencing another constant, namely this tuple array:
The tuple contains four additional tuples, each containing a pair of integer values. These integers are the enumerated TechTypes and UnitTypes in rising order. The way to reference a tuple is to use brackets, so the first tuple contained within tRebelUnits would be fetched with this statement:
Code:
tRebelUnits[0]
Because zero is the first index value of any tuple. This would yield the following value:
Code:
(eBronzeWorking, eAxeman)
If we assign this to a name:
Code:
tFirstTechUnit = tRebelUnits[0]
...then we can index this new tuple variable:
Code:
eFirstTech = tFirstTechUnit[0]
Because the TechType is the first value inside the tuple. Some other indexing examples:
Especially note the last example, as it first indexing accesses the second tuple (inside the main structure) and secondly indexes the first value - in that array. It would be possible to have nested data like this in absurdum and it would be possible to access it in this way.
Back to our function:
Code:
eTechType = tRebelUnits[i][0]
So this translates into "fetch the first value in the tuple indexed by the variable i, and assign it to the name eTechType". Now we need to know what index number i is, right?
Code:
for i in xrange(len(tRebelUnits) - 1, -1, -1):
The for and in key words (commands) iterate some variable through some set of values. In this case the values are generated by the generator function xrange(), and without going into the specifics of those God awful parameters, the yielded values are 3, 2, 1 and 0 in order. The len() built-in function fetches the length of the tRebelUnits array and is used for setting the starting value - 4 in this case (the - 1 of course gives us the starting value 3).
To clarify how the iteration works, it would be possible to do this with a list also:
Code:
lCountDown = [3, 2, 1, 0]
for i in lCountDown:
Now it should be obvious that the block of code following the iteration statement will bee looped a total of four times, and that the name i will change its value each time, from 3 to 0. It would be possible to rewrite this function and use a while statement instead, but that would require a couple of additional lines of code.
So, the variable eTechType will have a different value on each pass - a total of four different values. The first time it will be the first value contained in the fourth tuple (indexed by the value 3), the second time its the first value contained in the third tuple (2), and so on.
Code:
if pTeam.isHasTech(eTechType):
pTeam is of course the argument fed into the function and isHasTech() is a method of the CyTeam class. The parameter used is eTechType. The conditional statement is evaluated four times, each time with a different eTechType value. If the CyTeam.isHasTech() method invokation return True, then the entire expression equals True, and the condition is passed. You would probably have expressed it like this:
Code:
if pTeam.isHasTech(eTechType) == True:
...but the opeator and the operand adds nothing but a little clarity. It doesn't hurt either.
Finally, this is the exit line:
Code:
return tRebelUnits[i][1]
Whenever the conditional statement on the previous line equals True the function exits by returning a value. And this value is of course the second value (indexed by the value 1) in the current tuple being iterated and indexed by the variable i.
So, in conclusion; What the function does, is it iterates through the Techs specified in the data structure, from bottom and up. On the first pass it checks whether or not the team in question has the most advanced Tech, and if it does, then it returns the associated unit type - by referencing the tuple with the same index number. And if none of the TechTypes cause the conditional statement to pass, then the iteration stops after the fourth pass, and the code simply continues on the subsequent line on the original indentation level. That line contains the other return statement, returning the default unit type.
edit:
Spoiler:
This i probably a much clearer version of the function:
Code:
def getTechUnitType(pTeam):
for i in xrange(len(tRebelUnits) - 1, -1, -1):
eTechType, eUnitType = tRebelUnits[i]
if pTeam.isHasTech(eTechType):
return eUnitType
return eDefaultUnit
This is an abbreviated version of the same function:
Code:
def getTechUnitType(pTeam):
for i in xrange(len(tRebelUnits) - 1, -1, -1):
if pTeam.isHasTech(tRebelUnits[i][0]):
return tRebelUnits[i][1]
return eDefaultUnit
And this is how it could be based on the while command:
right I can rebegin testing today, on my list are:
Events - Done
Marius - Done
Byzantium -Done
XML Tags - Next up (by this I mean using XML tags for translation as well as testing different languages)
entire Rebellion feature - hopefully tomorrow!
Catapult Construction - as I go...
Then I have to translate missing object and patch a few things up (such as adding the catapult build to swordsmen, removing romes movement bonus from ships (Roman trait gives moral)) and then I was thinking of changing the first popup screen:
The sun rises on the (...) and make it civ specific instead... I believe that this screen is defined in python so it should be easy enough... just use if statements for isHuman should work
when do you think you will be finsihed with the senate class? Just so I know
The sun rises on the (...) and make it civ specific instead... I believe that this screen is defined in python so it should be easy enough... just use if statements for isHuman should work
I'll get started as soon as I'm done with G&G - so hopefully when you're done with whatever it is that you got on your plate.
Don't forget to test the AI Catapult Construction code, also! You know that a unit is "building" when its UNITAI value is showing as "UNITAI_UNKNOWN". So I basically disable the unit for 5 turns. Once the catapult is done however, both units should have UNITAI_ATTACK_CITY.
You of course are testing the mod with a revealed world map (Ctrl + z) so that you can see everything and also access all city screens. (Requires cheatmode by the way.)
This site uses cookies to help personalise content, tailor your experience and to keep you logged in if you register.
By continuing to use this site, you are consenting to our use of cookies.