老胡 发表于 2016-1-5 15:21:09

MagicStone脚本训练营(老胡、醉骚倾心打造)

本帖最后由 老胡 于 2016-1-5 20:10 编辑

本教程由老胡、醉骚倾心打造,在你写脚本有问题的时候,欢迎与我们交流。

在前面必须强调的:很多人有代码恐惧症,但是强烈建议你一定看完,然后动手尝试,代码流入门自然会有点难度,但是相信你可以克服这个症状,然后就能体会到醉骚同学说的“ms就是你想做什么那就能做什么的”。

教程目录
1、续
2、入门例子
3、不用选目标也能治疗
4、范围内找怪
5、小号跟随自动捡东西……
6、一个更复杂的例子:冬幕节任务“恶心的礼物”
7、快速了解API
8、你还需要进一步了解的


老胡 发表于 2016-1-5 15:22:51

一、续

本帖最后由 老胡 于 2016-1-5 18:06 编辑

为什么有这个帖子?    目前ms的用户明显比gc的少很多,脚本也少很多。我们想通过这个帖子,消除很多人对于ms的“畏惧”,让更多的人学会写ms的脚本。
本帖子的目标用户    本帖子的目标用户是脚本作者,如果你只是下载并使用别人的脚本,不需要看这个帖子。    看帖子之前,你需要先下载并了解ms插件的使用,否则请先去看ms区置顶帖。
gc比ms用起来更简单是一个误区!
[*]gc并不是你想象中的那样好用:如果你比较深度的使用过gc(在论坛发过脚本),并且看过老血发的段位分析帖子,你就会知道,一个真正能用的方案并不是简单的拖拖拽拽就可以实现的。你需要知晓各种函数、懂得条件判断、了解自定义目标、插入命令等等,而这些并不简单。
[*]gc相对ms来说更封闭,你的一些好的想法在gc中很难实现。例如打图腾、给范围内目标上dot,这样的函数并不难写,但是如果你想把你写的函数增加到gc中却很难,论坛只有少数几个高端玩家懂得怎么在gc里面添加自己的函数,lh改为自动更新插件之后,这少数的玩家更少了,大部分的更新依赖于少数人。
[*]gc更难调试,这个我就不多说了,用gc做过脚本的人都知道。



ms好在哪里?   ms一定比gc好吗,这是一个仁者见仁智者见智的问题,根据“群众的眼睛是雪亮的”原则,ms用户更少,所以ms并不比gc好。但是别忘了真理往往掌握在少数人的手里。那么ms的优势是什么?
[*]ms更灵活,这点应该是没有争议的。只要你能想到就可以做到,你写好一个“打图腾”函数,只需要把他放到你的脚本中,不需要去了解ms插件是怎么构成的。所以只要你有想法,你就可以实现。引用醉骚的名言“ms就是你想做什么那就能做什么的”。
[*]ms更好调试,与gc不同,ms提供了一个异常展示窗口,当你脚本出现异常的时候会在这里显示出来。另外如果你想知道你设置的某个条件是否成立,你只需要将这段代码拷贝到聊天框中,然后/print一下,就可以得到结果。
[*]ms做脚本更快,是的,比拖拽更快!!!什么???这不是gc的优势么?错了,gc的快是假象,ms才是真的快,还是举例子:


[*]在gc中,你写好了一个目标血量低于60%就用苦修,然后你想再加一个目标血量低于70%就用快速治疗、80%以上使用治疗术、90%以上使用盾,这时候你需要拖拽这几个技能进来,然后复制并修改条件,大概需要点击20+次,而如果你使用ms,只需要复制粘贴,然后修改技能名称和阈值。
[*]在gc中,如果你写好了牧师的脚本,现在要写萨满的,那么通常你就懒得拷贝了,因为来回切换脚本很麻烦。而ms不存在这个问题,你只需要拷贝粘贴,然后修改技能名称和阈值……对于手里有N个号的玩家来说,ms的酸爽难以言表~

老胡 发表于 2016-1-5 15:24:04

二、入门例子:施放一个简单的技能

本帖最后由 老胡 于 2016-1-5 18:06 编辑

1、ms里面使用msRun函数来施放技能,例如对目标施放火球术:msRun("火球术","target")
这里使用了msRun函数的两个参数,第一个是技能名称,第二个是目标,"target"代表当前目标

2、有一些技能是不需要目标的,例如加buff,则第二个参数省略即可。

msRun("真言术:韧");

3、加buff之前通常要判断该buff是否已经存在了
if not msGUB("真言术:韧") then
    msRun("真言术:韧");
end其中msGUB函数返回的是自己是否有某个buff,加一个not表示自己是否没有某个buff
这里使用了一个if语句,语法是if xxx then aaa end,红色部分是固定写法,xxx是条件,aaa是要执行的语句。
所以上面的例子就是当没有耐力的时候才加耐力

4、但是上面的例子依然不完善,如果战士吼了命令,会被我们覆盖掉,所以修改如下:
if not msGUB("真言术:韧") and not msGUB("命令怒吼") and not msGUB("深红契印") then
    msRun("真言术:韧");
end上面写了3个条件,3个条件中间使用and来连接,这个是lua的逻辑运算符,意思是当and左边和右边的条件都成立时才ok,所以这里就是当3个buff都不存在时才加耐力。

5、如果你熟悉了ms的api,该例子可以进一步简化为
if not msGUB("真言术:韧,命令怒吼,深红契印") then
    msRun("真言术:韧");
end

老胡 发表于 2016-1-5 15:25:11

三、不用选目标也能治疗

本帖最后由 老胡 于 2016-1-5 18:08 编辑

写过脚本的都知道,脚本有一个比手动强的地方在于,不需要我们手动切换目标,也可以根据自动根据我们得需要去切换目标和执行,我这里以治疗为例子来说明,对治疗来说,我们通常有下面两种需求:

1、对周围40码内血量最低的队友施放技能(例如圣光闪现)
2、当周围血量低于80%的人超过3个时(包括自己),释放AOE治疗技能,例如圣光普照、黎明圣光等

这两个问题是我在求助区问过的,羊总已经给出了很好的gc的解法,传送门,我们这里要说的是ms的。

需求1的解法:如果你第一次看这种代码,无法理解很正常,但是很简洁有木有,比gc简单大概3-5倍,而且当你切换职业的时候,你要做的只是拷贝粘贴,然后修改技能名称和阈值~~~local _y40 = msGetUnits(true,true,40,"player");
local _minunit , _minunit_hp = msGetMin("msII(unit)","msGHP(unit)",_y40);
if _minunit_hp < 80 then
    msRun("圣光闪现", _minunit);
end解释一下:

[*]1行:local a这样的东西表示定义一个临时变量,msGetUnits这个是ms提供的一个范围搜索目标的函数,msGetUnits(true,true,40,"player")的意思是搜索40码范围内可以治疗的所有玩家,然后将这些玩家放在一个table里面,存储到_y40这个变量中
[*]2行,利用msGetMin这个函数,对刚才的_y40中进行过滤,获取血量最少的玩家。这个函数新手看不懂不用纠结,需要你注意的是返回值,请注意这个函数执行之后,返回了两个值,所以我在前面定义了两个变量来接收,第一个是血量最低的玩家,第二个是该玩家的血量。这是lua很有意思的一个特性,很多语言都不能这样玩儿。总之,通过这一句,我们得到了血量最低的玩家,以及他的血量(比例)。
[*]3-5行,这个大概就不用太解释了,当该玩家血量低于80%的时候,对他施放圣光闪现。

为什么我们需要这样的函数呢?他可以帮助我们做到很多手工搞不定的东西,例如一个玩家血量突然到5%,马上给一个圣疗、保护……而通过手工,你通常反应不过来。

需求2的解法:
local _y30 = msGetUnits(true,true,30,"player");
local _target = msFindUnit("msGHP(unit)<=90",_y30,true);
if _target and #_target > 3 then
    msRun("黎明圣光");
end解释一下:

[*]1行,跟上面类似,获取的是30码范围内可治疗的队友,不是40码的原因是黎明圣光这个技能只治疗30码,所以这又是一个脚本的优势,有时候你看到团血有3人都掉血,你用了这个技能,但是他们离你35码……你蛋疼吗?
[*]2行,与上面类似,是对_y30的一个过滤,但是这里使用的函数是msFindunit,该函数更强大,当第三个参数为true时,该函数过滤完成后,依然返回一个table(看不懂也无所谓,就是多个目标),例如30码内血量90%以下的人有3个,这个函数就返回一个table,里面有3个目标
[*]3-5行,是一个条件判断,但是不同的是这里不是判断血量,而是目标个数,_target and #_target>3,的意思是目标个数大于3,#这个符号在lua中是获取table中的数量,目标有几个,就返回几,这里用大于3,也就是4个血量不满才治疗。


到这里,无聊的基础教程已经告一段落,下面开始骚弟将给大家带来一些有意思的东东,让大家领略一下ms的风采~~


羊~ 发表于 2016-1-5 15:28:22

本帖最后由 追悼者 于 2016-1-5 20:51 编辑

版主留言:借楼编辑.以下为@醉骚原帖内容
额….直接上干货吧,我文采也没有老胡的好,今儿干活还把手挤伤了 NNDMS脚本开发思路与过程一、为什么用MSGC作为一种图形化的LUA解锁界面,做得很赞,但是就像老胡说的,图形化虽然给我们带来了方便,但是同样的也拴住的一些人,虽然有了好的想法,但是不好表达出来。举个例子:(一)    刚刚过去的冬幕节大家也都晓得了,里面“恶心的礼物”这个任务着实让人恶心到了,做这个任务的时候我就在想‘尼玛抢个礼物够费劲的啊,为毛不能让机器来替我完成这个任务?’(有思路了)
(二)    我翻找GC的各个函数,各个判断,感觉额……不太好实现(以上纯属杜撰,冬幕节的时候我已经开始搞MS了^^),GC的函数都是封装好的,鼠标挨个点了才能用,那么我就MS自己码代码来搞。(一条路走不通,那就换一条。)
(三)干货:   local nums=GetObjectCount ()
2.      local name="怪礼物"
3.      for i = 1, nums do
4.         local obj = ObjectWithIndex(i)
5.         local ObjectName2 = ObjectName(ObjectPointer(obj))
6.         local unit=ObjectPointer(obj)
7.         
8.         -- print(FHINSight("target"))
9.         if ObjectIsType(obj,ObjectTypes.Object) and msGD("player",unit) <= 20 and ObjectName2 == name then
10.            local X, Y, Z = ObjectPosition(ObjectPointer(obj))
11.            msRun("ITEM128675",{X, Y, Z});
12.            
13.            print("周围20码发现怪礼物!!!开炸")   
14.         else
15.         end
16.      end
(四)首先我要让大家了解到一个名词:遍历
这货吊得很啊,他能遍历出我们身边所有的东西,物体,人物,物品,游戏对象(哎呀,反正就是很多了后面会讲到。)首先我们先遍历出来周围有些什么local nums=GetObjectCount ()----local“赋值”   nums“变量”   GetObjectCount ()“获取周围所有东西的数量,就是排出序列来”   意思就是把获取的周围这些东西都保存到nums里面一个循环结构fori=1,nums do end -----比如刚才遍历出来周围有5个东西,返回的数字是5,那么这个i就从1开始一直到5结束,挨个把这5个数值给i这个变量
下一步我们就要挨个检查周围的这一个东西有没有我们想要的

我们要定义几个变量1.         local obj = ObjectWithIndex(i)-------获取指定的对象(从那5个目标里面获取指定的,比如说第4个才是我们要找的,i循环到4的时候就OK了)
2.      local unit=ObjectPointer(obj)------把上面那个函数获取的 对象转变成类似于 “player”   “target”这种我们可调用的类型
3.      local ObjectName2 = ObjectName(unit) ----获取指定目标的名字定义好了那我们开始判断if ObjectIsType(obj,ObjectTypes.Object) and msGD("player",unit) <= 20 and ObjectName2 == name then

(五)一个小功能就这么实现了,可能已经有很多人给看晕了,觉得“卧槽,又他妈一对英文,这怎么搞!”      好吧,我只能说这都是有套路的,包括你们说的打TT的函数,周围目标上DOT的函数,周围谁血量低于XX的函数,都是这么来的,MS的一个函数msGetUnits()------获取周围目标这个函数就是这么个原理,只不过给作者封装成型,我们就省去了码代码的辛苦了,再举个简单的例子
我想要打周围指定怪物,就像我之前写的范围循环打怪的例子,也是这么来的

我们摘一段来看local result = msGetUnits(nil,nil,JL)    ------遍历周围的一切东西(包括人啊物体什么的)(六)不知道是不是起点高了点儿,但是MS 真的能做到很多很有意思的事情,比如昨天”厄瑞波斯”做了一个主城找人的小竞赛,我就把这个事情交给MS 来处理了,我只需要在暴风城一逛,就找到要找的人了,

这个FindUnit()函数就是我把上面的功能给封装了以后好调用
代码在这

这里的names可以给多个函数比如这样
FindUnit(“大金牙,暴风城卫兵, 老胡,醉骚”,100)


   最后我想说:MS不是一个刚接触LUA这个玩具的玩家就能很顺畅玩的了的,感觉GC满足不了你了,感觉自己的思维很灵活的,GC约束了你的双手时,来搞MS吧,可能今天我后面给的干货对于刚入行的新手(我也就是个刚入门的)来说,可能会稍微有点儿难度,但是如果你想来搞MS,有不明白的问题,请你直接MS发帖求助,我们第一时间为你解决,要求只有一点,你把题目写清楚,方便别的同学来查找,MS欢迎你们,欢迎你们有想法,但是自己却不知道该怎么用玩具表达出来,请来找我们~~~




陈·风暴烈酒 发表于 2016-1-5 15:58:55

七、快速了解API

本帖最后由 追悼者 于 2016-1-5 20:54 编辑

相信上面各种花样的函数已经让你醉了,之所以有gc、有ms,根本上还是因为暴雪提供了各种有意思的API,这些就是你编写脚本的利器,那么老胡带你了解一下,都有哪些东西吧。

1、首先是ms的API
下载帖子:http://www.luacn.net/thread-6205-1-1.html

ms的说明书中包括5大部分
1)第一部分是使用说明,这里是对spell、unit、number等基础概念的解释
2)第二部分是动作类函数,例如执行一个技能msRun、一键驱散、自动打断、执行一次脚本等等
3)第三部分是判断类函数,例如判断buff是否存在,判断目标是否正在施法等,判断类的函数一般都是返回true、false
4)第四部分是信息类函数:例如获取buff的层数、buff的剩余时间、获取满足条件的目标等等
5)第五部分不是ms本身的函数,而是作者列举的暴雪的常用函数

对于ms的说明书,我的建议是1、5两部分先看一遍,2、3、4这三部分大概看一下,大概知道有哪些函数就可以了,使用的时候再回来查,基本上一个完整的脚本写下来,你对这些函数就会有一个大致的了解了。(第一次是会比较折磨的,请不要放弃)

作者很贴心,很多函数后面都有使用的示例,照猫画虎即可。

2、然后是暴雪原生的API,你可以通过下面几个地址来访问
http://wow.gamepedia.com/World_of_Warcraft_API
http://wowwiki.wikia.com/wiki/World_of_Warcraft_API
http://wowprogramming.com/docs/api

当然了,上面这几个都是英文的网站,所以老胡搞了一个pdf的,但是精力有限,只翻译了一部分。
http://www.luacn.net/thread-11622-1-1.html

一个不好的消息是,暴雪提供了大约2000个左右的函数,所以你想先看一遍混个眼熟?难度有点大
好消息是ms的函数基本可以满足你90%的需要了,所以你只有很少的情况需要用到去查暴雪的API。


全职杀手 发表于 2016-1-5 16:01:52

八、你还需要了解的

本帖最后由 追悼者 于 2016-1-5 20:54 编辑

看完以上,如果你还是晕晕的,那说明你的智商是正常的,因为万事需要动手。

然后就像印象说的,你还需要几个好基友跟你一起探讨,追悼者、青山、醉骚、老胡等等都是很好的讨论对象。——当然了,老胡一般只喜欢妹子,另外几个男女均可。


当你没有思路的时候,下载几个别人的脚本,看看他们的思路。


自己的脚本成型之后,记得发到论坛,因为当你希望把自己的东西分享给别人的时候,会促使你更加用心的完善脚本。

印象 发表于 2016-1-5 16:09:30

看到不是/cast 火球术   我就已经放弃在看下文了。

羊~ 发表于 2016-1-5 16:13:59

本帖最后由 羊~ 于 2016-1-5 16:44 编辑

学习,学习~~MS。当年用MC第一个德的脚本还在我的收藏里面~~~

鬼谷子 发表于 2016-1-5 16:21:22

文笔不错啊,MS要发扬光大了
页: [1] 2 3 4 5
查看完整版本: MagicStone脚本训练营(老胡、醉骚倾心打造)