创建单位。



我们已经创建了一副空白地图了,那么现在来创建资源单位吧。

rmCreateObjectDef(string name): Creates an object definition. rmAddObjectDefItem(int defID, string unitName, int count, float clusterDistance): Add item to object definition. rmSetObjectDefMinDistance(int defID, float dist): Set the minimum distance for the object definition (in meters). rmSetObjectDefMaxDistance(int defID, float dist): Set the maximum distance for the object definition (in meters). rmPlaceObjectDefAtLoc(int defID, int playerID, float xFraction, float zFraction, int placeCount): Place object definition at specific location for given player. rmAddObjectDefConstraint(int defID, int constraintID): Add specified constraint to given object def.

我知道你是看不懂英文的

int AXXXX = rmCreateObjectDef("XXXXX");创建目标,定义名称,这个名称不能有相同的,否则都会变成单位都会第一个出现的定义单位。 rmAddObjectDefItem(AXXXX, "protoname", 数量, 生成1组的范围【如果为0,即使你设定数量为100都只能放置一个,一般6-12足够使用】); rmSetObjectDefMinDistance(AXXXX,最小定位可偏移距离,即为中心点位置偏移); rmSetObjectDefMaxDistance(AXXXX,最大定位可偏移距离,即为中心点位置偏移); rmPlaceObjectDefAtLoc(AXXXX, 玩家ID, X坐标, Z坐标, 放置数量【与上面的数量不一样,上面的数量是这个的子集,例如上面是2,这里是3,那么总共是6个,2个一组】); rmAddObjectDefConstraint(AXXXX,已用int定义的规则)

//这个是创建单位的模板:

int Unit1ID = rmCreateObjectDef("Unit1"); rmAddObjectDefItem(Unit1ID, "protoname",1,5.0); rmSetObjectDefMinDistance(Unit1ID,0.0); rmSetObjectDefMaxDistance(Unit1ID,30.0); rmPlaceObjectDefAtLoc(Unit1ID,0,0.50,0.50,1);

//猎物多了个rmSetObjectDefCreateHerd(Hred1ID,true);作用是受到伤害后会跑

int Hred1ID = rmCreateObjectDef("Hred1"); rmAddObjectDefItem(Hred1ID, "protoname",1,5.0); rmSetObjectDefMinDistance(Hred1ID,0.0); rmSetObjectDefMaxDistance(Hred1ID,30.0); rmSetObjectDefCreateHerd(Hred1ID,true); rmPlaceObjectDefAtLoc(Hred1ID,0,0.50,0.50,1);



下面我要在地图中心给大自然创建一个超级大炮:传送门

  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);//读取地图进度条



		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第二个值为被放置玩家对象,这里使用了for循环,循环值=1,<=玩家人数,所以会放置所有玩家的城镇中心。
			rmPlaceObjectDefAtLoc(TownCenterID, i, rmPlayerLocXFraction(i), rmPlayerLocZFraction(i));
		}


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

		for(i=1; <=cNumberNonGaiaPlayers)
		{
			//我暂时只能告诉你这个是调用城镇中心坐标,不解释太多,解释太多你听不懂。另外留意下for(i=1;<=xx){},这是是c++的一种循环格式。
			vector TCLocation = rmGetUnitPosition(rmGetUnitPlacedOfPlayer(TownCenterID, i));

			//放置起始单位
			rmPlaceObjectDefAtLoc(startingUnits, i, rmXMetersToFraction(xsVectorGetX(TCLocation)), rmZMetersToFraction(xsVectorGetZ(TCLocation)));
		}
		
		
		int FixedGunID = rmCreateObjectDef("FixedGun");
		rmAddObjectDefItem(FixedGunID, "SPCFixedGun",1,5.0);
		rmSetObjectDefMinDistance(FixedGunID,0.0);
		rmSetObjectDefMaxDistance(FixedGunID,30.0);
		rmPlaceObjectDefAtLoc(FixedGunID,0,0.50,0.50,1);
		//rmPlaceObjectDefAtLoc(FixedGunID,玩家ID等于大自然,(0.5,0.5就是地图中心),1组);放心复制吧,颜色不会影响到复制
		//你留意到橙色与绿色字体了吗?橙色是创建目标定义的名称,不能出现重复绿色是单位调用名必须加英文双引号""
		



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





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


					//愿神兽会保佑你不会出错。
 			/*----------------------------------------------------------------------------------------------*
			*    ┏┓   ┏┓										*
			*   ┏┛┻━━━┛┻┓									*
			*   ┃       ┃									*
			*   ┃   ━   ┃									*
			*   ┃ ┳┛ ┗┳ ┃									*
			*   ┃       ┃									*
			*   ┃   ┻   ┃									*
			*   ┃       ┃									*
			*   ┗━┓   ┏━┛     Code is far away from bug with the animal protecting		*
			*     ┃   ┃    									*
			*     ┃   ┃										*
			*     ┃   ┃										*
			*     ┃   ┃										*
			*     ┃   ┃										*
			*     ┃   ┗━━━┓									*
			*     ┃       ┣┓									*
			*     ┃       ┏┛									*
			*     ┗┓┓┏━┳┓┏┛									*
			*      ┃┫┫ ┃┫┫									*
			*      ┗┻┛ ┗┻┛									*
			*----------------------------------------------------------------------------------------------*/
	} //END








创建一个超级大炮已经成功了,下面来创建玩家附近资源。
我给每个玩家创建了10只大象,传送门
  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);//读取地图进度条



		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第二个值为被放置玩家对象,这里使用了for循环,循环值=1,<=玩家人数,所以会放置所有玩家的城镇中心。
			rmPlaceObjectDefAtLoc(TownCenterID, i, rmPlayerLocXFraction(i), rmPlayerLocZFraction(i));
		}


		//定义起始单位(civs.xml定义那些开局单位)
		int startingUnits = rmCreateStartingUnitsObjectDef(5.0);
		rmSetObjectDefMinDistance(startingUnits, 6.0);
		rmSetObjectDefMaxDistance(startingUnits, 10.0);
		
		
		int playerherdID = rmCreateObjectDef("starting herd");
		rmAddObjectDefItem(playerherdID, "ypWildElephant", 10, 6.0);
		rmSetObjectDefMinDistance(playerherdID, 8.0);
		rmSetObjectDefMaxDistance(playerherdID, 12.0);
		rmSetObjectDefCreateHerd(playerherdID, true);
		
		for(i=1; <=cNumberNonGaiaPlayers)
		{
			//我暂时只能告诉你这个是调用城镇中心坐标,不解释太多,解释太多你听不懂。另外留意下for(i=1;<=xx){},这是是c++的一种循环格式。
			vector TCLocation = rmGetUnitPosition(rmGetUnitPlacedOfPlayer(TownCenterID, i));

			//放置起始单位
			rmPlaceObjectDefAtLoc(startingUnits, i, rmXMetersToFraction(xsVectorGetX(TCLocation)), rmZMetersToFraction(xsVectorGetZ(TCLocation)));
			rmPlaceObjectDefAtLoc(playerherdID, i, rmXMetersToFraction(xsVectorGetX(TCLocation)), rmZMetersToFraction(xsVectorGetZ(TCLocation)));
		}
		//你可能看不懂for(i)下面的vector TCLocation;我现在可以告诉你这是获取地图上已有单位的X、Y、Z坐标,格式是(X,Y,Z);然后xsVectorGetX(TCLocation)将TCLocation的(X,Y,Z)坐标变成单个X坐标,同理xsVectorGetZ(TCLocation)转变成Z坐标;然后rmXMetersToFraction又把转变后的坐标转换成地图坐标(0.5,0.5那种)。至于那个i,就是c++中for循环的变量了:for(i=1; <=cNumberNonGaiaPlayers),循环值等于1,<=不计算大自然玩家的总玩家数,假设不计算大自然后的玩家人数等于3,第一次执行的i值为1,第二次循环又会执行相同的语句,此时i值变成1+1;第三次循i值变成1+1+1,所以就给3个玩家都创建了单位。
		
		int FixedGunID = rmCreateObjectDef("FixedGun");
		rmAddObjectDefItem(FixedGunID, "SPCFixedGun",1,5.0);
		rmSetObjectDefMinDistance(FixedGunID,0.0);
		rmSetObjectDefMaxDistance(FixedGunID,30.0);
		rmPlaceObjectDefAtLoc(FixedGunID,0,0.50,0.50,1);
		//rmPlaceObjectDefAtLoc(FixedGunID,玩家ID等于大自然,(0.5,0.5就是地图中心),1组);放心复制吧,颜色不会影响到复制
		
		



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





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


					//愿神兽会保佑你不会出错。
 			/*----------------------------------------------------------------------------------------------*
			*    ┏┓   ┏┓										*
			*   ┏┛┻━━━┛┻┓									*
			*   ┃       ┃									*
			*   ┃   ━   ┃									*
			*   ┃ ┳┛ ┗┳ ┃									*
			*   ┃       ┃									*
			*   ┃   ┻   ┃									*
			*   ┃       ┃									*
			*   ┗━┓   ┏━┛     Code is far away from bug with the animal protecting		*
			*     ┃   ┃    									*
			*     ┃   ┃										*
			*     ┃   ┃										*
			*     ┃   ┃										*
			*     ┃   ┃										*
			*     ┃   ┗━━━┓									*
			*     ┃       ┣┓									*
			*     ┃       ┏┛									*
			*     ┗┓┓┏━┳┓┏┛									*
			*      ┃┫┫ ┃┫┫									*
			*      ┗┻┛ ┗┻┛									*
			*----------------------------------------------------------------------------------------------*/
	} //END







给创建每个玩家创建10只大象已经成功,那么其他资源你可以自己完成了吧?传送门


  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);//读取地图进度条



		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第二个值为被放置玩家对象,这里使用了for循环,循环值=1,<=玩家人数,所以会放置所有玩家的城镇中心。
			rmPlaceObjectDefAtLoc(TownCenterID, i, rmPlayerLocXFraction(i), rmPlayerLocZFraction(i));
		}


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

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

		
		
		int playergoldID = rmCreateObjectDef("player mine");
		rmAddObjectDefItem(playergoldID, "Minegold", 1, 6);
		rmSetObjectDefMinDistance(playergoldID, 18.0);
		rmSetObjectDefMaxDistance(playergoldID, 22.0);

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

		int playerTree1ID = rmCreateObjectDef("player trees");
		rmAddObjectDefItem(playerTree1ID, PlayerTreeType, PlayerTreeCount, 8.0);
		rmSetObjectDefMinDistance(playerTree1ID, 6);
		rmSetObjectDefMaxDistance(playerTree1ID, 12);

		//不是说绿色字体的单位调用名必须加英文双引号吗,为什么上面的PlayerTreeType没有双引号?因为我在前面用string定义了PlayerTreeType ="TreeRedwood";,所以PlayerTreeType会转变成"TreeRedwood"。(PS:带双引号的必须用string定义,不能用int。)
		//另外你看见PlayerTreeCount没?那里原本是单位数量,被我改成了PlayerTreeCount,像上面PlayerTreeType一样;需要先用int定义(因为没有双引号所以用int),然后PlayerTreeCount会转变成定义的数值8,所以就是开局8棵树了。



		int playerBerryID=rmCreateObjectDef("player berries");
		rmAddObjectDefItem(playerBerryID, "BerryBush", rmRandInt(3,4), 3.0);
		rmSetObjectDefMinDistance(playerBerryID, 12);
		rmSetObjectDefMaxDistance(playerBerryID, 14);
		//看见rmRandInt(3,4)了吗,这是随机数,rmRandInt会随机返回两个数值中的一个数值。也就是说会随机出现3个浆果丛或4个浆果丛。

		

		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)));
		}
		
		int FixedGunID = rmCreateObjectDef("FixedGun");
		rmAddObjectDefItem(FixedGunID, "SPCFixedGun",1,5.0);
		rmSetObjectDefMinDistance(FixedGunID,0.0);
		rmSetObjectDefMaxDistance(FixedGunID,30.0);
		rmPlaceObjectDefAtLoc(FixedGunID,0,0.50,0.50,1);
		//rmPlaceObjectDefAtLoc(FixedGunID,玩家ID等于大自然,(0.5,0.5就是地图中心),1组);放心复制吧,颜色不会影响到复制
		



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





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


					//愿神兽会保佑你不会出错。
 			/*----------------------------------------------------------------------------------------------*
			*    ┏┓   ┏┓										*
			*   ┏┛┻━━━┛┻┓									*
			*   ┃       ┃									*
			*   ┃   ━   ┃									*
			*   ┃ ┳┛ ┗┳ ┃									*
			*   ┃       ┃									*
			*   ┃   ┻   ┃									*
			*   ┃       ┃									*
			*   ┗━┓   ┏━┛     Code is far away from bug with the animal protecting		*
			*     ┃   ┃    									*
			*     ┃   ┃										*
			*     ┃   ┃										*
			*     ┃   ┃										*
			*     ┃   ┃										*
			*     ┃   ┗━━━┓									*
			*     ┃       ┣┓									*
			*     ┃       ┏┛									*
			*     ┗┓┓┏━┳┓┏┛									*
			*      ┃┫┫ ┃┫┫									*
			*      ┗┻┛ ┗┻┛									*
			*----------------------------------------------------------------------------------------------*/
	} //END














你知道为什么ESOC地图的开局资源分布比官方制作的地图要平衡吗?因为官方地图设定的是中心点利用规则自动计算并且放置,而ESOC地图设定了两个矿场、两个肉群都是跟随城镇中心一起放置的(像上面的教程一样)。只不过最小放置距离设置得有点大,所以看不出来是跟随城镇中心放置的。传送门


  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);//读取地图进度条



		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));
		}


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

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

		int playergoldID = rmCreateObjectDef("player mine");
		rmAddObjectDefItem(playergoldID, "Minegold", 1, 6);
		rmSetObjectDefMinDistance(playergoldID, 18.0);
		rmSetObjectDefMaxDistance(playergoldID, 22.0);

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

		int playerTree1ID = rmCreateObjectDef("player trees");
		rmAddObjectDefItem(playerTree1ID, PlayerTreeType, PlayerTreeCount, 8.0);
		rmSetObjectDefMinDistance(playerTree1ID, 6);
		rmSetObjectDefMaxDistance(playerTree1ID, 12);

		



		int playerBerryID=rmCreateObjectDef("player berries");
		rmAddObjectDefItem(playerBerryID, "BerryBush", rmRandInt(3,4), 3.0);
		rmSetObjectDefMinDistance(playerBerryID, 12);
		rmSetObjectDefMaxDistance(playerBerryID, 14);
		

		
		
		
		int playerHerd2ID = rmCreateObjectDef("player Herd2");
		rmAddObjectDefItem(playerHerd2ID, "Bison", rmRandInt(10,11), 10.0);
		rmSetObjectDefMinDistance(playerHerd2ID, 36);
		rmSetObjectDefMaxDistance(playerHerd2ID, 38);
		rmSetObjectDefCreateHerd(playerHerd2ID, true);



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



		int playergold2ID = rmCreateObjectDef("player second mine");
		rmAddObjectDefItem(playergold2ID, "mine", 1, 0);
		rmSetObjectDefMinDistance(playergold2ID, 58.0);
		rmSetObjectDefMaxDistance(playergold2ID, 62.0);
		

		
		int playergold3ID = rmCreateObjectDef("player third mine");
		rmAddObjectDefItem(playergold3ID, "mine", 1, 0);
		rmSetObjectDefMinDistance(playergold3ID, 68.0);
		rmSetObjectDefMaxDistance(playergold3ID, 70.0);

		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 FixedGunID = rmCreateObjectDef("FixedGun");
		rmAddObjectDefItem(FixedGunID, "SPCFixedGun",1,5.0);
		rmSetObjectDefMinDistance(FixedGunID,0.0);
		rmSetObjectDefMaxDistance(FixedGunID,30.0);
		rmPlaceObjectDefAtLoc(FixedGunID,0,0.50,0.50,1);
		//rmPlaceObjectDefAtLoc(FixedGunID,玩家ID等于大自然,(0.5,0.5就是地图中心),1组);放心复制吧,颜色不会影响到复制
		



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





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


					//愿神兽会保佑你不会出错。
 			/*----------------------------------------------------------------------------------------------*
			*    ┏┓   ┏┓										*
			*   ┏┛┻━━━┛┻┓									*
			*   ┃       ┃									*
			*   ┃   ━   ┃									*
			*   ┃ ┳┛ ┗┳ ┃									*
			*   ┃       ┃									*
			*   ┃   ┻   ┃									*
			*   ┃       ┃									*
			*   ┗━┓   ┏━┛     Code is far away from bug with the animal protecting		*
			*     ┃   ┃    									*
			*     ┃   ┃										*
			*     ┃   ┃										*
			*     ┃   ┃										*
			*     ┃   ┃										*
			*     ┃   ┗━━━┓									*
			*     ┃       ┣┓									*
			*     ┃       ┏┛									*
			*     ┗┓┓┏━┳┓┏┛									*
			*      ┃┫┫ ┃┫┫									*
			*      ┗┻┛ ┗┻┛									*
			*----------------------------------------------------------------------------------------------*/
	} //END





这效果是不是有点差了?不是有点差,完全就是不及格。两个银矿、肉群都放在一起了。那么应该如何分开这些资源呢?这时候就要使用放置限制了(也可以叫放置规则),语句为rmAddObjectDefConstraint(int defID, int constraintID): Add specified constraint to given object def.。

只要出现命令表的(英文)内容你就头疼了吧?





首先,先用int 定义“限制”,可使用的限制语句如下:


-----------------------------------------------------------------------------------------------------------------------------
创建与某areaID最小间隔距离限制:
[(int   )] rmCreateAreaDistanceConstraint(string name, int areaID, float distance): Make an area distance constraint. 

创建与某areaID最大间隔距离限制:
[(int   )] rmCreateAreaMaxDistanceConstraint(string name, int areaID, float distance): Make an area max distance constraint. 

areaID就是用int定义的TownCenterID、playerherdID、playerTree1ID,不用管命令表的areaID、defID、riverID,只要是绘制地形、创建河流、放置单位、放置群组,全部都属于areaID,又或者说都可以用于rmCreateAreaDistanceConstraint与rmCreateAreaMaxDistanceConstraint  
-----------------------------------------------------------------------------------------------------------------------------

创建正方形限制
[(int   )] rmCreateBoxConstraint(string name, float startX, float startZ, float endX, float endZ, float bufferFraction): Make a box constraint. 


-----------------------------------------------------------------------------------------------------------------------------
创建与某class最小间隔距离限制
[(int   )] rmCreateClassDistanceConstraint(string name, int classID, float distance): Make a class distance constraint.

需要先用rmDefineClass("xxx")定义class,然后用语句将class加入到areaID、defID、riverID里面。
-----------------------------------------------------------------------------------------------------------------------------

创建与某个Unittype最小间隔距离限制(注:命令表可能有错,命令表写的是int classID,实际上是使用string Unittype)
rmCreateTypeDistanceConstraint(string name, string Unittype, float distance): Make a type distance constraint.

创建与某贸易路线最小间隔距离限制
rmCreateTradeRouteDistanceConstraint(string name, float minDistance): Make a constraint to avoid trade routes.

我就列举这几个限制,其实还有很多,自己去RM命令表查找


上面说了那么多,下面来创建限制吧。





你知道为什么ESOC地图的开局资源分布比官方制作的地图要平衡吗?因为官方地图设定的是中心点利用规则自动计算并且放置,而ESOC地图设定了两个矿场、两个肉群都是跟随城镇中心一起放置的(像上面的教程一样)。只不过最小放置距离设置得有点大,所以看不出来是跟随城镇中心放置的。
定义Class传送门     添加Class与放置限制到单位传送门


  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);//读取地图进度条

		//定义class
		int classStartingResource = rmDefineClass("startingResource");	//这个用作开局城镇资源
		int PlayerHerd2Class = rmDefineClass("PlayerHerd2C");		//这个用作玩家第二肉群
		int classGold = rmDefineClass("Gold");				//这个用作矿场


		//定义放置限制/规则【顺便说一句,如果存在两个相同限制/规则名称(不是说int后面那个,如果int出现两个相同你连地图都无法打开,我说的是带英文双引号那个""),只会执行第一个,另一个会失效,甚至会引发毁图效果】
		//定义avoidGold,并且设定距离Class“Gold”最小间隔距离为50
		int avoidGold = rmCreateClassDistanceConstraint ("avoid gold", rmClassID("Gold"), 50.0);

		//定义avoidPlayerHerd2Far,并且设定距离Class“PlayerHerd2C”最小间隔距离为50
		int avoidPlayerHerd2Far = rmCreateClassDistanceConstraint("avoid Player Herd2 far", rmClassID("PlayerHerd2C"), 52.0);

		//同理,不再解释。
		int avoidStartingResources = rmCreateClassDistanceConstraint("start resources avoid each other2", rmClassID("startingResource"), 4.0);
		
		


		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));
		}


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


int playerherdID = rmCreateObjectDef("starting herd"); rmAddObjectDefItem(playerherdID, "ypWildElephant", 10, 6.0); rmSetObjectDefMinDistance(playerherdID, 8.0); rmSetObjectDefMaxDistance(playerherdID, 12.0); rmSetObjectDefCreateHerd(playerherdID, true); //定义到到Class“startingResource”中,你往上搜索classStartingResource,我们有定义过的,当然你也可以直接在这里使用rmDefineClass("startingResource") rmAddObjectDefToClass(playerherdID, classStartingResource); //使用avoidStartingResources放置限制,也就是说距离Class“startingResource”最小间隔距离为4. rmAddObjectDefConstraint(playerherdID, avoidStartingResources); int playergoldID = rmCreateObjectDef("player mine"); rmAddObjectDefItem(playergoldID, "Minegold", 1, 6); rmSetObjectDefMinDistance(playergoldID, 18.0); rmSetObjectDefMaxDistance(playergoldID, 22.0); rmAddObjectDefToClass(playergoldID, rmDefineClass("startingResource")); //可以直接使用rmDefineClass("startingResource") rmAddObjectDefToClass(playergoldID, classGold); rmAddObjectDefConstraint(playergoldID, avoidStartingResources); 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); 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); 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); 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); //然后第三个肉群就会避开第二个肉群了 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); 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);
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 FixedGunID = rmCreateObjectDef("FixedGun"); rmAddObjectDefItem(FixedGunID, "SPCFixedGun",1,5.0); rmSetObjectDefMinDistance(FixedGunID,0.0); rmSetObjectDefMaxDistance(FixedGunID,30.0); rmPlaceObjectDefAtLoc(FixedGunID,0,0.50,0.50,1); rmSetStatusText("",0.50);//读取地图进度条 rmSetStatusText("",1.00);//读取地图进度条 //愿神兽会保佑你不会出错。 /*----------------------------------------------------------------------------------------------* *    ┏┓   ┏┓ * *   ┏┛┻━━━┛┻┓ * *   ┃       ┃ * *   ┃   ━   ┃ * *   ┃ ┳┛ ┗┳ ┃ * *   ┃       ┃ * *   ┃   ┻   ┃ * *   ┃       ┃ * *   ┗━┓   ┏━┛ Code is far away from bug with the animal protecting * *     ┃   ┃ * *     ┃   ┃ * *     ┃   ┃ * *     ┃   ┃ * *     ┃   ┃ * *     ┃   ┗━━━┓ * *     ┃       ┣┓ * *     ┃       ┏┛ * *     ┗┓┓┏━┳┓┏┛ * *      ┃┫┫ ┃┫┫ * *      ┗┻┛ ┗┻┛ * *----------------------------------------------------------------------------------------------*/ } //END





使用的放置限制只有几个,不过效果也差不多了,如果你真的想做一幅较好的地图,自己用心去多设定几个放置限制。


最后来设定以中心点放置的资源吧:这次我不使用class了,直接用单位标签就行
定义限制传送门     中心点创建资源传送门
  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);//读取地图进度条

		//定义class
		int classStartingResource = rmDefineClass("startingResource");	//这个用作开局城镇资源
		int PlayerHerd2Class = rmDefineClass("PlayerHerd2C");		//这个用作玩家第二肉群
		int classGold = rmDefineClass("Gold");				//这个用作矿场


		//定义放置限制/规则【顺便说一句,如果存在两个相同限制/规则名称(不是说int后面那个,如果int出现两个相同你连地图都无法打开,我说的是带英文双引号那个""),只会执行第一个,另一个会失效,甚至会引发毁图效果】

		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);
		
		
		//与所有带有gold标签的单位最小间隔距离为45
		int avoidGoldTypeFar = rmCreateTypeDistanceConstraint("coin avoids coin far ", "gold", 45.0);

		//与所有带有herd标签的单位最小间隔距离为45
		int avoidHerdTypeFar = rmCreateTypeDistanceConstraint("herd avoids herd far", "herd", 45.0);

		//与所有带有Tree标签的单位最小间隔距离为25
		int avoidTreeType = rmCreateTypeDistanceConstraint("Tree avoids Tree  ", "Tree", 25.0);
		


		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));
		}


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



		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);




		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);

		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);



		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);
		
		
		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);



		
		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);



		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);
		

		
		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);

		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 FixedGunID = rmCreateObjectDef("FixedGun");
		rmAddObjectDefItem(FixedGunID, "SPCFixedGun",1,5.0);
		rmSetObjectDefMinDistance(FixedGunID,0.0);
		rmSetObjectDefMaxDistance(FixedGunID,30.0);
		rmPlaceObjectDefAtLoc(FixedGunID,0,0.50,0.50,1);
		



//列举三种创建多组单位方式

//第一种:通过使用for循环全部语句创建多组单位,此方法执行效率最低,应尽量少用

for(i=0; <= cNumberNonGaiaPlayers*3) { int goldID = rmCreateObjectDef("gold"+i); //由于不能出现相同的名称,所以for循环给名称加上循环值很重要,不然会导致只会生成一组单位。 rmAddObjectDefItem(goldID, "mine", 1, 0.0); rmSetObjectDefMinDistance(goldID, rmXFractionToMeters(0.0)); //这里设定最大距离为rmXFractionToMeters(0.5),(从中心点0.5,0.5算起)即为全图 rmSetObjectDefMaxDistance(goldID, rmXFractionToMeters(0.5)); rmAddObjectDefToClass(goldID, classGold); rmAddObjectDefConstraint(goldID, avoidGoldTypeFar); //矿场与矿场之间间隔45 rmPlaceObjectDefAtLoc(goldID, 0, 0.50, 0.50); //最后面没有设定数量,默认为1组 } //假设cNumberNonGaiaPlayers=2,求最后循环的数量? //你的回答是? 6? 7? //正确答案是7,因为这里是i=0;所以本身就包括0,然后是1、2、3、4、5、6;合计等于7

//第二种:通过使用for循环最后一句“放置单位”来创建多组单位

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); //猎物与猎物间隔45 for(i=1; <= cNumberNonGaiaPlayers*3) { rmPlaceObjectDefAtLoc(CenterHerdID, 0, 0.50, 0.50); //只循环这一句,无需加循环值 } //假设cNumberNonGaiaPlayers=2,求最后循环的数量? //你的回答是? 6? 7? //正确答案是6,因为这里是i=1;每次循环+1,第一次循环为1,最终结果是1、2、3、4、5、6

//第三种,直接在最后一句“放置单位”那里设定多组

int GreenForestTreeObjectID = rmCreateObjectDef("Object Green forest trees"); rmAddObjectDefItem(GreenForestTreeObjectID, "TreeRedwood", 8, 15); rmAddObjectDefItem(GreenForestTreeObjectID, "TreeRedwood", 3, 5); rmAddObjectDefItem(GreenForestTreeObjectID, "UnderbrushCalifornia", 3, 10); rmSetObjectDefMinDistance(GreenForestTreeObjectID, rmXFractionToMeters(0.0)); rmSetObjectDefMaxDistance(GreenForestTreeObjectID, rmXFractionToMeters(0.47)); rmAddObjectDefConstraint(GreenForestTreeObjectID, avoidTreeType); //树木与树木间隔25 rmPlaceObjectDefAtLoc(GreenForestTreeObjectID, 0, 0.50, 0.50, cNumberNonGaiaPlayers*20); rmSetStatusText("",0.50);//读取地图进度条 rmSetStatusText("",1.00);//读取地图进度条 //愿神兽会保佑你不会出错。 /*----------------------------------------------------------------------------------------------* *    ┏┓   ┏┓ * *   ┏┛┻━━━┛┻┓ * *   ┃       ┃ * *   ┃   ━   ┃ * *   ┃ ┳┛ ┗┳ ┃ * *   ┃       ┃ * *   ┃   ┻   ┃ * *   ┃       ┃ * *   ┗━┓   ┏━┛ Code is far away from bug with the animal protecting * *     ┃   ┃ * *     ┃   ┃ * *     ┃   ┃ * *     ┃   ┃ * *     ┃   ┃ * *     ┃   ┗━━━┓ * *     ┃       ┣┓ * *     ┃       ┏┛ * *     ┗┓┓┏━┳┓┏┛ * *      ┃┫┫ ┃┫┫ * *      ┗┻┛ ┗┻┛ * *----------------------------------------------------------------------------------------------*/ } //END




最后的效果还不是很好,这是地图因为有点大,资源群组数太少、资源间隔限制太小,如果你真的像做一幅好一点的地图,就用心去多设定十几条条放置限制,合理调整资源发布。



本次教程结束。