请选择 进入手机版 | 继续访问电脑版
收起左侧

[教程] 帝国3剧情编辑器-触发程序获取UnitID

[复制链接]
こはね发表于 2019-10-11 01:53:35
先弄懂一件事,什么叫剧情名(ScenarioName)?剧情名是单位在一场游戏或剧情的string代码,,一般情况下不可能出现重复,剧情名从0开始计算,每增加一个单位。那个单位的剧情名就+1。
什么情况下会出现重复剧情名?用触发程序刷出的单位都是可以自己定义剧情名的,这种情况可以出现重复剧情名。
如何在地图编辑器获取剧情名?
我们通过帝国时代3编辑器的vartype ="unit"选项选取单位获取剧情名

    <Condition name="条件名称">
<Param name="选项调用名" dispName="$$22534$$显示名称,在前面加上$$xxxxx$$表示调用stringtabley.xml的名称" VarType="player">1</Param>
<Param name="选项调用名" dispName="$$25424$$显示名称" VarType="kbstat">预设值</Param>
<Param name="选项调用名" dispName="$$32954$$显示名称" varType="string">预设值</Param>
<Param name="选项调用名" dispName="$$22297$$显示名称" varType="operator">预设值</Param>
<Param name="选项调用名" dispName="Value" VarType="float">预设值</Param>
<Expression>此处输入条件(触发程序),自行参考kb或者tr命令表可以使用%选项调用名%调用上面的选项值</Expression>
</Condition>
<Effect name="效果名称">
<Param name="选项调用名" dispName="$$22348$$显示名称,在前面加上$$xxxxx$$表示调用stringtabley.xml的名称" VarType="group">default</Param>
<Param name="选项调用名" dispName="$$22434$$ProtoName" varType="protounit">预设值</Param>
<Param name="选项调用名" dispName="显示名称" varType="area">预设值</Param>
<Param name="选项调用名" dispName="显示名称" VarType="string">预设值</Param>
<Param name="选项调用名" dispName="显示名称" varType="long">预设值</Param>
<Param name="选项调用名" dispName="显示名称" varType="bool">预设值</Param>
<Command>此处输入触发程序,自行参考kb或者tr命令表,可以使用%选项调用名%调用上面的选项值</Command>
</Effect>
(提示:如果手机屏幕不够大可以从右向左滑动显示表格,推荐使用电脑查看本帖)






























varType 描述 返回值
bool
返回true或false
true、false
area
选取一个位置。
Vector坐标(X,Y,Z)
unit
选择一个单位。
返回剧情名(ScenarioName),第一个创建的单位的剧情名为0
ScenarioName
long
输入数值框,只能输入数值。
所输入的值
更多其他vartype值请参考https://www.aoebbs.net/thread-87-1-1.html✡传送门


UnitID有什么用?如何在剧情编辑器获取UnitID的值?

UnitID可以看作是每个单位的身份证,都是独一无二的,不会出现重复。一般来说UnitID从0开始按顺序计算;只要未出现过单位死亡UnitID与ScenarioName是一致的,但是当单位出现死亡后,UnitID就会被打乱,在地图会变成26万的数值,在剧情则会变成原UnitID+1;所以当出现单位死亡后我们无法使用vartype ="unit"选项来准确获取UnitID。

UnitID的作用如下,下面的命令都是采用UnitID,当我们需要设计触发程序时使用这些命令的时候,就必须要使用UnitID。

[(int )] kbUnitGetActionType( int unitID ): Returns the actionTypeID of the unit.

[(int )] kbUnitGetAreaID( int unitID ): Returns the area ID for this unit ID.

[(int )] kbUnitGetArmyID( int unitID ): Returns the army ID for this unit ID.

[(int )] kbUnitGetBaseID( int unitID ): Returns the base ID for this unit ID.

[(float )] kbUnitGetCurrentAICost( int unitID ): Returns the current AI cost (worth) for this unit ID.

[(float )] kbUnitGetCurrentHitpoints( int unitID ): Returns the current hitpoints for this unit ID.

[(float )] kbUnitGetHealth( int unitID ): Returns the health for this unit ID.

[(float )] kbUnitGetMaximumAICost( int unitID ): Returns the maximum AI cost (worth) for this unit ID.

[(float )] kbUnitGetMaximumHitpoints( int unitID ): Returns the maximum hitpoints for this unit ID.

[(int )] kbUnitGetMovementType( int unitTypeID ): Returns the movementType for this unitTypeID.

[(int )] kbUnitGetNumberWorkers( int unitID ): Returns the number of units currently working on the given unit.

[(int )] kbUnitGetPlanID( int unitID ): Returns the plan ID for this unit ID.

[(int )] kbUnitGetPlayerID(int unitID ): Returns the player ID for this unit ID.

[(vector)] kbUnitGetPosition( int unitID ): Returns the position for this unit ID.

[(int )] kbUnitGetProtoUnitID( int unitID ): Returns the unit's protounit ID.

[(int )] kbUnitGetTargetUnitID( int unitID ): Returns the target unit ID of the given unit.

[(int )] kbUnitGetWorkerID( int unitID, int index ): Returns the index-th worker unit ID.

[(bool )] kbUnitIsType( int unitID, long unitTypeID ): Returns true if the unit is of the unitTypeID.


既然无法使用vartype ="unit"准确获取UnitID,那么我们还有办法获取UnitID吗?

答案是有的,在KB命令表有一个"[(int )] kbGetBlockID( string blockName ): Returns the UnitID of the cinematic block. ",经过我的测试,这个命令能将ScenarioName转换成UnitID,并且返回UnitID的值。

我们可以在vartype ="unit"的基础上使用kbGetBlockID,这样就能准确获取编辑器上的UnitID了。


下面是一个获取UnitID的例子:

打开帝国3目录的trigger3文件夹,我们来设计一个触发程序,让它能获取UnitID,并且输出到聊天窗口。
(你可以修改typetest.xml;或者自己创建一个与typetest.xml结构一样的新xml文件)
(提示:如果手机屏幕不够大可以从右向左滑动显示表格,推荐使用电脑查看本帖)






























	<Effect name="*Advanced Get UnitID Test">
触发程序的名称为*Advanced Get UnitID Test
		<Param name="Player" dispName="player" VarType="player"></Param>
玩家选项,为什么要用到玩家选项?以下会讲到。
		<Param name="DstObject" dispName="Target Unit" varType="unit">default</Param>
vartype ="unit",返回剧情名的选项
		<Command>xsSetContextPlayer(%Player%);</Command>
KB大部分命令都需要xsSetContextPlayer设定玩家,否则会出问题,所以这里调用玩家选项(懒得去测试kbGetBlockID是否需要xsSetContextPlayer;直接加上最保险)
		<Command>trChatSend(0,"ScenarioName:&lt;color=0,1,0.4&gt;%DstObject%");</Command>
trChatSend发送到聊天窗口,前面的0是玩家ID,你可以修改成%Player%这样就变成你设定的玩家发送信息了。%DstObject%会自动变成你在剧情编辑器选取的单位,即为剧情名。
		<Command>trChatSend(0,"UnitID:&lt;color=0,1,0.4&gt;"+kbGetBlockID("%DstObject%"));</Command>
为什么这里会出现""+?因为trChatSend第二个函数为信息内容,引号里面的字符会变成纯字符输出,即使你在引号里面添加命令也会变成纯字符,但是你又想调用其他数值,这个时候你只能使用""+,例如""+kbGetBlockID("xxx")就等于将转换后的UnitID加入到聊天信息内容里面。另外注意一下kbGetBlockID这个命令的函数是带有引号""的,这个是string字符,必须添加引号,否则会导致所有触发程序失效。
	</Effect>


另外&lt;color=0,1,0.4&gt;为改变文字颜色,具体参考https://mod.aoebbs.net/99-17AOE3RGB.htm

<Effect name="*Advanced Get UnitID Test">
<Param name="Player" dispName="player" VarType="player"></Param>
<Param name="DstObject" dispName="Target Unit" varType="unit">default</Param>
<Command>xsSetContextPlayer(%Player%);</Command>
<Command>trChatSend(0,"ScenarioName:&lt;color=0,1,0.4&gt;%DstObject%");</Command>
<Command>trChatSend(0,"UnitID:&lt;color=0,1,0.4&gt;"+kbGetBlockID("%DstObject%"));</Command>
</Effect>


帝国3剧情编辑器-触发程序获取UnitID

帝国3剧情编辑器-触发程序获取UnitID

先在剧情编辑器放一些单位,然后让他们打斗,等到有单位死亡,我们再用触发程序,检测是否对应

帝国3剧情编辑器-触发程序获取UnitID

帝国3剧情编辑器-触发程序获取UnitID

帝国3剧情编辑器-触发程序获取UnitID

帝国3剧情编辑器-触发程序获取UnitID

帝国3剧情编辑器-触发程序获取UnitID

帝国3剧情编辑器-触发程序获取UnitID

帝国3剧情编辑器-触发程序获取UnitID

帝国3剧情编辑器-触发程序获取UnitID

帝国3剧情编辑器-触发程序获取UnitID

帝国3剧情编辑器-触发程序获取UnitID

帝国3剧情编辑器-触发程序获取UnitID

帝国3剧情编辑器-触发程序获取UnitID

全部都与UI显示的变量值相同,所以kbGetBlockID能将剧情名转换从UnitID。

最后重复一点:

当没有单位死亡的情况下UnitID与ScenarioName是一致的,但是哪怕只有一个单位死亡都会将UnitID打乱,这时候必须使用kbGetBlockID将剧情名转换成UnitID。

帝国3剧情编辑器-触发程序获取UnitID

帝国3剧情编辑器-触发程序获取UnitID

帝国3剧情编辑器-触发程序获取UnitID

帝国3剧情编辑器-触发程序获取UnitID
跳转到