[MOD] Medieval: Conquests

yeah that sounds perfect! :cool: being able to click on the yield headings to sort the cities by price will be great for planning optimal trades:king:

I agree. I don't think I have done much modding in the Domestic Adviser other than attempt to adjust the screen to fit all the new yields. Also, I added a page for the players Technology but they can be removed as I am moving this to the Founding Fathers page. Which, by the way, is in a rough state at the moment as I was attempting to add the Techs a player learned as well as Founding Dignitaries.

orlanth said:
That sounds cool actually, but the AI might do really badly with it (in the FfH mod, similar "curse" type promotions often caused AI units to sit around vainly trying to "heal" while slowly dying ) If they could get a UNITAI script to return to the nearest city that might still work though.

This seems fairly simple to add or adjust as the AI already has a contingency for when they are hurt to retreat to a city or somewhere safe to heal. But it may add too much micro management in worrying about all of your "bleeding" peasants. So instead of the unit being killed we are looking for an alternative that the player will still dread. Taking his gold would definitely be dreaded but what if the player is almost broke. We could then possibly damage, slow down, or send the unit back to town. If the unit was on a mission such as scouting or a missionary then sending it back to town wounded would be a good compensation. If it was a unit immigrating or moving from one town to another the unit could be damaged and made immobile for a time or held for ransom. If it is a peddler then all its goods could be stolen if it carried any if not then it would be like the immigrant.

Another thing that will need to be figured out is what is the bandit going to do after it has damaged your unit? We don't want it sitting there pounding your unit over and over so maybe the Bandit could go into "hiding" for a time and reappear again later. This would be easy to implement as the system is already in the game. When your units Learn at Natives or go to Europe they are in this "Hidden" state. Also, should it be possible for the player to hunt down this Bandit and get their money or goods back? :)
 
I agree. I don't think I have done much modding in the Domestic Adviser other than attempt to adjust the screen to fit all the new yields. Also, I added a page for the players Technology but they can be removed as I am moving this to the Founding Fathers page. Which, by the way, is in a rough state at the moment as I was attempting to add the Techs a player learned as well as Founding Dignitaries.
In other words I can ignore any changes you made as it will either be done automatically or you plan to move it somewhere else.

I decided to keep identical files and make DLL functions, which returns 0 or 1 depending on if a feature/page should be used or not. I think 3 such functions would be enough (one already implemented in RaR). I already planned adding a function to tell the index of last yield as it mean adding a new yield will not affect the python code at all. The goal is a python code, which adapts to whatever data is given to it and changes are only made in DLL/XML. No hardcoded values in python at all.
 
I invested a little time in the domestic advisor and made one which works for both RaRE and M:C. A nice bonus is that now M:C has total production and native buttons (same as RaRE).

For example since local prices are now more important, it would be great to have a Prices tab on the Domestic Advisor that shows a table of the buy/sell prices for all cities.
I looked into this and the really big question is: what exactly did you mean? I might be missing something, but it looks to me like there is only one local price common to all cities. Making a domestic advisor page with all cities seems pointless.
Listing prices at the natives is pointless too, but the native advisor does inform what they request.

Adding the markets to total production screen could be interesting though. That way we would have total production, total storage and selling price on one screen.
Maybe it shouldn't be called "total production" anymore, but that's another story.
 
I invested a little time in the domestic advisor and made one which works for both RaRE and M:C. A nice bonus is that now M:C has total production and native buttons (same as RaRE).

I looked into this and the really big question is: what exactly did you mean? I might be missing something, but it looks to me like there is only one local price common to all cities. Making a domestic advisor page with all cities seems pointless.
Listing prices at the natives is pointless too, but the native advisor does inform what they request.

Adding the markets to total production screen could be interesting though. That way we would have total production, total storage and selling price on one screen.
Maybe it shouldn't be called "total production" anymore, but that's another story.

Nice work! And having the different markets on a Advisor screen would be pretty sweet. And as you talk about it it sounds like it would be very modder friendly, even make it so you can add new markets and the screens auto adjust.

I think orlanth may be referring to an advanced economy system where cities of different civs have different markets maybe. Which would be neat in a way. I like how in Civ4 you could trade resources and those resources made your citizens happy. A system somewhat based on that is what I have envisioned. That's why you can only trade Spices and Silks from Foreign markets. Spices have a bigger purpose in your production, not sure if I done anything with Silks yet or not:crazyeye: I know I was thinking you could maybe change a Tailors production from Cloth to Silk Gowns just like the Armorsmith works.

I don't know if anyone has noticed it or not but a couple buildings like the Tavern have a +3 Fealty bonus that you can only get if you are selling Ale to the locals. This represents your peasantry having access to goods that they like and your realm gaining a bonus because of it.
 
I had actually assumed each city was going to be able to have its own prices :confused: was that not what's planned? IIRC, the vanilla game does already have different prices for different civs that can change independently, unless that was turned off for this mod. The degree to which the different civs' prices can affect each other is supposed to be determined by <EUROPE_MARKET_CORRELATION_PERCENT> in Assets/GlobalDefines.xml . (however maybe that's one of those tags Firaxis never implemented, I don't see a reference to it in the code chunk for prices that Kailric pointed out!)

Anyway, I think allowing local prices to differ somewhat from each other based on supply/demand would be the most interesting for trade, but at the least there should be some opportunity for national prices to be different; otherwise you won't want to look for markets where your goods are in demand and will always just sell to the closest city.
 
Nice work! And having the different markets on a Advisor screen would be pretty sweet. And as you talk about it it sounds like it would be very modder friendly, even make it so you can add new markets and the screens auto adjust.
Adding new markets automatically mean the DLL should provide python with an array of markets length of this array. I haven't looked enough at the code to figure out how much work that would be, but it may very well be worth it in the long run.

I had actually assumed each city was going to be able to have its own prices :confused: was that not what's planned [...]
Anyway, I think allowing local prices to differ somewhat from each other based on supply/demand would be the most interesting for trade, but at the least there should be some opportunity for national prices to be different; otherwise you won't want to look for markets where your goods are in demand and will always just sell to the closest city.
I agree with you that it would be more interesting that way. I just got confused with your statement that it should already be like that and the code told me something else.

I did a testrun to show prices for each city. Sure I don't have valid numbers to add, but that wasn't the important part here. I wanted to test the ability to add new pages easily.

During init I wrote
Code:
self.PRIZE_STATE  = self.addButton("PrizeState", "INTERFACE_CITY_CITIZEN_BUTTON")
self.YieldPages.add(self.PRIZE_STATE)
New button with a new page and the button uses the citizen icon (last string). The last line assigns yield columns to the page.

During update
Code:
elif(self.CurrentState == self.PRIZE_STATE):
    for iYield in range(self.YieldStart(), self.YieldEnd()):
        szText = unicode(i) + "/" + unicode(iYield)
        screen.setTableInt(szState + "ListBackground", (iYield % self.MAX_YIELDS_IN_A_PAGE) + 2, i, u"<font=2><color=0,255,0>" + szText + u"</color></font>", "", WidgetTypes.WIDGET_GENERAL, -1, -1, CvUtil.FONT_LEFT_JUSTIFY )
i is index of the city and iYield is the index of the yield. There is also access to a pointer to the city at this location, though I didn't use it. This code (and no other additions!) was enough for the attached screenshot. Notice that it starts with yield 18 because it's page 2. Yield 0-17 are on page 1 :)
That was a total of 6 lines where some of them were copy paste of existing code.

I think this system passed the easy to add pages test:high5:

Now if only szText would be set to the actual price, then it would be ready to use.

One thing. I know I skipped the mouseover text string. That would have looked like (copy paste of citizen button)
Code:
elif iData1 == self.CITIZEN_STATE:
    return localText.getText("TXT_KEY_DOMESTIC_ADVISOR_STATE_CITIZEN", ())

Also I miss some button icons. It's not a bug that the same buttons appear multiple times. They are in fact different buttons waiting for new graphics.
 

Attachments

  • Civ4ScreenShot0009.JPG
    Civ4ScreenShot0009.JPG
    154.8 KB · Views: 103
Also I miss some button icons. It's not a bug that the same buttons appear multiple times. They are in fact different buttons waiting for new graphics.
ok I could try my hand at crafting a few button images.. tho I warn I'm not the world's most amazing artist, and am also not above trying 2 adapt anything I can find on google images! :mischief:;) well just let me know what you'd have in mind for them and I can try to crank a few out :borg:

Thats awesome that you're making the new screen functions so flexible both for screen resolution issues & potential modmodding of other game content. After getting a new monitor, I just now realized Colonization 2071 probably looks horrible on all but my previous screen resolution! :blush:
 
Adding new markets automatically mean the DLL should provide python with an array of markets length of this array. I haven't looked enough at the code to figure out how much work that would be, but it may very well be worth it in the long run.
I agree with you that it would be more interesting that way. I just got confused with your statement that it should already be like that and the code told me something else.

Again great work! The markets can easily be expanded on as I listed them in the Enums.h and went from their and they already can be access in python. At the moment each Civ has it's own "market" that being its Europe but the player has no access to this in any form and I don't think the different markets effect each other. As you seen in the code orlanth showed markets are only set up through the "King" Civs. Each player could easily have its own market but code would have to be added to tap into that market. Also, it would be easy to add markets to each city. Just how to access these markets is the question. Does the player move a unit to the city and is instantly transported to the market screen? This would make sense as the "travel time" would be the time it takes the unit to actually move to the city. I actually tested a system like this in my privateer mod but never fully developed it but it worked fine.

On paper this system seems pretty cool as you would have access to the Bartering Markets that the Barbarian villages have, the Exotic Far Away Markets like Silk Road, and then the Markets you find in the Foreign Cities. All separate and based on local supply and demand. Pretty Sweet!
 
it would be easy to add markets to each city. Just how to access these markets is the question. Does the player move a unit to the city and is instantly transported to the market screen? This would make sense as the "travel time" would be the time it takes the unit to actually move to the city. I actually tested a system like this in my privateer mod but never fully developed it but it worked fine.
Hmm.. well in entering native cities and other civs' colonies, trade is already available through the diplo/barter interface; I'd guess you could continue to use that but have it use local price values as a starting point for the bartering (though it might also be cool to use a genuine market screen like Europe for them if that's easy to do):king: In entering your own cities the prices are already viewable in the city screen and you don't really "trade" with yourself; so I'd guess you could continue to use that and wouldn't need to "travel to" a market screen.

I like how in Civ4 you could trade resources and those resources made your citizens happy. A system somewhat based on that is what I have envisioned. That's why you can only trade Spices and Silks from Foreign markets. Spices have a bigger purpose in your production, not sure if I done anything with Silks yet or not I know I was thinking you could maybe change a Tailors production from Cloth to Silk Gowns just like the Armorsmith works.
...
On paper this system seems pretty cool as you would have access to the Bartering Markets that the Barbarian villages have, the Exotic Far Away Markets like Silk Road, and then the Markets you find in the Foreign Cities. All separate and based on local supply and demand. Pretty Sweet!
Yeah I think so too :king: would be neat if you get can get some small rewards for fulfilling certain demands, like a slight boost to Prosperity, Trade Points or Fealty.
 
Hmm.. well in entering native cities and other civs' colonies, trade is already available through the diplo/barter interface; I'd guess you could continue to use that but have it use local price values as a starting point for the bartering (though it might also be cool to use a genuine market screen like Europe for them if that's easy to do):king: In entering your own cities the prices are already viewable in the city screen and you don't really "trade" with yourself; so I'd guess you could continue to use that and wouldn't need to "travel to" a market screen.

You have a good point there. There is already a neat system set up for bartering at each city. This system could be enhanced in different ways however to add any needed functionality and then just leave the Trade Screens as they are.
 
Again great work! The markets can easily be expanded on as I listed them in the Enums.h and went from their and they already can be access in python.

Code:
enum DllExport TradeScreenTypes
{
	TRADE_SCREEN_DEFAULT = -1,

	TRADE_SCREEN_MOTHERLAND,
	TRADE_SCREEN_TRADE_FAIR,
	TRADE_SCREEN_SPICE_ROUTE,
	TRADE_SCREEN_SILK_ROAD,
	TRADE_SCREEN_EUROPE,

#ifdef _USRDLL
	NUM_TRADE_SCREEN_TYPES
#endif

};
If it works based on NUM_TRADE_SCREEN_TYPES like a normal generic solution would do, then it would provide 5 markets, not 3 :(
Setting it to work from TRADE_SCREEN_TRADE_FAIR to TRADE_SCREEN_SILK_ROAD isn't really generic at all and modders can easily break it. Not sure what the ideal solution would be here.
 
Code:
enum DllExport TradeScreenTypes
{
	TRADE_SCREEN_DEFAULT = -1,

	TRADE_SCREEN_MOTHERLAND,
	TRADE_SCREEN_TRADE_FAIR,
	TRADE_SCREEN_SPICE_ROUTE,
	TRADE_SCREEN_SILK_ROAD,
	TRADE_SCREEN_EUROPE,

#ifdef _USRDLL
	NUM_TRADE_SCREEN_TYPES
#endif

};
If it works based on NUM_TRADE_SCREEN_TYPES like a normal generic solution would do, then it would provide 5 markets, not 3 :(
Setting it to work from TRADE_SCREEN_TRADE_FAIR to TRADE_SCREEN_SILK_ROAD isn't really generic at all and modders can easily break it. Not sure what the ideal solution would be here.

In python you can always check to see if the active player has any attribute. So, just like I do to reveal the Trade Screen buttons as a player discovers them you can use that to determine which of the trade screen types or markets are viable at that time. In the LeaderHeadInfos I have added several new attributes like EconomyType and such. At the moment I am just using numbers for those types. Anyway, what I am getting at is we can add the Trade Screens to the LeaderHeadInfos or the CivilizationInfos so each leader can be assigned Trade Screens that they can access. That way you can make a check in python to see if the leader can even use the trade screen and then check to see if it has been unlocked.

Like you pointed out there are five possible trade screens. However, to add a new trade screen is not as simple as adding another Enum to the list. You have to get into the DLL and add in all the rules to how the trade screen functions, the way you access it, its travel time, how you return, and I also tied a new UnitTravelStateType to the trade screen.

I actually added in three different Enums for the TradeScreens, which could be reduced to just two or maybe just the UnitTravelStateType(EDIT: lots of time when I code I don't always work out my solution before I start codding and then when I am done I think, "wow, it would have been easier to just do this". So sometimes I have more code than needed). Anyway, you can look into the :canCrossOcean() function and see the details or rules for each trade screen type. What would be awesome is to add new XML file for TradeScreenInfos and have all the possible rules defined in that XML and then the :canCrossOcean() checks those rules instead of it being hardcoded. That way it would be more modder friendly:goodjob:

Edit: Also, to get all the info of each different market on the screen I may have to explain to you just how I set the system up. I know its a pain digging through the vanilla code trying to figure out what they was thinking or how the function works.
 
(EDIT: lots of time when I code I don't always work out my solution before I start codding and then when I am done I think, "wow, it would have been easier to just do this". So sometimes I have more code than needed).
That's a fairly common approach and it works ok with modding existing code. It really sucks if you make something from scratch. Also it's an approach where you really need source version control and can accept discarding your own changes because they were... well not up to code.
It's good to know you work like that. That makes it easier for me if I spot something where I think the coder went :cheers::crazyeye:. I haven't spotted such code yet apart from calling the same getDefineINT multiple times at the same location, but the cache killed that speed issue.

In python you can always check to see if the active player has any attribute. So, just like I do to reveal the Trade Screen buttons as a player discovers them you can use that to determine which of the trade screen types or markets are viable at that time. In the LeaderHeadInfos I have added several new attributes like EconomyType and such. At the moment I am just using numbers for those types. Anyway, what I am getting at is we can add the Trade Screens to the LeaderHeadInfos or the CivilizationInfos so each leader can be assigned Trade Screens that they can access. That way you can make a check in python to see if the leader can even use the trade screen and then check to see if it has been unlocked.
I need to figure out some more about python, or rather the Civ4col python engine. Python itself appears to be easy even though I had never seen it before I started modding... way back in May :). It's a mix between C++, perl and bash (3 languages I knew already).

I actually added in three different Enums for the TradeScreens, which could be reduced to just two or maybe just the UnitTravelStateType Anyway, you can look into the :canCrossOcean() function and see the details or rules for each trade screen type. What would be awesome is to add new XML file for TradeScreenInfos and have all the possible rules defined in that XML and then the :canCrossOcean() checks those rules instead of it being hardcoded. That way it would be more modder friendly:goodjob:
I think it should be moved to XML (for several reasons) and then we consider adding them to domestic advisor and stuff afterwards. Presumably something will change and it would mean double python work.

Edit: Also, to get all the info of each different market on the screen I may have to explain to you just how I set the system up. I know its a pain digging through the vanilla code trying to figure out what they was thinking or how the function works.
Generally speaking the vanilla code is close to not documented at all and several mods aren't either. Figuring out the thoughts behind the code can be really tricky.

New work and plans
I moved the cached CvPlayer::getYieldEquipmentAmount() from RaRE into M:C. The cache itself merged just fine with diff+patch, but the loop avoidance code turned out to be a bit more tricky. The idea is that it will know if all yields are 0 by checking a pointer for being NULL and if all are 0, then looping though them could be pointless. However somebody had to heavily modify a number of the loops, meaning I had to dig into them and figure out precisely what would happen if the value is 0. Luckily all of them can still be avoided in that case :)
I was scared that inventions would cause problems, but it turned out that they didn't cause any issues at all as they are implemented in a cache friendly way. I didn't change any code at all to fit with inventions.

I didn't do any speed tests, but this cache did reduce AI turn time from 40 to 33 seconds in RaRE meaning M:C is very likely highly affected as well. A similar speed improvement isn't unlikely.

Next up is the cache for CvCity::getMaxYieldCapacity(). Presumably this one will have a constant output as long as no buildings are added/removed. No need to loop through all buildings each time the number is needed. I wonder if it should reset the cache when gaining an invention. That might come in handy in the future, specially since it includes a function, which is called every time a building is added/removed. This gives a perfect place for adding more building related caches.

This is the last speedboost from RaRE, which mean it's the last speed improvement I have planned for M:C for now. However once I'm done I plan on profiling again and I may spot something. Once the slowest part is gone, something else becomes the slowest part.

Also I managed to move transport feeder from RaRE. That leaves the teacher list, though that one relies on TAC school system, which would then have to be implemented first. Since I have no EDU mod diff I can't merge it in as quickly as the stuff from RaRE and it may take a while to implement this.

Also the I spotted room for improvements in the domestic advisor. Presumably I will tweak it in the near future.
 
Next up is the cache for CvCity::getMaxYieldCapacity()
Done :hatsoff:

ok I could try my hand at crafting a few button images.. tho I warn I'm not the world's most amazing artist, and am also not above trying 2 adapt anything I can find on google images! :mischief:;) well just let me know what you'd have in mind for them and I can try to crank a few out :borg:
It's very likely that I will get back to you once I know for sure which icons are needed. At the moment they could change and it seems pointless to draw something only to discard it before it's ever used.
 
Ok sounds good. I just realized for a market/price button it would work perfect to reuse this one from vanilla, since it doesn't appear in the Advisor:
/Art/interface/Game Hud/Actions/trade_goods_high_res.dds
 
Ok sounds good. I just realized for a market/price button it would work perfect to reuse this one from vanilla, since it doesn't appear in the Advisor:
/Art/interface/Game Hud/Actions/trade_goods_high_res.dds
I will test this when I get the change. The idea is good.

I decided not to use the RaR button icon for natives because it somewhat would be misplaced to use a picture of a Sioux chief smoking a pipe :)
I don't know what would be fitting for natives in M:C though. Also should they even be called natives? After all both big and small players are "native Europeans". It's more like a major vs minor countries.


I simplified the domestic advisor further. Now adding a button is done by

self.NAME_STATE = self.addButton("button icon", "help text string")

No need to set help elsewhere. Also the name string was a relic of the previous design and is no longer needed. It just needs a unique string, which is now generated automatically.

I did some profiling again and I found absolutely no candidates for speed improvements. No single function stands out anymore and the DLL itself doesn't seem to be a major player in the overall profiling list. However my testing was cut a bit short because I was interrupted. Still almost 6 minutes of real gaming should reveal if something is really wrong and it didn't :)
In other news due to interruptions I only managed to play for 6 minutes today :(

The game itself appears to be much faster. Waiting for the AI feels shorter (I plan on timing it) and the interface feels more responsive. It kind of makes sense that the interface is faster (even though it wasn't a goal when I tested for slow code) because it accesses values from XML much faster. This is done all the time including in user interaction. Also say we have a free colonist, which is dragged to a piece of land in a city. Now it needs to generate the list of available professions. It used to go:
For each yield:
is (city stock + free colonist equipment) >= new profession equipment
Equipment was calculated for each and it went like that for all professions.
Now it goes "is farmer pointer NULL? Yes farmers don't use yields. It's valid without checking more. Next"
Unsurprisingly this appears to affect interface responsiveness when moving colonists around in the city. It still checks all yields if the new profession uses yields, but it reads them from an array instead of recalculating them each time and the vast majority of professions don't use yields, specially not those inside cities.
 
Plan sounds good, Nightinggale. One thing about the CvCity::getMaxYieldCapacity(). I think I may have modded it or I modded something cause some of the buildings actually increase max yield capacity for certain goods. Like the Armory increases storage for weapons and armor. I don't even know if its relevant or not but there it is:)
 
Plan sounds good, Nightinggale. One thing about the CvCity::getMaxYieldCapacity(). I think I may have modded it or I modded something cause some of the buildings actually increase max yield capacity for certain goods. Like the Armory increases storage for weapons and armor. I don't even know if its relevant or not but there it is:)
I spotted modifications and it should be taking those into consideration. However I don't think those changes even matter for how the cache works. Basically it has an array and looks up the array to get the capacity for each yield. The array is filled with data by calling the function it is meant to replace meaning it's the very same code, which is used to get the actual value. All it has to do is to recalculate the entire array each time one or more of the values might have changed and I set this trigger event to add/remove buildings. I plan on adding "gain invention" as a trigger as well, but it doesn't look like it matters with the current code. Still it would be nice to have as it mean it would just work even if new inventions ends up affecting it.
 
Unsurprisingly this appears to affect interface responsiveness when moving colonists around in the city. It still checks all yields if the new profession uses yields, but it reads them from an array instead of recalculating them each time and the vast majority of professions don't use yields, specially not those inside cities.

I had noticed that moving colonists around often would cause the whole screen to "flash" for a second like a slow down. I wondered what was causing this, so yay:goodjob:, to this being improved! Anyway, when it comes to making buttons I am no artist either. I just copy and paste images off the net mostly. I have a "blank" sample of neither every button type if anyone could use it. Its just a button with no art on it so you can paste art into it.

Cancelled.

You're hilarious mastrude, glad you showed up:)
 
Back
Top Bottom