创建森林



创建森林其实就是在创建地图的基础上加上几个语句,然后把地形语句删掉。
语句是: [( )] rmSetAreaForestClumpiness(int areaID, float density): Sets the forest density for an area. [( )] rmSetAreaForestDensity(int areaID, float density): Sets the forest density for an area. [( )] rmSetAreaForestUnderbrush(int areaID, float density): Sets the forest density for an area. [( )] rmSetAreaForestType(int areaID, string forestName): Sets the forest type for an area. 其实这几个语句与剧情编辑器的森林工具的操作是一样的。 [( )] rmSetAreaForestClumpiness(int areaID, 范围0-1.0): 设定部分树木与另一部分树木之间的间隔,数值越少越分散,数值越大越密集。 [( )] rmSetAreaForestDensity(int areaID, 范围0-1.0): 设定树木的密度,数值越大,密度越大,树木数量越多,当密度足够大的时候可以无视rmSetAreaForestClumpiness语句了。 [( )] rmSetAreaForestUnderbrush(int areaID, 范围0-1.0): 设定灌木丛密度,数值越大,灌木丛越多。 [( )] rmSetAreaForestType(int areaID, string forestName): 给地形设定森林类型,然后这个地形就变成森林了,string forestName参考下表。

森林在data3.bar的forest2.xml与data2.bar的forest.xml定义。

Amazon Rain Forest Andes Forest Araucania Forest Ashoka Forest
Bamboo Forest Bayou Swamp Forest Borneo Canopy Forest Borneo Forest
Borneo Palm Forest California Desert Forest California Madrone Forest California Pine Forest
California Redwood Forest Caribbean Palm Forest Carolina Marsh Forest Carolina Pine Forest
Ceylon Forest Christmas Forest Christmas Forest Coastal Japan Forest
Deccan Forest Eucalyptus Forest Ginkgo Forest Great Lakes Forest Snow
Great Lakes Forest Great Plains Forest Great Plains grass green Great Plains grass
Himalayas Forest Mongolian Fir Forest Mongolian Forest New England Forest
North Araucania Coastal Forest North Araucania Forest NW Territory Birch Forest NW Territory Forest
Painteddesert Forest Pampas Forest Patagonia Forest Patagonia Snow Forest
puya Forest Rockies Forest Rockies Snow Forest Saguenay Forest
Saxaul Forest Sonora Forest Texas Forest Dirt Texas Forest
Yellow River Forest Yucatan Forest Yukon Forest Yukon Snow Forest




例如这是一个地形:
  int TestID=rmCreateArea("Test ID Area");
  rmSetAreaSize(TestID, rmAreaTilesToFraction(500), rmAreaTilesToFraction(500));
  rmSetAreaWarnFailure(TestID, true);
  rmSetAreaSmoothDistance(TestID, 0);
  rmSetAreaCoherence(TestID, 0.0);
  rmSetAreaMix(TestID, "himalayas_a");
  rmSetAreaBaseHeight(TestID, 4.0);
  rmSetAreaElevationOctaves(TestID, 3);
  rmSetAreaObeyWorldCircleConstraint(TestID, false);
  rmSetAreaLocation(TestID, 0.5, 0.5);
  rmBuildArea(TestID);


将上述语句改成森林如下:
  int TestID=rmCreateArea("Test ID Area");
  rmSetAreaSize(TestID, rmAreaTilesToFraction(500), rmAreaTilesToFraction(500));
  rmSetAreaForestClumpiness(TestID, 0.80);
  rmSetAreaForestDensity(TestID, 0.70);
  rmSetAreaForestUnderbrush(TestID, 1.00);
  rmSetAreaForestType(TestID, "Christmas Forest");
  rmSetAreaWarnFailure(TestID, true);
  rmSetAreaSmoothDistance(TestID, 0);
  rmSetAreaCoherence(TestID, 0.0);
  //rmSetAreaMix(TestID, "himalayas_a");将设定地形类型语句删除,就算是保留也不会再起任何作用了。
  rmSetAreaBaseHeight(TestID, 4.0);
  rmSetAreaElevationOctaves(TestID, 3);
  rmSetAreaObeyWorldCircleConstraint(TestID, false);
  rmSetAreaLocation(TestID, 0.5, 0.5);
  rmBuildArea(TestID);

这是圣诞树,其实官方是有设定圣诞树模型的,不过没有加入到游戏中,所以只能在MOD里面看见圣诞树了,非MOD会显示为育空那种树木。









创建森林注意事项:创建森林应避开所有已有单位,包括水域(单位),否则会让原有的单位消失。 你有两种选择: 1.优先创建森林,在地图的第一个单位出现前就要创建,另外其他单位(城镇中心、群组等单位)应该避开森林,不然可能会导致无法放置。 2.创建森林时使用放置规则,避开所有单位,注:这种情况不能用rmSetAreaLocation设定定位点,不然可能会导致无法生成。 这个教程介绍第二种方法:传送门
  Debug.xs - 记事本 ____ X
文件(F)  编辑(E)  格式(O)  查看(V)  帮助(H)
	include "mercenaries.xs";
	include "ypAsianInclude.xs";
	include "ypKOTHInclude.xs";

	void main(void)
	{
		// ---------------------------------------- Map Info -------------------------------------------
		int playerTilesX=13200;			//设定地图X大小
		int playerTilesZ=13200;			//设定地图Z大小(帝国3的Y是高度,Z才是我们平常所用到的Y)


		//如果玩家大于4将playerTilesX与playerTilesZ改为11500(同一个值的int只能出现1次,当你需要修改数值的时候,不能再加入int)
		if (cNumberNonGaiaPlayers >4){	playerTilesX=11500;	playerTilesZ=11500;}



		if (cNumberNonGaiaPlayers >6){	playerTilesX=10500;	playerTilesZ=10500;}		//Modify Map X&Z Size of 6,7,8 Player



		int SizeX = 2*sqrt(cNumberNonGaiaPlayers*playerTilesX);
		int SizeZ = 2*sqrt(cNumberNonGaiaPlayers*playerTilesZ);



		string MapTerrain ="Carolinas\ground_marsh3_car";	//<-------- 地图地形,自己参照剧情编辑器 <--------

		string MapLighting ="319a_Snow";			//<-------- 照明,自己参照剧情编辑器 <--------

		string PlayerTerrain ="Carolinas\ground_marsh1_car";	//<--------- 玩家范围地形 <---------




		//设定地图XZ大小,分别调用上面用int定义的SizeX与SizeZ,即为rmSetMapSize(13200,13200);如果玩家大于4将改为11500
		rmSetMapSize(SizeX, SizeZ);



		rmSetMapElevationParameters(cElevTurbulence, 0.15, 2.5, 0.35, 3.0); // type, frequency, octaves, persistence, variation 

		rmSetMapElevationHeightBlend(1.0);


		//地形初始化,设定地图初始地形,调用上面用string定义MapTerrain,即为"Carolinas\ground_marsh3_car";
		rmTerrainInitialize(MapTerrain,6);



		//设定照明,调用上面用string定义MapLighting,即为"319a_Snow"
		rmSetLightingSet(MapLighting);



		rmSetGlobalRain(0.9);		//设定下雨
		chooseMercs();
		rmSetMapType("yucatan");
		rmSetMapType("water");
		rmSetMapType("default");	//设定地图类型,地图类型影响到宝藏
		rmSetMapType("land");
		rmSetMapType("bayou");
		rmSetSeaLevel(0); // this is height of river surface compared to surrounding land. River depth is in the river XML.

		rmSetStatusText("",0.01);//读取地图进度条

		int classStartingResource = rmDefineClass("startingResource");	
		int PlayerHerd2Class = rmDefineClass("PlayerHerd2C");		
		int classGold = rmDefineClass("Gold");	

		int avoidGold = rmCreateClassDistanceConstraint ("avoid gold", rmClassID("Gold"), 50.0);
		int avoidPlayerHerd2Far = rmCreateClassDistanceConstraint("avoid Player Herd2 far", rmClassID("PlayerHerd2C"), 52.0);
		int avoidStartingResources = rmCreateClassDistanceConstraint("start resources avoid each other2", rmClassID("startingResource"), 4.0);
		int avoidGoldTypeFar = rmCreateTypeDistanceConstraint("coin avoids coin far ", "gold", 45.0);
		int avoidHerdTypeFar = rmCreateTypeDistanceConstraint("herd avoids herd far", "herd", 45.0);
		int avoidTreeType = rmCreateTypeDistanceConstraint("Tree avoids Tree  ", "Tree", 25.0);
		
		

		//设定与带有abstractFish标签的单位最小间隔距离30
		int avoidFish = rmCreateTypeDistanceConstraint("FishToFish", "abstractFish", 30.0);

		//设定与陆地最小间隔距离9
		int avoidFishLand = rmCreateTerrainDistanceConstraint("FishTOLand", "land", true, 9.0);

		int avoidLand = rmCreateTerrainDistanceConstraint("ship avoid land", "land", true, 15.0);
		int shipsVsFlag = rmCreateTypeDistanceConstraint("flag avoid ships", "HomeCityWaterSpawnFlag", 2.0);
		int flagLand = rmCreateTerrainDistanceConstraint("flag vs land", "land", true, 16.0);
		int flagVsFlag = rmCreateTypeDistanceConstraint("flag avoid same", "HomeCityWaterSpawnFlag", 8.0);

		
		//与水域最小间隔距离为12
		int avoidWaterMin = rmCreateTerrainDistanceConstraint("avoid Lake Min", "water", true, 12.0);
		//数量太多了,自己按ctrl+F往下面搜索avoidWaterMin,其实就是给每一组单位都添加了这个avoidWaterMin放置限制


		int RiverRadius = 4.5;		int RiverRadius2 = 8.5;
		if(cNumberNonGaiaPlayers>=3)	{RiverRadius = 5.4;		RiverRadius2 = 10.2;}
		if(cNumberNonGaiaPlayers>=4)	{RiverRadius = 6.2;		RiverRadius2 = 11.7;}
		if(cNumberNonGaiaPlayers>=5)	{RiverRadius = 6.8;		RiverRadius2 = 12.8;}
		if(cNumberNonGaiaPlayers>=6)	{RiverRadius = 7.4;		RiverRadius2 = 14.0;}
		if(cNumberNonGaiaPlayers>=7)	{RiverRadius = 8.0;		RiverRadius2 = 15.2;}
		if(cNumberNonGaiaPlayers>=8)	{RiverRadius = 8.5;		RiverRadius2 = 16.2;}

		rmSetStatusText("",0.08);

	// ---------------------------------------------------------------- River 1 ------------------------------------------------------------------
		string RiverType = "Northwest Territory Water";	
		int RiverID = rmRiverCreate(-1, RiverType, 1, 1, RiverRadius, RiverRadius);
		rmRiverAddWaypoint(RiverID, 0.500, 0.518 );
		rmRiverAddWaypoint(RiverID, 0.478, 0.520 );
		rmRiverAddWaypoint(RiverID, 0.450, 0.525 );
		rmRiverAddWaypoint(RiverID, 0.420, 0.528 );
		rmRiverAddWaypoint(RiverID, 0.400, 0.530 );
		rmRiverAddWaypoint(RiverID, 0.380, 0.540 );
		rmRiverAddWaypoint(RiverID, 0.330, 0.565 );
		rmRiverAddWaypoint(RiverID, 0.300, 0.580 );
		rmRiverAddWaypoint(RiverID, 0.280, 0.590 );
		rmRiverAddWaypoint(RiverID, 0.260, 0.600 );
		rmRiverAddWaypoint(RiverID, 0.240, 0.620 );
		rmRiverAddWaypoint(RiverID, 0.210, 0.640 );
		rmRiverAddWaypoint(RiverID, 0.200, 0.655 );
		rmRiverAddWaypoint(RiverID, 0.180, 0.680 );
		rmRiverAddWaypoint(RiverID, 0.170, 0.700 );
		rmRiverAddWaypoint(RiverID, 0.160, 0.730 );
//		rmRiverAddWaypoint(RiverID, 0.140, 0.725 );
		rmRiverAddWaypoint(RiverID, 0.130, 0.720 );
		rmRiverAddWaypoint(RiverID, 0.125, 0.670 );
		rmRiverAddWaypoint(RiverID, 0.120, 0.650 );
		rmRiverAddWaypoint(RiverID, 0.190, 0.625 );
		rmRiverAddWaypoint(RiverID, 0.195, 0.610 );
		rmRiverAddWaypoint(RiverID, 0.125, 0.600 );
		rmRiverAddWaypoint(RiverID, 0.128, 0.560 );
		rmRiverAddWaypoint(RiverID, 0.129, 0.550 );
		rmRiverAddWaypoint(RiverID, 0.133, 0.533 );
		rmRiverAddWaypoint(RiverID, 0.139, 0.520 );
		rmRiverAddWaypoint(RiverID, 0.140, 0.500 );
		rmRiverAddWaypoint(RiverID, 0.145, 0.480 );
		rmRiverAddWaypoint(RiverID, 0.150, 0.461 );
		rmRiverAddWaypoint(RiverID, 0.160, 0.480 );
		rmRiverAddWaypoint(RiverID, 0.175, 0.430 );
		rmRiverAddWaypoint(RiverID, 0.195, 0.400 );
		rmRiverAddWaypoint(RiverID, 0.218, 0.370 );
		rmRiverAddWaypoint(RiverID, 0.235, 0.360 );
		rmRiverAddWaypoint(RiverID, 0.245, 0.350 );
		rmRiverAddWaypoint(RiverID, 0.265, 0.340 );
		rmRiverAddWaypoint(RiverID, 0.290, 0.310 );
		rmRiverAddWaypoint(RiverID, 0.300, 0.305 );
		rmRiverAddWaypoint(RiverID, 0.330, 0.288 );
		rmRiverAddWaypoint(RiverID, 0.300, 0.305 );
		rmRiverAddWaypoint(RiverID, 0.340, 0.275 );
		rmRiverAddWaypoint(RiverID, 0.355, 0.270 );
		rmRiverAddWaypoint(RiverID, 0.370, 0.265 );
		rmRiverAddWaypoint(RiverID, 0.380, 0.260 );
		rmRiverAddWaypoint(RiverID, 0.400, 0.265 );
		rmRiverAddWaypoint(RiverID, 0.420, 0.255 );
		rmRiverAddWaypoint(RiverID, 0.445, 0.250 );
		rmRiverAddWaypoint(RiverID, 0.450, 0.249 );
		rmRiverAddWaypoint(RiverID, 0.480, 0.248 );
		rmRiverAddWaypoint(RiverID, 0.500, 0.247 );
		rmRiverAddWaypoint(RiverID, 0.520, 0.249 );
		rmRiverAddWaypoint(RiverID, 0.530, 0.250 );
		rmRiverAddWaypoint(RiverID, 0.550, 0.255 );
		rmRiverAddWaypoint(RiverID, 0.560, 0.257 );
		rmRiverAddWaypoint(RiverID, 0.570, 0.261 );
		rmRiverAddWaypoint(RiverID, 0.590, 0.263 );
		rmRiverAddWaypoint(RiverID, 0.600, 0.267 );
		rmRiverAddWaypoint(RiverID, 0.620, 0.270 );
		rmRiverAddWaypoint(RiverID, 0.630, 0.275 );
		rmRiverAddWaypoint(RiverID, 0.650, 0.278 );
		rmRiverAddWaypoint(RiverID, 0.680, 0.288 );
		rmRiverAddWaypoint(RiverID, 0.690, 0.300 );
		rmRiverAddWaypoint(RiverID, 0.700, 0.305 );
		rmRiverAddWaypoint(RiverID, 0.730, 0.320 );
		rmRiverAddWaypoint(RiverID, 0.740, 0.333 );
		rmRiverAddWaypoint(RiverID, 0.750, 0.345 );
		rmRiverAddWaypoint(RiverID, 0.760, 0.355 );
		rmRiverAddWaypoint(RiverID, 0.770, 0.365 );
		rmRiverAddWaypoint(RiverID, 0.780, 0.375 );
		rmRiverAddWaypoint(RiverID, 0.790, 0.385 );
		rmRiverAddWaypoint(RiverID, 0.800, 0.390 );
		rmRiverAddWaypoint(RiverID, 0.810, 0.405 );
		rmRiverAddWaypoint(RiverID, 0.820, 0.420 );
		rmRiverAddWaypoint(RiverID, 0.830, 0.435 );
		rmRiverAddWaypoint(RiverID, 0.840, 0.450 );
		rmRiverAddWaypoint(RiverID, 0.850, 0.460 );
		rmRiverAddWaypoint(RiverID, 0.855, 0.500 );
		rmRiverAddWaypoint(RiverID, 0.860, 0.510 );
		rmRiverAddWaypoint(RiverID, 0.870, 0.520 );
		rmRiverAddWaypoint(RiverID, 0.875, 0.530 );
		rmRiverAddWaypoint(RiverID, 0.878, 0.540 );
		rmRiverAddWaypoint(RiverID, 0.880, 0.550 );
		rmRiverAddWaypoint(RiverID, 0.881, 0.560 );
		rmRiverAddWaypoint(RiverID, 0.882, 0.570 );
		rmRiverAddWaypoint(RiverID, 0.880, 0.600 );
		rmRiverAddWaypoint(RiverID, 0.878, 0.620 );
		rmRiverAddWaypoint(RiverID, 0.875, 0.640 );
		rmRiverAddWaypoint(RiverID, 0.874, 0.660 );
		rmRiverAddWaypoint(RiverID, 0.871, 0.680 );
		rmRiverAddWaypoint(RiverID, 0.870, 0.700 );
		rmRiverAddWaypoint(RiverID, 0.860, 0.730 );
		rmRiverAddWaypoint(RiverID, 0.850, 0.740 );
		rmRiverAddWaypoint(RiverID, 0.834, 0.730 );/*rmRiverAddWaypoint(RiverID, 0.834, 0.730 );*/
		rmRiverAddWaypoint(RiverID, 0.820, 0.700 );/*rmRiverAddWaypoint(RiverID, 0.829, 0.700 );*/
		rmRiverAddWaypoint(RiverID, 0.815, 0.670 );/*rmRiverAddWaypoint(RiverID, 0.820, 0.670 );*/
		rmRiverAddWaypoint(RiverID, 0.790, 0.660 );
		rmRiverAddWaypoint(RiverID, 0.780, 0.650 );
		rmRiverAddWaypoint(RiverID, 0.760, 0.640 );
		rmRiverAddWaypoint(RiverID, 0.750, 0.620 );
		rmRiverAddWaypoint(RiverID, 0.738, 0.600 );
		rmRiverAddWaypoint(RiverID, 0.720, 0.580 );
		rmRiverAddWaypoint(RiverID, 0.700, 0.570 );
		rmRiverAddWaypoint(RiverID, 0.680, 0.565 );
		rmRiverAddWaypoint(RiverID, 0.670, 0.560 );
		rmRiverAddWaypoint(RiverID, 0.660, 0.555 );
		rmRiverAddWaypoint(RiverID, 0.650, 0.550 );
		rmRiverAddWaypoint(RiverID, 0.640, 0.550 );
		rmRiverAddWaypoint(RiverID, 0.630, 0.545 );
		rmRiverAddWaypoint(RiverID, 0.620, 0.540 );
		rmRiverAddWaypoint(RiverID, 0.610, 0.535 );
		rmRiverAddWaypoint(RiverID, 0.600, 0.530 );
		rmRiverAddWaypoint(RiverID, 0.580, 0.528 );
		rmRiverAddWaypoint(RiverID, 0.560, 0.526 );
		rmRiverAddWaypoint(RiverID, 0.550, 0.525 );
		rmRiverAddWaypoint(RiverID, 0.530, 0.522 );
		rmRiverAddWaypoint(RiverID, 0.520, 0.520 );
		rmRiverAddWaypoint(RiverID, 0.510, 0.519 );
		rmRiverAddWaypoint(RiverID, 0.500, 0.518 );
		rmRiverSetBankNoiseParams(RiverID,0.00, 0, 0.0, 0.0, 0.0, 0.0);
		rmRiverBuild(RiverID);
		rmAddAreaToClass(RiverID,rmClassID("Lake"));




	// ---------------------------------------------------------------- River 2 ------------------------------------------------------------------
		int River2ID = rmRiverCreate(-1, RiverType, 1, 1, RiverRadius2+2, RiverRadius2+2);
		rmRiverAddWaypoint(River2ID, 0.18, 0.60 );
		rmRiverAddWaypoint(River2ID, 0.21, 0.50 );
		rmRiverAddWaypoint(River2ID, 0.32, 0.32 );
		rmRiverAddWaypoint(River2ID, 0.50, 0.31 );
		rmRiverAddWaypoint(River2ID, 0.60, 0.32 );
		rmRiverAddWaypoint(River2ID, 0.70, 0.38 );
		rmRiverAddWaypoint(River2ID, 0.80, 0.50 );
		rmRiverAddWaypoint(River2ID, 0.84, 0.62 );
		rmRiverAddWaypoint(River2ID, 0.77, 0.53 );
		rmRiverAddWaypoint(River2ID, 0.63, 0.47 );
		rmRiverAddWaypoint(River2ID, 0.53, 0.48 );
		rmRiverAddWaypoint(River2ID, 0.45, 0.45 );
		rmRiverAddWaypoint(River2ID, 0.33, 0.50 );
		rmRiverAddWaypoint(River2ID, 0.18, 0.60 );
		rmRiverAddWaypoint(River2ID, 0.38, 0.38 );
		rmRiverAddWaypoint(River2ID, 0.64, 0.42 );
		rmRiverSetBankNoiseParams(River2ID,0.00, 0, 0.0, 0.0, 0.0, 0.0);
		rmRiverBuild(River2ID);
	// -------------------------------------------------------------------------------------------------------------------------------------------
		rmSetStatusText("",0.12);
	// ---------------------------------------------------------------- River 3 ------------------------------------------------------------------
		int River3ID = rmRiverCreate(-1, RiverType, 1, 1, RiverRadius, RiverRadius);
		rmRiverAddWaypoint(River3ID, 0.84, 0.62 );
		rmRiverAddWaypoint(River3ID, 0.795, 0.675 );
		rmRiverAddWaypoint(River3ID, 0.87, 0.68 );
		rmRiverSetBankNoiseParams(River2ID,0.00, 0, 0.0, 0.0, 0.0, 0.0);
		rmRiverBuild(River3ID);

		int River4ID = rmRiverCreate(-1, RiverType, 1, 1, RiverRadius, RiverRadius);
		rmRiverAddWaypoint(River4ID, 0.18, 0.63 );
		rmRiverAddWaypoint(River4ID, 0.120, 0.635 );
		rmRiverAddWaypoint(River4ID, 0.180, 0.63 );
		rmRiverAddWaypoint(River4ID, 0.170, 0.67 );
		rmRiverSetBankNoiseParams(River4ID,0.00, 0, 0.0, 0.0, 0.0, 0.0);
		rmRiverBuild(River4ID);

	// -------------------------------------------------------------------------------------------------------------------------------------------



		rmPlacePlayersCircular(0.35, 0.35, 0.0);   	//圆形放置玩家

		//玩家范围
		float AreaSizePlayer = rmAreaTilesToFraction(700);
		for(i=1; <=cNumberNonGaiaPlayers)
		{
			int id=rmCreateArea("Player"+i);
			rmSetPlayerArea(i, id);
			rmSetAreaWarnFailure(id, false);
			rmSetAreaSize(id, AreaSizePlayer, AreaSizePlayer);
			rmSetAreaLocPlayer(id, i);
			rmSetAreaCoherence(id, 0.85);
			rmSetAreaSmoothDistance(id, 2);
			rmSetAreaMinBlobs(id, 1);
			rmSetAreaMaxBlobs(id, 1);
			rmSetAreaTerrainType(id,PlayerTerrain);
			rmBuildArea(id);
		}
		
		//定义城镇中心
		int TownCenterID = rmCreateObjectDef("player TC");
		if (rmGetNomadStart())
		{
			rmAddObjectDefItem(TownCenterID, "CoveredWagon", 1, 0.0);
		}
		else
		{
			rmAddObjectDefItem(TownCenterID, "TownCenter", 1, 0);
		}
		rmSetObjectDefMinDistance(TownCenterID, 0.0);
		rmSetObjectDefMaxDistance(TownCenterID, 20.0);
		for(i=1; <=cNumberNonGaiaPlayers)
		{	
			rmPlaceObjectDefAtLoc(TownCenterID, i, rmPlayerLocXFraction(i), rmPlayerLocZFraction(i));
		}
		rmAddObjectDefConstraint(TownCenterID, avoidWaterMin);


		//定义起始单位(civs.xml定义那些开局单位)
		int startingUnits = rmCreateStartingUnitsObjectDef(5.0);
		rmSetObjectDefMinDistance(startingUnits, 6.0);
		rmSetObjectDefMaxDistance(startingUnits, 10.0);
		rmAddObjectDefConstraint(startingUnits, avoidWaterMin);



		int playerherdID = rmCreateObjectDef("starting herd");
		rmAddObjectDefItem(playerherdID, "ypWildElephant", 10, 6.0);
		rmSetObjectDefMinDistance(playerherdID, 8.0);
		rmSetObjectDefMaxDistance(playerherdID, 12.0);
		rmSetObjectDefCreateHerd(playerherdID, true);
		rmAddObjectDefToClass(playerherdID, classStartingResource);
		rmAddObjectDefConstraint(playerherdID, avoidStartingResources);
		rmAddObjectDefConstraint(playerherdID, avoidWaterMin);




		int playergoldID = rmCreateObjectDef("player mine");
		rmAddObjectDefItem(playergoldID, "Minegold", 1, 6);
		rmSetObjectDefMinDistance(playergoldID, 18.0);
		rmSetObjectDefMaxDistance(playergoldID, 22.0);
		rmAddObjectDefToClass(playergoldID, rmDefineClass("startingResource"));
		rmAddObjectDefToClass(playergoldID, classGold);
		rmAddObjectDefConstraint(playergoldID, avoidStartingResources);
		rmAddObjectDefConstraint(playergoldID, avoidWaterMin);

		string PlayerTreeType ="TreeRedwood";
		int PlayerTreeCount = 8;

		int playerTree1ID = rmCreateObjectDef("player trees");
		rmAddObjectDefItem(playerTree1ID, PlayerTreeType, PlayerTreeCount, 8.0);
		rmSetObjectDefMinDistance(playerTree1ID, 6);
		rmSetObjectDefMaxDistance(playerTree1ID, 12);
		rmAddObjectDefToClass(playerTree1ID, classStartingResource);
		rmAddObjectDefConstraint(playerTree1ID, avoidStartingResources);
		rmAddObjectDefConstraint(playerTree1ID, avoidWaterMin);



		int playerBerryID=rmCreateObjectDef("player berries");
		rmAddObjectDefItem(playerBerryID, "BerryBush", rmRandInt(3,4), 3.0);
		rmSetObjectDefMinDistance(playerBerryID, 12);
		rmSetObjectDefMaxDistance(playerBerryID, 14);
		rmAddObjectDefToClass(playerBerryID, classStartingResource);
		rmAddObjectDefConstraint(playerBerryID, avoidStartingResources);
		rmAddObjectDefConstraint(playerBerryID, avoidWaterMin);
		
		
		int playerHerd2ID = rmCreateObjectDef("player Herd2");
		rmAddObjectDefItem(playerHerd2ID, "Bison", rmRandInt(10,11), 10.0);
		rmSetObjectDefMinDistance(playerHerd2ID, 36);
		rmSetObjectDefMaxDistance(playerHerd2ID, 38);
		rmSetObjectDefCreateHerd(playerHerd2ID, true);
		rmAddObjectDefToClass(playerHerd2ID, PlayerHerd2Class);
		rmAddObjectDefConstraint(playerHerd2ID, avoidWaterMin);



		
		int playerHerd3ID = rmCreateObjectDef("player Herd3");
		rmAddObjectDefItem(playerHerd3ID, "Turkey", rmRandInt(8,9), 8.0);
		rmSetObjectDefMinDistance(playerHerd3ID, 40);
		rmSetObjectDefMaxDistance(playerHerd3ID, 42);
		rmSetObjectDefCreateHerd(playerHerd3ID, true);
		rmAddObjectDefConstraint(playerHerd3ID, avoidPlayerHerd2Far);
		rmAddObjectDefConstraint(playerHerd3ID, avoidWaterMin);



		int playergold2ID = rmCreateObjectDef("player second mine");
		rmAddObjectDefItem(playergold2ID, "mine", 1, 0);
		rmSetObjectDefMinDistance(playergold2ID, 58.0);
		rmSetObjectDefMaxDistance(playergold2ID, 62.0);
		rmAddObjectDefToClass(playergold2ID, classGold);
		rmAddObjectDefConstraint(playergold2ID, avoidGold);
		rmAddObjectDefConstraint(playergold2ID, avoidWaterMin);
		

		
		int playergold3ID = rmCreateObjectDef("player third mine");
		rmAddObjectDefItem(playergold3ID, "mine", 1, 0);
		rmSetObjectDefMinDistance(playergold3ID, 68.0);
		rmSetObjectDefMaxDistance(playergold3ID, 70.0);
		rmAddObjectDefToClass(playergold3ID, classGold);
		rmAddObjectDefConstraint(playergold3ID, avoidGold);
		rmAddObjectDefConstraint(playergold3ID, avoidWaterMin);

		for(i=1; <=cNumberNonGaiaPlayers)
		{
			vector TCLocation = rmGetUnitPosition(rmGetUnitPlacedOfPlayer(TownCenterID, i));
			rmPlaceObjectDefAtLoc(startingUnits, i, rmXMetersToFraction(xsVectorGetX(TCLocation)), rmZMetersToFraction(xsVectorGetZ(TCLocation)));
			rmPlaceObjectDefAtLoc(playerherdID, i, rmXMetersToFraction(xsVectorGetX(TCLocation)), rmZMetersToFraction(xsVectorGetZ(TCLocation)));
			rmPlaceObjectDefAtLoc(playerTree1ID, i, rmXMetersToFraction(xsVectorGetX(TCLocation)), rmZMetersToFraction(xsVectorGetZ(TCLocation)));
			rmPlaceObjectDefAtLoc(playergoldID, i, rmXMetersToFraction(xsVectorGetX(TCLocation)), rmZMetersToFraction(xsVectorGetZ(TCLocation)));
			rmPlaceObjectDefAtLoc(playerBerryID, i, rmXMetersToFraction(xsVectorGetX(TCLocation)), rmZMetersToFraction(xsVectorGetZ(TCLocation)));
		
			rmPlaceObjectDefAtLoc(playerHerd2ID, i, rmXMetersToFraction(xsVectorGetX(TCLocation)), rmZMetersToFraction(xsVectorGetZ(TCLocation)));
			rmPlaceObjectDefAtLoc(playerHerd3ID, i, rmXMetersToFraction(xsVectorGetX(TCLocation)), rmZMetersToFraction(xsVectorGetZ(TCLocation)));
			rmPlaceObjectDefAtLoc(playergold2ID, i, rmXMetersToFraction(xsVectorGetX(TCLocation)), rmZMetersToFraction(xsVectorGetZ(TCLocation)));
			rmPlaceObjectDefAtLoc(playergold3ID, i, rmXMetersToFraction(xsVectorGetX(TCLocation)), rmZMetersToFraction(xsVectorGetZ(TCLocation)));
		
		}
		

			int NativeCenterID = rmCreateGrouping("Native Center ID", "native aztec village "+rmRandInt(rmRandInt(1,2),rmRandInt(3,rmRandInt(4,5))));
			rmSetGroupingMinDistance(NativeCenterID, 0.0);
			rmSetGroupingMaxDistance(NativeCenterID, rmXFractionToMeters(0.1));
			rmAddGroupingToClass(NativeCenterID, rmDefineClass("natives"));
			rmAddGroupingConstraint(NativeCenterID, avoidWaterMin);	//PS:群组与单位的放置限制语句不一样哦。
			rmPlaceGroupingAtLoc(NativeCenterID, 0,0.50,0.50);







		int FixedGunID = rmCreateObjectDef("FixedGun");
		rmAddObjectDefItem(FixedGunID, "SPCFixedGun",1,5.0);
		rmSetObjectDefMinDistance(FixedGunID,0.0);
		rmSetObjectDefMaxDistance(FixedGunID,30.0);
		rmAddObjectDefConstraint(FixedGunID, avoidWaterMin);
		rmPlaceObjectDefAtLoc(FixedGunID,0,0.50,0.50,1);


		for(i=0; <= cNumberNonGaiaPlayers*3)
		{
			int goldID = rmCreateObjectDef("gold"+i);
			rmAddObjectDefItem(goldID, "mine", 1, 0.0);
			rmSetObjectDefMinDistance(goldID, rmXFractionToMeters(0.0));
			rmSetObjectDefMaxDistance(goldID, rmXFractionToMeters(0.5));
			rmAddObjectDefToClass(goldID, classGold);
			rmAddObjectDefConstraint(goldID, avoidGoldTypeFar);
		rmAddObjectDefConstraint(goldID, avoidWaterMin);
			rmPlaceObjectDefAtLoc(goldID, 0, 0.50, 0.50);
		}





		int CenterHerdID = rmCreateObjectDef("Center Herd2");
		rmAddObjectDefItem(CenterHerdID, "BighornSheep",10, 8.0);
		rmSetObjectDefMinDistance(CenterHerdID, rmXFractionToMeters(0.0));
		rmSetObjectDefMaxDistance(CenterHerdID, rmXFractionToMeters(0.45));
		rmSetObjectDefCreateHerd(CenterHerdID, true);
		rmAddObjectDefConstraint(CenterHerdID, avoidHerdTypeFar);
		rmAddObjectDefConstraint(CenterHerdID, avoidWaterMin);


		for(i=1; <= cNumberNonGaiaPlayers*3)
		{
		rmPlaceObjectDefAtLoc(CenterHerdID, 0, 0.50, 0.50);
		}

		rmSetStatusText("",0.50);//读取地图进度条


			int avoidNative = rmCreateClassDistanceConstraint("avoid Native", rmClassID("natives"), 52.0);
			int avoidGoldTypeMin = rmCreateTypeDistanceConstraint("coin avoids coin Min", "gold", 15.0);
			int avoidTreeTypeMin = rmCreateTypeDistanceConstraint("Tree avoids Min", "Tree", 15.0);


			int NativeCenter2ID = rmCreateGrouping("Native Center ID", "native aztec village "+rmRandInt(rmRandInt(1,2),rmRandInt(3,rmRandInt(4,5))));
			rmSetGroupingMinDistance(NativeCenter2ID, 0.0);
			rmSetGroupingMaxDistance(NativeCenter2ID, rmXFractionToMeters(0.5));
			rmAddGroupingToClass(NativeCenter2ID, rmDefineClass("natives"));

			rmAddGroupingConstraint(NativeCenter2ID, avoidNative);
			rmAddGroupingConstraint(NativeCenter2ID, avoidGoldTypeMin);
			rmAddGroupingConstraint(NativeCenter2ID, avoidTreeTypeMin);
			rmAddGroupingConstraint(NativeCenter2ID, avoidWaterMin);	//PS:群组与单位的放置限制语句不一样哦。
			rmPlaceGroupingAtLoc(NativeCenter2ID, 0,0.50,0.50,3);


		



		int FountainID=rmCreateObjectDef("FountainOfYouth");
		rmAddObjectDefItem(FountainID, "SPCFountainOfYouth", 1, 0.0);
		rmSetObjectDefMinDistance(FountainID, 0.0);
		rmSetObjectDefMaxDistance(FountainID, 10);
		rmAddObjectDefConstraint(FountainID, avoidFishLand);
		rmPlaceObjectDefAtLoc(FountainID, 0, 0.50, 0.45, 1);

		int Fish1count = cNumberPlayers * 3;	string Fish1Name = "FishMoonBass";
		int Fish2count = cNumberPlayers * 3;	string Fish2Name = "FishMoonBass";
		int whalecount = (cNumberNonGaiaPlayers * 3) + rmRandInt(1,2);
		int Junkcount = cNumberPlayers;
		int RandomJunk = rmRandInt(0,1);
		//蓝色文字是海军旗帜的语句
		int waterSpawnPointID = rmCreateObjectDef("Flag");
		rmAddObjectDefItem(waterSpawnPointID, "HomeCityWaterSpawnFlag", 1, 0.0);
		rmSetObjectDefMaxDistance(waterSpawnPointID, 30);
		rmAddClosestPointConstraint(flagVsFlag);
		rmAddClosestPointConstraint(flagLand);

		for(i=1; <cNumberPlayers)
		{
			int ShipsID = rmCreateObjectDef("Ships"+i);		//这个是两个玩家的情况下给每个玩家创建1只独木舟。

			//这是一种没有出现过的if判断国家方法,总之我的语句很高级就对了。你去命令章节看下国家ID应该会明白是什么。
			if (rmGetPlayerCiv(i) <= 13 && rmGetPlayerCiv(i) != 8)
			{
				rmAddObjectDefItem(ShipsID,"Canoe", 1, 10.0);
			}
			else if (rmGetPlayerCiv(i) == 8)
			{
				rmAddObjectDefItem(ShipsID,"Canoe", 1, 10.0);
			}
			else if (rmGetPlayerCiv(i) >= 14 && rmGetPlayerCiv(i) <= 17)
			{
				rmAddObjectDefItem(ShipsID,"Canoe", 1, 10.0);
			}
			else if (rmGetPlayerCiv(i) == 19 || rmGetPlayerCiv(i) == 22 || rmGetPlayerCiv(i) == 26)
			{
				rmAddObjectDefItem(ShipsID,"Canoe", 1, 10.0);
			}
			else if (rmGetPlayerCiv(i) == 20 || rmGetPlayerCiv(i) == 23)
			{
				rmAddObjectDefItem(ShipsID,"Canoe", 1, 10.0);
			}
			else
			{
				rmAddObjectDefItem(ShipsID,"Canoe", 1, 10.0);
			}
			rmSetObjectDefMaxDistance(ShipsID, 30);
			rmAddClosestPointConstraint(shipsVsFlag);
			rmAddClosestPointConstraint(flagLand);
			TCLocation = rmGetUnitPosition(rmGetUnitPlacedOfPlayer(TownCenterID, i));
			vector closestPoint = rmFindClosestPointVector(TCLocation, rmXFractionToMeters(1.0));
			rmPlaceObjectDefAtLoc(waterSpawnPointID, i, rmXMetersToFraction(xsVectorGetX(closestPoint)), rmZMetersToFraction(xsVectorGetZ(closestPoint)));
			if(cNumberNonGaiaPlayers == 2)
			{
			rmPlaceObjectDefAtLoc(ShipsID, i, rmXMetersToFraction(xsVectorGetX(closestPoint)), rmZMetersToFraction(xsVectorGetZ(closestPoint)));
			}
		}
		rmClearClosestPointConstraints();

		rmSetStatusText("",0.80);
		int Fisch1=rmCreateObjectDef("Fish 1");
		rmAddObjectDefItem(Fisch1, Fish1Name, 1, 0.0);
		rmSetObjectDefMinDistance(Fisch1, 0.3);
		rmSetObjectDefMaxDistance(Fisch1, rmXFractionToMeters(0.5));
		rmAddObjectDefConstraint(Fisch1, avoidFish);
		rmAddObjectDefConstraint(Fisch1, avoidFishLand);
		rmPlaceObjectDefAtLoc(Fisch1, 0, 0.5, 0.5, Fish1count);

		int Fisch2=rmCreateObjectDef("Fish 2");
		rmAddObjectDefItem(Fisch2, Fish2Name, 1, 0.0);
		rmSetObjectDefMinDistance(Fisch2, 0.3);
		rmSetObjectDefMaxDistance(Fisch2, rmXFractionToMeters(0.5));
		rmAddObjectDefConstraint(Fisch2, avoidFish);
		rmAddObjectDefConstraint(Fisch2, avoidFishLand);
		rmPlaceObjectDefAtLoc(Fisch2, 0, 0.5, 0.5, Fish2count);

	
		//设定与隐藏标签(All即为所有单位)最小间隔距离15

//从制作一张好地图的角度上来说,我是不推荐只用一个avoidAll的,你看看别的地图用了多少放置限制?而你只用一个,这效果能不差吗

int avoidAllFar = rmCreateTypeDistanceConstraint("avoids All Unit far", "All", 15.0); int avoidTownCenter = rmCreateTypeDistanceConstraint("avoid Town Center", "townCenter", 25.0); for(f=1; <cNumberPlayers*3)//for循环不一定是i,只要不是数字弄什么值都可以。 { int ForestID=rmCreateArea("Forest ID Area"+f); rmSetAreaSize(ForestID, rmAreaTilesToFraction(500), rmAreaTilesToFraction(500)); rmSetAreaForestType(ForestID, "California Redwood Forest"); rmSetAreaForestClumpiness(ForestID, 0.80); rmSetAreaForestDensity(ForestID, 0.70); rmSetAreaForestUnderbrush(ForestID, 0.00); rmSetAreaWarnFailure(ForestID, true); rmSetAreaSmoothDistance(ForestID, 0); rmSetAreaCoherence(ForestID, 0.0); rmSetAreaBaseHeight(ForestID, 4.0); rmSetAreaElevationOctaves(ForestID, 3); rmSetAreaObeyWorldCircleConstraint(ForestID, false); rmAddAreaConstraint(ForestID, avoidTownCenter); rmAddAreaConstraint(ForestID, avoidAllFar); rmBuildArea(ForestID); }
rmSetStatusText("",1.00);//读取地图进度条 //愿神兽会保佑你不会出错。 /*----------------------------------------------------------------------------------------------* *    ┏┓   ┏┓ * *   ┏┛┻━━━┛┻┓ * *   ┃       ┃ * *   ┃   ━   ┃ * *   ┃ ┳┛ ┗┳ ┃ * *   ┃       ┃ * *   ┃   ┻   ┃ * *   ┃       ┃ * *   ┗━┓   ┏━┛ Code is far away from bug with the animal protecting * *     ┃   ┃ * *     ┃   ┃ * *     ┃   ┃ * *     ┃   ┃ * *     ┃   ┃ * *     ┃   ┗━━━┓ * *     ┃       ┣┓ * *     ┃       ┏┛ * *     ┗┓┓┏━┳┓┏┛ * *      ┃┫┫ ┃┫┫ * *      ┗┻┛ ┗┻┛ * *----------------------------------------------------------------------------------------------*/ } //END



可以看见森林避开了所有单位,但是却延伸到湖里了,这是因为使用rmSetAreaBaseHeight设定高度,把这句删除或者设定0.0就不会影响到湖了。如果你想保留这个高度,又不想影响到水域可以用放置规则避开水域。 例如rmCreateTerrainDistanceConstraint("avoid Lake Min", "water", true, 12.0); 你在上面的文本框搜索一下avoidWaterMin吧,之前已经设定过了,调用就可以。 最后修改如下:
  Debug.xs - 记事本 ____ X
文件(F)  编辑(E)  格式(O)  查看(V)  帮助(H)
	include "mercenaries.xs";



		int avoidWaterMin = rmCreateTerrainDistanceConstraint("avoid Lake Min", "water", true, 12.0);

此处省略576行语句

//从制作一张好地图的角度上来说,我是不推荐只用一个avoidAll的,你看看别的地图用了多少放置限制?而你只用一个,这效果能不差吗

//设定与隐藏标签(All即为所有单位)最小间隔距离10 int avoidAllFar = rmCreateTypeDistanceConstraint("avoids All Unit far", "All", 10.0); int avoidTownCenter = rmCreateTypeDistanceConstraint("avoid Town Center", "townCenter", 25.0); //避开边缘 int avoidEdge = rmCreatePieConstraint("Avoid Edge",0.5,0.5, rmXFractionToMeters(0.0),rmXFractionToMeters(0.48), rmDegreesToRadians(0),rmDegreesToRadians(360)); for(f=1; <cNumberPlayers*3)//for循环不一定是i,只要不是数字弄什么值都可以。 { int ForestID=rmCreateArea("Forest ID Area"+f); //这森林数量不够再加3个 rmSetAreaSize(ForestID, rmAreaTilesToFraction(500), rmAreaTilesToFraction(500)); rmSetAreaForestType(ForestID, "California Redwood Forest"); rmSetAreaForestClumpiness(ForestID, 0.80); rmSetAreaForestDensity(ForestID, 0.70); rmSetAreaForestUnderbrush(ForestID, 0.00); rmSetAreaWarnFailure(ForestID, true); rmSetAreaSmoothDistance(ForestID, 0); rmSetAreaCoherence(ForestID, 0.0); rmSetAreaBaseHeight(ForestID, 4.0); rmSetAreaElevationOctaves(ForestID, 3); rmSetAreaObeyWorldCircleConstraint(ForestID, false); rmAddAreaConstraint(ForestID, avoidTownCenter); rmAddAreaConstraint(ForestID, avoidAllFar); rmAddAreaConstraint(ForestID, avoidWaterMin); rmAddAreaConstraint(ForestID, avoidEdge); rmBuildArea(ForestID); }
rmSetStatusText("",1.00);//读取地图进度条 //愿神兽会保佑你不会出错。 /*----------------------------------------------------------------------------------------------* *    ┏┓   ┏┓ * *   ┏┛┻━━━┛┻┓ * *   ┃       ┃ * *   ┃   ━   ┃ * *   ┃ ┳┛ ┗┳ ┃ * *   ┃       ┃ * *   ┃   ┻   ┃ * *   ┃       ┃ * *   ┗━┓   ┏━┛ Code is far away from bug with the animal protecting * *     ┃   ┃ * *     ┃   ┃ * *     ┃   ┃ * *     ┃   ┃ * *     ┃   ┃ * *     ┃   ┗━━━┓ * *     ┃       ┣┓ * *     ┃       ┏┛ * *     ┗┓┓┏━┳┓┏┛ * *      ┃┫┫ ┃┫┫ * *      ┗┻┛ ┗┻┛ * *----------------------------------------------------------------------------------------------*/ } //END


森林已经避开水域了。 虽然是随意制作的地图,不过最后的效果也差不多了。我觉得不行.jpg 本次教程结束。