地图触发


地图可以像剧情编辑器那样添加触发程序,不过非常复杂,特别是台海战争那幅1V1地图,用触发设定AI刷兵、占领超级大炮我用了7天时间写上20个触发,地图触发的语句已经占了三分之二,不说那么多了,下面来看下三个触发程序的写法吧。:

1:旧版触发程序

. .. ... .... ..... ...... 太久没有使用这种旧版触发了,忘记怎样语句是怎样写的了。 幸好孙百里是用旧版本触发程序的,所以台海战争有他设定的旧版本触发程序: rmCreateTrigger("string triggerName"); //设定触发程序名称 rmSwitchToTrigger(rmTriggerID("string triggerName")); //开启某触发程序 rmSetTriggerPriority(3); //优先级 rmSetTriggerActive(true); //设定是否作用中,false为关闭状态 rmSetTriggerRunImmediately(true); //设定是否立即运行,false为开局5秒后才允许 rmSetTriggerLoop(false); //设定是否无限循环本触发,false为只执行一次 rmAddTriggerCondition("string conditionType"); //设定条件,必须与游戏目录的trigger3文件夹里面的typetest.xml文件中的Condition name=""对应 rmSetTriggerConditionParamInt("string paramName", int value, false); //设定条件内容,paramName必须与条件名称在同一个触发,与typetest.xml的Param name=""对应,typetest.xml那个条件有多少个选项你就添加多少句,注意Int只能填数字,不加Int,第二个值要加英文双引号 rmSetTriggerConditionParam("string paramName", "string value", false); //同上 rmAddTriggerEffect("string effectType"); //设定效果,必须与游戏目录的trigger3文件夹里面的typetest.xml文件中的Effect name=""对应 rmSetTriggerEffectParamInt("string paramName", int value, false); //设定效果内容,paramName必须与条件名称在同一个触发,与typetest.xml的Param name=""对应,typetest.xml那个效果有多少个选项你就添加多少句,注意Int只能填数字,不加Int,第二个值要加英文双引号 rmSetTriggerEffectParam("string paramName", "string value", false); //同上
模板: rmCreateTrigger("string triggerName"); rmSwitchToTrigger(rmTriggerID("string triggerName")); rmSetTriggerPriority(3); rmSetTriggerActive(true); rmSetTriggerRunImmediately(true); rmSetTriggerLoop(false); rmAddTriggerCondition("string conditionType"); rmSetTriggerConditionParamInt("string paramName", int value, false); rmSetTriggerConditionParam("string paramName", "string value", false); rmAddTriggerEffect("string effectType"); rmSetTriggerEffectParamInt("string paramName", int value, false); rmSetTriggerEffectParam("string paramName", "string value", false);
优点:官方设定的触发程序,除此之外没有优点。 缺点: 1.体积庞大。 2.受typetest.xml限制,所有string conditionType、string effectType、string paramName必须与typetest.xml的设定对应。存在中文路径无法运行。 3.存在中文路径的帝国3目录将无法运行,联机会与非中文路径的不同步。 4.大部分涉及玩家ID的触发无法输出0,即为不能设定为对大自然起作用。 5.自定义触发需要自己修改trigger3文件夹里面的xml文件,不能与没有修改过的玩家联机,(其实可以算是不能自定义触发程序了)。 样板:在TaiwanStrait(台湾海峡)地图能找到类似触发程序。

           

2:ESOC UI2.2地图开创的C++脚本触发程序

这是由大佬改写的,可以作为正常的触发程序使用: 条件:首先必须在地图的void main(void)前面添加以下语句:
void oxy(string xs="") { rmAddTriggerEffect("SetIdleProcessing"); rmSetTriggerEffectParam("IdleProc", "false); */ "+xs+" /* "); } void oxyA(string xs="") { rmAddTriggerEffect("SetIdleProcessing"); rmSetTriggerEffectParam("IdleProc", "false); "+xs+"/* trSetUnitIdleProcessing(false"); } void oxyZ(string xs="") { rmAddTriggerEffect("SetIdleProcessing"); rmSetTriggerEffectParam("IdleProc", "false); */ "+xs+" trSetUnitIdleProcessing(false"); }
然后在你需要在输入触发程序的地方输入
rmCreateTrigger("GamestartInit"); rmSwitchToTrigger(rmTriggerID("GamestartInit")); rmSetTriggerRunImmediately(true); oxyA("}}"); //---------在下面输入规则(触发),旧版本触发程序会输出类似下面的规则,输出的名称叫rule _触发程序名-------- //----可以无限添加规则---------- oxy("rule _Debug active runImmediately { "); oxy("if((trTime()-cActivationTime) >= 1.00000000){"); oxy("trChatSendSpoofed(0,\"QQ Group : 85442352\");"); oxy("xsDisableRule(\"_Debug\");"); oxyZ("}} /*"); oxy("rule _Debug2 active runImmediately { "); //rule _后面的文字相当于旧版触发程序的触发名称 oxy("if((trTime()-cActivationTime) >= 1.00000000){"); oxy("trChatSendSpoofed(0,\"QQ Group : 85442352\");"); oxy("xsDisableRule(\"_Debug2\");"); oxyZ("}} /*"); oxy("rule _Debug3 active runImmediately { "); //active代表作用中,改成inactive就变成关闭状态 oxy("if((trTime()-cActivationTime) >= 1.00000000){"); oxy("trChatSendSpoofed(0,\"QQ Group : 85442352\");"); oxy("xsDisableRule(\"_Debug3\");"); oxyZ("}} /*"); //-------------------规则必须在上面添加------------ //触发程序结尾,所有规则必须在上面添加,超出此处将无效。 oxy("rule _Temp inactive { if(true){"); oxyZ("xsDisableSelf();");
优点: 1.极大简化了触发程序的语句。 2.可以自定义触发程序。 3.最高可输出2万+个字符。 4.所有触发将以命令形式显示,有不懂看命令表就行了。 5.可以联合RM命令使用,例如在同一个触发内根据国家不同生成不同效果。 6.可以联合XS数组使用。 7.制作方便,查看方便,修改方便。 8.涉及玩家ID的触发可以输出0,即为设定对象为大自然。 缺点: 1.所有规则都必须放在开头与末尾之间。 2.一个引号里面的内容最多只能输入125个字符,超出将会导致无法打开游戏,可以使用加号使两个引号连接起来。例如:"125"+"xxxxxxx" 3.所有语句都是在英文双引号""下使用,触发中的string值的双引号""必须用c++转移字符\"\"代替,例如oxy("xsDisableRule(\"_Debug3\");");。这个对喜欢用notepad++语法高亮的人来说是末日吧?因为在引号内全部会变成灰色字体,还不如直接在记事本编辑。 4.存在中文路径的帝国3目录将无法运行,联机会与非中文路径的不同步。 样板:在China Map(中国)地图、TaiwanStrait(台湾海峡)地图、Lake of the Moon(月之湖)等地图能找到类似触发程序。

3:某大佬开创的新C++脚本触发程序

rmCreateTrigger("TriggerName active runImmediately{trChatSendSpoofed(0,\"QQ Group : 85442352\");xsDisableSelf();}/*"); rmCreateTrigger("*/rule _TriggerEnd");
//TriggerName相当于旧版本触发名称,等于rule _TriggerName 优点: 1.极大简化了触发程序的语句。 2.可以自定义触发程序。 3.所有触发将以命令形式显示,有不懂看命令表就行了。 4.即时存在中文路径的帝国3目录也能运行,联机永远都会同步(除非对方有意炸图,或者双方文件不一致)。 5.涉及玩家ID的触发可以输出0,即为设定对象为大自然。 缺点: 1.不能输入任何空格,因为输入空格会自动转换成_,你只能用tab制表符代替空格。(不知道什么是tab制表符?你的键盘的Q建左边有个tab建,那个就是制表符) 2.最高只能输出255个字符,超出255字符会导致所有触发程序失效。(不小心超出了怎么办?去打开我的文档/My Game/Age of Empires 3/Trigger3/trigtemp.xs这个文件,找到你的触发,会发现某个地方少了一截,那里就是上限了) 3.因为这种触发使用作用在语句双引号""里面的/*、*/注释,所以每创建一个触发就要用一个空触发把注释关掉,否则再任何添加触发都会无效。 4.不能换行,所有判断、循环必须写在同一行。 5.不能用/**/注释,至于为什么?自己参考第三点。 6.一个引号里面的内容最多只能输入125个字符,超出将会导致无法打开游戏,可以使用加号使两个引号连接起来。例如:"125"+"xxxxxxx" 7.所有语句都是在英文双引号""下使用,触发中的string值的双引号""必须用c++转移字符\"\"代替,例如oxy("xsDisableRule(\"_Debug3\");");。这个对喜欢用notepad++语法高亮的人来说是末日吧?因为在引号内全部会变成灰色字体,还不如直接在记事本编辑。 样板:在我修改过的Christmas(冬季奇境)地图底部能找到类似触发程序。你可能会看不懂SC0-SC6有什么作用,SC0是判断有多少个贸易站(创建贸易站之后的第一个单位ID-第一个贸易站单位ID=贸易站数量),SC1-SC-6就是分别第一个贸易站单位ID加上0-5(因为rmGetUnitPlaced在一组只能获取第一个创建的单位ID)。

给玩家1创建一个开局10秒后增加100黄金的触发:

如果你用过剧情编辑器应该知道给玩家增加资源的触发有Grant Resources,计算秒数的条件是Timer,下面我会介绍三种方法创建这个触发
这是游戏目录的trigger3文件夹里面的typetest.xml的内容: <Condition name="Timer"> <Param name="Param1" dispName="$$22291$$Seconds" VarType="long">0</Param> <Expression>(trTime()-cActivationTime) >= %Param1%</Expression> </Condition> <Effect name="Grant Resources"> <Param name="PlayerID" dispName="$$22301$$Player" varType="player">1</Param> <Param name="ResName" dispName="$$22455$$Resource" varType="resource">food</Param> <Param name="Amount" dispName="$$22456$$Amount" varType="long">100</Param> <Command>trPlayerGrantResources(%PlayerID%, "%ResName%", %Amount%);</Command> </Effect>

方法1.旧版触发:

//第一个值必须与typetest.xml对应 rmCreateTrigger("Gold"); rmSwitchToTrigger(rmTriggerID("Gold")); rmSetTriggerPriority(3); rmSetTriggerActive(true); rmSetTriggerRunImmediately(true); rmSetTriggerLoop(false); rmAddTriggerCondition("Timer"); rmSetTriggerConditionParamInt("Param1", 10, false); rmAddTriggerEffect("Grant Resources"); rmSetTriggerEffectParamInt("PlayerID", 1, false); rmSetTriggerEffectParam("ResName", "Gold", false); rmSetTriggerEffectParamInt("Amount", 100, false); //第二个值为什么是这样填写的?你去参考一下剧情编辑器,制作一个相同的触发看看。

方法2.C++脚本触发1:传送门

  Debug.xs - 记事本 ____ X
文件(F)  编辑(E)  格式(O)  查看(V)  帮助(H)
	include "mercenaries.xs";
	include "ypAsianInclude.xs";
	include "ypKOTHInclude.xs";
//别光点传送门,这里也要添加。
	void oxy(string xs="") {
 	 	rmAddTriggerEffect("SetIdleProcessing");
		 	rmSetTriggerEffectParam("IdleProc", "false); */ "+xs+" /* ");
	}

	void oxyA(string xs="") {
 	 	rmAddTriggerEffect("SetIdleProcessing");
 	 	rmSetTriggerEffectParam("IdleProc", "false); "+xs+"/* trSetUnitIdleProcessing(false");
	}

	void oxyZ(string xs="") {
 	 	rmAddTriggerEffect("SetIdleProcessing");
		 	rmSetTriggerEffectParam("IdleProc", "false); */ "+xs+" trSetUnitIdleProcessing(false");
	}

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



		rmSetPlacementSection(0.6, 0.00);
		rmPlacePlayersCircular(0.40, 0.40, 0.0);


	//	rmSetPlayerResource(1, "Food", 200);

		//玩家范围
		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 TestID=rmCreateArea("Test ID Area");
  rmSetAreaSize(TestID, rmAreaTilesToFraction(500), rmAreaTilesToFraction(500));
  rmSetAreaWaterType(TestID, "Cinematic Ship Ocean");
  rmSetAreaWarnFailure(TestID, true);
  rmSetAreaSmoothDistance(TestID, 0);
  rmSetAreaCoherence(TestID, 0.0);
  //rmSetAreaMix(TestID, "himalayas_a");将设定地形类型语句删除,就算是保留也不会再起任何作用了。
  rmSetAreaBaseHeight(TestID, 4.0);//地形高度可加,也可以不加,看你自己想怎样设定。
  rmSetAreaElevationOctaves(TestID, 3);
  rmSetAreaObeyWorldCircleConstraint(TestID, false);
  rmSetAreaLocation(TestID, 0.5, 0.5);
  rmBuildArea(TestID);

rmSetOceanReveal(true);



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

	rmCreateTrigger("Gold");
	rmSwitchToTrigger(rmTriggerID("Gold"));
	rmSetTriggerPriority(3);
	rmSetTriggerActive(true);
	rmSetTriggerRunImmediately(true);
	rmSetTriggerLoop(false);
	rmAddTriggerCondition("Timer");
	rmSetTriggerConditionParamInt("Param1", 10, false);
	rmAddTriggerEffect("Grant Resources");
	rmSetTriggerEffectParamInt("PlayerID", 1, false);
	rmSetTriggerEffectParam("ResName", "Gold", false);
	rmSetTriggerEffectParamInt("Amount", 100, false);

	//下面就是C++脚本触发了,上面是旧版本触发,上面的触发最后会输出成下面蓝色文字双引号""内那种形式
	rmCreateTrigger("GamestartInit");
	rmSwitchToTrigger(rmTriggerID("GamestartInit"));
	rmSetTriggerRunImmediately(true);
	oxyA("}}");

	oxy("rule _Resources active runImmediately { ");
	oxy("if((trTime()-cActivationTime) >= 10.00000000){");	//Timer会输出成(trTime()-cActivationTime),意思是(游戏总时间-这个触发作用时长)
	oxy("trPlayerGrantResources(1,\"Gold\",100);");	//是不是很简洁?旧触发要去typetest.xml找名称,这种只需要去命令表找一下就OK了(对我这中比较熟悉命令的人来说)
	oxy("xsDisableRule(\"_Resources\");");	//关闭触发自身,相当于旧触发的rmSetTriggerLoop(false);,,不关闭就变成循环触发;rmSetTriggerLoop(false);最后也会变成这种形式。
	oxyZ("}} /*");

	//上面因为注释太乱了,再写一个加100食物、500木材的触发
	
	oxy("rule _ResourcesFood active runImmediately { ");
	oxy("if((trTime()-cActivationTime) >= 10.00000000){");
	oxy("trPlayerGrantResources(1,\"Food\",100);");
	oxy("trPlayerGrantResources(1,\"Wood\",500);");
	oxy("xsDisableRule(\"_ResourcesFood\");");
	oxyZ("}} /*");



	oxy("rule _Temp inactive { if(true){");
	oxyZ("xsDisableSelf();");


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


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

方法3.C++脚本触发2:传送门

//绿色背景是tab制表符;xsDisableSelf();是关闭触发本身,因为整个触发只能输入255字符,所以语句字数越少越好,xsDisableRule(\"_AddGoldEnd\");是把那个用来辅助结尾的触发关闭了,反正放着也没什么用,关闭了吧。 rmCreateTrigger("AddGold active runImmediately{if((trTime()-cActivationTime)>=10){trPlayerGrantResources(1,\"Gold\",100);xsDisableSelf();xsDisableRule(\"_AddGoldEnd\");}}/*"); rmCreateTrigger("*/rule _AddGoldEnd"); //不能出现任何空格,这个用来结尾的触发除外。
  Debug.xs - 记事本 ____ X
文件(F)  编辑(E)  格式(O)  查看(V)  帮助(H)
	include "mercenaries.xs";
	include "ypAsianInclude.xs";
	include "ypKOTHInclude.xs";
//别光点传送门,这里也要添加。
	void oxy(string xs="") {
 	 	rmAddTriggerEffect("SetIdleProcessing");
		 	rmSetTriggerEffectParam("IdleProc", "false); */ "+xs+" /* ");
	}

	void oxyA(string xs="") {
 	 	rmAddTriggerEffect("SetIdleProcessing");
 	 	rmSetTriggerEffectParam("IdleProc", "false); "+xs+"/* trSetUnitIdleProcessing(false");
	}

	void oxyZ(string xs="") {
 	 	rmAddTriggerEffect("SetIdleProcessing");
		 	rmSetTriggerEffectParam("IdleProc", "false); */ "+xs+" trSetUnitIdleProcessing(false");
	}

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



		rmSetPlacementSection(0.6, 0.00);
		rmPlacePlayersCircular(0.40, 0.40, 0.0);


	//	rmSetPlayerResource(1, "Food", 200);

		//玩家范围
		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 TestID=rmCreateArea("Test ID Area");
  rmSetAreaSize(TestID, rmAreaTilesToFraction(500), rmAreaTilesToFraction(500));
  rmSetAreaWaterType(TestID, "Cinematic Ship Ocean");
  rmSetAreaWarnFailure(TestID, true);
  rmSetAreaSmoothDistance(TestID, 0);
  rmSetAreaCoherence(TestID, 0.0);
  //rmSetAreaMix(TestID, "himalayas_a");将设定地形类型语句删除,就算是保留也不会再起任何作用了。
  rmSetAreaBaseHeight(TestID, 4.0);//地形高度可加,也可以不加,看你自己想怎样设定。
  rmSetAreaElevationOctaves(TestID, 3);
  rmSetAreaObeyWorldCircleConstraint(TestID, false);
  rmSetAreaLocation(TestID, 0.5, 0.5);
  rmBuildArea(TestID);

rmSetOceanReveal(true);



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

	rmCreateTrigger("Gold");
	rmSwitchToTrigger(rmTriggerID("Gold"));
	rmSetTriggerPriority(3);
	rmSetTriggerActive(true);
	rmSetTriggerRunImmediately(true);
	rmSetTriggerLoop(false);
	rmAddTriggerCondition("Timer");
	rmSetTriggerConditionParamInt("Param1", 10, false);
	rmAddTriggerEffect("Grant Resources");
	rmSetTriggerEffectParamInt("PlayerID", 1, false);
	rmSetTriggerEffectParam("ResName", "Gold", false);
	rmSetTriggerEffectParamInt("Amount", 100, false);

	rmCreateTrigger("GamestartInit");
	rmSwitchToTrigger(rmTriggerID("GamestartInit"));
	rmSetTriggerRunImmediately(true);
	oxyA("}}");
	oxy("rule _Resources active runImmediately { ");
	oxy("if((trTime()-cActivationTime) >= 10.00000000){");
	oxy("trPlayerGrantResources(1,\"Gold\",100);");
	oxy("xsDisableRule(\"_Resources\");");
	oxyZ("}} /*");


	//上面因为注释太乱了,再写一个加100食物、500木材的触发
	
	oxy("rule _ResourcesFood active runImmediately { ");
	oxy("if((trTime()-cActivationTime) >= 10.00000000){");
	oxy("trPlayerGrantResources(1,\"Food\",100);");
	oxy("trPlayerGrantResources(1,\"Wood\",500);");
	oxy("xsDisableRule(\"_ResourcesFood\");");
	oxyZ("}} /*");


	oxy("rule _Temp inactive { if(true){");
	oxyZ("xsDisableSelf();");




	rmCreateTrigger("AddGold	active	runImmediately{if((trTime()-cActivationTime)>=10){trPlayerGrantResources"+"(1,\"Gold\",100);xsDisableSelf();xsDisableRule(\"_AddGoldEnd\");}}/*");
	rmCreateTrigger("*/rule	_AddGoldEnd");


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


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

算一下我们刚才加了多少资源?旧版触发+100金,C++脚本触发①+100金+100肉+500木,C++脚本触发②+100金, 上面是单独给玩家1创建的,如果要给所有玩家创建要怎样做呢? 用for循环就行传送门
  Debug.xs - 记事本 ____ X
文件(F)  编辑(E)  格式(O)  查看(V)  帮助(H)
	include "mercenaries.xs";
	include "ypAsianInclude.xs";
	include "ypKOTHInclude.xs";
//别光点传送门,这里也要添加。
	void oxy(string xs="") {
 	 	rmAddTriggerEffect("SetIdleProcessing");
		 	rmSetTriggerEffectParam("IdleProc", "false); */ "+xs+" /* ");
	}

	void oxyA(string xs="") {
 	 	rmAddTriggerEffect("SetIdleProcessing");
 	 	rmSetTriggerEffectParam("IdleProc", "false); "+xs+"/* trSetUnitIdleProcessing(false");
	}

	void oxyZ(string xs="") {
 	 	rmAddTriggerEffect("SetIdleProcessing");
		 	rmSetTriggerEffectParam("IdleProc", "false); */ "+xs+" trSetUnitIdleProcessing(false");
	}

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



		rmSetPlacementSection(0.6, 0.00);
		rmPlacePlayersCircular(0.40, 0.40, 0.0);


	//	rmSetPlayerResource(1, "Food", 200);

		//玩家范围
		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 TestID=rmCreateArea("Test ID Area");
  rmSetAreaSize(TestID, rmAreaTilesToFraction(500), rmAreaTilesToFraction(500));
  rmSetAreaWaterType(TestID, "Cinematic Ship Ocean");
  rmSetAreaWarnFailure(TestID, true);
  rmSetAreaSmoothDistance(TestID, 0);
  rmSetAreaCoherence(TestID, 0.0);
  //rmSetAreaMix(TestID, "himalayas_a");将设定地形类型语句删除,就算是保留也不会再起任何作用了。
  rmSetAreaBaseHeight(TestID, 4.0);//地形高度可加,也可以不加,看你自己想怎样设定。
  rmSetAreaElevationOctaves(TestID, 3);
  rmSetAreaObeyWorldCircleConstraint(TestID, false);
  rmSetAreaLocation(TestID, 0.5, 0.5);
  rmBuildArea(TestID);

rmSetOceanReveal(true);



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




	

//循环方法1,循环所有语句,创建cNumberNonGaiaPlayers个触发:

for(i=1; <=cNumberNonGaiaPlayers) { rmCreateTrigger("Gold"+i); //为什么要加循环值i呢?因为不能出现两个相同名称的触发,否则会全体触发失效。 rmSwitchToTrigger(rmTriggerID("Gold"+i)); rmSetTriggerPriority(3); rmSetTriggerActive(true); rmSetTriggerRunImmediately(true); rmSetTriggerLoop(false); rmAddTriggerCondition("Timer"); rmSetTriggerConditionParamInt("Param1", 10, false); rmAddTriggerEffect("Grant Resources"); rmSetTriggerEffectParamInt("PlayerID", i, false); rmSetTriggerEffectParam("ResName", "Gold", false); rmSetTriggerEffectParamInt("Amount", 100, false); }

//循环方法2,仅循环效果语句:

rmCreateTrigger("AllPlayerGold"); rmSwitchToTrigger(rmTriggerID("AllPlayerGold")); rmSetTriggerPriority(3); rmSetTriggerActive(true); rmSetTriggerRunImmediately(true); rmSetTriggerLoop(false); rmAddTriggerCondition("Timer"); rmSetTriggerConditionParamInt("Param1", 10, false); for(i=1; <=cNumberNonGaiaPlayers) { rmAddTriggerEffect("Grant Resources"); rmSetTriggerEffectParamInt("PlayerID", i, false); rmSetTriggerEffectParam("ResName", "Gold", false); rmSetTriggerEffectParamInt("Amount", 100, false); } rmCreateTrigger("GamestartInit"); rmSwitchToTrigger(rmTriggerID("GamestartInit")); rmSetTriggerRunImmediately(true); oxyA("}}");

//循环方法1,RM层循环所有语句,创建cNumberNonGaiaPlayers个触发:

//为什么是"+i+"?因为我们是在地图语句循环的,属于RM层,不属于TR触发层;所以引号内的语句要用"+i+",意思是"左边的xxx"加上循环值i再加上"右边的xxxx"。 //第一句双引号加了颜色,这样你应该看的懂是怎样一回事。 for(i=1; <=cNumberNonGaiaPlayers) { oxy("rule _Resources"+i+" active runImmediately { "); oxy("if((trTime()-cActivationTime) >= 10.00000000){"); oxy("trPlayerGrantResources("+i+",\"Gold\",100);"); oxy("xsDisableRule(\"_Resources"+i+"\");"); oxyZ("}} /*"); } //关闭本身也要加上"+i+",不然就没法正常关闭,直接变成执行无限次的循环触发了,或者你可以直接使用xsDisableSelf();

//循环方法2,RM层循仅环命令语句(会在地图生成cNumberNonGaiaPlayers个语句):

oxy("rule _ResourcesFood active runImmediately { "); oxy("if((trTime()-cActivationTime) >= 10.00000000){"); for(i=1; <=cNumberNonGaiaPlayers) { oxy("trPlayerGrantResources("+i+",\"Food\",100);"); oxy("trPlayerGrantResources("+i+",\"Wood\",500);"); } oxy("xsDisableRule(\"_ResourcesFood\");"); oxyZ("}} /*");

//循环方法3,TR层循仅环命令语句(输出语句与下面一样,到了执行触发,再循环):

oxy("rule _AddResources active runImmediately { "); oxy("if((trTime()-cActivationTime) >= 10.00000000){"); oxy("for(i=1; <="+cNumberNonGaiaPlayers+")"); oxy("{"); oxy("trPlayerGrantResources(i,\"Food\",100);"); //TR层的循环直接填i就行 oxy("trPlayerGrantResources(i,\"Wood\",500);"); oxy("}"); oxy("xsDisableRule(\"_AddResources\");"); oxyZ("}} /*"); //注:cNumberNonGaiaPlayers无法在TR层使用,要加上"++"使它变成RM层数据。另一个计算玩家数量的变量cNumberPlayers可以在TR层使用。

//再加一个将玩家资源信息发送到聊天的触发

//发送聊天信息的是trChatSendSpoofed(fromID message): Changes the chat status, but does not append player. //trChatSendSpoofed(0,\"\");(0就是大自然) //返回玩家资源语句为trPlayerResourceCount(playerID, resource): returns the number of resources for the player. //trPlayerResourceCount(playerID, \"\") //发送聊天触发11秒后再执行(因为触发是按顺序执行的,如果是十秒就先执行这个,再执行下面的触发 oxy("rule _SendChat active runImmediately { "); oxy("if((trTime()-cActivationTime) >= 11.00000000){");) for(i=1; <=cNumberNonGaiaPlayers) { oxy("trChatSendSpoofed(0,\"Player"+i+" <color=0,1,0>Food:\"+trPlayerResourceCount("+i+", \"Food\"));"); oxy("trChatSendSpoofed(0,\"Player"+i+" <color=0,1,1>Wood:\"+trPlayerResourceCount("+i+", \"Wood\"));"); oxy("trChatSendSpoofed(0,\"Player"+i+" <color=0.25,1,0.25>Gold:\"+trPlayerResourceCount("+i+", \"Gold\"));"); } oxy("xsDisableRule(\"_SendChat\");"); oxyZ("}} /*"); //有时候你设定随机数或者不明白RM命令设定的值(坐标、vector坐标那些)是什么,可以用这种触发返回那个值,用trChatSendSpoofed(0,\""+此处写上int定义之类的+"\");发送到聊天窗口。 //怎么一会用"+ +",一会儿不用?已经说了RM层语句与TR层语句不通用,TR层调用RM层数值要用"+ +"。 //<color=0,1,0>那几个是改变本次聊天字体颜色。 oxy("rule _Temp inactive { if(true){"); oxyZ("xsDisableSelf();");

//循环方法1,RM层循环所有语句,创建cNumberNonGaiaPlayers个触发:

for(i=1; <=cNumberNonGaiaPlayers) { rmCreateTrigger("AddGold"+i+" active runImmediately{if((trTime()-cActivationTime)>=10){trPlayerGrantResources("+i+",\"Gold\",100);xsDisableSelf();xsDisableRule(\"_AddGoldEnd"+i+"\");}}/*"); rmCreateTrigger("*/rule _AddGoldEnd"+i+""); }

//循环方法2,TR层循仅环命令语句(输出语句与下面一样,到了执行触发,再循环):

rmCreateTrigger("AddGold active runImmediately{if((trTime()-cActivationTime)>=10){for(i=1;<cNumberPlayers){trPlayerGrantResources"+"(i,\"Gold\",100);}xsDisableSelf();xsDisableRule(\"_AddGoldEnd\");}}/*"); rmCreateTrigger("*/rule _AddGoldEnd"); //上面已经说过了cNumberNonGaiaPlayers不能在TR层使用,所以用cNumberPlayers代替,但是我还是推荐使用"+cNumberNonGaiaPlayers+",为什么呢?C++脚本触发程序只能输出255个字符,"+cNumberNonGaiaPlayers+"从RM转成数字后会变成只有一个字符(游戏最多能有8人),所以比cNumberPlayers节省了14个字符。
rmSetStatusText("",1.00);//读取地图进度条 //愿神兽会保佑你不会出错。 /*----------------------------------------------------------------------------------------------* *    ┏┓   ┏┓ * *   ┏┛┻━━━┛┻┓ * *   ┃       ┃ * *   ┃   ━   ┃ * *   ┃ ┳┛ ┗┳ ┃ * *   ┃       ┃ * *   ┃   ┻   ┃ * *   ┃       ┃ * *   ┗━┓   ┏━┛ Code is far away from bug with the animal protecting * *     ┃   ┃ * *     ┃   ┃ * *     ┃   ┃ * *     ┃   ┃ * *     ┃   ┃ * *     ┃   ┗━━━┓ * *     ┃       ┣┓ * *     ┃       ┏┛ * *     ┗┓┓┏━┳┓┏┛ * *      ┃┫┫ ┃┫┫ * *      ┗┻┛ ┗┻┛ * *----------------------------------------------------------------------------------------------*/ } //END
补充<color=0,1,0>颜色值参考帝国3RGB

统计上面一共加了多少资源?
旧版本触发	:所有玩家+100金 *2个
C++脚本触发1	:所有玩家+100金 *1个;所有玩家+100食物+500木材 *2个
C++脚本触发2	:所有玩家+100金 *2个
合计:




最后补充:有不懂语句是什么作用的,可以去查看XS、KB、TR命令表搜索命令 触发程序不仅可以使用TR命令,还可以使用XS、KB以及一小部分UI命令。 使用KB命令注意事项,使用KB命令必须加上xsSetContextPlayer来设定KB命令的对象玩家。 [(void )] xsSetContextPlayer( int playerID ): Sets the current context player ID (DO NOT DO THIS IF YOU DO NOT KNOW WHAT YOU ARE DOING). [(float )] kbTotalResourceGet( int resourceID ): Returns the total amount of the given resource gathered to this point in the game. 例如获取玩家1采集了多少食物(食物的resourceID为2):xsSetContextPlayer(1);kbTotalResourceGet(2); 获取所有玩家采集了多少食物for(i=1;<cNumberPlayers){xsSetContextPlayer(i);{kbTotalResourceGet(2);} 获取这些值有什么用呢?如下 用if判断玩家食物是否大于100 for(i=1;<cNumberPlayers) { xsSetContextPlayer(i); if(kbTotalResourceGet(2)>100) { } } 个人推荐使用第一种C++脚本语言触发程序这种触发方便,也能自定义,还能写出非常复杂的触发。 第二种可以在中文路径使用的C++脚本语言触发程序适用小批量触发程序,你自己也懂的,在天朝每10个人就有7个人安装路径存在中文字符,小批量能用这种触发程序就用这种。 为了避免因为中文路径导致的不同步现象,可以这样设定: 以下语句为开局踢出中文路径玩家: /* It can't use in Chinese path .*/ rmCreateTrigger("GameStart"); rmSwitchToTrigger(rmTriggerID("GameStart")); rmSetTriggerActive(true); rmSetTriggerRunImmediately(true); rmSetTriggerPriority(5); rmAddTriggerEffect("Quest Var Set"); rmSetTriggerEffectParam("QVName", "Path", false); rmSetTriggerEffectParamInt("Value", 1, false); /*the next Trigger will kick "Chinese Path Player" out of the game.*/ rmCreateTrigger("Path active runImmediately{if(trQuestVarGet(\"Path\")!=1){"+"showSPCNote(\"Error!\",\"Use-the-English-path-to-install-the-Age-of-Empires-III,please.\");"+"uiMessageBox2(20948);trEndGame();trYouWin(true);}xsDisableSelf();}/*"); rmCreateTrigger("*/rule _PathEnd"); 这效果是怎样达成的呢? 已知帝国3安装目录存在中文路径所有触发程序将会失效,那么我们就用官方版本的触发程序用Quest Var Set设定一个值,设定那个值为1。而中文路径的帝国3因为触发程序失效,那个值就不为1,这时候我们使用可以在中文路径运行的第二种C++脚本触发程序,获取那个值,不等于1就执行效果trEndGame();结束游戏,trYouWin(true);自己离开游戏(出局)。有一点要说明的是不是用触发设定那个玩家出局,而是让那个玩家自己离开游戏才不会导致出现问题。 你觉得单位ID是怎样导出的? string kbGetUnitTypeName( int unitTypeID ): Returns the name of the unit type trChatSend(fromID message): Changes the chat status oxy("rule _Debug29 active runImmediately { "); oxy("if((trTime()-cActivationTime) == 1.00000000){"); oxy("trChatSendSpoofed(0,\"<color=0,1,1>\"+kbGetUnitTypeName(0));"); oxy("trChatSendSpoofed(0,\"<color=0,1,1>\"+kbGetUnitTypeName(1));"); oxy("trChatSendSpoofed(0,\"<color=0,1,1>\"+kbGetUnitTypeName(2));"); oxy("trChatSendSpoofed(0,\"<color=0,1,1>\"+kbGetUnitTypeName(1463));"); oxy("trChatSendSpoofed(0,\"<color=0,1,1>\"+kbGetUnitTypeName(1464));"); oxy("xsDisableRule(\"_Debug29\");"); oxyZ("}} /*"); oxy("rule _Unittype active runImmediately { "); oxy("if((trTime()-cActivationTime) >= 1.00000000){"); for(u=1; <1800) { oxy("trChatSendSpoofed(0,\"<color=0,1,1>"+u+":\");"); } oxy("xsDisableRule(\"_Unittype\");"); oxyZ("}} /*"); 整合两个触发 oxy("rule _Unittype2 active runImmediately { "); oxy("if((trTime()-cActivationTime) >= 1.00000000){"); for(u=1463; <1800) { oxy("trChatSend(0,\"<color=0,1,1>"+u+" \"+kbGetUnitTypeName("+u+"));"); } oxy("xsDisableRule(\"_Unittype2\");"); oxyZ("}} /*");

这是我用来测试触发程序遗留下来的资料,里面的写法你可以自己参考一下

include "mercenaries.xs"; // ensure extras void oxy(string xs="") { rmAddTriggerEffect("SetIdleProcessing"); rmSetTriggerEffectParam("IdleProc", "false); */ "+xs+" /* "); } void oxyA(string xs="") { rmAddTriggerEffect("SetIdleProcessing"); rmSetTriggerEffectParam("IdleProc", "false); "+xs+"/* trSetUnitIdleProcessing(false"); } void oxyZ(string xs="") { rmAddTriggerEffect("SetIdleProcessing"); rmSetTriggerEffectParam("IdleProc", "false); */ "+xs+" trSetUnitIdleProcessing(false"); } void main(void) { rmSetMapSize((2*sqrt(cNumberNonGaiaPlayers*12000)), (2*sqrt(cNumberNonGaiaPlayers*12000))); rmSetMapElevationParameters(cElevTurbulence, 0, 0, 0, 0); rmSetMapElevationHeightBlend(1.0); rmTerrainInitialize("caribbean\ground7_crb",6); rmSetMapType("caribbean"); rmSetMapType("water"); rmSetMapType("default"); rmSetMapType("water"); rmSetMapType("land"); rmSetLightingSet("319a_Snow"); rmSetSeaLevel(6); rmSetStatusText("",0.10); chooseMercs(); int PlayerClass=rmDefineClass("Player"); int LakeClass= rmDefineClass("Lakes"); int CliffClass= rmDefineClass("Cliffs"); rmDefineClass("ExplorerUnit"); rmDefineClass("MainForest"); rmDefineClass("MainItems"); rmDefineClass("Nativ"); int CWvsCW=rmCreateTypeDistanceConstraint("CWTOCW", "CoveredWagon", 30.0); int FOvsTC=rmCreateTypeDistanceConstraint("FOTOTC", "TownCenter", 20.0); //Tree=单位调用名--鹿,创建规则放置时,间隔Deer类型单位30距离。 int AvoidDeer = rmCreateTypeDistanceConstraint("Deer Distance", "Deer", 30.0); rmSetStatusText("",0.20); float Breite0 = 3.0; int seaI = rmRiverCreate(-1, "Coastal Japan", 1, 1, Breite0, Breite0); rmRiverAddWaypoint(seaI, 0.70, 0.40 ); rmRiverAddWaypoint(seaI, 0.70, 0.30 ); rmRiverAddWaypoint(seaI, 0.80, 0.20 ); rmRiverSetBankNoiseParams(seaI,0.00, 0, 0.0, 0.0, 0.0, 0.0); rmRiverBuild(seaI); rmAddAreaToClass(seaI,rmClassID("Sea")); rmPlacePlayersCircular(0.35, 0.35, 0.0); int IDRiver = rmRiverCreate(-1, "Great Lakes", 1, 1, 10.0, 10.0); rmRiverAddWaypoint(IDRiver, 0.70, 0.30 ); rmRiverAddWaypoint(IDRiver, 0.85, 0.30 ); rmRiverAddWaypoint(IDRiver, 0.80, 0.30 ); rmRiverAddWaypoint(IDRiver, 0.80, 0.35 ); rmRiverAddWaypoint(IDRiver, 0.80, 0.25 ); rmRiverAddShallow(IDRiver,1.00); rmRiverAddShallows(IDRiver,10.00,8); rmRiverSetBankNoiseParams(IDRiver,0.00, 0, 0.0, 0.0, 0.0, 0.0); rmRiverBuild(IDRiver); int DestroyID=rmCreateArea("Destroy ID Area"); rmSetAreaSize(DestroyID, 0.10, 0.10); rmSetAreaLocation(DestroyID, .5, .5); rmSetAreaWarnFailure(DestroyID, true); rmSetAreaSmoothDistance(DestroyID, 50); rmSetAreaCoherence(DestroyID, 1.0); rmSetAreaMix(DestroyID, "himalayas_a"); rmSetAreaElevationType(DestroyID, cElevFractalSum); rmSetAreaElevationVariation(DestroyID, 4.0); rmSetAreaBaseHeight(DestroyID, 4.0); rmSetAreaElevationOctaves(DestroyID, 3); rmSetAreaObeyWorldCircleConstraint(DestroyID, false); rmBuildArea(DestroyID); // ****************************************** TRADE ROUTE ********************************************** int tradeRouteID = rmCreateTradeRoute(); int socketID=rmCreateObjectDef("sockets to dock Trade Posts"); rmAddObjectDefItem(socketID, "SocketTradeRoute", 1, 0.0); rmSetObjectDefAllowOverlap(socketID, true); rmSetObjectDefMinDistance(socketID, 0.0); rmSetObjectDefMaxDistance(socketID, 6.0); int tpvariation = rmRandInt(0,1); float socket01 = 0.10; float socket02 = 0.28; float socket03 = 0.43; float socket04 = 0.69; float socket05 = 0.90; float socketB01 = 0.10; float socketB02 = 0.28; float socketB03 = 0.41; float socketB04 = 0.69; float socketC01 = 0.10; float socketC02 = 0.43; float socketC03 = 0.69; int socketcount = rmRandInt(rmRandInt(3,4),5); if (tpvariation > 0.5) { //South Start rmSetObjectDefTradeRouteID(socketID, tradeRouteID); rmAddTradeRouteWaypoint(tradeRouteID, 0.00, 0.52); rmAddTradeRouteWaypoint(tradeRouteID, 0.20, 0.51); rmAddTradeRouteWaypoint(tradeRouteID, 0.40, 0.40); rmAddTradeRouteWaypoint(tradeRouteID, 0.55, 0.45); rmAddTradeRouteWaypoint(tradeRouteID, 0.68, 0.68); rmAddTradeRouteWaypoint(tradeRouteID, 0.80, 0.65); rmAddTradeRouteWaypoint(tradeRouteID, 1.00, 0.50); socket01 = 0.10; socket02 = 0.28; socket03 = 0.45; socket05 = 0.92; socketB01 = 0.15; socketB02 = 0.29; socketB03 = 0.55; socketB04 = 0.75; socketC01 = 0.20; socketC02 = 0.43; socketC03 = 0.69; } else { //North Start rmSetObjectDefTradeRouteID(socketID, tradeRouteID); rmAddTradeRouteWaypoint(tradeRouteID, 1.00, 0.50); rmAddTradeRouteWaypoint(tradeRouteID, 0.80, 0.65); rmAddTradeRouteWaypoint(tradeRouteID, 0.68, 0.68); rmAddTradeRouteWaypoint(tradeRouteID, 0.55, 0.45); rmAddTradeRouteWaypoint(tradeRouteID, 0.40, 0.40); rmAddTradeRouteWaypoint(tradeRouteID, 0.20, 0.51); rmAddTradeRouteWaypoint(tradeRouteID, 0.00, 0.52); socket01 = 0.08; socket02 = 0.22; socket03 = 0.55; socket05 = 0.90; socketB01 = 0.22; socketB02 = 0.44; socketB03 = 0.69; socketB04 = 0.90; socketC01 = 0.22; socketC02 = 0.55; socketC03 = 0.80; } bool placedTradeRouteA = rmBuildTradeRoute(tradeRouteID, "snow"); vector socketLoc = rmGetTradeRouteWayPoint(tradeRouteID, 0.00); if (socketcount == 3) { socketLoc = rmGetTradeRouteWayPoint(tradeRouteID, socketC01); rmPlaceObjectDefAtPoint(socketID, 0, socketLoc); socketLoc = rmGetTradeRouteWayPoint(tradeRouteID, socketC02); rmPlaceObjectDefAtPoint(socketID, 0, socketLoc); socketLoc = rmGetTradeRouteWayPoint(tradeRouteID, socketC03); rmPlaceObjectDefAtPoint(socketID, 0, socketLoc); } if (socketcount == 4) { socketLoc = rmGetTradeRouteWayPoint(tradeRouteID, socketB01); rmPlaceObjectDefAtPoint(socketID, 0, socketLoc); socketLoc = rmGetTradeRouteWayPoint(tradeRouteID, socketB02); rmPlaceObjectDefAtPoint(socketID, 0, socketLoc); socketLoc = rmGetTradeRouteWayPoint(tradeRouteID, socketB03); rmPlaceObjectDefAtPoint(socketID, 0, socketLoc); socketLoc = rmGetTradeRouteWayPoint(tradeRouteID, socketB04); rmPlaceObjectDefAtPoint(socketID, 0, socketLoc); } if (socketcount == 5) { socketLoc = rmGetTradeRouteWayPoint(tradeRouteID, socket01); rmPlaceObjectDefAtPoint(socketID, 0, socketLoc); socketLoc = rmGetTradeRouteWayPoint(tradeRouteID, socket02); rmPlaceObjectDefAtPoint(socketID, 0, socketLoc); socketLoc = rmGetTradeRouteWayPoint(tradeRouteID, socket03); rmPlaceObjectDefAtPoint(socketID, 0, socketLoc); socketLoc = rmGetTradeRouteWayPoint(tradeRouteID, socket04); rmPlaceObjectDefAtPoint(socketID, 0, socketLoc); socketLoc = rmGetTradeRouteWayPoint(tradeRouteID, socket05); rmPlaceObjectDefAtPoint(socketID, 0, socketLoc); } // ************************************************************************************************************* int TreeID= rmCreateObjectDef("Create TreeNewEnglandSnow"); rmAddObjectDefItem(TreeID, "TreeNewEnglandSnow", 10, 20.0); rmSetObjectDefMinDistance(TreeID, 0.0); rmSetObjectDefMaxDistance(TreeID, 12); rmPlaceObjectDefAtLoc(TreeID, 0, 0.5, 0.5,10); int SPCFixedGunID= rmCreateObjectDef("FixedGun"); rmAddObjectDefItem(SPCFixedGunID, "SPCFixedGun", 1, 6.0); rmSetObjectDefMinDistance(SPCFixedGunID, 0.0); rmSetObjectDefMaxDistance(SPCFixedGunID, 16); rmPlaceObjectDefAtLoc(SPCFixedGunID, 0, 0.2, 0.2,1); int SPCFixedGun2ID= rmCreateObjectDef("FixedGun2"); rmAddObjectDefItem(SPCFixedGun2ID, "SPCFixedGun", 1, 6.0); rmSetObjectDefMinDistance(SPCFixedGun2ID, 0.0); rmSetObjectDefMaxDistance(SPCFixedGun2ID, 16); rmPlaceObjectDefAtLoc(SPCFixedGun2ID, 0, 0.8, 0.8,1); int DeerID= -1; for(d=1;<=5) { DeerID= rmCreateObjectDef("Deer"+d); rmAddObjectDefItem(DeerID, "Deer", 20, 12.0); rmSetObjectDefMinDistance(DeerID, 0.0); //rmXFractionToMeters(1.0)=全图 rmSetObjectDefMaxDistance(DeerID, rmXFractionToMeters(1.0)); //往上面搜索AvoidDeer,这个是定义放置规则,例如间隔距离 rmAddObjectDefConstraint(DeerID, AvoidDeer); rmPlaceObjectDefAtLoc(DeerID, 0, 0.5, 0.5,1); } int ExplorerID= rmCreateObjectDef("Explorer"); rmAddObjectDefItem(ExplorerID, "Explorer", 1, 6.0); rmAddObjectDefItem(ExplorerID, "OutlawMusketeer", 8, 6.0); rmSetObjectDefMinDistance(ExplorerID, 0.0); rmSetObjectDefMaxDistance(ExplorerID, 16); rmPlaceObjectDefAtLoc(ExplorerID, 0, 0.5, 0.5,1); rmSetStatusText("",0.30); float AreaSizePlayer = rmAreaTilesToFraction(700); for(i=1; <cNumberPlayers) { int id=rmCreateArea("Player"+i); rmSetPlayerArea(i, id); rmSetAreaWarnFailure(id, false); rmSetAreaSize(id, AreaSizePlayer, AreaSizePlayer); rmAddAreaToClass(id, PlayerClass); rmSetAreaLocPlayer(id, i); rmSetAreaCoherence(id, 0.05); rmSetAreaMinBlobs(id, 1); rmSetAreaMaxBlobs(id, 1); rmSetAreaTerrainType(id,"caribbean\ground7_crb"); rmBuildArea(id); } rmSetStatusText("",0.35); int TCID = rmCreateObjectDef("player TC"); rmAddObjectDefItem(TCID, "TownCenter", 1, 0); rmAddObjectDefItem(TCID, "CoveredWagon", 1, 10); rmAddObjectDefItem(TCID, "CrateofWheatBundleLarge", 4, 7); rmAddObjectDefItem(TCID, "CrateofWoodLarge", 4, 9); rmAddObjectDefItem(TCID, "CrateofCoinLarge", 4, 12); rmAddObjectDefItem(TCID, "CrateofFoodLarge", 4, 15); rmAddObjectDefItem(TCID, "Plantation", 1, 50); rmAddObjectDefItem(TCID, "Settler", 11, 16); rmAddObjectDefItem(TCID, "Market", 1, 30); rmSetObjectDefMinDistance(TCID, 0.0); rmSetObjectDefMaxDistance(TCID, 20.0); for(i=1; <cNumberPlayers) { rmPlaceObjectDefAtLoc(TCID, i, rmPlayerLocXFraction(i), rmPlayerLocZFraction(i)); } int ExplorerUnits = rmCreateStartingUnitsObjectDef(5.0); rmSetObjectDefMinDistance(ExplorerUnits, 6.0); rmSetObjectDefMaxDistance(ExplorerUnits, 10.0); rmSetStatusText("",0.70); for(i=1; <cNumberPlayers) { vector TCLocation = rmGetUnitPosition(rmGetUnitPlacedOfPlayer(TCID, i)); vector closestPoint = rmFindClosestPointVector(TCLocation, rmXFractionToMeters(1.0)); rmPlaceObjectDefAtLoc(ExplorerUnits, i, rmXMetersToFraction(xsVectorGetX(TCLocation)), rmZMetersToFraction(xsVectorGetZ(TCLocation))); } for(i=1; <cNumberPlayers) { TCLocation = rmGetUnitPosition(rmGetUnitPlacedOfPlayer(TCID, i)); closestPoint = rmFindClosestPointVector(TCLocation, rmXFractionToMeters(1.0)); } rmClearClosestPointConstraints(); rmSetStatusText("",0.80); rmSetStatusText("",0.90); // Text rmSetStatusText("",0.25); // Text rmSetStatusText("",0.35); // ********************************************** Define *********************************************** rmCreateTrigger("xiaoyu"); rmSwitchToTrigger(rmTriggerID("xiaoyu")); rmSetTriggerRunImmediately(true); oxyA("}}"); // //是注释,在下一行换行符之前的内容都是无效的。 /*这种也是注释,中间的内容无效*/ //""一对非转义引号内字符最长只能为125个,好像是127,我记不清了,你自己注意点 /* //oxy("trChatSendSpoofed(0,trTime()+\"<color=0,255,255>000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000:<color=0,255,0>\");"); 上面的因为字符长度过长,导致无法打开地图。 解决方法如下:多加一队引号(下面的"+") //oxy("trChatSendSpoofed(0,trTime()+\"<color=0,255,255>00000000000000000000000000000000000000000000"+"0000000000000000000000000000000000000000000000000000000:<color=0,255,0>\");"); */ //active默认开启 //inactive默认关闭 //runImmediately立刻运行 oxy("rule _StartTech active runImmediately { "); oxy("if((trTime()-cActivationTime) >= 1.00000000){"); oxy("trModifyProtounit(\"Explorer\", 0, 0, -400);"); oxy("trModifyProtounit(\"Explorer\", 0, 0, 400);"); oxyZ("}} /*"); /* 上面的trModifyProtounit等于触发程序的Modify Protounit <Effect name="Modify Protounit"> <Param name="ProtoUnit" dispName="$$22449$$ProtoUnit" varType="protounit">Villager</Param> <Param name="PlayerID" dispName="$$22301$$Player" VarType="player">1</Param> <Param name="Field" dispName="$$25417$$Field" varType="pufield">0</Param> <Param name="Delta" dispName="$$25418$$Delta" varType="float">1.0</Param> <Command>trModifyProtounit("%ProtoUnit%", %PlayerID%, %Field%, %Delta%);</Command> </Effect> trModifyProtounit(unit, player, field, delta) */ //玩家0为大自然 for(i=1;<=cNumberNonGaiaPlayers) { oxy("rule _Explorer"+i+" active runImmediately { "); oxy("if(trPlayerActive("+i+")){"); /*往上面搜索ExplorerID,只对第一个放置的单位有效*/ oxy("if(trCountUnitsInArea(\""+rmGetUnitPlaced(ExplorerID, 0)+"\","+i+",\"unit\",35) >= 3){"); oxy("if(trCountUnitsInArea(\""+rmGetUnitPlaced(ExplorerID, 0)+"\",0,\"OutlawMusketeer\",45) == 0){"); oxy("trUnitSelectClear();"); oxy("trUnitSelectByID("+rmGetUnitPlaced(ExplorerID, 0)+");"); oxy("trUnitConvert("+i+");"); oxy("trUnitSelectClear();"); oxy("trUnitSelectByID("+rmGetUnitPlaced(ExplorerID, 0)+");"); oxy("trUnitHighlight(10, true);"); oxy("trUnitSelectClear();"); oxy("trUnitSelectByID("+rmGetUnitPlaced(ExplorerID, 0)+");"); oxy("trUnitChangeProtoUnit(\"Explorer\");"); oxy("trChatSend(0,\"Player"+i+" has rescued an Explorer, who joins the cause.\");"); for(p=1;<=cNumberNonGaiaPlayers) { oxy("xsDisableRule(\"_Explorer"+p+"\");"); } oxy("}}}"); oxy("else{"); oxy("xsDisableRule(\"_Explorer"+i+"\");"); oxyZ("}} /*"); } oxy("rule _LOS active runImmediately { "); oxy("if((trTime()-cActivationTime) >= 10.00000000){"); for(p=1; <cNumberPlayers) { oxy("trModifyProtounit(\"TownCenter\","+p+",2,1000);"); oxy("trTechSetStatus("+p+",446,2);"); } oxy("xsEnableRule(\"_Fog\");"); oxy("xsEnableRule(\"_LOS2\");"); oxy("xsDisableRule(\"_LOS\");"); oxyZ("}} /*"); oxy("rule _LOS2 inactive runImmediately { "); oxy("if((trTime()-cActivationTime) >= 2.00000000){"); for(p=1; <cNumberPlayers) { oxy("trModifyProtounit(\"TownCenter\","+p+",2,-1000);"); } oxy("xsDisableRule(\"_LOS2\");"); oxyZ("}} /*"); oxy("rule _Fog inactive runImmediately { "); oxy("if(trPlayerActive(trCurrentPlayer())){"); oxy("trSetFogAndBlackmap(true,false);"); oxy("xsDisableRule(\"_Fog\");"); oxyZ("}} /*"); /* oxy("rule _Debug2 inactive runImmediately { "); oxy("if((trTime()-cActivationTime) >= 1.00000000){"); for(p=1; <cNumberPlayers) { oxy("xsSetContextPlayer("+p+");"); oxy("trChatSendSpoofed(0,trTime()+\"<color=0,255,255>P"+p+"Colonialize:<color=0,255,0>\"+kbTechGetStatus("+p+",284,8));"); } oxy("xsDisableRule(\"_Debug2\");"); oxyZ("}} /*"); */ oxy("rule _Debug24 inactive runImmediately { "); oxy("xsSetContextPlayer(1);"); oxy("if((trTime()-cActivationTime) >= 5.00000000){"); oxy("trChatSendSpoofed(0,trTime()+\"<color=0,255,255>P1Colonialize:<color=0,255,0>\"+kbTechGetStatus(421));"); oxy("xsDisableRule(\"_Debug24\");"); oxy("xsEnableRule(\"_Debug25\");"); oxyZ("}} /*"); oxy("rule _Debug25 inactive runImmediately { "); oxy("xsSetContextPlayer(1);"); oxy("if((trTime()-cActivationTime) >= 5.00000000){"); oxy("trChatSendSpoofed(0,trTime()+\"<color=0,255,255>P1Colonialize:<color=0,255,0>\"+kbTechGetStatus(421));"); oxy("xsDisableRule(\"_Debug25\");"); oxy("xsEnableRule(\"_Debug24\");"); oxyZ("}} /*"); oxy("rule _Debug26 inactive runImmediately { "); oxy("if((trTime()-cActivationTime) >= 10.00000000){"); for(p=1; <cNumberPlayers) { oxy("trUnitCreate(\"Learicorn\",\"Learicorn"+p+"\",0.5,0.5,0.5,0,"+p+");"); } oxy("xsDisableRule(\"_Debug26\");"); oxy("xsEnableRule(\"_Debug27\");"); oxyZ("}} /*"); oxy("rule _Debug27 inactive runImmediately { "); oxy("if((trTime()-cActivationTime) >= 10.00000000){"); for(p=1; <cNumberPlayers) { oxy("trUnitCreate(\"Learicorn\",\"Learicorn"+p+"\",0.5,0.5,0.5,0,"+p+");"); } oxy("xsDisableRule(\"_Debug27\");"); oxy("xsEnableRule(\"_Debug26\");"); oxyZ("}} /*"); oxy("rule _Debug28 active runImmediately { "); oxy("if((trTime()-cActivationTime) == 1.00000000){"); oxy("trChatSendSpoofed(0,\"<color=0,255,255>QQ Group:85442352\");"); oxy("trChatSendSpoofed(0,\"<color=0,255,255>QQ Group:347551328\");"); oxy("xsDisableRule(\"_Debug28\");"); oxyZ("}} /*"); oxy("rule _Debug30 inactive runImmediately { "); oxy("if((trTime()-cActivationTime) == 1.00000000){"); for(u=1; <1700) { oxy("trChatSend(0,\"<color=0,255,0>"+u+" <color=0,255,255>\"+kbGetUnitTypeName("+u+"));"); } oxy("xsDisableRule(\"_Debug30\");"); oxyZ("}} /*"); oxy("rule _Debug31 inactive runImmediately { "); oxy("if((trTime()-cActivationTime) == 1.00000000){"); for(u=1463; <1667) { oxy("trChatSend(0,\"<color=0,255,0>"+u+" <color=0,255,255>\"+kbGetUnitTypeName("+u+"));"); } oxy("xsDisableRule(\"_Debug31\");"); oxyZ("}} /*"); oxy("rule _Debug32 inactive runImmediately { "); oxy("if((trTime()-cActivationTime) == 1.00000000){"); oxy("trChatSend(0,\"<color=0,255,0>1111111111111111111<color=0,255,255>\");"); oxy("trChatSend(0,\"<color=0,1,0>1111111111111111111<color=0,255,255>\");"); oxy("trChatSend(0,\"<color=0,145,0>1111111111111111111<color=0,255,255>\");"); oxy("trChatSend(0,\"<color=255,255,0>1111111111111111111<color=0,255,255>\");"); oxy("trChatSend(0,\"<color=1,1,0>1111111111111111111<color=0,255,255>\");"); oxy("xsDisableRule(\"_Debug32\");"); oxyZ("}} /*"); oxy("rule _Debug33 inactive runImmediately { "); oxy("if((trTime()-cActivationTime) >= 0.00000000){"); for(p=0; <cNumberPlayers) { oxy("trModifyProtounit(\"Cannonball\","+p+",8,60);"); } oxy("xsDisableRule(\"_Debug33\");"); oxyZ("}} /*"); oxy("rule _Debug34 inactive runImmediately { "); oxy("if((trTime()-cActivationTime) >= 5.00000000){"); for(p=1; <cNumberPlayers) { if (rmGetPlayerCiv(p) >= 19 && rmGetPlayerCiv(p)<=26) { oxy("xsSetContextPlayer("+p+");"); oxy("trChatSendSpoofed(0,trTime()+\"<color=0,255,255>P"+p+"ypBigTradeTaxRemove:<color=0,255,0>\"+kbTechGetStatus(2398));"); oxy("trChatSendSpoofed(0,trTime()+\"<color=0,255,255>P"+p+"ypBigTradeTaxEnable:<color=0,255,0>\"+kbTechGetStatus(2399));"); oxy("trChatSendSpoofed(0,trTime()+\"<color=0,255,255>P"+p+"ypBigConsulateRussians:<color=0,255,0>\"+kbTechGetStatus(2110));"); oxy("trChatSendSpoofed(0,trTime()+\"<color=0,255,255>P"+p+"ypBigConsulateFrench:<color=0,255,0>\"+kbTechGetStatus(2112));"); /* oxy("trChatSendSpoofed(0,trTime()+\"<color=0,255,255>P"+p+"cUnitStateABQ(Consulate):<color=0,255,0>\"+kbUnitCount("+p+",922,cUnitStateABQ));"); */ oxy("trChatSendSpoofed(0,trTime()+\"<color=0,255,255>P"+p+"cUnitStateAlive(Consulate):<color=0,255,0>\"+kbUnitCount("+p+",922,cUnitStateAlive));"); oxy("trChatSendSpoofed(0,trTime()+\"<color=0,255,255>P"+p+"cUnitStateAliveOrBuilding(Consulate):<color=0,255,0>\"+kbUnitCount("+p+",922,cUnitStateAliveOrBuilding));"); oxy("trChatSendSpoofed(0,trTime()+\"<color=0,255,255>P"+p+"cUnitStateAny(Consulate):<color=0,255,0>\"+kbUnitCount("+p+",922,cUnitStateAny));"); oxy("trChatSendSpoofed(0,trTime()+\"<color=0,255,255>P"+p+"cUnitStateBuilding(Consulate):<color=0,255,0>\"+kbUnitCount("+p+",922,cUnitStateBuilding));"); oxy("trChatSendSpoofed(0,trTime()+\"<color=0,255,255>P"+p+"cUnitStateDead(Consulate):<color=0,255,0>\"+kbUnitCount("+p+",922,cUnitStateDead));"); oxy("trChatSendSpoofed(0,trTime()+\"<color=0,255,255>P"+p+"cUnitStateNone(Consulate):<color=0,255,0>\"+kbUnitCount("+p+",922,cUnitStateNone));"); oxy("trChatSendSpoofed(0,trTime()+\"<color=0,255,255>P"+p+"cUnitStateQueued(Consulate):<color=0,255,0>\"+kbUnitCount("+p+",922,cUnitStateQueued));"); } } oxy("xsEnableRule(\"_Debug35\");"); oxy("xsDisableRule(\"_Debug34\");"); oxyZ("}} /*"); oxy("rule _Debug35 inactive runImmediately { "); oxy("if((trTime()-cActivationTime) >= 5.00000000){"); for(p=1; <cNumberPlayers) { if (rmGetPlayerCiv(p) >= 19 && rmGetPlayerCiv(p)<=26) { oxy("xsSetContextPlayer("+p+");"); oxy("trChatSendSpoofed(0,trTime()+\"<color=0,255,255>P"+p+"ypBigTradeTaxRemove:<color=0,255,0>\"+kbTechGetStatus(2398));"); oxy("trChatSendSpoofed(0,trTime()+\"<color=0,255,255>P"+p+"ypBigTradeTaxEnable:<color=0,255,0>\"+kbTechGetStatus(2399));"); oxy("trChatSendSpoofed(0,trTime()+\"<color=0,255,255>P"+p+"ypBigConsulateRussians:<color=0,255,0>\"+kbTechGetStatus(2110));"); oxy("trChatSendSpoofed(0,trTime()+\"<color=0,255,255>P"+p+"ypBigConsulateFrench:<color=0,255,0>\"+kbTechGetStatus(2112));"); // oxy("trChatSendSpoofed(0,trTime()+\"<color=0,255,255>P"+p+"cUnitStateABQ(Consulate):<color=0,255,0>\"+kbUnitCount("+p+",922,cUnitStateABQ));"); oxy("trChatSendSpoofed(0,trTime()+\"<color=0,255,255>P"+p+"cUnitStateAlive(Consulate):<color=0,255,0>\"+kbUnitCount("+p+",922,cUnitStateAlive));"); oxy("trChatSendSpoofed(0,trTime()+\"<color=0,255,255>P"+p+"cUnitStateAliveOrBuilding(Consulate):<color=0,255,0>\"+kbUnitCount("+p+",922,cUnitStateAliveOrBuilding));"); oxy("trChatSendSpoofed(0,trTime()+\"<color=0,255,255>P"+p+"cUnitStateAny(Consulate):<color=0,255,0>\"+kbUnitCount("+p+",922,cUnitStateAny));"); oxy("trChatSendSpoofed(0,trTime()+\"<color=0,255,255>P"+p+"cUnitStateBuilding(Consulate):<color=0,255,0>\"+kbUnitCount("+p+",922,cUnitStateBuilding));"); oxy("trChatSendSpoofed(0,trTime()+\"<color=0,255,255>P"+p+"cUnitStateDead(Consulate):<color=0,255,0>\"+kbUnitCount("+p+",922,cUnitStateDead));"); oxy("trChatSendSpoofed(0,trTime()+\"<color=0,255,255>P"+p+"cUnitStateNone(Consulate):<color=0,255,0>\"+kbUnitCount("+p+",922,cUnitStateNone));"); oxy("trChatSendSpoofed(0,trTime()+\"<color=0,255,255>P"+p+"cUnitStateQueued(Consulate):<color=0,255,0>\"+kbUnitCount("+p+",922,cUnitStateQueued));"); } } oxy("xsEnableRule(\"_Debug34\");"); oxy("xsDisableRule(\"_Debug35\");"); oxyZ("}} /*"); oxy("rule _Debug36 inactive runImmediately { "); oxy("if((trTime()-cActivationTime) == 1.00000000){"); oxy("trTechSetStatus(1,116,2);"); oxy("trChatSend(0,trTime()+\"<color=0,255,0>Debug36 Active<color=0,255,255>\");"); oxy("xsDisableRule(\"_Debug36\");"); oxyZ("}} /*"); oxy("rule _Debug37 inactive runImmediately { "); oxy("if((trTime()-cActivationTime) == 1.00000000){"); oxy("for(i=1;<cNumberPlayers){xsSetContextPlayer(i);for(c=0;<2549){if(kbTechCostPerResource(c,6)>0){trTechSetStatus(i,c,0);}}}"); // oxy("for(i=1;<=cNumberNonGaiaPlayers){xsSetContextPlayer(i);for(c=0;<2549)"+"{if(kbTechCostPerResource(c,6)>0){trTechSetStatus(i,c,0);}}"); // oxy("for(i=1;<=cNumberNonGaiaPlayers[can not ues cNumberNonGaiaPlayers in "TR"]){}"); oxy("xsDisableRule(\"_Debug37\");"); oxyZ("}} /*"); oxy("rule _Debug38 inactive runImmediately { "); oxy("if((trTime()-cActivationTime) == 1.00000000){"); oxy("for(i=1;<cNumberPlayers){xsSetContextPlayer(i);if(kbGetCivForPlayer(i)==0){}}"); oxy("xsDisableRule(\"_Debug38\");"); oxyZ("}} /*"); oxy("rule _Debug40 inactive runImmediately { "); oxy("if((trTime()-cActivationTime) >= 5.00000000){"); for(p=1; <cNumberPlayers) { oxy("xsSetContextPlayer("+p+");"); oxy("trChatSendSpoofed(0,trTime()+\"<color=0,255,255><color=0,255,0>\"+kbGetCivName(kbGetCiv()));"); oxy("if(kbGetCivName(kbGetCiv()) == \"chinese\"){"); oxy("trChatSendSpoofed(0,trTime()+\"<color=0,255,255><color=0,255,0>\"+kbGetCivName(kbGetCiv()));}"); } oxy("xsDisableRule(\"_Debug40\");"); oxy("xsEnableRule(\"_Debug41\");"); oxyZ("}} /*"); oxy("rule _Debug41 inactive runImmediately { "); oxy("if((trTime()-cActivationTime) >= 5.00000000){"); for(p=1; <cNumberPlayers) { oxy("xsSetContextPlayer("+p+");"); oxy("trChatSendSpoofed(0,trTime()+\"<color=0,255,255><color=0,255,0>\"+kbGetCiv());"); } oxy("xsDisableRule(\"_Debug41\");"); oxy("xsEnableRule(\"_Debug40\");"); oxyZ("}} /*"); oxy("rule _Debug42 active runImmediately { "); oxy("if((trTime()-cActivationTime) == 1.00000000){"); oxy("trChatSendSpoofed(0,\"cMapResources:"+cMapResources+"\");"); oxy("trChatSendSpoofed(0,\"cMapSize:"+cMapSize+"\");"); oxy("trChatSendSpoofed(0,\"cConnectEnemies:"+cConnectEnemies+"\");"); oxy("trChatSendSpoofed(0,\":cConnectAllies"+cConnectAllies+"\");"); oxy("trChatSendSpoofed(0,\":cConnectPlayers"+cConnectPlayers+"\");"); oxy("trChatSendSpoofed(0,\":cConnectAreas"+cConnectAreas+"\");"); oxy("trChatSendSpoofed(0,\"cRandomMapName\");"); oxy("trChatSendSpoofed(0,\"cMyTeam\");"); oxy("xsDisableRule(\"_Debug42\");"); oxyZ("}} /*"); for(i=1; <cNumberPlayers) { /* if (rmGetPlayerCiv(i) >= 19 && rmGetPlayerCiv(i)<=26) { oxy("rule _CheckConsulate"+i+" inactive runImmediately { "); oxy("if(trPlayerActive("+i+")){"); oxy("if(trTechStatusCheck("+i+",2399,2)){"); oxy("xsDisableRule(\"_CheckConsulate"+i+"\");"); oxyZ("}} /*"); } */ } /* oxy("rule _Debug inactive runImmediately { "); oxy("xsSetContextPlayer(1);"); oxy("int cc=kbUnitCount(1,1509,8);"); oxy("if((trTime()-cActivationTime) >= 1.00000000){"); oxy("if(cc >= 1.00000000){"); oxy("trChatSend(1,\"\"+cc);"); //oxy("xsEnableRule(\"_Debug1\");"); //oxy("xsDisableRule(\"_Debug\");"); oxyZ("}}} /*"); oxy("rule _Debug1 inactive runImmediately { "); oxy("if((trTime()-cActivationTime) >= 1.00000000){"); for(p=1; <cNumberPlayers) { oxy("xsSetContextPlayer("+p+");"); oxy("trChatSendSpoofed(0,trTime()+\"<color=0,255,255>P"+p+"Settler:<color=0,255,0>\"+kbUnitCount("+p+",284,8));"); oxy("trChatSendSpoofed(0,trTime()+\"<color=0,255,255>P"+p+"Unit:<color=0,255,0>\"+kbUnitCount("+p+",1463,8));"); oxy("trChatSendSpoofed(0,trTime()+\"<color=0,255,255>P"+p+"All:<color=0,255,0>\"+kbUnitCount("+p+",1509,8));"); } oxy("xsEnableRule(\"_Debug\");"); oxy("xsDisableRule(\"_Debug1\");"); oxyZ("}} /*"); */ /* oxy("rule _SocketCount active runImmediately { "); oxy("for(UnittypeID=3000;>-1){if(kbGetUnitTypeName(UnittypeID) ==\"TownCenter\") Break;}"); oxy("if((trTime()-cActivationTime) == 1.00000000){"); oxy("trQuestVarSet(\"cSocketCount\",kbUnitCount(1,928,cUnitStateAny));"); oxy("xsDisableRule(\"_SocketCount\");"); oxyZ("}} /*"); oxy("rule _SentSocketCount active runImmediately { "); oxy("if((trTime()-cActivationTime) >= 5.00000000){"); oxy("trChatSendSpoofed(0,trTime()+\"<color=0,255,255>SocketCount:<color=0,255,0>\"+trQuestVarGet(\"cSocketCount\"));"); oxy("trChatSendSpoofed(0,trTime()+\"<color=0,255,255>SocketCount:<color=0,255,0>\"+kbUnitCount(1,928,cUnitStateAny));"); oxy("trChatSendSpoofed(0,trTime()+\"<color=0,255,255>SocketCount:<color=0,255,0>\"+kbGetUnitTypeName(928));"); oxyZ("}} /*"); */ oxy("rule _Temp inactive { if(true){"); oxyZ("xsDisableSelf();"); // ************************************************* New Trigger ************************************************* // rmCreateTrigger("SocketCountStart active runImmediately{xsSetContextPlayer(0);for(UnittypeID=3000;>-1){if(kbGetUnitTypeName(UnittypeID)"+"==\"SocketTradeRoute\") Break;}if(trTime()==0)"+"{trQuestVarSet(\"SocketCount\",kbUnitCount(0,UnittypeID,255));xsDisableSelf();}}/*"); // rmCreateTrigger("SocketCountStart active runImmediately{xsSetContextPlayer(0);if(trTime()==1)"+"{trQuestVarSet(\"SocketCount\",kbUnitCount(0,490,255));xsDisableSelf();}}/*"); // rmCreateTrigger("*/rule _SocketCountEnd"); // ******************************************* rmCreateTrigger不受中文路径影响,但不支持空格,一个触发总字符总数有上限,大概输出255字符后就无法继续输出。 // ******************************************* 与上面的规则触发一样,一对引号""内只能输入125个字符,超过就需要用加号附加另一对引号"" // ******************************************* 例如:"这里有125个字符"+"11111" // ******************************************* 一对引号""内需要增加另一对引号需要使用转义字符\"\",例如:" \"1111\" " // ******************************************* rmCreateTrigger不能使用/**/形式的注释。该触发联机可用 int SC1 = rmGetUnitPlaced(socketID, 0); int SC2 = rmGetUnitPlaced(socketID, 0)+1; int SC3 = rmGetUnitPlaced(socketID, 0)+2; int SC4 = rmGetUnitPlaced(socketID, 0)+3; int SC5 = rmGetUnitPlaced(socketID, 0)+4; //用贸易站下一个单位ID减去贸易站ID float SC0 = rmGetUnitPlaced(TreeID,0)-rmGetUnitPlaced(socketID,0); if(SC0== 1) { for(i=1; <cNumberPlayers) { rmCreateTrigger("CustomStart"+i+" active runImmediately{if(trPlayerControlsSocket("+i+",\"\"+"+SC1+")){trChatSend(0,\"Player"+i+" ABCDEFG:\");xsDisableSelf();}}/*"); rmCreateTrigger("*/rule _CustomEnd"+i); } } if(SC0== 2) { for(i=1; <cNumberPlayers) { rmCreateTrigger("CustomStart"+i+" active runImmediately{if(trPlayerControlsSocket("+i+",\"\"+"+SC1+")&&trPlayerControlsSocket("+i+",\"\"+"+SC2+")){trChatSend(0,\"Player"+i+" ABCDEFG:\");xsDisableSelf();}}/*"); rmCreateTrigger("*/rule _CustomEnd"+i); } } if(SC0== 3) { for(i=1; <cNumberPlayers) { rmCreateTrigger("CustomStart"+i+" active runImmediately{if(trPlayerControlsSocket("+i+",\"\"+"+SC1+")&&trPlayerControlsSocket("+i+",\"\"+"+SC2+")&&trPlayerControlsSocket("+i+",\"\"+"+SC3+")){trChatSend(0,\"Player"+i+" ABCDEFG:\");xsDisableSelf();}}/*"); rmCreateTrigger("*/rule _CustomEnd"+i); } } if(SC0== 4) { for(i=1; <cNumberPlayers) { rmCreateTrigger("CustomStart"+i+" active runImmediately{if(trPlayerControlsSocket("+i+",\"\"+"+SC1+")&&trPlayerControlsSocket("+i+",\"\"+"+SC2+")&&trPlayerControlsSocket("+i+",\"\"+"+SC3+")&&trPlayerControlsSocket("+i+",\"\"+"+SC4+")){trChatSend(0,\"Player"+i+" ABCDEFG:\");xsDisableSelf();}}/*"); rmCreateTrigger("*/rule _CustomEnd"+i); } } if(SC0== 5) { for(i=1; <cNumberPlayers) { rmCreateTrigger("CustomStart"+i+" active runImmediately{if(trPlayerControlsSocket("+i+",\"\"+"+SC1+")&&trPlayerControlsSocket("+i+",\"\"+"+SC2+")&&trPlayerControlsSocket("+i+",\"\"+"+SC3+")&&trPlayerControlsSocket("+i+",\"\"+"+SC4+")&&trPlayerControlsSocket("+i+",\"\"+"+SC5+")){trChatSend(0,\"Player"+i+" ABCDEFG:\");xsDisableSelf();}}/*"); rmCreateTrigger("*/rule _CustomEnd"+i); } } // 注:rmCreateTrigger不支持输出空格,可使用tab字符作为代替。如果需要输出聊天时可以用{StringID} // xsDisableSelf();为关闭触发本身,等同于rmSetTriggerLoop(false);;如果不关闭触发就会变成循环触发,等同于rmSetTriggerLoop(true);。 // 因为rmCreateTrigger要创建一个结束触发来辅助上一个触发生成,虽然没有影响,但是可以另开一个触发关闭这些触发。 rmCreateTrigger("DisableStart active runImmediately{xsDisableSelf();for(p=1;<cNumberPlayers)"+"{xsDisableRule(\"_CustomEnd\"+p);xsDisableRule(\"_DisableEnd\");}}/*"); rmCreateTrigger("*/rule _DisableEnd"); // 注意rmCreateTrigger引号""里面的for循环不要有空格,否则会输出为字符_ ;就是这个字符“_”,然后导致触发程序失效。 /* //********************************************************************************************************************************** <Condition name="Player Controls Socket"> <Param name="PlayerID" dispName="$$22301$$Player" VarType="player">1</Param> <Param name="Socket" dispName="$$32975$$Socket" VarType="unit">default</Param> <Expression>trPlayerControlsSocket(%PlayerID%, "%Socket%")</Expression> </Condition> "%Socket%"为剧情名,所以不能使用加减法。例如""+1=1;""+1+1=11。加减法可以在RM层进行,往上搜索int SC2。 旧版本触发,只列举5个贸易站,其他不列出 for(i=1; <cNumberPlayers) { rmCreateTrigger("FourOfAKind"+i); rmSwitchToTrigger(rmTriggerID("FourOfAKind"+i)); rmSetTriggerActive(true); rmSetTriggerRunImmediately(true); rmSetTriggerLoop(false); rmSetTriggerPriority(4); rmAddTriggerCondition("Player Controls Socket"); rmSetTriggerConditionParamInt("PlayerID", i, false); rmSetTriggerConditionParam("Socket", ""+SC1, false); rmAddTriggerCondition("Player Controls Socket"); rmSetTriggerConditionParamInt("PlayerID", i, false); rmSetTriggerConditionParam("Socket", ""+SC2, false); rmAddTriggerCondition("Player Controls Socket"); rmSetTriggerConditionParamInt("PlayerID", i, false); rmSetTriggerConditionParam("Socket", ""+SC3, false); rmAddTriggerCondition("Player Controls Socket"); rmSetTriggerConditionParamInt("PlayerID", i, false); rmSetTriggerConditionParam("Socket", ""+SC4, false); rmAddTriggerCondition("Player Controls Socket"); rmSetTriggerConditionParamInt("PlayerID", i, false); rmSetTriggerConditionParam("Socket", ""+SC5, false); rmAddTriggerEffect("Send Chat"); rmSetTriggerConditionParamInt("PlayerID", i, false); //旧版本触发不支持("PlayerID", 0, false);;ID 0为以大自然身份发送消息 rmSetTriggerEffectParam("SetName","hc_revolution"); rmSetTriggerEffectParam("Message","Player"+i+"ABCDEFG"); } */ //******************************************************************************************************************************** } //END