こはね 发表于 2019-10-11 01:53:35

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

<span style="font-size:16px;">先弄懂一件事,什么叫剧情名(ScenarioName)?剧情名是单位在一场游戏或剧情的string代码,,一般情况下不可能出现重复,剧情名从0开始计算,每增加一个单位。那个单位的剧情名就+1。
什么情况下会出现重复剧情名?用触发程序刷出的单位都是可以自己定义剧情名的,这种情况可以出现重复剧情名。
如何在地图编辑器获取剧情名?
我们通过帝国时代3编辑器的vartype ="unit"选项选取单位获取剧情名
<style>
.PictureClass td{border:solid windowtext 1.0pt;}
.TableClass td{border:solid windowtext 1.0pt;}
.PictureClass{width:0vw;}
.TableClass{width:0vw;}
pre{white-space: pre-wrap;word-wrap:break-word;font-family:Calibri,宋体;}
</style>
<pre style="font-family:calibri,宋体;font-size:14px;white-space: pre-wrap;word-wrap: break-word;">    &lt;Condition name="条件名称"&gt;
      &lt;Param name="选项调用名" dispName="$$22534$$显示名称,在前面加上$$xxxxx$$表示调用stringtabley.xml的名称" <font color="#ff0000">VarType="player"</font>&gt;1&lt;/Param&gt;
      &lt;Param name="选项调用名" dispName="$$25424$$显示名称" <font color="#ff0000">VarType="kbstat"</font>&gt;预设值&lt;/Param&gt;
      &lt;Param name="选项调用名" dispName="$$32954$$显示名称" <font color="#ff0000">varType="string"</font>&gt;预设值&lt;/Param&gt;
      &lt;Param name="选项调用名" dispName="$$22297$$显示名称" <font color="#ff0000">varType="operator"</font>&gt;预设值&lt;/Param&gt;
      &lt;Param name="选项调用名" dispName="Value" <font color="#ff0000">VarType="float"</font>&gt;预设值&lt;/Param&gt;
      &lt;Expression&gt;此处输入条件(触发程序),自行参考kb或者tr命令表可以使用%选项调用名%调用上面的选项值&lt;/Expression&gt;
    &lt;/Condition&gt;
    &lt;Effect name="效果名称"&gt;
      &lt;Param name="选项调用名" dispName="$$22348$$显示名称,在前面加上$$xxxxx$$表示调用stringtabley.xml的名称" <font color="#ff0000">VarType="group"</font>&gt;default&lt;/Param&gt;
      &lt;Param name="选项调用名" dispName="$$22434$$ProtoName" <font color="#ff0000">varType="protounit"</font>&gt;预设值&lt;/Param&gt;
      &lt;Param name="选项调用名" dispName="显示名称" <font color="#ff0000">varType="area"</font>&gt;预设值&lt;/Param&gt;
      &lt;Param name="选项调用名" dispName="显示名称" <font color="#ff0000">VarType="string"</font>&gt;预设值&lt;/Param&gt;
      &lt;Param name="选项调用名" dispName="显示名称" <font color="#ff0000">varType="long"</font>&gt;预设值&lt;/Param&gt;
      &lt;Param name="选项调用名" dispName="显示名称" <font color="#ff0000">varType="bool"</font>&gt;预设值&lt;/Param&gt;
      &lt;Command&gt;此处输入触发程序,自行参考kb或者tr命令表,可以使用%选项调用名%调用上面的选项值&lt;/Command&gt;
    &lt;/Effect&gt;
</pre>(提示:如果手机屏幕不够大可以从右向左滑动显示表格,推荐使用电脑查看本帖)
<div style="width:98%;overflow-x:auto;"><table class="PictureClass" style="color:black"><tr>
<td>varType</td>
<td>描述</td>
<td>返回值</td>
</tr>
<tr>
<td>bool</td>
<td><img src="Age_of_Empires_III_Modding_Tutorial/99/bool.png"><br>返回true或false</td>
<td>true、false</td>
</tr>
<tr>
<td>area</td>
<td><img src="Age_of_Empires_III_Modding_Tutorial/99/area.png"><br>选取一个位置。</td>
<td>Vector坐标(X,Y,Z)</td>
</tr>
<tr>
<td>unit</td>
<td><img src="Age_of_Empires_III_Modding_Tutorial/99/unit.png"><br>选择一个单位。<br>返回剧情名(ScenarioName),第一个创建的单位的剧情名为0</td>
<td>ScenarioName</td>
</tr>
<tr>
<td>long</td>
<td><img src="Age_of_Empires_III_Modding_Tutorial/99/input.png"><br>输入数值框,只能输入数值。</td>
<td>所输入的值</td>
</tr>
<tr>
<td><a href="thread-87-1-1.html">更多</a></td>
<td>其他vartype值请参考<a href="thread-87-1-1.html">https://www.aoebbs.net/thread-87-1-1.html</a></td>
<td><a href="thread-87-1-1.html">✡传送门</a></td>
</tr>
</table></div>
<br/>
<br/>
<br/>
<b><span style="color:red">UnitID有什么用?如何在剧情编辑器获取UnitID的值?</span></b>
<br/>
UnitID可以看作是每个单位的身份证,都是独一无二的,不会出现重复。一般来说UnitID从0开始按顺序计算;只要未出现过单位死亡UnitID与ScenarioName是一致的,但是当单位出现死亡后,UnitID就会被打乱,在地图会变成26万的数值,在剧情则会变成原UnitID+1;所以当出现单位死亡后我们无法使用vartype ="unit"选项来准确获取UnitID。
<br/>
<br/>
UnitID的作用如下,下面的命令都是采用UnitID,当我们需要设计触发程序时使用这些命令的时候,就必须要使用UnitID。
<pre style="font-family:calibri,宋体;font-size:14px;white-space: pre-wrap;word-wrap: break-word;">
[(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.
</pre>
<br/>
既然无法使用vartype ="unit"准确获取UnitID,那么我们还有办法获取UnitID吗?
<br/>
<br/>答案是有的,在KB命令表有一个"[(int   )] kbGetBlockID( string blockName ): Returns the UnitID of the cinematic block. ",经过我的测试,这个命令能将ScenarioName转换成UnitID,并且返回UnitID的值。
<br/>我们可以在vartype ="unit"的基础上使用kbGetBlockID,这样就能准确获取编辑器上的UnitID了。
</span>
<br/>
<br/>
<br/>
<br/>
<br/><span style="font-size:22px;">下面是一个获取UnitID的例子:</span>
<span style="font-size:16px;">
打开帝国3目录的trigger3文件夹,我们来设计一个触发程序,让它能获取UnitID,并且输出到聊天窗口。
(你可以修改<span style="color:red">typetest.xml</span>;或者自己创建一个与typetest.xml结构一样的新xml文件)
</pre>(提示:如果手机屏幕不够大可以从右向左滑动显示表格,推荐使用电脑查看本帖)
<div style="width:98%;overflow-x:auto;">
<table class="TableClass">
<tr>
<td><pre>        &lt;Effect name="*Advanced Get UnitID Test"&gt;</td>
<td>触发程序的名称为*Advanced Get UnitID Test</td>
</tr>
<tr>
<td><pre>                &lt;Param name="<span style="color:blue">Player</span>" dispName="player" VarType="player"&gt;&lt;/Param&gt;</td>
<td>玩家选项,为什么要用到玩家选项?以下会讲到。</td>
</tr>
<tr>
<td><pre>                &lt;Param name="<span style="color:red">DstObject</span>" dispName="Target Unit" varType="unit"&gt;default&lt;/Param&gt;</td>
<td>vartype ="unit",返回剧情名的选项<img src="Age_of_Empires_III_Modding_Tutorial/99/unit.png"></td>
</tr>
<tr>
<td><pre>                &lt;Command&gt;xsSetContextPlayer(<b>%</b><span style="color:blue">Player</span><b>%</b>);&lt;/Command&gt;</td>
<td>KB大部分命令都需要xsSetContextPlayer设定玩家,否则会出问题,所以这里调用玩家选项(懒得去测试kbGetBlockID是否需要xsSetContextPlayer;直接加上最保险)</td>
</tr>
<tr>
<td><pre>                &lt;Command&gt;trChatSend(0,"ScenarioName:&amp;lt;color=0,1,0.4&amp;gt;<b>%</b><span style="color:red">DstObject</span><b>%</b>");&lt;/Command&gt;</td>
<td>trChatSend发送到聊天窗口,前面的0是玩家ID,你可以修改成<b>%</b><span style="color:blue">Player</span><b>%</b>这样就变成你设定的玩家发送信息了。<b>%</b><span style="color:red">DstObject</span><b>%</b>会自动变成你在剧情编辑器选取的单位,即为剧情名。</td>
</tr>
<tr>
<td><pre>                &lt;Command&gt;trChatSend(0,"UnitID:&amp;lt;color=0,1,0.4&amp;gt;"+kbGetBlockID(<b><span style="color:orange">"</span<</b>%DstObject%<b><span style="color:orange">"</span></b>));&lt;/Command&gt;</td>
<td>为什么这里会出现""+?因为trChatSend第二个函数为信息内容,引号里面的字符会变成纯字符输出,即使你在引号里面添加命令也会变成纯字符,但是你又想调用其他数值,这个时候你只能使用""+,例如""+kbGetBlockID("xxx")就等于将转换后的UnitID加入到聊天信息内容里面。另外注意一下kbGetBlockID这个命令的函数是带有引号""的,这个是string字符,必须添加引号,否则会导致所有触发程序失效。</td>
</tr>
<tr>
<td><pre>        &lt;/Effect&gt;</td>
<td></td>
</tr>
</table>
</div>
另外&amp;lt;color=0,1,0.4&amp;gt;为改变文字颜色,具体参考<a href="Age_of_Empires_III_Modding_Tutorial/99-17AOE3RGB.htm">https://mod.aoebbs.net/99-17AOE3RGB.htm</a>
<pre>
        &lt;Effect name="*Advanced Get UnitID Test"&gt;
                &lt;Param name="Player" dispName="player" VarType="player"&gt;&lt;/Param&gt;
                &lt;Param name="DstObject" dispName="Target Unit" varType="unit"&gt;default&lt;/Param&gt;
                &lt;Command&gt;xsSetContextPlayer(%Player%);&lt;/Command&gt;
                &lt;Command&gt;trChatSend(0,"ScenarioName:&amp;lt;color=0,1,0.4&amp;gt;%DstObject%");&lt;/Command&gt;
                &lt;Command&gt;trChatSend(0,"UnitID:&amp;lt;color=0,1,0.4&amp;gt;"+kbGetBlockID("%DstObject%"));&lt;/Command&gt;
        &lt;/Effect&gt;
</pre>
<br/>
<br/>
<br/>先在剧情编辑器放一些单位,然后让他们打斗,等到有单位死亡,我们再用触发程序,检测是否对应
<br/>
<br/>
<br/>
<br/>
<br/>
<br/>
<br/>
<br/>
<br/>
<br/>
<br/>
<br/>
<br/>全部都与UI显示的变量值相同,所以kbGetBlockID能将剧情名转换从UnitID。
<br/>
<br/>最后重复一点:
<br/>当没有单位死亡的情况下UnitID与ScenarioName是一致的,但是哪怕只有一个单位死亡都会将UnitID打乱,这时候必须使用kbGetBlockID将剧情名转换成UnitID。
<br/>
<br/>
<br/>
</span>
页: [1]
查看完整版本: 帝国3剧情编辑器-触发程序获取UnitID