Making new "tradeable" categories

I'm curious how you made the UB part work. Did you change the UB for the civilization? Depending on how you did it, it could be possible to allow the player to build any type of the ones they have available. You'd need to ensure they don't build 2 of the same class, but that's not hard.

You may be right. In order to do this, I created a function in the CVInfos file like this:
Code:
[COLOR="Green"]/**************************************************************************************************/
/** MOD:         Trade Unique Buildings                                                          **/
/** Author:	 JDHalfrack                                                                      **/
/** Created:     4/02/09                                                                         **/
/** Moddified:   N/A                                                                             **/
/** Code Effect:                                                                                 **/
/**************************************************************************************************/
/** CODE START **/[/COLOR]

void CvCivilizationInfo::setCivilizationBuilding(int iOriginalBuildingClass, int iNewBuilding)
{
	FAssertMsg(iOriginalBuildingClass < GC.getNumBuildingClassInfos(), "Index out of bounds");
	FAssertMsg(iOriginalBuildingClass > -1, "Index out of bounds");
	FAssertMsg(iNewBuilding < GC.getNumBuildingInfos(), "Index out of bounds");
	FAssertMsg(iNewBuilding > -1, "Index out of bounds");
	m_piCivilizationBuildings[iOriginalBuildingClass] = iNewBuilding;
}

[COLOR="green"]/** CODE END **/
/**************************************************************************************************/[/COLOR]

Basically, the way I understand it, each building has a unique integer "ID" number associated to it. These ID numbers are created at the MOD loading time instead of being permanent because there are can be infinitely many buildings based on the user's specifications. However, these buildings must fall into a BuildingClassType.

The BuildingClassTypes are also assigned unique integer IDs at the MOD loading time because users can also create as many BuildingClasstypes as they desire.

The way the game works is that when the MOD loads, it creates an array called m_piCivilizationBuildings. This array contains GC.getNumBuildingClassInfos() elements. GC.getNumBuildingClassInfos() returns the number of different BuildingClassTypes.

So, let's say there are 20 different BuildingClassTypes: BUILDINGCLASS_PALACE, BUILDINGCLASS_WALLS, BUILDINGCLASS_BARRACKS, etc.... Now, when the MOD loads, it creates an array for each civilization that would contain 20 elements in it. Then, it finds the default building for each BuildingClassType. So, for BUILDINGCLASS_WALLS it would find "BUILDING_WALLS" instead of "BUILDING_CELTIC_DUN." Well, if BUILDINGCLASS_WALLS has been assigned the ID of "1" and BUILDING_WALLS has the unique ID of 12, and BUILDING_CELTIC_DUN has the unique ID of 13. The game assigns the value of 12 to m_piCivilizationBuildings[1]. Well, if you are the Celts, it wouldn't assign 12 to m_piCivilizationBuildings[1], instead it would assign 13.

So, the problem is that you can't really assign more than one building that uses the same BuildingClassType because it has to (and I mean it MUST) overwrite the previous value. The only way it may work is to dynamically create a new BuildingClassType when a trade is completed and increase the sixe of m_piCivilizationBuildings by one and assign the new building to it. But I really doubt that would work the way it sounds.

Anyway, does that all make sense?

JD
 
You may want to look at how Dom Pedro did things for his Dynamic Unique Units modcomp.

You are right in what is happening for the game to access things. But the catch here is that you are changing the programs memory of what the XML contained. That means if I play a game and trade to acquire all of the Unique Buildings out there, then I start up a new game as the same civilization (without quitting to desktop), I will START with all of those unique buildings available!

The only way to undo a trade with your approach here is to quit to the desktop and start the mod back up again (or Unload the mod to get back to base BtS and then reload it, same thing). That is because you are rigging the result of the trade to CvCivilizationInfos, which only ever changes at the start of the game loading from desktop. Dom Pedro changes it so that everything is based on CvPlayer, so whenever you start a new game, it will reset you back to base and you progress from there as normal.


I am not certain how your approach will work with savegames. You should try running a game till you trade for a new UB, saving, quitting completely to the desktop, and then reloading. See if you still have the unique building added to your availability.
 
Yes, xienwolf is correct to my knowledge. You should consider everything in the CvXXXInfo class to be read-only. This data is not saved when you save a game, and it is loaded from the XML only when you start civ (or load a new mod which restarts civ).
 
Oky, I see what you mean. I can see how to do it correctly now. It's going to take a bit longer than I had thought, though, because now, I have to find every instance where the game is calling the getDefaultBuildingIndex to make sure it's not trying to find a player's unique building from the default civilizationbuildings array. Instead I have to make a new array that is "per player" and that only initializes when a game starts and then deletes when reseting and make all functions refer to that array. Or something like that. It makes sense to me in my head.

JD
 
Exactly. The linked modcomp can point you to doing all of that though, as it does exactly the same thing, but had a different reason for the player having different UU/UB than the Civ Infos would have assigned to them.
 
I can tell you that I make use of that function in BUG. Given that you'll have a lot of code to modify to make this work, you have two options:

Easy Route

Create CvPlayer::getRealBuilding(BuildingClassTypes eBuildingClass) that does the same thing as the CvCivilizationInfo function but looking in the player's array you mentioned above.

Long Haul

Create CvPlayer::canBuildBuilding(BuildingTypes eBuilding). This would allow the player to build any of the UBs for which they have traded--even when trading for multiple Courthouse replacements. This would be a lot harder and require some serious changes in the Python and C++ code.
 
Oky, I see what you mean. I can see how to do it correctly now. It's going to take a bit longer than I had thought, though, because now, I have to find every instance where the game is calling the getDefaultBuildingIndex to make sure it's not trying to find a player's unique building from the default civilizationbuildings array. Instead I have to make a new array that is "per player" and that only initializes when a game starts and then deletes when reseting and make all functions refer to that array. Or something like that. It makes sense to me in my head.

JD

Bingo! You've got it. :thumbsup: That's how I allowed for changing UU's in my mod.

This is awesome stuff.... could this be extended to trading contact with other civs, like in Civ3?

For example, I am England and I have met France. However, I meet Germany and Germany has no contact with France. In Civ3 you could trade contact between civs like this.

Cheers,
ripple01

I've actually added this into my own mod. I'll be looking for beta-testers in about a week or so. I've added a number of new tradeable items including: Worker trading, Military Unit trading, Corporation trading (relocates HQ to one of the other player's cities), Contact trading, Embassy trading (new game feature), as well as Vote trading.. in other words, if I'm running for Pope, I can get players to pledge their votes for me in the next election, which allows for more wheeling and dealing behind the scenes.

To All:
I'd like to point out that new trade items were not possible prior to the 3.17 patch, so I'd like to thank the folks at Firaxis for adding this when they really didn't have to! :goodjob:

There are a couple of limitations for modders with tradeable items... First, you can't trade quantified values. You know how you click on the Gold or Gold Per Turn item and you get that nice little popup in which you can put the exact amount of gold you want to trade? You can't do that in the SDK. Which stinks because I wanted to add the ability trade Food.

Second thing is that you're really limited to one piece of information. For example, I wanted to make it so that you can ask another player to vote for any valid team for Secretary General. So if you're not elligible, you can at least swing the votes in favor of someone you like. The problem is that this would require the trade table to display all possible VoteSources (UN, Apostolic Palace, etc.) and then break each down by elligible candidates. Can't do that. So I had to compromise and limit it to a vote for YOU.

But aside from that, the sky's the limit... For example, another thing I've considered adding is the ability to marry off children. Under this system, each player would get a certain number of male and female children. Then there would be a trade item called Political Marriage. When you seal the deal, the game will randomly pair off one offspring from each player's child pools. This would be great for a European scenario/mod. Personally, I just want to see the AI deny you as their worst enemy saying "I will not make whores of my daughters!" ;)
 
Another hypothetical question: say US traded you the Mall, could you then trade away the mall?
 
Back
Top Bottom