1. We have added a Gift Upgrades feature that allows you to gift an account upgrade to another member, just in time for the holiday season. You can see the gift option when going to the Account Upgrades screen, or on any user profile screen.
    Dismiss Notice

New Diplomacy Options

Discussion in 'Civ4Col - Medieval: Conquests' started by Kailric, Jun 20, 2014.

  1. Kailric

    Kailric Jack of All Trades

    Joined:
    Mar 25, 2008
    Messages:
    3,094
    Location:
    Marooned, Y'isrumgone
    I am wanting to write a tutorial on how to add new Diplomacy Options, but I would like to add a new Diplomacy option in the process. I keep forgetting the steps myself so I want to get them wrote down. The question is what option should I do? Here is a list of some of the things I have in mind, please post your own...

    Fix up Ransom Knight Code
    Leaders will appear and offer to Random back your Knights defeated in battle

    Poaching and Hunting Rights

    You can give or take away Hunting Rights on your land. This I will save until I visit the whole Hunting mechanic and do it all at once.

    Trade Commodity Deals
    Such as a certain amount of Goods each turn is delivered to a City.

    Pope Decrees (I take these ideas from the different Councils the Papacy held)
    Banned Civics
    This is already in the develop branch

    Banned Techs
    Such as Crossbow. I can easily mod the Banned Civics code to included this

    Declare a City Holy

    You can no longer attack that City and it is declared holy. Either by a Martyr, a Relic, Shrine, etc.

    Declare Holy War
    The Pope declares a Crusade against one of his rivals

    Truce of God
    Ends all Wars for a certain amount of turns

    Robbers of pilgrims and of merchants shall be excommunicated
    This will be a good one for when we add the Bandit profession

    There are plenty more Councils to draw inspiration from for Papal Decrees

    Giving away your Sons and Daughters to marriage in order to form alliances was a big deal back then. I wonder if we could make this fit into M:C some how.


    Current Diplomacy Options

    Trade Techs
    Make Research Pacts
    Help each other on a Research Project

    Trade Relations
    This is required before someone will Open Their Borders. Merchants and Traders are the only ones allowed to cross borders

    Open Borders
    Any unit my cross borders

    Contact Info
    As in Civ games you can trade Contacts.

    Hunting Rights
    Hunters are allowed on each others land. Still need to add Diplomacy Options to ban Native Civs from hunting on your land.

    Adding new Diplomacy Options and Events Tutorial

    Spoiler :

    In this Tutorial we will give a brief example on how to add new Diplomacy Options and Events. To do this you will need to be able to work with XML, Python, and C++ in the DLL.
    First off we need to decide what we want our new Diplomacy Option to do. For this tutorial we will be adding a new Crusade Diplomacy Option for the Pope. The goal is for the Pope to check to see if there are any Civs that he is Annoyed with and then check to see if there are any Players he is Pleased with. If he finds both he may ask the one to Crusade against the other, while staying out of the fight himself.
    First we can visit CIV4DiplomacyInfos.xml to create our new option:
    Code:
    <DiplomacyInfo>
     <Type>AI_DIPLOCOMMENT_ACCEPT_HOLY_WAR</Type>
       <Responses>
         <Response>
           <Civilizations/>
           <Leaders>
             <Leader>
               <LeaderType>LEADER_THE_ANGLO_POPE</LeaderType>
               <bLeaderType>1</bLeaderType>
             </Leader>
           </Leaders>
           <Attitudes/>
           <DiplomacyPowers/>
           <DiplomacyText>
             <Text>AI_DIPLO_JOIN_HOLY_WAR_1</Text>
           </DiplomacyText>
         </Response>
       </Responses>
    </DiplomacyInfo>
    A DiplomacyInfo is setup with responses. Think of it as a conversation. For the Initial Response the Pope will state his request. You can have Civs set up to give Unique responses by creating another Response, but for this exercise we just need the Pope&#8217;s response.

    First we need to define a Type. The Type will need to be Unique and not used by any other Diplomacy Option. Here we have used AI_DIPLOCOMMENT_ACCEPT_HOLY_WAR.

    So, we have added the Pope to the list of Leaders. The Code will check here for the Leader in question. If you do not add a Leader then all Leaders will use this Response. So, technically since the Pope is the only Leader that will use this DiplomacyInfo we do not have to add a Leader here.

    Moving on, the DiplomacyText is the text that will be displayed in the game. It is the message the Pope is speaking to the player. You can use multiple text here. For example we can add a AI_DIPLO_JOIN_HOLY_WAR_2, which has a slightly different message. This can add a bit of randomness to the conversations so they don&#8217;t seem so static.

    Next we need to add the Player&#8217;s Options:
    Code:
    <DiplomacyInfo>
       <Type>USER_DIPLOCOMMENT_ACCEPT_HOLY_WAR</Type>
       <Responses>
         <Response>
           <Civilizations/>
           <Leaders/>
           <Attitudes/>
           <DiplomacyPowers/>
           <DiplomacyText>
             <Text>AI_DIPLO_ACCEPT_HOLY_WAR_1</Text>
           </DiplomacyText>
         </Response>
       </Responses>
    </DiplomacyInfo>
    Here we have simply added the Type and what the DiplomacyText will be. For this initial tutorial this is all we will need.

    For the next step we will be using Python. I use the Free Komodo python editor.
    Open up CvDiplomacy.py in your chosen editor and find a suitable spot to add our code. I chose to put the initial code just below the Kiss Pinky code.
    Code:
    elif (self.isComment(eComment, "AI_DIPLOCOMMENT_KISS_PINKY")):
    	#iDiplomacyType = 1
    	# We can accept their demands
    	self.addUserComment("USER_DIPLOCOMMENT_KISS_PINKY", -1, -1)
    
    	# Or reject them...
    	player = gc.getPlayer(gc.getGame().getActivePlayer())
    	eYield = player.getHighestTradedYield()
    	iCityId = player.getHighestStoredYieldCityId(eYield)
    	city = player.getCity(iCityId)
    	if city.isNone():
    		szCityName = u""
    	else:
    		szCityName = city.getNameKey()
    
    self.addUserComment("USER_DIPLOCOMMENT_TAX_PARTY", eYield, -1, szCityName, gc.getYieldInfo(eYield).getTextKey())
    #TKs Med
    elif (self.isComment(eComment, "AI_DIPLOCOMMENT_ACCEPT_HOLY_WAR")):
    
    	# We can accept their demands
    	self.addUserComment("USER_DIPLOCOMMENT_ACCEPT_HOLY_WAR", -1, -1)
    	# Or reject them...
    	self.addUserComment("USER_DIPLOCOMMENT_NO_JOIN_WAR", -1, -1)
    
    First we allow the code to find our new Option in &#8220;isComment&#8221;, in the Python definition&#8221; def determineResponses&#8221;. When our option is found it then checks for what the player&#8217;s choices will be. Here we have added the Accept Holy War option plus the Generic NO_JOIN_WAR option.

    With this much codded the Diplomacy Popup can appear in the game with the Pope asking the Player if he wants to go on a Crusade. The Player will have the two options to choose from. Now we must add code for what happens when the Player makes a choice. This is handled in the Python definition &#8220;def handleUserResponse&#8221;.
    Code:
    #TK if we accept the holy war
    elif (self.isComment(eComment, "USER_DIPLOCOMMENT_ACCEPT_HOLY_WAR")):
    	diploScreen.diploEvent(DiploEventTypes.DIPLOEVENT_ACCEPT_HOLY_WAR, diploScreen.getData(), -1)
    	self.setAIComment(self.getCommentID("AI_DIPLOCOMMENT_THANKS"))
    # If we refuse to join their war
    elif (self.isComment(eComment, "USER_DIPLOCOMMENT_NO_JOIN_WAR")):
    	diploScreen.diploEvent(DiploEventTypes.DIPLOEVENT_NO_JOIN_WAR, -1, -1)
    	self.setAIComment(self.getCommentID("AI_DIPLOCOMMENT_JOIN_DENIED"))
    We have added our code just above the generic No Join War comment. Here is where we set it up so that Python speaks to the DLL and makes the magic happen. This is handled in the DiploEventTypes code, which we will describe in detail in a bit. First to finish our Python code, we have chosen to allow the conversation to continue by adding the AI_DIPLOCOMMENT_THANKS comment, which is generic code that allows you to return to a general state of Diplomacy Options. However, If we want the Conversation to end after the Player chooses to accept we should replace this code with diploScreen.closeScreen().

    As you can see you can actually keep the conversation going by adding new AI_DIPLOCOMMENT types. Also, here is where you change the Emotions the AI player displays in the game by using the def performHeadAction. By using the examples given you can cause the in Game model of the AI player to show a Friendly attitude, Furious attitude, etc. However, the LeaderHead model in question has to have the animations for this to truly take effect.

    Now, to get this new option to work we must setup the DLL. This is the C++ work. First we need to edit CvEnums.h to add our new DiploEventTypes, which does not break saved games by the way. Add the DIPLOEVENT_ACCEPT_HOLY_WAR to the end of the function &#8220;enum DllExport DiploEventTypes&#8221; using the existing code for example.

    You will also need to add this enum to the CyEnumsInterface.cpp in order for Python to know what this new enum is. Add .value("DIPLOEVENT_ACCEPT_HOLY_WAR", DIPLOEVENT_ACCEPT_HOLY_WAR) to the python::enum_<DiploEventTypes>("DiploEventTypes") values.

    Now that the DLL and Python know what our new enum is we move on to the brains of the operation.

    First we open CvPlayerAI.cpp and here we need to added a new function. I created the new function bool CvPlayerAI::AI_doDiploAskJoinHolyWar(PlayerTypes ePlayer) which I will not go into the details on adding functions here as this is covered in other tutorials on the web plus it helps to have a general knowledge of C++ to do this part. However, I will explain where in the code this new function needs to go.

    Our new function, AI_doDiploAskJoinHolyWar will allow the Pope to search for a target player to ask others to Crusade against. This new function is added to void CvPlayerAI::AI_doDiplo(). This function is called every turn and cycles through all the Diplomacy Options and attempts to find one that has all the right elements in place in order to happen.

    I add the below code just before the AI checks if it wants to AI_doDiploAskJoinWar
    , which is it asks someone if they want to join a war. In the below code it basically checks if the Player has been contacted yet, if not it checks to see if there are any Holy Wars to negotiate and if so it sets the Human player as having been contacted. This prevents the AI from having multiple requests per turn on human players.

    Code:
    if (!kPlayer.isHuman() || !abContacted[kPlayer.getTeam()])
    {
    	if (AI_doDiploAskJoinHolyWar(ePlayer))
    	{
    		if (kPlayer.isHuman())
    		{
    			abContacted[kPlayer.getTeam()] = true;
    		}
    	}
    }
    That sets up the initial popup, but now we need to add what happens when the Player makes his choice. This is handled in CvPlayer.cpp&#8217;s void CvPlayer::handleDiploEvent

    Go there now and we add the below code:

    Code:
    case DIPLOEVENT_ACCEPT_HOLY_WAR:
    	AI_changeMemoryCount(ePlayer, MEMORY_ACCEPTED_JOIN_WAR, 1);
    	GET_TEAM(GET_PLAYER(ePlayer).getTeam()).declareWar(((TeamTypes)iData1), false, WARPLAN_DOGPILE);
    
    	for (iI = 0; iI < MAX_PLAYERS; iI++)
    	{
    		if (GET_PLAYER((PlayerTypes)iI).isAlive())
    		{
    			if (GET_PLAYER((PlayerTypes)iI).getTeam() == ((TeamTypes)iData1))
    			{
    					GET_PLAYER((PlayerTypes)iI).AI_changeMemoryCount(getID(), MEMORY_HIRED_WAR_ALLY, 1);
    			}
    		}
    	}
    	break;
    Here, we set the Crusading Player at war with target Player. There are a couple of other things here that are important. We change the MEMORY_ACCEPTED_JOIN_WAR memory enum by 1. This allows the Pope to have a positive modifier to this event. Memory types allow the AI to remember what has or hasn&#8217;t happened to them in relation to other players. This effects their attitudes towards that player. For this event we simply reused the generic Join War memory but perhaps we should create a new memory type specific to this event. That however is outside this tutorial.

    The other thing that happens is another memory type is increased, that being MEMORY_HIRED_WAR_ALLY. This memory type tells the AI that it has recently hired an Ally which is used in other parts of the code.

    Though I did not display it, there is one other type of enum that is used besides Memory types and that is the Contact types. Each Leader has Contract type attributes that determine how often and when the AI will contact another player for all the different Diplomatic events. For this example I reused the CONTACT_JOIN_WAR timer in the AI_doDiploAskJoinHolyWar function. When the AI contacts the player we do:

    Code:
    AI_changeContactTimer(ePlayer, CONTACT_JOIN_WAR, GC.getLeaderHeadInfo(getPersonalityType()).getContactDelay(CONTACT_JOIN_WAR));
    This sets it up so that this AI Player will not Contact this Player on this issue for a set amount of more turns.

    Each Diplomatic Event can have its own MemoryTypes and ContactTypes that can greatly increase realistic AI behavior. Note; adding either of these two will break saved games.

    That's it for now. I must head on out as the Pope just asked me to Crusade against some ruffians. Happy Coding:goodjob:
     
  2. Trade Winds

    Trade Winds Chieftain

    Joined:
    Nov 21, 2013
    Messages:
    235
    Declaring or stopping war against a Christian civ because its holiness (had bribed the papacy) or its sins (someone paid more)

    Easy modders way (I think):
    Sending a Noble as a present to a civ (or trading him in a trade screen) in exchange of some truce.

    Difficult way (I think):
    Having an intricate personal adscription of cities entitled to noblemen of all kinds so that you can tie two noblemen of different civs together and they can access their respective cities and in that way build an alliance between the two civs. This idea needs brushing.
     
  3. orlanth

    orlanth Storm God. Yarr!

    Joined:
    Nov 17, 2001
    Messages:
    1,760
    K, these sound like good ideas :goodjob: Will these still work for mods where there's not only one main "Pope" civ who applies for almost everyone? Ie if some civs have their own unique parent civ rather than everyone sharing one Pope in common. Or if there are a few Pope-like leaders, who are the Parent of different groups of civs (like Pope parent of Catholic civs, Caliph the parent of Muslim civs, Patriarch parent of Orthodox civs, etc). It would be cool if each Parent can have his own likes and dislikes and decrees etc.
     
  4. Kailric

    Kailric Jack of All Trades

    Joined:
    Mar 25, 2008
    Messages:
    3,094
    Location:
    Marooned, Y'isrumgone
    Only if you set up a Civ to be the Religious Center will all Players have the same Civ. And at the moment there is only one Religious Center, but I will make it so you can have more. I need to make so that you can just add a "Parent Civ" to a Civilization as well.
     
  5. Kailric

    Kailric Jack of All Trades

    Joined:
    Mar 25, 2008
    Messages:
    3,094
    Location:
    Marooned, Y'isrumgone
    I've added a tutorial on adding new Diplomacy Events to the opening post. I do this for myself as well as any others as I am always forgetting the steps to doing diplomacy:p

    I will add this to the wiki as well at some point.
     
  6. Nightinggale

    Nightinggale Chieftain Supporter

    Joined:
    Feb 2, 2009
    Messages:
    4,110
    All this talk about diplomacy is giving me an idea. In some places we call gDLL->getInterfaceIFace()->addPopup(). The exe will then generate the popup window and it will appear on start turn.

    What if we make our own variable containing all the arguments and make a vector of those in CvPlayer. We then add CvPlayer::addPopup() to fill the vector. During the player's turn, if the vector isn't empty, a new button appear. Clicking that button will take something from the vector and call DLL->getInterfaceIFace()->addPopup(). There is then a new answer, which is "postpone answer", which puts the popup arguments back into the vector.

    The player can't hit end turn before the vector is empty.

    This way we can make a popup window type, which we can answer at any time during the turn instead of at the start of the turn. If you are asked to declare war, you can postpone the answer, look at where possible enemy units are, how many they are and so on and then answer. It would also make sense to be able to check city storage when somebody tries to sell you some yields and so on.

    Also it allows a very important improvement. The answers in the popup will be recalculated each time the window pops up. This mean if your only answer is "sorry, I don't have the money", you can postpone the answer, sell something and then the "buy something" answer appears.
     
  7. Kailric

    Kailric Jack of All Trades

    Joined:
    Mar 25, 2008
    Messages:
    3,094
    Location:
    Marooned, Y'isrumgone
    That's cool, I was having a similar thought on the Holy War, where you could say, "Let me consult my advisors. (Wait a turn)", and then have a turn to check out all the factors. But with your idea we can just have a new generic response added instead. I like it very much!
     
  8. Kailric

    Kailric Jack of All Trades

    Joined:
    Mar 25, 2008
    Messages:
    3,094
    Location:
    Marooned, Y'isrumgone
    We now have a Delayed Response reply in a bunch of the Diplomatic requests. If the option appears you can select "Let me consult my advisors" and then an "Diplomats Waiting" Icon will appear in the top right top left corner. Select this when you are ready to make your response. Also, you can not go to next turn until all Diplomats are dealt with. "Madness? Let me consult my advisors... This is Sparta!"

    We have also separated Open Borders and Trade Relations. Trade Relations does what Open Borders use too, except you are only allowed to move about with none military units. Open Borders will allow you to use any unit. You will need to have Trade Relations before you can have Open Borders.
     
  9. Nightinggale

    Nightinggale Chieftain Supporter

    Joined:
    Feb 2, 2009
    Messages:
    4,110
    It's actually top left corner :p
     
  10. Kailric

    Kailric Jack of All Trades

    Joined:
    Mar 25, 2008
    Messages:
    3,094
    Location:
    Marooned, Y'isrumgone
    I meant from the perspective of the AI, just in case any of them are listening;)
     
  11. Fullerene

    Fullerene Chieftain

    Joined:
    Aug 26, 2009
    Messages:
    228
    Gender:
    Male
    My idea for the diplomacy

    It might or might not fit to the Medieval: Conquest, but you should check it out. I really feel that diplomacy could be lot more interesting than it is now ( in all Civ games).
     
  12. Kailric

    Kailric Jack of All Trades

    Joined:
    Mar 25, 2008
    Messages:
    3,094
    Location:
    Marooned, Y'isrumgone
    While I like the idea of spending points to do things, I'll have to think it through more.


    On another note, I have been trading Techs with Genseric in my current game and it has me thinking. While Genseric loves my techs and is willing to pay a decent price, there should be a draw back to giving away all your techs to Minor Civs. Perhaps, if a Minor Civs tech level is the Same or Greater than yours there is a Chance they will advance to Major Civ Status and become more Competition, how about them apples?

    Currently, Minor Civs will offer you Techs that you do not have, so Tech trading is advancing along pretty well.

    Edit: Hmm, I wonder if you added a boolean for bIsNative. Currently when a Player is checked for being a Native it all goes back to the Civilization Info. I wonder what would happen if we added a boolean check, and if a Minor Civ becomes a Major Civ the boolean would be false. I wonder what that would do? :D
     
  13. Lib.Spi't

    Lib.Spi't Overlord of the Wasteland

    Joined:
    Feb 12, 2009
    Messages:
    3,675
    Location:
    UK
    I really like the idea of the possibility that minor nation could rise up to play a larger role on the main stage.

    That would make people more nervous of being too friendly as you may suddenly find yourself with new competition instead of some one you can absorb at leisure.
     
  14. Kailric

    Kailric Jack of All Trades

    Joined:
    Mar 25, 2008
    Messages:
    3,094
    Location:
    Marooned, Y'isrumgone
    Another Diplomacy option idea:

    In my current game I am "friends" with the Turks but their Cultural Borders are advancing over mine. My capital city has lost one of its tiles because of this, so I am thinking that we can have a new Agreement that allows you to keep what borders you currently have and also return any lost tiles that are adjacent to your cities. Basically once your borders meet, no Civ's territory will advance over the other.

    Would this be a good idea? What could the agreement be called?
     
  15. Lib.Spi't

    Lib.Spi't Overlord of the Wasteland

    Joined:
    Feb 12, 2009
    Messages:
    3,675
    Location:
    UK
    Sovereignty Agreement/Accord/Concession?

    I think it would need to be locked to the highest relations only, as 'cultural warfare' is one of those peaceful methods of conquest, that have you have to try and engage in like everything else.
     
  16. Kailric

    Kailric Jack of All Trades

    Joined:
    Mar 25, 2008
    Messages:
    3,094
    Location:
    Marooned, Y'isrumgone
    Right, only if you are on very good terms. Perhaps "Sovereignty of Borders Agreement".
     
  17. Fullerene

    Fullerene Chieftain

    Joined:
    Aug 26, 2009
    Messages:
    228
    Gender:
    Male
    It could be interesting if there was Pope elections in the game. Getting your candidate in the Papal office would give you some control over the Pope. For example declaring the Crusade. And it would be one prerequirement for some sort of "Emperor' victory type. Maybe cross production would have some effect for how many votes you have.

    I know that electing the Pope might not fit well with current game mechanics, but I just think it's interesting idea.
     
  18. Fullerene

    Fullerene Chieftain

    Joined:
    Aug 26, 2009
    Messages:
    228
    Gender:
    Male
    Could we go as far as implementing our own Diplomacy Screen? I can imagine that it would remove lot of possible limitations of current diplomacy interface. At least I believe that if we use some imagination the diplomacy options could be much more interesting. Maybe some group diplomacy could occur or some really sophisticated trade deals or something.
     
  19. Lib.Spi't

    Lib.Spi't Overlord of the Wasteland

    Joined:
    Feb 12, 2009
    Messages:
    3,675
    Location:
    UK
    It is certainly possible, DOaNE has 4 'Home screens' and when you enter negotiations with natives it is a completely new screen. What you can make it do I don't know, I imagine it will be quite a large project to completely rebuild it.
     
  20. Kailric

    Kailric Jack of All Trades

    Joined:
    Mar 25, 2008
    Messages:
    3,094
    Location:
    Marooned, Y'isrumgone
    Since we have complete control over when a Diplomacy Screen should appear (in the DLL) we there for have full control over every aspect of that Diplomacy Screen. If you wanted to work up some grand details on a proposed change and post in a new thread about it then by all means go for it. :goodjob: My hands are full at the moment with other aspects.
     

Share This Page