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

MapScriptTools (.. and Associated Maps)

Discussion in 'Civ4 - Map Scripts' started by Temudjin, Jul 15, 2010.

  1. Maniac

    Maniac Apolyton Sage

    Joined:
    Nov 27, 2004
    Messages:
    5,588
    Location:
    Gent, Belgium
    In Planetfall's CvMapGeneratorUtil, Tundra gets changed to 33% Flat Polar, 33% Flat Moist, 16% Rocky Moist and 16% Rocky Polar.

    Thanks! :D

    I certainly agree that not all mapscripts should follow the Planetfall highland generation, though I do think it would be nice to have it as an option in SmartMap for instance. I'll have another look if I can figure out the highlands code myself.

    The sea unity pods aren't units, but IMPROVEMENT_UNITY_POD_SEA. And I was mistaken about the name :mischief: - it's called New Sargasso.

    What is the Big Dent?

    If you'd like more landmark names, rather than given an exhaustive list of all landmark names in SMAC, it might be easier for both of us if you downloaded the SMAC demo, a mere 20 MB. Then place and extract the attached saves in "Sid Meier's Alpha Centauri's Demo" to have a look at the Map of Planet.

    Perhaps the Isle of Dexamenus/Mnemi*ache (spelling probably incorrect) can be used here.

    That also returns false in vanilla. This is the function:

    Code:
    bool CvPlayer::startingPlotWithinRange(CvPlot* pPlot, PlayerTypes ePlayer, int iRange, int iPass) const
    {
    	PROFILE_FUNC();
    
    	//XXX changes to AI_foundValue (which are far more flexible) make this function
    	//    redundant but it is still called from Python.
    	return false;
    }
    I haven't looked deeper into this issue myself, but perhaps the key might be figuring out the difference between the MST mapscripts and Planetfall's original mapscript, where starting positions do work fine.
     

    Attached Files:

  2. Maniac

    Maniac Apolyton Sage

    Joined:
    Nov 27, 2004
    Messages:
    5,588
    Location:
    Gent, Belgium
    I'm not sure if your problem was the same as mine, but in the past I stared myself blind on the PFHL_MultilayeredFractal() class, assuming the code responsible for highland creation was somewhere in there. Now I've looked at it again however, I see that class is only responsible for the distinction between land and water, and that hills and peaks are added afterwards:

    Code:
    def generatePlotTypes():
    	NiTextOut("Setting Plot Types (Python PlanetFall Highlands) ...")
    	
    	gc = CyGlobalContext()
    	map = CyMap()
    	dice = gc.getGame().getMapRand()
    	iW = map.getGridWidth()
    	iH = map.getGridHeight()
    	plotTypes = [PlotTypes.PLOT_OCEAN] * (iW*iH)
    	terrainFrac = CyFractal()
    	
    	fractal_world = PFHL_MultilayeredFractal()
    	plotTypes = fractal_world.generatePlotsByRegion()
    	terrainFrac.fracInit(iW, iH, h_grain, dice, 0, -1, -1)
    	
    	iHighlandThreshold = terrainFrac.getHeightFromPercent(h_highlands)
    	iPeaksThreshold = iHighlandThreshold - (iHighlandThreshold * h_peaks) 
    
    	# Now the main loop, which will assign the plot types.
    	for x in range(iW):
    		for y in range(iH):
    			i = y*iW + x
    			val = terrainFrac.getHeight(x,y)
    			if plotTypes[i] == PlotTypes.PLOT_OCEAN:
    				continue # Water plots already set.
    			if val >= iHighlandThreshold:
    				plotTypes[i] = PlotTypes.PLOT_HILLS
    			elif val >= iPeaksThreshold and val < iHighlandThreshold:
    				plotTypes[i] = PlotTypes.PLOT_PEAK
    			else:
    				pass
    
    	return plotTypes
    I believe the only possible difficulty with getting this code to work for other mapscripts is making sure all land plots are PLOT_LAND (ie, flatland) in the plotTypes array before the "main loop" is run.
     
  3. Maniac

    Maniac Apolyton Sage

    Joined:
    Nov 27, 2004
    Messages:
    5,588
    Location:
    Gent, Belgium
    As an exercise to see if I understand Planetfall's highland generation, I'd like to make the Pangaea usable for Planetfall.

    I barely understand Pangaea (I don't understand any mapscript well for that matter), but I think in that mapscript generateTerrainTypes() is the place to add hills and peaks. First stumbling block: to get Planetfall's highland code to work, I need an array of what plottypes the plots are at that point. How can I get that inside generateTerrainTypes()??

    Edit: Never mind. In SmartMap, the hills and peak are generated in generatePlotTypes.
     
  4. Temudjin

    Temudjin Chieftain

    Joined:
    Oct 16, 2007
    Messages:
    90
    Yes, I've got that wrong. I'll change that in planetFallMap.mapPfallTerrain().

    Sorry no option (yet), but I've upgraded the highland code in planetFallMap.buildPfallHighlands(), which now produces more additional hills/peaks in more clustered ranges. The Land/Hills and Land/Peaks percentages should now be comparable to your own Planetfall map.

    Thanks - I'll look into it. Also at the Demo.
    Do you mind if I give your great dunes a name? I thought 'The Great Dunes", but only once and only if there are at least three tiles of them together.

    A mountain range. In Earth3.py I use a single BigDent special region to simulate the Himalayas.

    Though not in Vanilla or Warlords, but it does indeed in BtS. This is strange as that potentially breaks the findStartingPlot() function in CvMapGeneratorUtil.py, since the minimum distance to other starting-plots is not tested anymore. Several map-scripts call that function. It may be an issue for the unofficial patch.

    :goodjob:Finally I've run the 'Scattered Pods' problem to the ground. It seems that in assignStartingPlots() or findStartingPlot() the following code:

    Code:
    def assignStartingPlots():
    	if mst.bPfall:
    		CyPythonMgr().allowDefaultImpl()
    	else:
    		... other code
    
    def nextFunction():
    
    
    has not the same results as:
    Code:
    def assignStartingPlots():
    	if mst.bPfall:
    		CyPythonMgr().allowDefaultImpl()
    		return
    	... other code
    
    def nextFunction():
    
    
    sadly only the first version will take the 'Scattered Landing Pods' option into account and I'll have to adjust for that.

    You're probably right. And it's indeed the fractals that look odd to me.
    My point was however that some scripts take more care building their landscape and their terrain than others, and I'd like to preserve that. On the other hand I already mostly use the Planetfall terrain-generator regardless and generally adjust things a lot. On the gripping hand, I'll probably try and put an option into Tectonics and look if/how it works.
     
  5. Temudjin

    Temudjin Chieftain

    Joined:
    Oct 16, 2007
    Messages:
    90
    That was actually easier than I thought, although I used the brute force approach here.

    I've just copied PFHL_MultilayeredFractal(), generatePlotTypes() {renaming the function, adding the plotTypes parameter/result and commenting out only two lines }, and a few global constants from planetfall.py.
    Then I inserted a call before the end of the original generatePlotTypes() before the plotTypes where returned thus changing aforementioned plotTypes.

    So at least Tectonics_mst.py will have a new option, whether to use the original Planetfall Highlands generator or the plot adjustment approach with planetFallMap.buildPfallHighlands().
     
  6. Afforess

    Afforess The White Wizard

    Joined:
    Jul 31, 2007
    Messages:
    12,239
    Location:
    Austin, Texas
    Temudjin, I like how your mapscript tools enable the Erebus Mapscript for normal BTS games. I was wondering, what would it take to convert the ErebusContinents mapscript? I'm not exactly familiar with how mapscripts work; what is the conversion process?
     
  7. Maniac

    Maniac Apolyton Sage

    Joined:
    Nov 27, 2004
    Messages:
    5,588
    Location:
    Gent, Belgium
    Do you mean to give it a sign on the map? This is just a personal preference and probably a minority view, but I'm not really fond of signs on the map, as they obstruct my view of the plot just north of the plot with the sign. People can already see it's the Great Dunes by hovering their mouse over the feature.

    By the way, I'm wondering if you can think of a better (and still fast) way to determine a good location for the Great Dunes. Currently I have this in the SDK:

    Code:
    int iDunes = 0;
    	int* piShuffle6 = shuffle(GC.getMapINLINE().numPlotsINLINE(), GC.getGameINLINE().getMapRand());
    	for (int iI = 0; iI < GC.getMapINLINE().numPlotsINLINE(); iI++)
    	{
    		pPlot = GC.getMapINLINE().plotByIndexINLINE(piShuffle6[iI]);
    		iDunes = 0;
    		if (pPlot->canHaveFeature((FeatureTypes)GC.getInfoTypeForString(GC.getDefineSTRING("FEATURE_DUNES"))))
    		{
    			for (int iJ = 0; iJ < NUM_DIRECTION_TYPES; iJ++)
    			{
    				pAdjacentPlot = plotDirection(pPlot->getX_INLINE(), pPlot->getY_INLINE(), ((DirectionTypes)iJ));
    				if (pAdjacentPlot != NULL)
    				{
    					if (pAdjacentPlot->canHaveFeature((FeatureTypes)GC.getInfoTypeForString(GC.getDefineSTRING("FEATURE_DUNES"))))
    					{
    						if (iDunes == 0)
    						{
    							pPlot->setFeatureType((FeatureTypes)GC.getInfoTypeForString(GC.getDefineSTRING("FEATURE_DUNES")));
    						}
    						pAdjacentPlot->setFeatureType((FeatureTypes)GC.getInfoTypeForString(GC.getDefineSTRING("FEATURE_DUNES")));
    						iDunes++;
    					}
    				}
    			}
    		}
    		if (iDunes > 0)
    		{
    			break;
    		}
    	}
    	SAFE_DELETE_ARRAY(piShuffle6);
    This often results in 'Great Dunes" of only three plots. I'd prefer for the Great Dunes to exist in the greatest extension of arid terrain on the map, and then for the Great Dunes to possible stretch over more than at most a 9 plot square.

    In that case I don't think the landmark will be very noticable in Planetfall, considering Planetfall is already supposed to have large plateaus of highland bordered by a "mountain ridge" of walkable Ridges/Peaks. At least I didn't recognize what it was supposed to be while test-generating various maps.

    For the record, personally I think it's ok if the Scattered Landing Pods option uses starting plot code of the mapscript rather than what the Planetfall SDK would produce (except for the startingplot normalization code which should still not be used). Does this mean, if I understand things correctly, this is the code-way to go?;

    Code:
    def assignStartingPlots():
    	if mst.bPfall and not bScatteredLandingPods:
    		CyPythonMgr().allowDefaultImpl()
    		return
    	else:
    	... other code
    What do you mean by 'gripping hand'?

    I don't understand why you copied PFHL_MultilayeredFractal() if the goal was only to get the Planetfall highland generation rather than also the land/water generation. :confused:

    Anyway, I'd like to try and add the highland generation code to SmartMap? Could you please attach any files you have modified in the meantime? I figure I might as well make the modifications on the most up to date files you have.
     
  8. Baleur

    Baleur Chieftain

    Joined:
    Jul 9, 2010
    Messages:
    526
    Location:
    Qingdao, China
    I'm very split on these maps...
    I love the idea of unique locations even in BUG games, such as the mountain clusters, atlantis-ruins and various lakes and stuff. But they also have a bad side, they make every map seem the same.. When every map you generate has a mountain cluster and a dark lake, it defeats the purpose of most of these great mapscripts (such as perfectworld2, planet generator even though you didnt tweak that one yet, tectonics etc).

    I mean, i love what you are trying to do here, and i suppose the main thing was making mod-compatability.
    But i find myself regenerating the maps and seeing the same map, with the same locations just in different places.
     
  9. OnmyojiOmn

    OnmyojiOmn Chieftain

    Joined:
    Aug 4, 2006
    Messages:
    371
    Nobody should be using PerfectWorld2 when there's PerfectWorld2f. I updated it for your script so I could use it with FFH. It seems to work pretty well.
     

    Attached Files:

  10. Temudjin

    Temudjin Chieftain

    Joined:
    Oct 16, 2007
    Messages:
    90
    Sorry for my long absence, but much to my chagrin there was something called 'Real Live' which interfered :( and then there was (still is..) Civ5 - the final answer to modding :rolleyes:.

    @Maniac:
    See: 'The Mote in God's Eye' 1974 by Larry Niven (w/J. Pournelle) and the sequel 'The Gripping Hand' 1993 - 'Ringworld' is also by Larry Niven.

    @Baleur:
    I try my best to randomise those special locations as much as reasonable. In the end it's not to hard to just reduce the number of appearances (or the probability of their appearance) or comment them out.
    The calls are found in: addRivers(), addFeatures() and normalizeStartingPlotLocations()

    @OnmyojiOmn:
    Thanks. I incorporated your changes into PerfectWorld_206f1_mst.py
    I've also converted PerfectMongoose, which also has Fuyus balancing.
     
  11. Xyth

    Xyth History Rewritten

    Joined:
    Jul 14, 2004
    Messages:
    4,051
    Location:
    Aotearoa
    I don't know if this is still in development or not but I recently discovered it and would like to try integrate it into my mod. I use a Mac and unfortunately it's throwing some errors. I'm initially trying it with just Tectonics_316a_mst.py (in /Mods/<modname>/PrivateMaps/) and MapScriptTools.py (in /Mods/<modname>/Assets/Python/). This is the error on mod launch:

    Code:
    Traceback (most recent call last):
    
      File "<string>", line 1, in ?
    
      File "<string>", line 52, in load_module
    
      File "Tectonics_316a_mst", line 117, in ?
    
      File "<string>", line 52, in load_module
    
      File "MapScriptTools", line 2205, in ?
    
      File "MapScriptTools", line 2037, in __init__
    
      File "MapScriptTools", line 2126, in getCivPaths
    
    NameError: global name 'join' is not defined
    Failed to load python module Tectonics_316a_mst.
    ERR: Call function getNumHiddenCustomMapOptions failed. Can't find module Tectonics_316a_mst
    ERR: Call function getNumCustomMapOptions failed. Can't find module Tectonics_316a_mst
    ERR: Call function getNumHiddenCustomMapOptions failed. Can't find module Tectonics_316a_mst
    ERR: Call function getNumCustomMapOptions failed. Can't find module Tectonics_316a_mst
    ERR: Call function getNumHiddenCustomMapOptions failed. Can't find module Tectonics_316a_mst
    ERR: Call function getNumCustomMapOptions failed. Can't find module Tectonics_316a_mst
    Looking at the getCivPaths procedure it seems 'join' isn't meant to be a variable at all - is it a Python 2.4 command? (Assuming I'm interpreting this all correctly). If so, is there some way of making it Python 2.3 compatible like there was for 'set'?
     
  12. EmperorFool

    EmperorFool Chieftain

    Joined:
    Mar 2, 2007
    Messages:
    9,633
    Location:
    Mountain View, California
    Edit: Ignore the below. There's a simple error on line 2126. Insert the bold "os.path." before "join".

    Code:
    self.rootDir = [b][COLOR="Red"]os.path.[/COLOR][/b]join( self.userDir, "Civilization IV " + self.appName )
    
    I don't have the code in front of me, so post the line that uses join() along with some surrounding context. It should be easy to write a quick function to do what join() does. The following is without looking anything up, and it's been a while since I did any Python:

    Code:
    if "join" not in string.__dict__:
        def join(self, items):
            if not items:
                return ""
            else:
                joined = ""
                for item in items:
                    joined += self + item
                return joined[len(self):]
        string.join = join
    
    Looking at the 2.3 documentation, it looks like the string module has a join() function, and the string class has a join() method. So I don't know why this doesn't work. I need to see the code.
     
  13. Xyth

    Xyth History Rewritten

    Joined:
    Jul 14, 2004
    Messages:
    4,051
    Location:
    Aotearoa
    Thanks, that cleared that up. I'm now getting some errors in individual mapscripts related to 'set()' but I'm guessing I can clear those up by copying the code you suggested earlier from MapScriptTools.py. Others seem to be working fine now though. Cheers!
     
  14. dommain

    dommain Chieftain

    Joined:
    Feb 5, 2010
    Messages:
    187
    The Master of Mana (aka. Wild Mana) mod doesn't work under the FFH like it should. It doesn't produce any unique landmarks except for 1 (randomly assigned to a hut).
     
  15. LunarMongoose

    LunarMongoose Chieftain

    Joined:
    Jan 29, 2006
    Messages:
    731
    Gender:
    Male
    Location:
    Boston, MA, USA
    First time I've looked at this thread; wow, not bad, Temudjin! :) :) :)

    This definitely opens up the option of putting more custom maps in my mod. I'm also very interested in: Deep Ocean and Trenches (though I'm sure Maniac will kill me if I steal any more stuff from Planetfall lol, plus I have to like the graphics for em, which I vaguely remember looking at a long time ago); bigger coasts if that means what I'm assuming it does; and your new river code (even though you weren't able to add it to PW/PM).

    I would tend to not want to mess with starting location placement, move or hillify resources, merge small islands, or add an Atlantis-type island, but I'm intrigued by the Big Bog idea, hehe.

    Anyway, I'll definitely be taking a close look at this when I have time... thanks for making it!
     
  16. And

    And Chieftain

    Joined:
    Nov 27, 2006
    Messages:
    19
    Good Morning,
    I have a simple question. Playing BtS, where do I have to put the maps (*.py files)? In the Public Maps under the Civ4 folder? Or into Public Maps under the BtS folder? Or in the Public Maps under the My Games etc etc folder?
    I searched for an answer but I only got infos related to pre-BtS games. It's possible that I didn't search well enough of course :)
    Thanks in advance!
     
  17. EmperorFool

    EmperorFool Chieftain

    Joined:
    Mar 2, 2007
    Messages:
    9,633
    Location:
    Mountain View, California
    Put them in any BTS PublicMaps folder--either where you installed BTS or in My Games / Beyond the Sword. The latter is created by BTS to hold user-created stuff such as saved games, screen shots, custom maps, mods, etc. The install location works too but is sometimes not writable by a non-Administrator user.
     
  18. And

    And Chieftain

    Joined:
    Nov 27, 2006
    Messages:
    19
    Thank you very much!
     
  19. Xyth

    Xyth History Rewritten

    Joined:
    Jul 14, 2004
    Messages:
    4,051
    Location:
    Aotearoa
    I'm still tinkering with this to get it to run on Mac. One error I'm getting is related to sort(). Basically there are a few instances in the main file where sort() has something in the brackets. One example:

    Code:
    vList = dict.values()
    		vList.sort( key = lambda test: len(test[1]) )
    		vList.reverse()
    These are causing Python exceptions, though everything still seems to function properly. I have no idea what the bit in the brackets does, removing it (changing each occurrence to .sort()) seems to have no ill effect but I thought I should ask just in case.
     
  20. EmperorFool

    EmperorFool Chieftain

    Joined:
    Mar 2, 2007
    Messages:
    9,633
    Location:
    Mountain View, California
    It provides a different method for sorting. It looks like the items in the list are themselves lists with at least two elements. The above sorts the list items by the length of their second elements. I think you could achieve the same effect manually.

    Code:
    vList = [(len(x[1]), x) for x in dict.values()]
    vList.sort()
    vList.reverse()
    vList = [x for _, x in vList]
    
     

Share This Page