【超级宏官方教程】【第三部分:进阶教程】【作者团联合撰写】
把你的宏推向新的境界!当你写宏写到一定程度的时候,你将会需要更强大的功能和更高级的编程技术,以便更能精确的解决各种问题。在之前,碍于各种功能限制,宏一直以来都只能满足基本循环而做不到极限循环和各种辅助,但是超级宏一些强大的功能足以让你用专业的编程态度去处理宏,打开PVE宏新的一页。
宏,从此不再是小打小闹的玩意儿。
如何写一个更高级的宏?写宏最需要以及最重要的东西可以归纳为就两件事:1. 宏本身的功能,此为硬性需求2. 你的编程技术,此为软性需求
硬性需求和软性需求的重要性用一个简单的例子来说明如果你有很强大的驾驶技术但是没有车或者只有老爷车,那你也成就不了什么东西而如果你有一流的跑车,但是很渣的驾驶技术,你不只成就不了任何东西,你甚至还会闹车祸搞出人命
硬性需求就好比跑车的品质,而软性需求就好比驾车的技术必须要两者都满足才可以达到更高的境界,好刀配名士,缺一不可
此教程所准备的硬性技术以及软性技术硬性技术为了能让写手们更快上手,我们准备了各种高级功能的教程,也包括了硬性的和软性的,都是由经验丰富的宏手写的
硬性技术教程有:1. if 功能2. 变量与自定义变量3. nowtime功能
软性技术教程有:1. 逻辑运算基础2. 宏控制3. 时间控制4. 表达式优化
硬性的东西很容易掌握,但是软性的东西却不,这好比跑车可以量产,但是驾驶技术好的人却不能量产所以软性的东西很多时候都得靠你自己,当然也不代表我们无从指导,不然的话也就不会有这个教程而有时候,是掌握了更高级的硬性技术后,更好的软性技巧也会自然而然学会就好像一辆跑车如果具备了更先进的控制系统,那么你就可以用锻炼出更犀利的转弯和刹车技术所以硬性东西也可以造就软性东西的进步,电脑也是如此,有了更强大的硬件才能刺激画面更强大的游戏的发展
编程就如同人类的其他技艺一样,是无止境的,唯有不停的努力才可以一直创造出新的高峰
希望你们有朝一日也可以成为一流的作者,深刻体会到写宏的乐趣,共勉之
第一节:逻辑运算基础插件基础逻辑运算及逻辑结构分析插件的逻辑运算,主要是根据lua的规则编写而成。lua的逻辑运算相当方便,使用lua的逻辑运算写宏,相当的方便。所有这些在编写过程中并不区分字母大小写。例如:
/Cast 无相诀
意思就是:如果“生命值比例小于0.3”,则释放技能“无相诀”一般来说“中括号”里面的都属于逻辑判断的内容!而无需判断,直接省略判断语句即可!
例如:
/Cast 无相诀
完全省略了判断语句,无需判断即能释放!1.真假判断在插件中,只有 false 会被判断为假,其他全部会被判断为真。例:/skill 后撤上例的意思 ,如果在战斗状态, 则释放后撤技能2.分句间的“且”“或”逻辑运算例句1:
/Cast 无相诀
其中逗号,是“且”运算,表示多个条件都成立
该句的意思是:如果“战斗状态中”并且“生命值比小于0.3”,则释放技能“无相诀”例句2:
/Cast 徐如林
其中分号,是“或”运算,表示多个条件其中之一成立
这句的意思是:如果“生命值比小于0.5” 或者 “内力值比小于0.5”,则释放技能“徐如林”例句3:/print /print 第一句,是连续三个判断,做“且”运算. 从左到右, 如果遇到值为false的,该判断的返回结果就是false(假). 否则会返回最后一个判断的值如果[在战斗状态][又存在目标][自身又在读条] 则会返回 的值,即自身的运功进度。第二句,连续三个判断,做“或”运算. 从左到右, 如果遇到值为真的 ,就会返回该判断的值, 否则会返回false(假,也是最后一个判断的值)如果 life<1 为假 , mana<1为真 ,则会返回mana<1的值,即true(真) , 最后一个判断根本不会进行判断。对于某些较为复杂的语句如何理解呢?例:
/cast 技能x
看起来是不是好复杂!不用怕,教你如何分解
可以看出来句子中,冒号后面的,用“&”“|”拆分后有4个部分
“aaa>2”、“bbb”、“ccc”、“ddd<3”
把这四个部分分别接上都前面的内容“buff:”,再将“&”换成逗号,将“|”换成分号,即:
就变成几个小短句了!就变成我们最熟悉的内容了!
相信你一定很容易就能掌握了!3.关于优先级例句:
/Cast 技能x
中括号的内容如何理解?
根据优先级,“或”运算(分号)的优先级 低于 “且”运算(逗号)的优先级
为了便于理解,用小括号分解中括号的内容即是:
[(fight,life<0.3) ; (nofight,mana<0.3)]
优先级高的逗号先结合,就给他加个括号!
意思就是:如果(fight,life<0.3)或者(nofight,mana<0.3),则释放技能“技能x”
是不是很容易嘛!
关于详细的运算优先级,请参见命令文档。4.其他的运算除了最基本的或且运算外,超级宏还提供了非运算、大小比较运算、数字五则运算等,
在使用的过程中,注意他们的优先级,弄不明白,可以用前面提到的加括号方法来整理语句,以便理解与运用!
同时,括号可以改变默认的结合优先级,更方便的写成想要的内容!5. if 结构插件支持标准的IF 结构,支持多层嵌套例:/if /skill 后撤/else/skill 蹑云逐月/end上句的意思是: 如果在战斗状态,则释放 [后撤] ,否则释放[蹑云逐月]。6. 用 ”或” ”且” 结构模拟 if 结构/if /var v_a/else/var v_a/end上句用到了自定义变量的结构.(详细请参加其他说明文档),代码的意思就是 如果战斗状态, 则赋值v_a为生命值 ,否则赋值为内力值。我们可以用逻辑运算来模拟这句代码的意思:/var v_a这句的意思跟上句是一模一样的。因为根据,插件的运算规则 ,对进行判断, 由于“且”的结合优先级比“或”高,他就等同于[(fight , life) ; mana]这样就类似两个分句的或运算,即(fight , life) 或 mana, 由于上面的例子讲到,或运算,返回遇到的第一个真的值,所以(fight , life)为真就返回他的值, 否则会返回 mana的值(真假与否都会返回)。fight , life 又是两个语句间的且运算, 且运算,返回第一个假,否则会返回最后一个值则,如果战斗状态,返回life的值,否则会返回false(假)。上面的串起来就是 .如果fight 返回life ,否则返回mana,跟if结构的逻辑一模一样。用 ”或” ”且” 结构模拟 if 结构 的一个例外/var [ fight , horse ; life]v_b用例5的分析,这句的意思就是 如果fight ,则赋值 horse ,否则 life但是,如果当fight为真,horse为假的时候. (fight , horse)总体的值为假,则运算结果为life即horse为假,无论fight的值为何,都会返回life的运算结果,这时用传统的IF结构才能胜任,如下:/if /var v_b/else/var v_b/end7.常见逻辑结构解析/skill 钟林毓秀 —第一句示例/skill 钟林毓秀 —第二句示例/skill [(tmbufftime:钟林毓秀 ; 0)<1.5]钟林毓秀–第三局句示例第一句 与 第二、三句表示的逻辑原理并不相同 返回的是 目标存在归属于自身的该buff的剩余时间,当目标有该buff的时候就会返回剩余时间, 当没有该buff的时候会返回false在插件中 false(假) 用来做大小比较/加减乘除余 运算的时候, 会返回false (假)即 会被判断为假所以第一句的意思是: 目标存在归属自身的该buff ,且剩余时间小于1.5秒的时候释放钟林毓秀,如果要表示没有该buff,或者该buff时间 小于1.5 秒,则为第二句 [ tnombuff:钟林毓秀 ; tmbufftime:钟林毓秀<1.5]用 ”或”运算但是从代码的简洁度及运算的速度来看,我们可以有更高级的表现方式第三句 其中的 (tmbufftime:钟林毓秀 ; 0)根据前面提到的逻辑运算方式 [ false ; 0 ]返回的是第一个遇到的 真,所以他等同于 0那么这个小分句的意思,就是 如果存在该buff,则返回时间, 不存在则返回0那么 [ (tmbufftime:钟林毓秀 ; 0)<1.5]的意思就可以表示为,存在该buff的时间小于1.5秒,或者不存在该buff,与第二句,完全一样! 提高 了简洁度,同时,tnombuff 的运算时间远比 一个 ”或” 运算的时间长,也提高了效率!http://121.199.25.18/wp-includes/js/tinymce/plugins/wordpress/img/trans.gif
第二节:条件判断(if结构)条件语句(If,Elseif,Else,End)
当您编写代码时,您常常需要为不同的判断执行不同的动作。 您可以在代码中使用条件语句来完成此任务。 if、elseif 以及else 语句用于执行基于不同条件的不同动作。 一般来说,if可以单用,但elseif和else是必须配合if使用的。有if结构的必须由end来闭合。1.if 语句在条件成立时执行一系列动作语法:/if [条件A] —-可多个条件并列/skill ……/var ……/end —每个if,必须要有一个配套的end,切记实例:/if /skill 打断,厥阴指 —-万花打断技能/end2.If…Else 语句 如果您希望在某个条件成立时执行一些代码,在条件不成立时执行另一些代码,请使用 if….else 语句。语法:
/if [条件A]/skill ……/var ……/else/skill ……/var ……/end —每个if,必须要有一个配套的end,切记实例:/if /ownp 无诗—万花ZB405武器/else/ownp 朱明承夜 —万花445特效武器/end3.ElseIf 语句 如果希望在多个条件之一成立时执行代码,请使用 elseif 语句:语法:
/if [条件A]/skill ……/var ……/elseif [条件B]/skill ……/var ……/elseif [条件C]/skill ……/var ……/end —每个IF必须要有一个配套的end实例:/var v_uy —定义一个存储商阳指剩余时间的变量/var v_vl —定义一个存储钟林毓秀剩余时间的变量/var v_lc —定义一个存储兰摧玉折剩余时间的变量/if /var v_dot/elseif /var v_dot/elseif /var v_dot/end教程是固定的,命令的用法却不是固定的,教程给的只是基础的用法,深入的用法,在不违反基本语法规则的情况下,还是得靠自己灵活的应用。
第三节:变量与自定义变量变量与自定义变量变量的基本含义例句1:
/Skill 无相诀变量的含义即是:每次运行都可能是不同的值。
变量一般都是写在方括号内进行逻辑运算,从而影响到一行语句的运行结果。
例句中,每次运行,life的值都可能是不同的值,从而影响到无相诀的施放,那么这里 life就是一个变量。
广泛一点,整个方括号内的也都可以看作一个变量。变量的类型目前插件的变量类型,有布尔型、数字型、字符串型。布尔型,即 “真”<true> ,假<false> 两种结果
/Skill 战八方
如的判断结果只有两种,<true><false>
变量值为<true>的时候,判断为真,执行技能[战八方]数字型,如life、mana、sun、moon 这类,是个数字
一般用来进行大小比较
例如:
/Skill 赤日轮字符串型,很少用到。暂不讲解!为了了解变量的类型,可以查阅说明文档中相关部分。
同时,插件提供了打印功能,可以打印出变量的运行结果
用这处理方式,就可以在聊天栏的黄字中看到输出的结果,便于宏的调试关于“真”与“假”/cast [...] 技能
类似这样的语句,中括号当中的判断结果,
如果是为<false>,那么就称之为“假”,就不会执行释放技能!
除<false>之外的所有值,都会被判断为真,而执行释放技能!自定义变量简析如例句1中,<life>这个变量是属于插件本身提供的判断。
而自定义变量,就是我们通过命令赋值,需要的时候再调用运算。所有的自定义变量名都是以“v_”开头,
/var定义或者修改变量的值,使用时如同插件本身的判断一样处理即可。例句2:
/var v_life
/Skill 无相诀上例句中,第一行通过/var 命令将life的值赋值给 自定义变量 v_life
第二行,直接引用变量进行判断,如同使用life一样宏头部自定义开关变量以“#”开头的宏头部命令中,#varbool、#varnum定义的开关,本质上也是一个自定义变量例句3:(一篇结构完整的简短的宏)
#name 自定义变量
#varbool v_a
#varnum v_b,2
/Skill 后撤
/Skill 扶摇直上上面的宏内容定义了两个开关,
一个是#varbool定义的开关,变量名为v_a,他的值在<true><false>之间切换,默认值为<true>
另外一个#varnum 定义的开关,变量名为v_b,他的值在<1><2>之间切换,默认值为<1>
后面两句/Skill的执行,完全依赖于这两个自定义变量的值自定义变量的生命周期#varbool、#varnum定义的变量,会在加载时设置默认值,会一直存在
未进行任何赋值操作的变量,默认返回值为<false>。
仅通过/var 命令赋值的变量,在游戏小退、修改宏之后会重置为<false>。
一般来说,超级宏里面有四种自定义变量1. varbool2. varbox3. varnum4. v_变量varnum是写法比较高明的varbox,故只剩下三种变种(其实严格来说还有一种,但是为了使教程通俗易懂,故不在此教程里面)首先说下varbool和varnum,varbool和varnum是用在头部的变量,可以改变宏的界面,让用户可以通过界面选择他要的功能,达到与用户沟通的目的,是超级宏的特点功能之一。当初的主流宏的功能还是很简单的时候,宏写手们都是冲着这个功能而纷纷改用超级宏,为剑三PVE宏打开了全新的一页,新手请务必马上熟练这个功能。varbool指的就是布尔(bool)的方式来定义一个变量,简单的说法就是,只有开和关。
写法是:#varboolv_变量的名字,tip:变量的作用,tip_1:开启状态,tip_2:关闭状态,Icon:1234分析:#varbool告诉插件你正在定义一个varbool变量v_变量的名字:就是在这里定义变量,必须以v_开头,超级宏所有的变量都是以v_开头,其次是变量名字非常重要,确保对宏写手来说易于辨认,因为需要在宏里面引用,写法不可以错tip这里就是告诉用户这个这个变量是做什么的,你要写什么都可以,迟些在宏里面不会引用到,因为只是给用户看的,建议写得直观点,让用户可以马上明白tip_1:如前面所说varbool有两个状态,开或者关(真或者假),所以tip_1就是解释第一个也就是默认的状态—-开。你写什么都可以,不过一般上都是写模式开启中之类的,同样的这个也不会引用在宏里面。还有不要把tip_1和tip搞乱,tip是向用户解释整体功能,tip_1是针对开关的状态解释。tip_2如果你已经明白tip_1那么tip_2也是同样的道理,只是tip_2是解释第二个开关,也就是关闭状态。icon:1234选择你要的图标,游戏里的图标都可以通过ctrl来查找iconID,如果不设置这点的话,将会使用默认太极图图标。那么要怎样在码里面引用这个varbool呢?很简单:/skill 技能因为【v_变量的名字】非假即真,直接使用就可以例子#varboolv_自动扶摇,tip:扶摇模式,tip_1:开启状态,tip_2:关闭状态,Icon:1485http://121.199.25.18/wp-content/uploads/2013/12/QQ%E6%88%AA%E5%9B%BE20131218094756-80x40.jpg http://121.199.25.18/wp-content/uploads/2013/12/QQ%E6%88%AA%E5%9B%BE20131218094835-80x44.jpg/skill 扶摇直上
varnum理解了varbool那么varnum就很好理解了,varnum其实是更加弹性的varbool,varbool只能有两种状态,而varnum却可以拥有一个直到N状态,也就是说varbool能做到的varnum都能做到,varnum能做到的varbool未必能做到,写法是:#varnumv_变量名字 ,3 ,tip:变量的作用, tip_1:开关1的作用, tip_2:开关2的作用, tip_3:开关3的作用, Icon_1:1111, Icon_2:2222, Icon_3:3333varnum的解释和varbool一样,所以这里就只解释当中的差别3
这个代表的是有3个状态,可以设置1~n个状态,不过1是没有意义,所以实用上是2~n个状态tip_n的数量就看你有多少个状态了,icon也是不过varbool虽然有两个状态但是icon只有一个,那是因为varbool是非假即真,图标只是亮着(真)和不亮(假),一个图标就可以代表两个状态。例子#varnumv_日月模式 ,3 ,tip:明教技能模式, tip_1:自动模式, tip_2:主日模式, tip_3:主月模式, Icon_1:3869, Icon_2:3868, Icon_3:3808http://121.199.25.18/wp-content/uploads/2013/12/QQ%E6%88%AA%E5%9B%BE20131218101319-80x36.jpg http://121.199.25.18/wp-content/uploads/2013/12/QQ%E6%88%AA%E5%9B%BE20131218101337-80x37.jpghttp://121.199.25.18/wp-content/uploads/2013/12/QQ%E6%88%AA%E5%9B%BE20131218101350-80x37.jpg在宏里面引用的话:/skill 自动模式的循环/skill 主日模式的循环/skill 主月模式的循环与varbool不同,必须使用=n来决定当前状态
v_变量这可谓是超级宏的精髓了,这个非头部的可自定义变量,你可以用也可以完全不用,因为其功能是让你的宏的结构更高明,变化更弹性,主要是用来改善宏的写法,但是在比较高级的用法会无可避免的需要用到这自定义变量不过不在这教程的讨论范围之内。使用v_变量的方法就是赋值,赋值何解?赋值就是,代数字上来说,如果我们要定义a为1的话,写法就是a=1,这就是赋值v_变量可以存很多种类的数值,当中包括–数字12345–真假true false–字符串每一种方式都可以用直接与非直接方式赋值接下来我们就看看如何为v_变量进行各种赋值,如果要检查的话,可以用print来检查结果尝试以下数字赋值:直接方式:/var v_数字/print 打印12345间接方式/var v_数字/print 打印你现在公共cd的时间尝试以下真假赋值:直接方式:/var v_真假/print 打印true间接方式:/var v_战斗/print 如果在战斗中会打印true反之会打印false尝试以下的字符串赋值:直接方式/var v_string
/print 就会打印xxx间接方式/var v_string/print 就会打印目标的名字以上的功能都非常强大,请务必尽快掌握
第四节:时间戳(nowtime)时间戳——nowtime参数<nowtime>/<now>基本含义该参数返回的当前时间,单位为秒。其数值本身没有实际意义。他的常见使用方式为:
1)某一个特殊时刻,将now赋值给某一个自定义变量
2)通过该变量与now进行大小比较判断,执行需要的语句示例一:对某部分语句进行执行频率限制有某玩家遇到由于网络延迟,导致切换武器不停变化。
由此提出能不能只对换武器的语句段落进行频率限制,限制他0.5秒只执行一次!
so easy,好吧!使用<nowtime>命令帮助你!示例:
/If
/Var v_Mark…/end如上例,模拟上面语句执行过程:第一次执行,v_mark尚未赋值,返回值为<false>,从而[(v_Mark;0)]执行结果为0,
接着判断为真,就进入/If内部语句的执行。接着对v_Mark赋值为<现在的时间+0.5秒>。执行换武器语句段.第二次执行,<v_mark>为数值,即为进行的判断,
如果两次间隔小于0.5秒,那么判断为假,其内部语句不会执行。
如果间隔大于0.5秒,判断为真,则执行/if内部的语句,赋值,切换武器等…完美地对换武器语句进行了限制对抗服务器延迟,解决冰心4玳弦问题由于超级宏释放技能之间缝隙极小,外加服务器及网络的延迟因素导致的玳弦急曲第三段的效果延迟出现
从而使使用用常规语句的宏会多打一次玳弦
那么,我们可以从now入手,解决这个问题/If
/if –识别第三段快结束时的时刻
/Var v_marktime –赋值自定义变量,进行标记
/end
/Return –保护引导
/end/Skill 剑气长江
/Skill 剑气长江 –预判急曲已经三层
/Skill 玳弦急曲上面示例通过now的时间轴变量,预判了急曲buff层数,从而完美地解决了这个问题。
也可以看作是模拟手动的一种方式!
第五节:宏控制宏控制首先恭喜读者你跳过/看懂了前面的人写的乱七八糟的东西,进入到了这个小节。 注意:这个小节的部分内容需要你能够了解前面大部分内容,并且有一定的宏基础的情况下再仔细研读。本小节主要要针对的内容,是如何控制宏的各语句运行。 由于众所周知的原因,初涉写宏的新人经常会发现,在不必要的时候打了不必要的技能,技能顺序混乱,或者出于输出的需要要调整一部分技能的顺序,这些需求会越来越多。本节将要讲的,是如何应用超级宏的函数,对这些进行控制。1.顺序控制由于众所周知的原因,超级宏的代码是逐行运行的。例如:Code 1-1
/skill [条件A]技能A
/skill 技能B
/skill 技能A那么宏在执行的时候会首先判断:如果满足了条件A,那么执行技能A(当然这里会有一个合法释放的前提,如果技能A不能被释放,那么自然不会释放);然后顺序执行下一行,执行技能B,再下一行,执行技能A,结束。但是事实上,如果技能A和技能B之间有公共CD,那么技能B和后续的技能A均会被公共CD限制,从而,一旦执行成功一个技能,那么后面的技能会进入公共CD而无法执行。顺序控制在宏的写作过程中,都已经被有意识的应用于宏的各个角落,但毫无疑问,通过调整语句顺序来控制技能顺序,是控制中最简便的一种。然而,大多数情况下,当我们遇到问题时,简单的顺序控制无法达成其应有的效果。2./if顺序控制的原理,是各技能之间有公共CD,通过公共CD使技能不能发动而达成限制后续技能执行,从而达到控制执行顺序的问题。然而,并非所有的技能都与大部分技能公共CD。每个门派都或多或少有一些非常重要但没有公共CD的技能,包括特效腰坠的使用也是没有公共CD的。此外,如果在引导读条中通过宏发动了非引导读条技能,那么会中断引导读条。如上例,若技能A是一个引导读条技能,那么假如条件A是真,技能A的读条会一闪而逝,因为其读条被技能B的执行强制打断。另有一些情况下,简单的使用顺序调整,无法达到控制技能发动的目的,此时,/if就会派上用场。与/if相配合的是/else(/elseif)和/end。使用/if可以简单的控制一个技能序列是否在指定的条件下执行,同时可以使用/if来合并多个相同条件的技能的使用。例如:以下语句用来实现,只在条件1下执行这些技能序列:Code 2-1/if [条件1]/skill 技能A/var v_参数A/skil 技能B/print /end以下是一个技能序列:Code 2-2/skill [条件1]技能A
/skill [条件1,条件3]技能B
/skill [条件1,条件2,条件3]技能C/skill [条件1,条件4,!条件3]技能D/skill [!条件1,条件2]技能B/skill [!条件1,条件3]技能D上面的技能序列可以使用/if合并为:Code 2-3/if [条件1]/skill 技能A/skill [条件3]技能B/skill [条件2,条件3]技能C/skill [条件4,!条件3]技能D/else/skill [条件2]技能B/skill [条件3]技能D/end
3.更多的/if使用/if,可以简单的为多个技能或技能组合划定发动条件,同时使我们的宏看上去高端大气上档次了很多。如果有必要,可以在/if里面再用一个/if。例如,上面的code 2-3还可以写作:Code 3-1/if [条件1]/skill 技能A/if [条件3]/skill 技能B/skill [条件2]技能C/else/skill [条件4]技能D/end/else/skill [条件2]技能B/skill [条件3]技能D/end唯一需要注意的是,每使用一个/if,都要有一个/end与之对应,同时注意与/if对应的/else(/elseif),以免产生不必要的逻辑错误。4./return/return从作用上来讲,相当于一个/if:只要满足/return的条件,在这个/return之后的所有语句都不会再执行。最常见的用法当属众所周知的/return ,用来保护读条的语句。5./var变量可以使宏变化多端,这并不是随便说说。变量分两种,一是在头部定义的控制变量,二是在宏中直接定义的宏变量。这两者在使用时并没有太大区别,唯一区别是控制变量可以由使用者在宏面板上任意改变。使用变量来控制一个技能的执行,如下例:Code 5-1#name 测试#varbool v_变量A,tip:这是一个变量/skill 技能A/skill 技能B这是一个完整的宏,通过调整面板上变量开关,可以使宏执行,或不执行技能A。当然,我们也可以这样复杂一点:Code 5-2#name 另一个测试#varnum v_等级,6,tip:只是一个等级/if /var v_test/else/var v_test/end/skill 技能A/skill 技能B/skill 技能C/skill 技能D/skill 技能E这个宏定义了一个v_等级的变量,此外,我们还在宏内容中定义了一个变量v_test,该变量被赋予true与false两种值,通过这些变量计算不同的条件真假,判断不同技能的执行。需要注意的是,数字型变量当单独作为条件时,只要拥有确切的数值,不论数值是多少,一概认为条件成立。
第七节:表达式优化表达式优化在进入本节之前,我们的重点内容依然是注意事项:注意:请在阅读本节前,仔细阅读并确保自己已经明确不同的判断参数返回值的类型属于true、false和num中的何种,并确保自己知道true、false、num之间的区别。请在阅读本节前,尽可能掌握变量命令/var的基本用法。1.变量前文已经对变量进行了最基本的介绍,那么请读者在此处回忆一下变量的几种情况,以及各种基本运算符号。注意:本节中所有的变量,意指由宏定义的,以v_开头的具有相应数值的量。相应的,所有数字、true或false,以及通过参数引入的数值或真值(如:buff:调息,bufftime:风·灭气>5),均视为常量。我们为什么要引入一个变量?最主要也是最广泛使用的作用,就是引入变量开关,使使用者可以通过调整变量的值来控制宏的语句执行。第二个比较广泛的应用,是通过将复杂的条件定义为一个新的变量,来方便对这个条件进行引用。通常此类变量拥有一个十分有意义的名字,如某知名唐门宏中的v_队里有一堆唐门,v_救命啊他要放追命了,等等。变量的另一个广泛应用,就是用来存储一些中间结果,以应用到后面的宏或变量表达式中。如不少宏,通过开关定义了加速阈值等级,再通过计算获得对应的技能的时间,以用于后文的计算。2.变量表达式变量表达式是区别于常量表达式的一个概念。表达式的概念请右转百度百科。我们在写宏的时候,每个语句中,使用中括号[]所括起来的整个部分,就是一个表达式。当用于/skill、/if、/dia等等语句的时候,以表达式的真值来决定其运行;用于/var或/print时,则是对相应表达式的值进行赋值或打印。常量表达式指表达式的所有量均为常量的表达式;使用了变量的表达式则称为变量表达式。3.表达式优化本节的重点,是如何针对宏中的大量表达式进行优化。本节所有例子将均从本站知名宏中节选,部分内容可能有删改。3-1 常量表达式优化常量表达式通常不需要进行大量优化,但在超级宏的架构上,可以将部分庞大的表达式进行合并。例如:/skill 打断,后撤
/skill 打断,后撤可以优化为/skill 打断,后撤又如:/skill 风来吴山
/skill 风来吴山可以优化为:/skill 风来吴山此类例子较多,但有时合并会导致表达式变得冗长不利于阅读。
3-2 /if下的/skill(/dia、/return等等)优化实际上,由于除/var和/print以外的语句表达式的真值即决定其是否执行,因此在实际应用中,如果不是需要降低表达式长度以利阅读,此类语句可以通过优化不使用/if即完成判断。/var也可以使用相应的表达式算法来优化使之不需要/if。唯有/print,由于种种原因,必须使用/if来限制其执行与否以防止刷屏。在进行带有/else的/if的优化时,需要预先计算好,优化后的语句真值是否与优化前相同。针对/if下的/skill优化举例:/if
/skill 啸日
/else
/skill 啸日
/end
/if [(rage<17,v_剑气=1);(rage<20,v_剑气=2)]
/skill 啸日
/end可以优化为:/skill 啸日/skill 啸日当然,本例中的两个语句可以通过合并为一个语句,但那样将会导致语句过长。一般情况下,通过/if的优化获得的语句还可以进一步优化。3-3 真值表达式的优化在深入本节之前,请再次确认自己已经明白三种基本逻辑运算(或、且、非;超级宏中分别为’;'、’,'、’!')的关系。观察上例中的(cd:黄龙吐翠,cdtime:平湖断月>1.5;!cdtime:平湖断月>1.5)。如果我们定义:/var v_a/var v_b那么这个表达式可以写作(v_a,v_b;!v_b)。可以很清楚的明确,这个表达式只有当v_a与!v_b同为假时才为假,其他时候均为真。因此这个表达式可以写作(v_a;!v_b),也即(cd:黄龙吐翠;cdtime:平湖断月<=1.5)绝大多数情况下,只涉及到两个量的布尔表达式,都可以进行一定程度上的简化。3-4 数值表达式的优化超级宏中,数值型变量均可参与简单的加减乘除计算,如上例中的(rage<17,v_剑气=1;rage<20,v_剑气=2),可以简单的简化为rage<14+v_剑气*3(前提是v_剑气只能取为1或2)。又例如,计算花间在梦歌状态下的加速,可以写作:/var v_speed –无BUFF的面板加速/var v_nowspeed3-5 混合表达式算法在超级宏中,涉及到数值的计算,以及数值与真值的混合计算,参考下面的规则:true and 3 = 32 and 3 = 3false and 3 = falsetrue or 3 = true2 or 3 = 2false or 3 = 3根据这一点,我们可以简化很多混合表达式。最常用的简化形式是(a,b;c)型表达式,意为当a为真是,值为b,否则为c。
3-6 /if下的/var优化最简单的情况是下面这种情况,在很多宏中都有这样的情况:/if
/var v_快雪可断
/else
/var v_快雪可断
/end此种情况可以很直接的写成:/var v_快雪可断另一种可以优化的情况是如下的情况:/if
/var v_动态变量
/else
/var v_动态变量
/end该情况可以利用上文所述的(a,b;c)型表达式简单的优化成:/var v_动态变量有的时候,/if语句是对/var有着执行约束,如下例:/if
/var v_ind
/end该语句限制了只有在cdtime:芙蓉并蒂>=5时才对v_ind修改数值,因此此例可以同样写为:/if /var v_ind/else/var v_ind/end从而可以优化为/var v_ind再根据真值优化可以进一步简化为/var v_ind下面是一个针对变量的综合优化例子,是某宏中的一个限定执行模块,只在当前循环中v_st9=1时执行一次:【声明:此模块及其优化结果引自变速箱-花间宏,直接转载或引用请注明引用来源】/if
/var v_mention
/var v_tomention
/else
/var [!v_mention] v_tomention
/end
/if
/var v_mention
/var v_tomention
/end前面的一个/if块可以简单的优化为/var v_mention/var v_tomention后面一个/if因为限制了只有当v_tomention为真的时候才执行,而当v_tomention为假时,需要保持原来的值,因此可以写为/var v_mention/var v_tomention根据上下文语句,由于当v_mention置为true时,v_tomention会在下一个循环置为false,因此最后一个语句可以被省略。全文优化结果为:/var v_mention
/var v_tomention
/if
/end
/var v_mention
补充内容:一些宏语句简化技巧BY燕羽天@大明宫 等效于if a, b ,else c 相当于a是b与c的选择开关
[!a,b] 等效于if a,恒为false,else b. 相当于a是b的赋值开关
if a为 恒为true,else b
[(a,b;0)+x]等效于 if a,b+x, else x. 相当于a是b的加法选择开关
等效于if a,1,elseif b,2相当于奇穴a,b的判断开关
等效于 初始化变量a为x,a不能为布尔变量
2013/12/26 第三章·第7节:表达式优化—— 主稿:楚玄枫2013/12/26 第三章·第6节:时间控制 —— 主稿:楚玄枫2013/12/26 第三章·第5节:宏控制 —— 主稿:楚玄枫2013/12/26 第三章·第4节:时间戳(nowtime) —— 主稿:YYL2013/12/26 第三章·第3节:变量与自定义变量(var) —— 主稿:龙蔡、YYL2013/12/26 第三章·第2节:条件判断(if结构) —— 主稿:Jachou2013/12/26 第三章·第1节:逻辑运算基础—— 主稿:YYL2013/12/26 第三章·中级教程:引言—— 龙蔡
页:
[1]