Requesting following features

yay the ERE works correctly!!! (well preliminary testing anyway!) next up Marius Reform...

but it did spawn it self an army of advanced Swordsmen (but maybee thats because I took byzantium with an advanced swordsman and so it thinks it is my most advanced unit....???
 
ok marius callback!

File "CvEventInterface", line 23, in onEvent
File "CvEventManager", line 187, in handleEvent
File "CvEventManager", line 390, in onBeginGameTurn
File "ModEvents", line 112, in eventMarius
File "ModEvents", line 100, in setRomeExtraXP
File "DataStorage", line 34, in setPlayerData
File "DataStroage", line 48, in getPlayerScriptDict

IndexError: list index out of range

what the problem wiht this one?:think:

edit: going on a few turns, it appears that the Marius Event happens EVERY turn when rome has over 10 cites and a mission counter of 0... is it just the call back or a unseen problem....
 
About the traceback - I found a bug in CivPlayer that caused the player data to never initialize. (I think this was caused by me changing the import statements around and never testing every change properly.) Use the new version attached below. (You'll be able to switch to a "release version" eventually. This will probably include the DataStorage code also. But thanks for testing in the meanwhile! :D)

About the spawning advanced swordsman units: It seems that the ERE Rebellion uses the same method of getting the unit type than the civil war var code does - namely the default way. And this is defined by the data structure we agreed upon:
Code:
tRebelUnits = (
(eBronzeWorking, eAxeman),
(eIronWorking, eSwordsman),
(eAdvancedBronzeWorking, eAdvancedSpearman),
[B](eAdvanceIronWorking, eAdvancedSwordsman)[/B]
)
So Rome would have to had Advanced Iron Working, then?
 

Attachments

but it doesnt... maybee the update tech code has a bug?

do I just replace my civplayer with this?
 
There could be any number of things wrong with the rebel-unit-from-tech process. I never did test it properly because you either didn't have all the XML in order - or I just couldn't figure out/be bothered with what units should have been spawned. It was quite the mess, so I more or less took a leap of faith in my own code. :p

What was the top Roman Tech at the time and what unit did you expect? How and why did the result strike you as incorrect? How should it work? Are you positive that all constants/enums/whatelse are in order? (Because I really wouldn't know at this point.)

It might also be necessary to be able to recreate any bugs you find, so I hope you have autosaves or whatnot for that. Because it would be possible to follow exactly what the code does every step of the way - in the debug log.

Regarding CivPlayer you simply replace the old version. I have however already written a completely new version of the module, but you can do without it until we find some new issue that needs to be corrected. I'll try to test the new module myself in the meanwhile.
 
I was testing the ERE code, and I captured byzantium with some worldBuildered Advanced Swordsman (top tech bronzeworking) and the ERE got advanced swordsmen.... they should have axes? or spears?
 
I was testing the ERE code, and I captured byzantium with some worldBuildered Advanced Swordsman (top tech bronzeworking) and the ERE got advanced swordsmen.... they should have axes? or spears?
Well... According to the data structure we made it should indeed have been axemen - unless they have been replaced with some other unit type, or the eAxeman constant has been incorrectly defined. I just don't know without having your set of files and looking it up in the XML.

But, if you send over the associated files - and preferably a save game - I can totally debug this to find out exactly where the advanced swordsman type is coming from.
 
Ok, I did some testing and it turns out that eAdvanceIronWorking constant is pointing to the integer value -1. This is not correct and the problem is most likely in the eNums module. Make sure that eAdvancedIronWorking is assigned the correct value! And in order to achieve this you need to use the correct name for the Tech (from the XML).

You might as well go through all of the eNums that are connected to your own XML edits to ensure that everything matches.
Spoiler :
I'm guessing that these two:
Code:
eAdvancedBronzeWorking = getIndex("Tech", "Advanced Bronze Working")
eAdvanceIronWorking = getIndex("Tech", "Advanced Iron Working")
should really be:
Code:
eAdvancedBronzeWorking = getIndex("Tech", "Bronze Working II")
eAdvanceIronWorking = getIndex("Tech", "Iron Working II")
This unorthodox way of naming XML tags really makes the use of the getIndex() helper not very helpful at all. You might as well use:
Code:
eAdvancedBronzeWorking = gc.getInfoTypeForString("TECH_ADVANCED_BRONZE_ WORKING_ II")
eAdvanceIronWorking = gc.getInfoTypeForString("TECH_ADVANCED_IRON_ WORKING_ II")
Because then you'd be able to simply copy-paste the tags from the XML.
 
btw The event still fires everyturn the missioncoutner is above 0 and iCities is more than 10... my friend says that in c++ there is a killcode command thing... is there anything to stop the marius reform once it has fired (saving bExtraXP but stop stopping the marius code?) and It didn't give any xp...



?
 
Post the event and we'll see. It shouldn't be hard at all.
 
Code:
##Marius Reform##
iMissionsNeeded = 0
iCitiesNeeded = 10
mariusHeader = "Marius Reform"
mariusMessage1 = "An old soldier called Marius has called for the Roman Army to be reorganized, this means that as of now, all your cities give units +1 experience on build!"
mariusMessage2 = "A man called Marius has called for the Roman Army to be reformed!"
def eventMarius():
    if getNumPlayerCities(eRome) >= iCitiesNeeded and getGlobalData("iMissionCounter") >= iMissionsNeeded:
        addMessage(mariusMessage2, (), eWhite)
        showPopup(mariusHeader, mariusMessage1)
        setRomeExtraXP()

the ExtraXP corresponds to your datastorage stuff in my customFeatures:
Code:
#Marius XP give#
def isRomeExtraXP():
	"""
	Returns True if the "bExtraXP" flag has been set. Otherwise returns False.
	"""
	return getPlayerData(pointer("Rome", playerID), "bExtraXP")
       
def grantExtraXP(pUnit):
	if isRomeExtraXP() and pUnit.getOwner() == pointer("Rome", playerID):
		pUnit.setExperience(iRomeExtraXP, iRomeExtraXP)
 
added this line to marius (so that gaul etc can't get popup: if isHuman("Rome") == True:
 
You're aware of that the iMissionsNeeded value is set to zero, right? But you're just trying to make it fire once only? Ok, the you have two options. Either you make the check on some game date - the target date - and the isDate() function will ensure that the condition only passes once.

The other option is complicated, but you should totally do it because I already made you the DataStorage module for exactly this sort of thing. So you define another custom global value ("bMariusFired"?) and give it the default value of False with setGlobalData() on gameStart. Then you use the getGlobalData() method to check if the value is False or not. And if it is - then fire the event and also set the value to True (same method as above). This will prevent the condition passing anymore.

I didn't give you any code or any helper for this, because I do believe that you can figure out the specifics yourself. :king:
 
ok I will figure out how to do it... what about the not giving xp increase problem?

During testing as I have no senate module yet and I don't want to wait for missions I am only using cities...
 
Aha, there was another issue. Where did you plug in grantExtraXP() in the Event Manager? Because it needs to be in onUnitBuilt().
 
And I think you should do as much testing on what you already have before adding too much new stuff to the mod. But I guess its just too much fun and you simply can't help yourself? :p
 
ok here we go:

Code:
def setupKill():
    setGlobalData("bMariusFired", False)

def killMariusCode():
    setGlobalData("bMariusFired", True)

def getMariusFired():
    getGlobalData("bMariusFired")

and then in code:

##Marius Reform##
iMissionsNeeded = 0
iCitiesNeeded = 10
mariusHeader = "Marius Reform"
mariusMessage1 = "An old soldier called Marius has called for the Roman Army to be reorganized, this means that as of now, all your cities give units +1 experience on build!"
mariusMessage2 = "A man called Marius has called for the Roman Army to be reformed!"
def eventMarius():
    if getNumPlayerCities(eRome) >= iCitiesNeeded and getGlobalData("iMissionCounter") >= iMissionsNeeded and getMariusFired() == False:
        if isHuman("Rome") == True:
            addMessage(mariusMessage2, (), eWhite)
            showPopup(mariusHeader, mariusMessage1)
            setRomeExtraXP()
            killMariusCode()

with the thingys included... I will add it into the eventmanager next to the other datas (rebels and missioncount...)

I added this to onunit build:

Code:
	def onUnitBuilt(self, argsList):
		'Unit Completed'
		city = argsList[0]
		unit = argsList[1]
		player = PyPlayer(city.getOwner())
		CvAdvisorUtils.unitBuiltFeats(city, unit)
		
		if (not self.__LOG_UNITBUILD):
			return
		CvUtil.pyPrint('%s was finished by Player %d Civilization %s' 
			%(PyInfo.UnitInfo(unit.getUnitType()).getDescription(), player.getID(), player.getCivilizationName()))

		Custom.grantExtraXP(unit)

as you can see... in the right place... but I didn't define in the onGameStart...? should I have done?
 
You forgot about the return command again. :D

Function (and methods of classes and instances) always return something. If the code isn't exiting via a return line it will always return None as a default.

So if you want a function to return a specific value, then you need to explicitly state this with a return statement.
 
Back
Top Bottom