MapScriptTools (.. and Associated Maps)

I did have a look, but only a cursory one, which apparently didn't extend to figuring out tundra (that was more than a year ago). Do you mean the transformation should be: 50% FlatPolar, 25% RockyPolar, 25% FlatMoist ? I guess I could do that.

In Planetfall's CvMapGeneratorUtil, Tundra gets changed to 33% Flat Polar, 33% Flat Moist, 16% Rocky Moist and 16% Rocky Polar.

The code is in mapPfallTerrain() lines 2090+ which you already found. Just change:

Thanks! :D

Good question :confused:. Upon consideration I guess I want to create those ridges and highlands of Planetfall as they are a vital part of the Planetfall gameplay, but I don't think I'd want to go quite as far with them. Ideally I'd want to retain at least the general theme of the other map-scripts. Which of course means I'm not going to copy Planetfall's code (which I don't quite understand either).

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.

Thanks, I may use one or two of those ideas to make new special regions for Planetfall. Not Sargasso Sea though, as there would be units involved and I'll avoid that (for now).

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.

Any ideas for additional names for known special regions whould be very welcome indeed:

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.

For LostIsle I have only

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

I couldn't find a solution for the 'Scattered Pods' problem yet. But having checked on my end, I've snooped a bit on yours and found an oddity:

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.
 

Attachments

  • Planet.zip
    57.5 KB · Views: 246
Which of course means I'm not going to copy Planetfall's code (which I don't quite understand either).

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.
 
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.
 
In Planetfall's CvMapGeneratorUtil, Tundra gets changed to 33% Flat Polar, 33% Flat Moist, 16% Rocky Moist and 16% Rocky Polar.
Yes, I've got that wrong. I'll change that in planetFallMap.mapPfallTerrain().

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.
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.

The sea unity pods aren't units, but IMPROVEMENT_UNITY_POD_SEA. And I was mistaken about the name - it's called New Sargasso.
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.

What is the Big Dent?
A mountain range. In Earth3.py I use a single BigDent special region to simulate the Himalayas.

I couldn't find a solution for the 'Scattered Pods' problem yet. But having checked on my end, I've snooped a bit on yours and found an oddity:
That also returns false in vanilla. This is the function:
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.

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 afterward:
..
I believe the only possible difficulty with getting this code to work for other map-scripts is making sure all land plots are PLOT_LAND (ie, flatland) in the plotTypes array before the "main loop" is run.
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.
 
On the gripping hand, I'll probably try and put an option into Tectonics and look if/how it works.
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().
 
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?
 
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.

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.

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

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.

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

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

On the gripping hand

What do you mean by 'gripping hand'?

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().

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.
 
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.
 
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.
 

Attachments

  • PerfectWorld_206f_mst.zip
    50 KB · Views: 276
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:
What do you mean by 'gripping hand'?
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.
 
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'?
 
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.
 
Edit: Ignore the below. There's a simple error on line 2126. Insert the bold "os.path." before "join".

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!
 
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).
 
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!
 
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!
 
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.
 
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.
 
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]
 
Top Bottom