Requesting following features

I do have faith in the code! (apart from the fact that you mentioned a variable before it was defined :p) I couldn't test as every time I end turn I get around 100 exceptions :rolleyes:! now the calendar is fixed (for reasons god emperor explained) I can continue to test the code :p
 
I expect there to be more issues and bumps in the road. But my solution was already working a year ago, and it keeps working to this day. The problem is that we adapted bits and pieces of my original code for your mod. And I haven't tested any of this particular build myself, so I'm clearly not talking about things working perfectly. But with a little faith we can fix the issues. Because the basic idea is tried and tested, and we will be tweaking things so that you get exactly what you need.
 
works, a little hitch with my defining (the calendar adjustments changed it) so it went on the next turn but when I tried it again with a different date (that actually was a date in the revise) it worked perfectly and on the turn I wanted it to happen on! Congratz on some more error free code! I will document tommorrow morning or night if I have the time :rolleyes:
 
Great news! :king:
 
and you have well earned that king :p 2 in a row... I'm impressed :D
 
As said, the basic code is one year old and tested by several modders. (100-200 downloads.)
 
Code:
def changeGold(self, iChange):
	"""
	Grants iChange of Gold. A negative value will subtract gold.
	"""
	giveGold(iChange, eRome)

def grantUnit(self, eUnit):
        """
        Spawns one free unit in capital of eUnit type.
        """
	spawnUnits(eRome, eUnitType, tCoords, iNum)

def grantGoldenAge(self, iNumTurns):
        """
        Starts a Golden Age for iNumTurns.
        """
	giveGoldenAge(eRome, iTurns)

def changeHappiness(self, iHappiness):
        """
        Changes the happiness of all of Rome's cities, can also be used negatively
        """
	lCities = getCityList("rome")
	for pCity in (city.GetCy() for city in lCities):
		pCity.changeExtraHappiness(iHappiness)

def grantUpgrade():
        """
        Gives a random building increased defence or modifers for Rome ONLY
        """
	pass

def grantBuilding(self):
        """
        Gives a random building in a random city in rome
        """
	targetCity = getRandCity("rome")
	building = getRandBuilding(targetCity, bPresent=False)
	if not isWonder(building):
		targetCity.setNumRealBuilding(building, 1)

def grantCivic(self, pCivic = gc.getInfoTypeForString('CIVIC_REPUBLIC')):
        """
        Gives the player an anarchy free civic swap to republic by default 
        """
	bBasic = True
	pPlayer = gc.getPlayer(eRome) #instance("Rome").get(CyPlayer)?
	if pPlayer.isCivic(pCivic):
		pPlayer.setCivics(0, pCivic)
		showPopup(senateHeader, freeCivicMessage)
	else:
		print "No usable civic for FreeCivic()"

def grantTech(self, header=freeTechMessage):
        """
        Grants a free tech to the player
        """
    	pPlayer = instance("Rome").get(CyPlayer)
	if pPlayer.isHuman():
	        pPlayer.chooseTech(1, header, False)
	else:
		pPlayer.AI_chooseFreeTech()

def CitySelect(self):
	"""
	As far as I know this was for a reward where the player gets to receive a free city (providing any 	spots are left...) This code will be difficult, I guess a random list of city locations could be collected 	from Historical cities (if it doesn't already exist in game) and presented to the player (giving them the 	name corosponding to the coords) to choose!
	"""
	pass

# penalties
def rebelUnit(self, eUnitType):
        """
        Spawns a rebel unit somewhere in the radius of a random city!
        """
	#I will do this easily!
	spawnUnits(eItalianRebels, eUnitType, tCoords, iNum)

def destroyBuilding(self):
        """
        Destroys a building in a random roman city (could be replaced by an arguement within the 	giveBuilding function changing
        setNumRealBuilding and bPresent to a building destruction)
        """
	targetCity = getRandCity("rome")
	building = getRandBuilding(targetCity, bPresent=True)
	if not isWonder(building):
		targetCity.setNumRealBuilding(building, 0)

def anarchyTurns(self, iAnarchy):
        """
        Gives iAnarchy turns of anarchy
        """
	pPlayer = instance(player).get(CyPlayer)
	pPlayer.changeAnarchyTurns(iAnarchy)

def civilWar(self):
        """
        Starts a civil war in Rome, however I am not sure how the code would decide on the cities to use 	(this code is a bit of a mess
        atm :p) any ideas?
        """
	condition = False #this should be changed...
	if condition:
		lCities = 
	        CivilWar.initCivilWar(instance("Rome"), lCities)

	else:
		lCities = 
        	CivilWar.initCivilWar(instance("Rome"), lCities)
 
Firstly, these aren't functions, but rather instance method belonging to the SenateOutcome class. So you need to adjust the indentation accordingly.

For the grantHappiness() method I suggest we use CyPlayer.changeExtraHappiness() instead of CyCity.changeExtraHappiness. That would be easier, more robust and over-all better.

Can you specify grantUpgrade(), please? Perhaps look in the API for stuff that can actually be done. (I doubt defensive modifiers are there, but yields and production probably is.)

This is pretty nonsensical:
pCivic = gc.getInfoTypeForString('CIVIC_REPUBLIC')
I'm guessing it should be eCivic and that would be defined in the eNums module, not?

Over-all you could just define pCivRome = instance("Rome") as a constant and be done with it. No need to fetch the instance in every single method.

I'll have a look at civilWar() and see how that should be set up. (I don't remember myself, but the code should be readable, with any luck. :p)

I can also give selectCity() - my suggestion for name - a try. Should it be a pop-up with multi-option player selection, or should a script do the choosing for the player? You could augment the city coords/name array in HistoricalCities with dates. So if there is a date, then it means that it is a historical Roman settlement (colony). Those sites would be relevant for this script, then, and the auto-chooser would fetch the entry which is closets to the current game date. Or, perhaps, if there is no available colony within some date range, then the scenario would resort to granting a random reward instead. (The same with republic civic and probably other methods as well: If any method returns False, then its an instant random reward/penalty. Good?)

Give the current code a once-over and I'll get back to you on the blank spots. We'll get this done yet! :king:
 
the dates could over complicate things (plus a lot more work for me :p), but using the coords and names in a popup for the player to choose would be good, to see a function you made on the yields thing check the original code I posted! Those functions I posted were just for documentation purposes I didn't think of actually using method indenation
 
the dates could over complicate things (plus a lot more work for me :p), but using the coords and names in a popup for the player to choose would be good,
I can see your point on the dates, but doing a multi-option pop-up complicates things for me. :p

to see a function you made on the yields thing check the original code I posted!
What yields? What code? Post again (just the relevant bit). Other than that, I'm quite confident I can manage, if I just can figure out what this is in reference to. (I don't generally keep track of "useful" bits of code for reference - its quicker to just write new code than to look-up something I did ages ago.)

Those functions I posted were just for documentation purposes I didn't think of actually using method indenation
I'm gonna write actual code, so it helps if the template we're using is properly indented.
 
Code:
def buildingOutput(pCity, eBuilding, iFood=0, iProduction=0, iCommerce=0):
        """
        Adds or subtracts the integer amount of iFood, iProduction or iCommerce from the associated YieldType of
        eBuildingClass (integer) in pCity.
        """
        eBuildingClass = getBuildingClassType(eBuilding)
        tOutputChange = iFood, iProduction, iCommerce
        for iYield in range(len(tOutputChange)):
                pCity.setBuildingYieldChange(eBuildingClass, iYield, tOutputChange[iYield])

There!

If you want I can help with the popup things?
 
So, you wanna use buildingOutput() for the grantUpgrade() method? What should the building be? What yield should be changed? How much? (You might be able to do this yourself, actually.)

If you already have a handle on creating the multi-option pop-up then you can totally set it up. The question is what you need from me? An array of cities? (Perhaps tuples containing CyCity objects and city names, right?)
 
well I will look into multioptional popups (I believe I have seen something like that before...) and once we have that basic form down we can work on the code that supplies the options to the popup (actually sounds really fun to do :p)

The city affected and the building affected would probably be at random, easy enough to do I will see if I can forge a method for it :p there will be flaws with the plan so I will have to think carefully, is there any way to increase the defensive 'Bonus' provided by walls? that would always be a logical option :lol:
 
well I will look into multioptional popups (I believe I have seen something like that before...) and once we have that basic form down we can work on the code that supplies the options to the popup (actually sounds really fun to do :p)
It shouldn't be a problem, since there is both a pop-up class or two in the API, and there is also a helper module in one of the game version Python folders, which wraps those methods into functions. I think we wanna create a wrapper function for our pop-ups, in the event we wanna use them again.

The city affected and the building affected would probably be at random, easy enough to do I will see if I can forge a method for it :p there will be flaws with the plan so I will have to think carefully, is there any way to increase the defensive 'Bonus' provided by walls? that would always be a logical option :lol:
The problem with random buildings is that there is no clear-cut way to access what buildings are present in a city. You can only check whether or not a certain building is present. Also, you should probably limit this feature to only some key buildings, each with a default bonus. It should make sense, at least.

Then the issue becomes iterating through cities randomly, looking for these buildings. Continue until all cities are checked for all relevant buildings. Add the associated bonus once one is found.

I believe that the defensive city bonus we used for a Gallic power in Glory & Greatness was made possible by Asaf altering the SDK... But you could always check the API, just to make sure.
 
This is the module we're already using for pop-ups:
C:\Program\Firaxis Games\Sid Meier's Civilization 4\Assets\Python\pyHelper\Popup.py
From Utils.py:
Code:
from Popup import PyPopup
As far as I can see, what is needed for the multi-choice pop-up - beyond what we've already done - is to call createRadioButtons() with the number of available cities/colonies as the parameter. Then, we invoke setRadioButtonText() while iterating through the radio button IDs and the city names.

Then, we have to define the pop-up as a game event, somehow, in the CvEventManager module. This would catch the ID of the radio button selected, and we can apply the code we wanna use.

Also, we need to define all pop-up IDs... somehow.

I was looking for a tutorial/guide for pop-ups, but couldn't find one. :p
 
Scratch that. We should use CyPopupInfo (in the API) instead!

Spoiler :
I found this code (for CvEventManager), used for triggering random events on a keyboard command:
Code:
                popupInfo = CyPopupInfo()
                popupInfo.setButtonPopupType(ButtonPopupTypes.BUTTONPOPUP_PYTHON)
                popupInfo.setText(CyTranslator().getText("TXT_KEY_POPUP_SELECT_EVENT",()))
                popupInfo.setData1(iPlayer)
                popupInfo.setOnClickedPythonCallback("selectOneEvent")
                for i in range(gc.getNumEventTriggerInfos()):
                    trigger = gc.getEventTriggerInfo(i)
                    popupInfo.addPythonButton(str(trigger.getType()), "")
                popupInfo.addPythonButton(CyTranslator().getText("TXT_KEY_POPUP_SELECT_NEVER_MIND", ()), "")
                
                popupInfo.addPopup(iPlayer)
Then we have this bit for CvScreensInterface:
Code:
def selectOneEvent(argsList):
    iButtonId = argsList[0]
    iData1    = argsList[1]
        
    eventTriggerName = None
    eventTriggerNumber = -1

    if iButtonId < gc.getNumEventTriggerInfos():
        eventTriggerName = gc.getEventTriggerInfo(iButtonId).getType()
        eventTriggerNumber = iButtonId
    if eventTriggerName == None:
        return
    if eventTriggerNumber == -1:
        return

...

    pPlayer = gc.getPlayer(iData1)
    pPlayer.trigger(eventTriggerNumber)
We clearly don't have to copy-paste all of it, but rather mirror the key bits in our own code. So we basically need to iterate cities (if CyCity instances aren't valid, the we need to pass a tuple containing the PlayerType and the City ID) instead of EventTriggerTypes. And instead of triggering random events, we need to flip that city.
So I guess this is in the bag, then. What I need to focus on now, is compiling that city list. So... what are the rules? What cities are relevant? Cities with Roman culture? Cities close to Roman borders? Cities that are unhappy? What?

And after that: What historical city sites would be of interest? How will the human player know where that site is located just by reading the name? Or should the player only get one suggestion and has to either accept or decline it. (There could be a blinking dot in the mini-map for the location.)

edit: Duh! I knew I had seen a tutorial, once... :p
 
For the civilWar() punishment method we need to compile a list of cities. Again; what are the rules? Should there be any randomness? Perhaps a possibility that Rome itself defects (the Senate revolts, so to speak)? Or should it only be unhappy cities? What level of unhappiness? Is distance to Rome a factor? Number of city defenders, perhaps? How many cities should take part in a revolt?
 
AHHHHH!!!!!!! why didn't I think of that! The ping idea is great and I am pretty sure it will be easy to do(it actually exists in game on the edge of the minimap there is a button which creates a blue pulse on the map and a blink on the minimap, used for multiplayer where teams want to show places of interest)!!! well, I guess the receiving of nearby cities would be good, add to the list all cities that are not roman but with atleast 25% roman culture inside. (add that as a constant incase I want to increase it) Also there should be a box, inside that box is where rome could get a city founded for them, the code needs to scan HistoricalCities for coords within the box and pick maybe 2 or 3 to add the the list inside the popup. This could be really good code... shame I have to finish the rest of the module before it get really get used :lol:
 
not sure about the civil war... I will mull it over... Really exited about the city gifting code though, it's going to be great!
 
Back
Top Bottom