创建单位。




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

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




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



本次教程结束。