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

Trade Route Screens, Tutorials, Questions, etc.

Discussion in 'Civ4Col - Medieval: Conquests' started by Kailric, Jan 4, 2014.

  1. Kailric

    Kailric Jack of All Trades

    Joined:
    Mar 25, 2008
    Messages:
    3,095
    Location:
    Marooned, Y'isrumgone
    Nice! So, your saying I can add CivicInfos to EuropeInfos and I want have any loading errors? That will come in lots of handy. I'll test this out soon as I can.

    Now, this sounds exciting:) What was I doing? :crazyeye:
     
  2. Nightinggale

    Nightinggale Deity

    Joined:
    Feb 2, 2009
    Messages:
    4,354
    You should be able to add CivicInfos to EuropeInfos and EuropeInfos to CivicInfos at the same time without adding special code to handle circles like that. This will surely come in handy once I do something about journeyman again. Unit, UnitClass and Professions could all end up relying on the two others.

    I have no idea either. However git provides a list of changed lines in the code and with a whole lot of luck I might be able to figure out what you have done and in rare cases make sense of it :lol:
     
  3. Kailric

    Kailric Jack of All Trades

    Joined:
    Mar 25, 2008
    Messages:
    3,095
    Location:
    Marooned, Y'isrumgone
    I just pushed my newest changes to git. I think one issue I am having is I forget to close 2010 Express before I pull and that causes issues. Anyway, I made the push finally and I could use your help with a matter(Nightinggale:)).

    Ok, I have managed to get an Auto Sail to Trade Screen button working. It works just as before. If you are not on a TradeScreen Plot it will auto send your unit to the nearest accessible plot.

    In the Vanilla code they added an attribute to plots called m_iDistanceToOcean. This lets a unit know how far the Europe plot is and if it can access it. This is used for the Automatic sail to europe command. Now, I made my own array version of this for each new trade screen and named it "m_aiTradeScreenDistance". That part of the code works ok, but I am having trouble figuring out how to read and write the data for saved games. I have tried a few ways but nothing works. CvPlots has a strange read and write feature that I can not figure out. At the moment I have simply commented out aiTradeScreenDistance from the read and write. Needless to say, when you load a saved game all the aiTradeScreenDistance digits revert to MAX_SHORT.

    Anyway, if you can figure out how to read and write that array for me that would be great. Also, I am still working out how void CvGame::updateOceanDistances() sets up the distances. I have added code for it to update my aiTradeScreenDistance array. It is really tricky code for me but I have got it to work somewhat. Most of the plots get set correctly but some of them get stuck with the MAX_SHORT default when they should have a correct int instead. I can probably work that out eventually but if you glanced over it I wouldn't mind.

    I have added new help text to the CvGameTextMgr to help with this code. If you press Ctrl Z it will reveal all plots (you may have known this), then if you mouse over a plot and hold shift it will tell you the distances to the nearest route that has a EuropeType assigned to it.

    I did manage to add in my m_iTradeScreenAccess and use it as an bitmap for my new function isTradeScreenAccessPlot just like we talked about. All that seems to be working great! Thanks for your help with that:goodjob:
     
  4. Nightinggale

    Nightinggale Deity

    Joined:
    Feb 2, 2009
    Messages:
    4,354
    I have done that a few times and each time it asked me to reload. I just said yes to all and so far it has worked each time.

    You save before m_apaiCultureRangeCities and load before m_aiCulture. Naturally this will never work. However fixing this issue didn't help at all :confused:

    I have decided to change the array into a just-in-time array because then it will be able to just use the load/save code written into those (which works everywhere else). This mean the default value shouldn't be 0, but MAX_SHORT. I already planned on making a non-default constructor, which allows setting the default value. I just as well code that now as we need it now.

    When I looked at it, it looked like it sets access points to 0. When setting a value to X it set plots next to it to X+1 if that is lower than current value. This is done recursively and eventually it will fill out everything. It's actually not very different from PlotGroup spread, except it increases the counter instead of sharing the value (PlotGroup ID) between plots.

    You screwed up something (or vanilla did) as it is supposed to spread across DOMAIN_SEA, but it happily spreads across DOMAIN_LAND as well. This can give access from lakes to ocean even though we know there is no path for a ship to move there.

    I will look into this. In fact I will try to make a new design where the distance isn't static. We can update if we build a city on the coast as the city can then work as a canal, which in turn provides access to a lake. Likewise the lake should lose its distance count if the city goes away. The only flaw here is that you risk getting a distance, but you not allowed to pass by city owner. However this problem exists in vanilla too.

    Now I see what I should have done with plotgroups :lol:


    One thing I noticed is that old savegames are broken. Either we do a great deal in fixing it or we say "screw old savegames". If we do the latter, then I think we should clean up the load code. There is a lot of special code to handle old savegames, which turns into a messy and hard to read code.
     
  5. Kailric

    Kailric Jack of All Trades

    Joined:
    Mar 25, 2008
    Messages:
    3,095
    Location:
    Marooned, Y'isrumgone
    I wouldn't call this a "screw up" as the AI needs land values assigned a distance as well. This is separate from path finding and may have nothing to do with it. The AI uses the distance to determine a plots value for founding a settlement among other things. I didn't change the default code at all just added my own code for the Trade Screen distances. If we get the AI to use the trade screens they'll need these distances as well.

    This would be very handy to have. This could set up a Canal Improvement as well. Improvements already have an "actasCity" tag that probably allows a ship to pass through it.
    Edit: In fact I recall this being an issue of Ships traveling across country. I may have put a stop to it, but we can just ad a bactAsCanal tag if need be.

    Yeah, I've added lots of code to the message manager for helping me in debugging. It is very handy. Like, you can see what TradeScreen a unit has assigned to it by holding Alt I believe. I need to keep an I on this for debugging any potential issues in the Automate code. I use the UnitTradeMarket functions to get and set what Europe a unit is traveling to. Since the Automate commands don't have any way to pass an argument that I seen, I use these functions to tell the code what route the unit is on. Python also uses these functions to determine what units to display in the Trade Screens. Anyway, that's just another thing you can now track.


    We should just "screw old savegames" at the moment. I just don't have the time to deal with this, plus the few testers we have(that come and go) just need to know that saved games will probably get messed up. With this new Trade Screen code I am adding it would really be a pain to fix up saved games at the moment. So, let's not worry about that until we get through all of it. I still need several new tags added in as well as fixing up the Techs to unlock the trade screens as of now they are all available at the start for testing.

    So, if you are working to fix my save game issue and the set distance to ocean I can work on those new tags I mentioned to get the Trade Screen code fully moddable.
     
  6. Nightinggale

    Nightinggale Deity

    Joined:
    Feb 2, 2009
    Messages:
    4,354
    I fixed saving. I still wonder why the normal array didn't save correctly, but at least the just-in-time array works as intended.

    I recommend that you take a look at the changes to see how just-in-time arrays work. They do more or less what you wrote, except it's a class where well tested member functions do the tasks for you.

    https://github.com/Nightinggale/Medieval_Tech/commit/025dd2df6711f09999a94ff21538b7cc0fa97ea8

    EDIT: forgot to mention that I changed distance from int to short. We know that it will always contain a number between 0 and MAX_SHORT. Allocating memory to store even bigger numbers than that is a waste.

    I realized one more bonus from this. Order inside each file no longer matters either. Item 2 can link to item 5 and it can figure it out anyway. It used to be unable to link to anything below itself in the same file.
     
  7. Kailric

    Kailric Jack of All Trades

    Joined:
    Mar 25, 2008
    Messages:
    3,095
    Location:
    Marooned, Y'isrumgone
    Thanks bunch. I took a look see and it seems simple enough. I am thinking we need an array for each player that keeps track of travel times to each Trade Screen separately. Right now techs can only reduce travel times for all trade routes all at once but not individually. This way we can have Events such as discovering a faster route to reach the Spice Route markets and then save the info to the player. Anyway, I am not sure of the advantages of a just-n-time arrays but I can attempt one for this purpose.

    This is a good deal also. I think some xml used a "second pass" feature that allowed for this but not all of them where set up that way.

    I work up this morning with an epiphany. Remember when I said that adding a new trade screen still meant we had to edit the dll to add in a new Control type. Well, I haven't tested it yet but I think I see an easy way to do this. The code can already pop up a trade screen when your unit arrives, so all I need to do is add in a new Widget type; call it, WIDGET_TRADE_SCREEN. Then in the python MainScreen attach this widget to the TradeScreen button instead of a Control type. Then all I need to do is pass the EuropeType Info over to the Widget and the Widget will pop up the correct trade screen. It all works in my head, now just need to see if it works in reality. Still not sure about hotkeys but at this point it's not critical.

    Actually, I should call it WIDGET_POP_UP_SCREEN, because this could be used to pop up any screen.
     
  8. Nightinggale

    Nightinggale Deity

    Joined:
    Feb 2, 2009
    Messages:
    4,354
    Set it in CvPlayer::updateInventionEffectCache(). It is called on game start, load and whenever a civic is added or removed. This allows civics, which modifies travel time by -1 (or whatever you set the int to) and you can then collect multiple of those in any order.

    Don't store travel time as ints btw. A char would do. No sane mod would have a travel time higher than 127 turns. In fact if we really want to push memory usage down, then we can lower the limit to 4 bits (15 turns). This would allow 8 travel times to be stored in a single int, allowing the cache to be put inside the player class (no pointer), which would make the code run faster. However I would be surprised if this part turns out to be a bottleneck, which mean this likely isn't worth the time experimenting with something like this. Sounds like something fun to do though :)

    They are normal arrays, but with a set of member functions to handle most tasks. Compared to regular arrays they do:
    • set length automatically
    • allocate automatically when a non-default value is written
    • assumes the whole array to be the default value when not allocated
    • can figure out freeing itself if it detects it's full of default values
    • functions for read/write the arrays, making read/write code a single line
    • uses constructor/deconstructor to set NULL pointer and free meaning it will not leak memory (vectors of just-in-time arrays doesn't call deconstructor!)
    • check if pointer is allocated (all values set to default) without even spending time on looping (feature alone reduced next turn calculation time by 5% in RaRE)
    • well tested code
    Say we want to know the combined yields in all transports in a plot.
    Code:
    YieldArray<int> aeArray;
    (loop units)
    {  (loop yields in unit)
    {     aeArray.add(eYield, iAmount);
    }}
    
    // do something with the result using aeArray.get(eYield)
    I didn't skip any code for the array here. This will work because YieldArray tells the length, default is 0 (we didn't ask for anything else), it's allocated when written to if iAmount != 0 and it is freed once you return from this function. It is hard to leak memory with this level of automation ;)

    Also the "do something with result" might be set in "if (aeArray.isAllocated())" if it can be skipped if the array only contain 0s. No need to waste time looping to detect that.

    There is a bunch of neat extra features in the header, like ::length() meaning you don't even have to consider how to get that when looping. It's also full of asserts to detect wrong usage.

    virtual bool CvInfoBase::readPass3(). 3 files used that one, but not anymore. The new read system broke when attempting to do this. Besides there is no longer a need for it.

    Just think of the argument. What if the argument is 1. Is it EuropeScreen 1 or screen 1 for some other stuff? Maybe the easiest is to make a dedicated one to prevent clashes. Alternatively non-trade screens could get 32 added to the argument. That way any argument higher than 32 is known not to be a trade screen (remember we hardcoded max 32 elsewhere).
     
  9. Kailric

    Kailric Jack of All Trades

    Joined:
    Mar 25, 2008
    Messages:
    3,095
    Location:
    Marooned, Y'isrumgone
    Right, I thought of this contingency. You can pass at least two arguments to the widget. Right now we only need 1 argument for the Trade Screens but say there is every a need for other screens we can send two arguments and the second tells the code what screen type it is.

    Edit: I just tested this out for the trade screens and it worked great! One more step in making the Trade Screens modder friendly :) The coolest part it only took 10 min, I love it when the vanilla code is that useful!

    Thanks for all the info. I actually didn't realize what "char" did. I always just used "int" so yeah there may be places in the code where we can free up memory. I also seen your post about the Dll coding thread, thanks for the info there too. I'll reply to it when or if I ever have something useful to add;) :crazyeye::goodjob:
     
  10. Kailric

    Kailric Jack of All Trades

    Joined:
    Mar 25, 2008
    Messages:
    3,095
    Location:
    Marooned, Y'isrumgone
  11. Trade Winds

    Trade Winds Warlord

    Joined:
    Nov 21, 2013
    Messages:
    235
    I&#8217;ve downloaded the latest git for testing, but it freezes on my computer at the end of the first turn. (It may it be the debbuger, but I see no messages.)
     
  12. Kailric

    Kailric Jack of All Trades

    Joined:
    Mar 25, 2008
    Messages:
    3,095
    Location:
    Marooned, Y'isrumgone
    Fixed and pushed changes, there was some kind of infinite loop at the CvPlayer.cpp
    Code:
    void CvPlayer::verifyCivics()
    {
    	for (int iI = 0; iI < GC.getNumCivicOptionInfos(); iI++)
    	{
    	    ///TK Update 1.1b
    	    if (iI == CIVICOPTION_INVENTIONS)
    	    {
    	        continue;
    	    }
    	    ///TKe
    It was iI = CIVICOPTION_INVENTIONS instead of the ==:crazyeye:
     
  13. Trade Winds

    Trade Winds Warlord

    Joined:
    Nov 21, 2013
    Messages:
    235
    Hunting for more bugs!!
     
  14. Kailric

    Kailric Jack of All Trades

    Joined:
    Mar 25, 2008
    Messages:
    3,095
    Location:
    Marooned, Y'isrumgone
    You will probably find several. I found one, the Trade Screen does not appear. This may not effect the game, but still needs to be fixed.

    I also fixed the FaireWeather map hopefully.

    Ok, I fixed the Tech Screen and the Trade Tech Screen and pushed the changes. This should not effect saved games.
    I'll fix it so these errors not happen again soon as I have the chance, have to leave quickly at the moment....
     
  15. Lib.Spi't

    Lib.Spi't Overlord of the Wasteland

    Joined:
    Feb 12, 2009
    Messages:
    3,707
    Location:
    UK
    Hey kail, I am working through your tutorial, but I have gotten stuck at step 4.

    I am in CvMainInterface.py, but I cannot find any of the lines under

    'def SetGlobals ( self, screen ):'

    have i downloaded the wrong file or something, were these lines in the last 'public' release of medi, or was it something completely new added only to the git version, if it is the latter then I may have copied something in the wrong order or some such... But I am just a bit confused so I thought I would post up before I investigate incase you or someone else comes up with the solution before me :D

    EDIT:
    Nevermind, it does look like I copied something in the wrong order ai I checked the master file and it is different...ugh idiot! this could cause me some problems if I screwed this up with several files I may have to go back to the beginning and start again..

    NEXT EDIT:

    Ok this time I am stuck on this step:

    "Next add the code below to def updateTravelRoutes:"

    Can't find it, and this time my files are definately merged properly :D

    is it supposed to be in CvMainInterface.py?

    I await your magic poop!
     
  16. Kailric

    Kailric Jack of All Trades

    Joined:
    Mar 25, 2008
    Messages:
    3,095
    Location:
    Marooned, Y'isrumgone
    Yes, it's in CvMainInterface. The question is are you attempting at add a Trade Route screen to another mod or to M:C? There is code in CvMainInterface and all the Trade Screen files that will only work with the M:C dll. The updateTravelRoutes is in CvMainInterface:

    Code:
    def updateTravelRoutes( self ):
    
    		screen = CyGInterfaceScreen( "MainInterface", CvScreenEnums.MAIN_INTERFACE )
    		ePlayer = gc.getGame().getActivePlayer()
    
    		if ( ePlayer < 0 or ePlayer >= gc.getMAX_PLAYERS() ):
    			return 0
    
    		if (gc.getPlayer(ePlayer).isAlive()):
    			pPlayer = gc.getPlayer(ePlayer)
    			#for screen in range(gc.getNumEuropeInfos()):
    			#activeTeam = gc.getTeam(player.getTeam())
    			if (pPlayer.getHasTradeRouteType(TRADE_SCREEN_SPICE_ROUTE_MARKET)):	
    				screen.show("SpiceRouteScreenButton")
    				
    			else:
    				screen.hide("SpiceRouteScreenButton")
    				
    			if (pPlayer.getHasTradeRouteType(TRADE_SCREEN_SILK_ROAD_MARKET)):	
    				screen.show("SilkRoadScreenButton")
    				
    			else:
    				screen.hide("SilkRoadScreenButton")
    			
    			if (pPlayer.getHasTradeRouteType(TRADE_SCREEN_TRADE_FAIR_MARKET)):	
    				screen.show("TradeFairScreenButton")
    				
    			else:
    				screen.hide("TradeFairScreenButton")
    					
    		return 0
     
  17. Lib.Spi't

    Lib.Spi't Overlord of the Wasteland

    Joined:
    Feb 12, 2009
    Messages:
    3,707
    Location:
    UK
    yeah it is MC I got the master from git, then had to merge it with alkl the art etc. from the public download.

    I have now checked the CvMainInterface against the one form the the git, and it says it is identical, but when i search for 'def updateTravelRoutes:' it says it doesn't exist..

    So I find myself confounded..

    I took the master branch from git is that the wrong one? because both my version and the version from the master branch have no 'def updateTravelRoutes:'

    it has the SetGlobals part but not the updateTravel....
     
  18. Kailric

    Kailric Jack of All Trades

    Joined:
    Mar 25, 2008
    Messages:
    3,095
    Location:
    Marooned, Y'isrumgone
    The master branch should be the correct one. So, you have opened up CvMainInterface from the M:C mod and there is no updateTravelRoutes? Maybe something isn't set right in your search options. You may have checked something like "match case" or something. I do that sometimes. Open up CvMainInterface from the M:C mod then go to line 2579, updateTravelRoutes is there. If it is not then something is messed up for sure:)
     
  19. Lib.Spi't

    Lib.Spi't Overlord of the Wasteland

    Joined:
    Feb 12, 2009
    Messages:
    3,707
    Location:
    UK
    nice one!

    I searched for updateTravelRoutes: and that is what messed me up :D

    it might be worth writing it like this

    def updateTravelRoutes( self ):

    in the tutorial for what to search for, that way if there are other idiots like me who copy a colon that isn't meant to be copied, it won't mess up the search :D hehe

    Right! Hammer Time!
     
  20. Lib.Spi't

    Lib.Spi't Overlord of the Wasteland

    Joined:
    Feb 12, 2009
    Messages:
    3,707
    Location:
    UK
    Ok so it looks like I have messed something up somewhere...

    I followed the tutorial, but when I loaaded the game I had no interface! :D

    So I have probably screwed up something in the python, ah wait, maybe python exceptions are not on for Col. let's go check that....
     

Share This Page