游戏王卡组些卡如何入门

这真的是同【哔---】交友群,新浪微博@久远苍月,大家一起快乐的决斗吧!
粉丝:5593
视频地址复制
Flash地址复制
Html地址复制
离线看更方便
用或其他应用扫描二维码
自制 上一次实卡决斗之后很多小伙伴来问我问一些卡片相关的东西姑且是做这样一次实卡的相关介绍,实卡决斗第二期正在上传中~感谢大家的支持啦,抽奖也会在稍后将发出的第二期末尾做出~
广播电视节目制作经营许可证:(沪)字第1248号
网络文化经营许可证:沪网文[6号
信息网络传播视听节目许可证:0910417
互联网ICP备案:沪ICP备号-3
沪ICP证:沪B2-
违法不良信息举报邮箱:
违法不良信息举报电话: 转 3【教程资源】ygocore卡片添加教程完整版_游戏王ygocore吧_百度贴吧
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&签到排名:今日本吧第个签到,本吧因你更精彩,明天继续来努力!
本吧签到人数:0可签7级以上的吧50个
本月漏签0次!成为超级会员,赠送8张补签卡连续签到:天&&累计签到:天超级会员单次开通12个月以上,赠送连续签到卡3张
关注:108,736贴子:
【教程资源】ygocore卡片添加教程完整版
教程极长,楼下会分段发。教程文件下载地址:也就是的完整版,补上了后面的章节。所以那个贴就别回了,免得挖坟。我发这个教程链接之前,考虑过以下背景和因素:①普及度——尽管网盘一直放着完整版教程,但是鲜被有需要的人注意到,从以前帖子的挖坟度、还有其它圈子推荐的残缺写卡教程上面可见一斑。②入手度——从其它直接给出网盘下载地址的帖子上可以看出,大家都比较忙,如果不是拿起即看即用,效果可能不好,所以尽量在帖子里面发。③需求度——每次一出新卡包,就有人表达希望ygocore立刻更新完,但这要在更新者翻很多倍的情况下才能做到。那么教程是关键。如果有写卡方面的问题,请在看完教程之后再提问,否则可能很难解释清楚。考虑到教程有点久远,故回复中可能会进行一些讨论,请有心者多花几分钟留意一下。大家如果觉得有用,就顶起和相互转发,我会根据反馈考虑是否在置顶ygocore添加一些基本的开发和修复工具。
楼下放资源和教程
Photoshop CS3下载地址...
美到没朋友(???╰╯???) ...
发布一个资源犯了两次错...
虽说不是多年,但也是楼...
没有时之笛,没有SKY,...
我是真不行了,昨天这关...
废话不多说,昨天完成了...
楼下发地址和介绍
楼主苦心潜水许多年,最...
另外,这个是添加教程而非说明文档,并且相关软件一直在更新中,比如DataEditorX更适合作为小白的编卡工具,所以详细说明、最新信息以这两个地址为准:
声明:本人曾写过太阳神三国杀的lua扩展,发现ygocore也是通过lua语法+API函数来作为脚本。本教程由@卡鲁洛斯编写,本人仅做整理工作,为的是让更多的人加入ygocore的lua脚本编写工作。但是由于人太少,使的脚本编写的人很少。为了使得ygocore像太阳神三国杀有个庞大的lua编写群体,本人为了大家方便阅读,因此整理他的教程。以下是@卡鲁洛斯的教程这篇教程是我自己写的,而我本人也是正在自学写卡。写这个教程的目的是为了什么?我也是最近才听说开源项目里英文版的卡片更新速度最快,同时也是听另外一个写卡的网友说在国内参与写卡的加上他和作者还有外加的那几个都不知道有没有10个人……国外的玩家果然比较热情,参与的人多。另外听这个网友说,有些想要写卡的人跑来问他要怎么实现奥蕾哈刚的效果……我瞬间就心疼了……尼玛还有一大堆正规卡还没录入,就惦记着去加这些没头没脑反都反规则的原创卡。所以我就觉得有必要让真正有意去为YGOCORE做出贡献的人开一个大门。于是就有了这个教程,希望能号召更多人参与YGOCORE的写卡事业。正如我所说,我也在学习写卡,所以可能教程里面会有很多不足,那就请原谅了。另外,与其说这是教程还不如说这是个学习笔记……都是我在学习写卡的过程中的一些心得。好郁闷……为了让教程更加容易入门内容反而越弄越乱。这个教程其实是第二版,第一版教程在我的电脑里,但是写的实在是太过“专业” ,只考虑到自己能看懂,没考虑到读者。所以我就重新把教程拆开来按入门的顺序重新排列,弄成空间上的第二版。但是第二版里面很多内容都是抄自第一版,并非完全的重写,搞得有些地方牛头不对马嘴,例如无端端就冒出了还没讲过的东西,无端端又提及了一些没有讲到的章节。由于赶进度,关于这个编排混乱的现象我暂时没办法从头开始检查,希望看这个教程的人能够帮忙指出哪里不对劲,给出一些建议,我好重新调整。另外,这个玩意儿与其说是个教程还不如说是个笔记。其实也就是我学些卡从里面分析来的一些心得,不权威啊!所以看的时候如果觉得不对,请不用怀疑了,直接跟我发信息,我去修正。在作者亲自解释之前,我曾经一度认为operation的执行会根据OperationInfo里的cagetory信息发出EVENT_事件来供判定发动效果。不过我错了!operationInfo里的信息是写入连锁中的,表示该连锁里面包含某种操作类别,但是并没有引发时点。而星尘龙效果的时点是CHAINING(连锁中),不是DESTROY(破坏)。可见星尘龙是连锁中的时候进入时点,然后判断那个连锁里有没有破坏的操作类别。事实上我的理解与真相本质上是相同的,但是我却把这个解释成了时点,最后背向而驰误导了大众。我在这里先道个歉。如今我已经对我原本的说法进行了大规模的修正,但是我又苦于操作类别操作类别,连锁信息连锁信息,的解释有点太蒙人,于是我用了宣言这个词来指代。实质意思就是我们游戏王实卡对战时,自己效果发动时需要向对方发出宣言,宣布自己连锁里的操作的类别。以便对方针对这个宣言发动效果。例如:小明雪人发动效果,开连锁,他向对方宣言要破坏对方的怪兽卡。对方根据连锁中的这个宣言发动效果,无效该连锁的效果并破坏效果所属卡片。这样一切都明了了。
YGOCORE 游戏王CORE的自定义卡片教程(1)——第一章·基础篇(上)第一章:基础篇1.1 预备工具为YGOCORE添加自定义卡片和对应的卡片效果需要用到的工具有:DataEditor——卡片数据库添加软件这个软件是用来给card.cdb里登记卡片用的。YGOCORE只加载登记过的卡片,没登记过的卡片游戏中不存在。通常怪兽卡直接用这个软件添加即可在游戏中正常使用。这个软件要放到YGOCORE里的任意子目录中才有效,根目录会出错。下载地址:utility.7z 276KBNotepad++——文本编辑软件,编写lua脚本这个软件是用来编辑卡片lua脚本用的。编辑的时候记得要在格式菜单里面选择【utf-8 无BOM】编码,其他编码的lua脚本无效。图片编辑软件——修改卡图sizeYGOCORE的卡图有具体要求:大卡图必须177*254,小卡图必须44*64。超过这个尺寸,游戏中将报错。而各大卡查网站的公用卡图size是160*232,所以不能直接给YGOCORE用。作者提供的一些帮助文本作者已经别写了一个比较简略的说明文本讲解了如何添加自定义卡片,但是实在是太简略了,有很多细节没有详细说明。因此我才打算更详细的去写这个教程。虽然有我的教程,但是作者的帮助文本还是很必须的,毕竟我的教程是基于作者的说明来的。Script.txt是作者的说明文本,里面十分简陋而无序的说明了效果编写相关……。其中的function.txt里面记录了作者编写的各种函数的信息,为我们查找提供了方便(但是仍然漏了一些函数没有记录进去……)。知识这绝对是必须的,本教程只涉及YGOCORE卡片的添加过程和细节,但是lua脚本,lua语言我是不会讲的。那么是不是需要去了解lua语法?那是肯定的。但是没有必要精通lua,只要将lua的基本语法搞懂就行了,不会写也要会看会改。当然,最好有编程基础,这样看起代码来要高效得多。这些工具在游戏王YGOCORE贴吧的公共网盘里有提供下载:位于相关工具目录utility.7z 276KB卡库编辑器+写卡说明||放入游戏目录的任意子目录来运行
1.2卡片添加流程第一步:打开DataEditor录入卡片信息,傻瓜式无需讲解太多。右边的描述一定要写,不然你就别想在里搜到你的卡片。不过要注意,卡片的种类(魔/陷/怪)将会决定该卡片在YGOCORE中的基本行为,例如放置的位置。如果你添加的卡本应该是陷阱卡,但是你却设置成了魔法卡,那么在游戏中你可能会看到陷阱卡像魔法卡一样在魔陷区发动的怪事(笑)。第二步:加入卡图。我们可以直接用卡查的卡图,用图片编辑软件将图片的大小(宽高)转换成YGOCORE能够使用的大小,然后放到YGOCORE的pic文件夹里面。大卡图放到pic\,小卡图放到pic\thumbnali。这时候你已经可以打开YGOCORE,搜索你添加的卡了。如果你这时候测试,会发现这张卡用不了(如果是通常怪兽卡的话就可以直接用了),那是因为这张卡还没有写“效果”——以“c+卡片id”命名的lua脚本。第三步:编写“卡片效果”——lua脚本。原则上lua的脚本可以用任何文字编辑软件写,但是lua却要求其编码格式必须是【utf-8 无BOM】,而windows自带的utf-8编码是有BOM的(关于这个BOM是什么意思不必理会)。所以记事本写的lua脚本文件YGOCORE无法使用。所以我们就要用++来写,以【utf-8 无BOM】编码来写(不要写完才改编码,不然你会感动到哭的),最后以“c+卡片ID”命名,保存成后缀为lua的文件。然后将这个文件放到YGOCORE的Script\ 中。※以后“卡片ID“一律简称为“ID”卡片的添加就结束了。这三步里面最简单的是前两步,很傻瓜很简单。最有学问的是第三步,编写lua脚本。这也是我这篇教程里面着重讲解的内容——YGOCORE脚本编写。Hello Card!没想到写卡也可以来个“Hellocard!”……世界变了好吧,跟着我做第一张自创的卡片。首先将卡片登记进YGOCORE的数据库,卡密千万别跟已经存在的卡撞车,尽量取奇葩一点的密码。我们这次做的hello card是一张魔法卡。第一步打开DateEditor照着上图设置,设置完后新增记录录入数据。效果分类可以不选,不过能选就尽量选。第二步、用++新建一个文档格式那里选择【utf-8无BOM格式】写入如下代码--hello cardfunction c.initial_effect(c)--Activatelocal e1=Effect.CreateEffect(c)e1:SetType(EFFECT_TYPE_ACTIVATE)e1:SetCode(EVENT_FREE_CHAIN)c:RegisterEffect(e1)end上面这几条代码是一个效果能够发动的最基本代码,必须要有Type和Code。Type是类型,Code是事件又或者说是时点。这个以后的学习中会慢慢了解到的。第三步、将这个文档以c+卡片ID为文件名保存成lua格式文件。放到YGOCORE的script目录里面。打开,编辑卡组搜索“你好卡片”,然后就发现我们的卡了。接着就去测试这个卡片,将卡片放到卡组的最前面这样做是有原因的,如果你想要开局就抽到你想要测试的卡,那么最好放到最前,然后主机的时候选择开局不洗牌,这样开局就上手了,哈哈。这就是我们的卡,能发动哦!发动看看吧!什么都没发生……那是肯定的,因为我们还没为效果写具体的功能。※有没有人注意到我的卡片里面有虫洞这张卡?
YGOCORE 王CORE的自定义卡片教程(2)——第一章·基础篇(下)术语说真的,我并不太乐意提起术语这个词,因为我本人王玩的也不怎么好,有时候很多规则也搞不太懂,在这里讲术语只会被人笑我小白,但是我又不得不去说一下。我怕丢脸,所以我现在干脆就不要脸了(一把扯下自己的脸皮)。在编程的角度下王的一些规则定义跟玩家角度下略有不同。所以YGOCORE编程角度上的规则术语跟游戏王的术语有出入。1、“选取对象”不等于“取对象”一个效果effect有没有“取对象”的性质是由效果的其property属性决定的。如果有取对象的操作,但是却没有为效果的property属性设置“取对象”属性,那么即使那个操作发生了,也无法触发某些卡片的反对象效果。2、效果发动与连锁在YGOCORE里面,效果如果单发,没有其他效果连锁上去,那么此时认为该效果也是一个连锁,连锁序号为0。也就是说只要效果发动都视为连锁,又或者说YGO里面效果的发动与连锁其实是一个意思。而此时如果有第二个效果连锁,该连锁的连锁序号为1。连锁都归duel管理,连锁序号也是储存在duel自己的某个变量中。3、宣言与事件/时点有些卡片的效果是针对宣言来判定的,特招宣言,破坏宣言等。宣言是连锁的信息之一。当连锁中包含某种宣言的时候就认为这个效果的类别被确定了!星尘龙的效果就是一个例子,他针对所有操作中带有破坏宣言的效果来判定发动效果。事件/时点是跟王里的时点概念一样。4、效果与操作effect类的各种成员变量和成员函数,仅仅是描述了这个效果的属性和行为,而具体的操作是由其函数里面所调用的duel的函数实现的。效果不发出事件/时点,操作中往往会发起宣言。duel就是YGOCORE的引擎,它有游戏的各种操作,大部分都会显示在画面上。5、事件与时点在玩家的角度上叫做时点,在YGOCORE的角度上称之为事件。在YGOCORE里面事件跟时点是同一样东西。由于实在是很难照顾好读者,所以有时候我会事件/时点这样写有时候又会单独的只写事件或者时点,不过一定要明白这两个东西在YGOCORE里面是同义词。只有事情发生了,才有时点。宣言不是时点。(我刚开始都搞糊涂了,以为宣言是时点。现在大规模修正 哭……)6、玩家的操作与玩家的行为其实在YGOCORE里面也是一对同义词。
YGOCORE 游戏王CORE的自定义卡片教程(3)——第一章续第一章续原本我是在第一章的第二节了里面准备了YGOCORE程序内部结构这一个内容的(这可是我辛辛苦苦看源码分析出来的),但是经过我深思熟虑我发现这内容除了我以外对于其他人没有任何意义……囧,所以就不贴出来了,只粗略的讲一讲YGOCORE里面会用到的自定义类型(其实就是面向对象里的类,这个不懂无所谓)2.1 自定义类型YGOCORE有三大自定义类型(就是YGOCORE自己定义出来的类型,面向对象里直接就是类的意思)YGOCORE里面各种处理的都基于这些类型的变量的。Card ——卡片类Group ——卡片组类Effect ——效果类这些类型都有成员变量(属性)和成员函数(行为)在lua里面调用这些类型的成员函数的方式如下卡片对象 : 对象成员函数C#######:GetXXXXXX()※注意中间的操作符,lua里面调用对象的成员函数都要这样做。而函数库里的就用点,例如Duel.Destroy()破坏某张卡。其实这不是严格上的解释,但是为了让大家快速入门,关于lua的语法特性我就能忽略就忽略。直接简单明了的说明。这三个类型里面最重要的是effect类,因为我们的效果就是effect类。我们写卡最有学问,最复杂,最耗时间,最头疼的就是写effect类的具体功能。所以我会详细的讲effect类。2.1.1 Card类是什么?Card类就是卡片类,YGOCORE在游戏开始的时候会从卡组deck文件里面读取 c+ID,然后以这个c+ID为名创建一个卡片对象,其实可以看做是card类型的变量吧。这个卡片对象有属于这个卡片的各种行为和属性。而我们YGOCORE的决斗系统Duel就是把弄这些卡片对象,将他们解放、破坏弄来弄去。Card类有什么属性(成员变量)有什么行为(成员函数),就到作者提供的function.txt里面查询(Set函数都是设置属性,Get函数都是获取属性)。由于Card对象不需要我们去创建和定义,所以我们根本就没要在意它需要设定什么值。只需要“拿来”就行了,用Get开头的成员函数获取一个现有的卡片的信息,然后对信息进行处理(主要是判断)。2.1.2 Group类是什么?Group类是卡片组类,不是卡组啊,是卡片组,卡组是Deck。卡片组是一堆卡片的集合,有些操作需要涉及到一组卡片例如卡片检索,需要将卡组里面符合条件的卡放到一起呈现在你面前让你选。这时候放到一起就放到了卡片组里面去了。这个类型跟card一样,我们不许要去设置,都是“拿来”(Get)。2.1.3 Effect类!高潮来了。这是最重要的类,我们的卡片的效果就是通过我们编写脚本来创建和定义这个类来实现具体的效果操作的。同时effect类也跟Card和Group一样可以“拿来”(Get)。以下是effect类的基本属性红色的属性conditioncost target operation就是效果的具体功能,他们都是函数需要我们自己去写实现代码,或者留空不设置。还记得我们的hello card么?hello card里面就没有设置这四个,但是依然可以用,可以发动效果。
2.2 YGOCORE三大函数库YGOCORE的脚本系统有四大部分组成(实质就是函数库)Duel ——决斗系统Card ——卡片系统Group ——卡片组系统Effect ——效果系统Duel决斗系统主要负责整个决斗环境,它相当于是“一双手“,拿起卡片,放下卡片,抽一张卡,选择卡片,擦看卡片,破坏卡片等等等等的这些“手操作”都是由duel中的函数实现的。也就是说想要让YGOCORE“动起来”,想要将那些卡片弄来弄去,就要靠这个。这四个系统里面与图形引擎最亲密的就是Duel,大部分我们能够看得见的操作都是duel函数的作用。而其他三个系统则比较隐性,一般我们察觉不到他们工作。同时效果的连锁也是由Duel来控制,效果1发动-》效果2连锁-》效果3连锁,这些连锁会被duel一一记录然后逆向处理。Card卡片系统——对应card类型的函数它负责的是卡片的一些操作,大部分的参数是用来获取卡片的信息的,获取后用来逻辑判断。Group卡片组系统——对应Group类型的函数Effect效果系统——对应effect类型的函数基本Card卡片系统,大部分参数用来获取效果信息,另外他还能获取这个效果所属的那张卡片card。
2.3 常量Effect类这就讲完啦?我还没弄懂呢?不必急,effect是个大学问,不是一两下就能弄懂的。在此之前要补一补另外一个知识——常量。还记得effect属性表里面,属性的中文名下方有些会带有大写字母的单词出现吗?那就是常量,属性的标识值。大部分属性都要用常量来设置。常量都定义在script\constant.lua 文件里面。当我们为自己的effect类Set属性的时候,从function.txt那里就可以看到这个属性应该用什么常量赋值。最常用到的值有effect属性值里的那些,然后就是REASON_了。重要常量EVENT是Effect类的一个属性,代表的是时点,效果什么时候发动就是这个来判断的。REASON是Card的一个属性,代表的是原因,我更喜欢称之其为“被XXX”。关于REASON可能大家很陌生,但是如果给它换个说法可能就容易明白了。REASON就是“被xxxx”的意思,是属于card的一个属性,意思是这个卡片“因什么原因”。还记得或者上面的游戏王,如果你打开墓第你会发现卡片上面都有一些图标表示其被送入墓地的原因——有“被战斗破坏”“被无效”“被破坏”等等。这些标识就是REASON的值。当效果e发动破坏某张卡的效果时,duel就会执行操作将那张卡破坏并给那张卡写入一个原因REASON,那张卡就有了个“因什么原因“而来到这个位置的信息。而以后我们的一些效果可能需要判断卡片的原因,例如”某个卡片被送去墓地的话可以发动这个效果,但是如果是被战斗破坏送去墓地的话就不能发这个效果“,这里就有个原因需要判断。CATEGORY是Effect类的一个属性,它代表着那个效果具有什么种类的效果,例如卡片破坏类,除外类等等等等。这类量很重要的原因在于,决斗系统duel的函数会用到这个。为什么?难道duel也有这个属性?duel不是一些函数而已吗?是这样的,duel就是“一双手“,我们玩弄卡片的操作就是靠着双手做出来的,而我们的行为是照着效果去做的。也就是说,效果说要破坏一张卡片,那么我们就做出破坏卡片的操作,但是这时候我们有必要“宣言”我们的操作。而这个CAGETGORY在操作中就是“宣言效果类别”,以供某些需要针对宣言来发动的效果判定之用,例如星尘龙的“破坏宣言&判定。小明:发动雪人的效果,雪人的效果是破坏场上一张卡。BOMB!——你那张卡片破坏!(小明指了指那张卡做出了破坏宣言)小王:啊?你要破坏我的卡片?确定?那我发动星尘龙效果,无效并破坏你那张卡。小明:啊~~~~NO~~~~从上是不是看出了什么眉头,没错,我们根据效果的类别做出同类别的行为,而这个行为需要作出宣言,这个宣言是以行为/操作的类别为依据产生的。这个宣言时点又会被别的效果捕获用来判断效果是否可以针对这个宣言发动效果。但是从上你会发现,效果的类别跟操作的宣言类别似乎是分开的,是的,效果的类别跟操作的宣言类别是分开的。一般情况下,我们的操作宣言类别都是跟效果类别一样,但是有时候会例外。有时卡片确实是破坏类别的效果但是我们却做出其他类别的宣言。有一个十分典型的例子,那就是那个经典的游戏王议题:星尘龙为什么不能无效潜行狙击手的破坏效果。哈哈,玩游戏王的人都知道这经典的议题。至于为什么,这里就留给读者自己去思考,我在第二章续——关于SetOperationInfo()函数会详细的讲解。
2.3.1常量的一些操作——这一部分可以先跳过这是附带讲解,常量也有一些操作,但是常量的操作十分的蛋疼……它的操作是二进制位操作。与操作/ +操作在用常量设置属性的时候,有时候需要多个常量组合起来使用,这时候要用“+”操作符。例如,效果类型EFFECT_TYPE_ 我们有些卡片的类型是“单体效果型+诱发必发型”例如三眼怪,这时候类型的设置就要将两种类型组合起来,那么就用“+”操作符EFFECT_TYPE_SINGLE+EFFECT_TYPE_TRIGGER_F※那两个常量是什么意思可以暂时不用理会,又或者你好奇心旺盛可以直接去查constant.lua。2.3.2位操作这个是最蛋疼的部分……二进制位操作……但是又必须弄明白。希望大家忍痛看完。因为YGOCORE里面有一些地方做的实在是很不人性化,没有相关函数,直接用二进制来控制……例如区域,有时候我们需要设置某个区域不可用(不带选择的),但是YGOCORE没有SetDisableField(integerSequence)函数,更是没有区域序号Sequence的常量……所有的操作都要用1010的二进制来表示,这样想虫洞这张卡的最后的那个效果要实现起来就很头疼,实在是很痛苦。虽然最后还是让我给克服了(笑)。关于区域的操作以后会另开讲解。有时候我们需要过滤常量,例如REASON量我们知道有些常量可以互相叠加,REASON量里面REASON_EFFECT+REASON_DISCARD=REASON_EFFECT_DISCARD
被效果丢弃
0x4040(REASON_EFFECT_DISCARD这个常量没有被定义进constant.lua里,是我自己瞎掰的)
因此万一我们要判断卡片的原因reason属性里是否有这个原因,这时候不能直接r== REASON_DISCARD
※r代指卡片的reason属性因为REASON_EFFECT_DISCARD虽然也是DISCARD但是明显它与REASON_DISCARD的数值是不一样的。REASON_EFFECT_DISCARD(0x4040) ≠ REASON_DISCARD(0x4000)但是REASON_EFFECT_DISCARD(0x4040)却包含有REASON_DISCARD(0x4000)这时候我们需要过滤过滤出该卡片是否包含有REASON_DISCARD(0x4000) --最好的例子魔轰神里面被丢卡是指所有的丢卡,包括被代价丢卡,被回合丢卡,被效果丢卡,这时候就要判断参数r是否包含丢卡成分。我们可以用bit.band函数判断r中是否带有REASON_DISCARD这个函数的作用如下bit.band(A,B)== AB二进制相同的部分 or 0传入A,B两个数值,如果有相同部分就返回他们数值中相同的部分,如果没相同部分返回0。如 bit.band(0x0)=0x40000x4040
0x40400x4000
0x4000————————————————结果
0x4000那么魔轰神判断代码就可以写成下面这样bit.band(r,REASON_DISCARD)==REASON_DISCARD——意思就是 r中是否含有丢卡成分你也可以不用这个办法,直接用组合的方式将所有REASON_DISCARD的组合给写出来如果你这样做的话我会鄙视你的。※bit是作者写的辅助函数之一,说明在function.txt开头那里,我已经添加了更详细的注释。除了bit.band外还有bit.bor等其他4个位操作。这些bit函数的用法实在是奇葩,主要用于常量和卡片放置区域的运算或者其他什么底层的运算,因为这些量都是二进制数值表示的,要从中得出什么逻辑含义就只能二进制运算。除非是汇编级、整天对着二进制数的程序员,不然就算是那些高级编程语言者也会觉得这些函数很恶心。更别说那些不懂编程的小白了……直接就吐了。※注意,常量是用16进制赋值的,但是他们对应的二进制值有个规律——那么多位里面只有一个1其余都是0。也正是如此才能利用二进制位运算来抽取数值中的信息。REASON_DESTROY=0x1
1REASON_RELEASE=0x2
10REASON_TEMPORARY=0x4
100REASON_MATERIAL=0x8
2.4 两大基本效果类型YGOCORE里面有两大基本效果类型,对应于现实世界的游戏王其实就是按效果开不开连锁分类的:开连锁的效果——触发型效果(带有发动行为)不开连锁的效果——永续型效果(没有发动行为)他们之间还有个更加直观的区别。在YGOCORE里面,开连锁的效果都会在屏幕上显示放大了的自己的卡图,还有闪烁。(魔力之枷发动的时候开连锁。)而不开连锁的效果则没有。※永续型效果不等于永续魔法陷阱卡的效果,其实“永续型”这个称呼有点混扰视听,我本人不是很赞同这个称呼,如果要我改个名的话,我会叫它作用/影响型效果。两大基本效果代码能发动起作用的最基本要求有:触发型效果:必须要有Type和Code。Type必须为EFFECT_TYPE_ACTIONS下方的任意一个类型。回想起我们的hello card,你就知道我们的hello card是触发型的效果。而e1第一个效果的Type就是发动型的意思。Code必须是EVENT_常量,是时点/事件的意思。永续型效果:必须要Type,Code、Range和Target Range。Type属性只能是EFFECT_TYPE_SINGLE(单体影响),EFFECT_TYPE_FIELD(群体影响)以及EFFECT_TYPE_EQUIP(被装备者影响)中的一个,不能与其他效果组合。Code是EFFECT_常量。Range是生效区域LOCATION值,TargetRange是作用区域也是LOCATION值。有一种奇葩的永续型效果是不需要range的,那就是全局效果,这个是实际写效果的时候会用到的技巧,不是基本效果之一。EFFECT_TYPE_常量最开始的那三个紫色的TYPE是永续型的TYPE,永续型效果的TYPE只能是这三个中的其中一个。绿色的那几个TYPE是触发型的TYPE,触发型TYPE里面只有TRIGGER(诱发)必须跟TYPE_SINGLE或TYPE_FIELD连用。触发型的property(附加性质)永续型的property值
2.4.1两大基本类型的基本代码我曾经在hello card里面演示那短短的几段代码时说过,这几段代码是效果能够发动的最基本代码。其实那几段代码就是是触发型效果能够发动的最基本代码。但是如果你试一下将那张自创卡的YGOCOR卡库里面的卡种改成永续魔法卡,看看会发生什么事?哈哈,这张魔法卡发动完后就像永续魔法卡那样留场了!没错,还记得准备篇我怎么解释DataEditor的作用的么。DataEditor将卡片的基本信息录入卡库,热这些基本信息决定了卡片在YGOCORE里面的基本行为。我指的就是卡片的种类决定了卡片的行为。如通常/速攻魔法卡发动完后就扔墓地不会留场,永续魔法卡发动后除非被破坏或者送去墓地不然会一直留场。YGOCORE的这一个性质的意义非凡啊,还记得【2.1.3 effect类】的属性表里面的Range-生效区域属性么。规定了该效果需要卡片在哪个区域正面表示时才生效。所以如果给通常/速攻魔法卡添加永续型效果毫无意义,因为它根本就不留场。不过你可以把Range设置成墓地LOCATION_GRAVE,这样的话卡片在墓地效果就能生效。好了言归正传,这两种类型的基本代码其实从要求那里已经能够看出了,只要将他们最低限度最低要求的代码写出来那么这个类型的效果就能发动。样板--触发型local e1=Effect.CreateEffect(c)
e1:SetType(EFFECT_TYPE_ACTIVATE)
e1:SetCode(EVENT_FREE_CHAIN)
e1:SetOperation(c.op) –调试用
c:RegisterEffect(e1)--永续型local e2=Effect.CreateEffect(c)
e2:SetType(EFFECT_TYPE_FIELD)
e2:SetCode(EFFECT_CANNOT_ATTACK)
e2:SetRange(LOCATION_SZONE)
e2:SetTargetRange(LOACATION_MZONE,LOCATION_MZONE)
c:RegisterEffect(e2) 2.4.2 Hello Card 2.0!现在我们为当初写的那个HelloCard 添加一个最基本的永续型效果。做法跟上次一样,不过这次为了让卡片留场,我们要修改卡库里面Hello Card的卡种,改成永续+魔法。然后往lua脚本里面这样写--hello cardfunction c.initial_effect(c)
--Activate
local e1=Effect.CreateEffect(c)
e1:SetType(EFFECT_TYPE_ACTIVATE)
e1:SetCode(EVENT_FREE_CHAIN)
e1:SetOperation(c.op) –调试用
c:RegisterEffect(e1)
local e2=Effect.CreateEffect(c)
e2:SetType(EFFECT_TYPE_FIELD)
e2:SetCode(EFFECT_CANNOT_ATTACK)
e2:SetRange(LOCATION_SZONE)
e2:SetTargetRange(LOACATION_MZONE,LOCATION_MZONE)
c:RegisterEffect(e2)end function c.op(e,tp,eg,ep,ev,re,r,rp)Duel.SelectYesNo(tp,1)ende1就是触发型效果的最基本代码,e2就是永续型效果的最基本代码。以后我们写效果都是用这两种类型的效果不断细化组合出更具体的效果。是否注意到这次的hello card里我为我们第一次写的效果e1加了一段代码?
e1:SetOperation(c.op)效果初始化函数下面还有个function c.op(……) 函数的定义回到【2.1.3Effect类】那一节回顾一下operation是什么属性,没错,operation就是卡片效果处理操作,是一个函数,而我在这里定义的c.op函数就是效果的效果处理函数,负责处理效果的操作。这次这个函数里面只调用了Duel.SelectYesNo(tp,1),作用就是效果处理的时候弹出选一个是/否对话框,供玩家选择。它在这里的实际用处是用来检查operation函数有没有被执行,换句话就是这个效果有没有真正的发动和处理。但是在正式写效果脚本时,这个函数是用来跟玩家交互的,也就是获取玩家的选择。现在赶紧去测试你的hello card,你会发现hallo card发动的时候弹出了这个对话框,证明效果发动并且真的处理。但是永续型效果却无法用这种方式调试,因为永续型效果一般不带operation。这就惨了,我怎么知道自己写的永续型效果有没有起作用?这就要慢慢来了。一般是先用容易检测到的永续型效果来测试基本代码是否无误,然后再修改成更具体的代码,这里涉及到效果脚本的调试请看2.5效果脚本的调试。※再提供多一段代码给你,将这段代码添加到hallo card里看看。local e3=Effect.CreateEffect(c)
e3:SetType(EFFECT_TYPE_TRIGGER_F+EFFECT_TYPE_FIELD)
e3:SetCode(EVENT_TO_GRAVE)
e3:SetRange(LOCATION_SZONE)
e3:SetOperation(c.op)
c:RegisterEffect(e3)在测试之前你能不能看懂这个效果什么意思?
2.5 效果脚本的调试这是很重要的环节,虽然我们还没有详细的讲解到condition target cost operation函数的具体细节,但是以目前学到的知识,各位其实都已经可以去设计没有实际操作但是又可以发动的空效果effect了,例如我们写的hello card。通过不断的尝试各种各样的效果组合来了解各种效果的运作特点在正式编写效果脚本前是很有意义的。由于路飞君的提点,重新修正了脚本调试的方法。有一点要注意:在上面我选了Duel.SelectYesNo作为调试用函数,来测试operation函数有没有被执行。但是这个函数只允许在Cost,Target和operation这三个函数里面使用,condition是不能加这个函数检测的。人非圣人孰能无过,尤其是像我们没有专用编译器帮你差错,直接在文本编辑器上面码代码,很容就写错字,弄错标点什么的,效果不能发动或者发动了不起作用。这时候就要靠YGOCORE去帮你找出脚本中哪一行出错。开启YGOCORE的Debug模式(调试模式)给YGOCORE创建一个快捷方式的目标文件那里添加–Debug 这几个字这样YGOCORE的调试模式就开启了。 测试卡片的时候,脚本的错误都会记录在YGOCORE根目录的error.log文件里面。 现在我们试一下将SetOperation函数里面的c.op删掉,保存然后测试卡片。 这时候打开error.log,找到自己的lua脚本。这两句就是调试信息,写明了是什么错误。 [Script error:][string “c######.lua”]:行号错误原因重要的是行号和错误原因,我们直接根据行号查看自己lua所在那行代码,然后根据错误原因去检查哪里出错。Error.log里面说我的lua脚本第8行缺少了个function参数。打开一看,第八行SetOperation还真的少了个operation函数参数(废话……不刚才自己弄得么)拼写错误的话error.log是怎么提示的?信息显示第5行 SetTpe 呼叫失败。看到这个难道还不明白么。如果我们将符号常量写错了会怎么样?我将SetType的EFFECT_TYPE_ACTIVATE写成了EFFEC_TYPE_ACTIVATE。测试一下。没有产生新的调试信息,我写错了符号常量但是YGOCORE却没有检测出则个错误。看来YGOCORE是不会检查符号常量的拼写错误的。这里就要注意了,这种错误要靠自己去排查检查。不过一般代码没写错,那么就肯定是符号常量有错。脚本编写与调试步骤(各个阶段都要配合error.log调试信息)第一步:先将效果的最基本代码写出来。其实就是hello card的那种,只把能发动效果的最低限度的代码写出来。然后测试,看能不能够发动。第二步:为添加调试用operation函数,调试函数就用duel.SelectYesNo()来充当。然后再测试,看看效果发动后有没有进入处理。target,cost也用这种方法。第三步:通过error.log调试condition。第四步:代码的具体实现阶段。condition target cost operation这四个函数畅通无阻后,就开始往里面编写具体的处理代码。这时候的调试就主要依靠error.log调试信息了。当然在target cost operation这三个函数里面,我们也可以使用调试函数来按步跟踪。按照以上的步骤我们就将代码debug分成了四个阶段,再配合YGOCORE提供的error.log调试信息,消除bug也就更准确方便了。到时候,只要对应哪个阶段去检查该阶段的代码即可。要养成经常检查error.log的习惯。
YGOCORE 游戏王CORE的自定义卡片教程(4)——第二章·进阶篇(上)第二章
进阶篇上一章是入门,让大家体验了下如何为卡片添加效果。但是真正要学会添加具体效果仅仅靠那些三脚猫功夫是远远不够的。我们还需要了解一下YGOCORE的运作过程,接着要了解效果effect代码的基本样式。2.1 YGOCORE的运作机制运作机制有纵向和横向两个过程--==纵向过程!--触发型效果进入连锁的操作系统发出事件消息 EVENT_XXX第一步、检查时点 EVENT_XXX
CODE 触发阶段--进入效果第二步、检查条件 不满足前提条件不能发动
检查阶段第三步、检查和处理对象
设置operation信息OperationInfo(操作信息,包括宣言)
对象不存在则不能发动第四步、检查和处理cost
--处理效果 第五步、效果的处理操作
操作阶段--此时系统根据Operation的OperationInfo里CATEGORY信息在连锁中“发出宣言”--退出效果控制权返回系统系统自己又会根据当前情况继续发出各种事件消息 EVENT_XXX如此循环--不进入连锁的永续型效果第一步、检查生效范围
LOCATION_XXXX
range第二步、检查条件condition
前提条件不满足则不生效第三步、检查和处理cost --处理效果第五步、效果的处理操作
Operation--==横向过程值得一提的是! YGOCORE是先按步,再按卡片顺序的进行处理的。例如我们场上有 3张卡 A B C那么YGOCORE就先依次检查ABC是否满足时点
--第一步再依次检查ABC是否满足前提条件
--第二步 再依次检查ABC是否存在对象
--第三步 再依次检查ABC是否有满足cost
--第四步最后依次执行ABC的处理操作
--第五步※从这里知道,如果一张卡片能否发动依次取决于前三步是否都满足,如果自己编写的效果lua脚本满足了各种条件的情况下仍无法发动则应当去检查前三步所涉及的函数及其代码是否有误。而之前就说过,这三个函数可以留空不写,留空则表示永远满足。
2.2 主角登场——效果类型effect脚本我们在两次的Hello Card里面已经写过最基础的“空效果”——只有发动而没有实际功能的效果。其实已经对effect效果的创建过程有了比较清晰的认识。但是一个真正意义上完整的效果往往十分复杂,有很多细节。我们就拿魔轰神兽刻耳柏拉,那只三头猫(应该是猫吧)的效果来作说明,注意这个效果是触发型效果。一个效果里面往往有很多的信息,包括了时点code,前提条件condition,目标对象target,操作operation等。时点code是指这个效果能够被触发的,前提条件condition是这个效果能够发动的前提,目标对象target是这个效果作用的目标(目标不存在不能发动,也就是空发不能),操作operation是这个效果的最终处理操作。对于魔轰神兽的效果,我们可以从中抽离出上面几点信息。这张卡(type:EFFECT_TYPE_SINGLE)从手卡(condition)丢弃(reason:REASON_DISCARD)去墓地时(code:EVENT_TO_GRAVE),这张卡在自己场上特殊召唤(operation:SpecialSummon,LOCATION_MZONE)。(由于没有可以两个字,所以是type:EFFECT_TRIGGER_F诱发必发) 整理出来后就是以下:Code时点:进墓地时Type类型:只针对这张卡SINGLE+触发必发型TRIGGER_FCondition:进墓地前在手卡+被丢弃operation:发动效果的这张卡+表侧表示+特殊召唤+自己场上Target:好像没有噔噔!一下子就抽离出了这么多信息,effect的脚本编写其实就是将这些信息填充进我们的空效果里面。然后去看看魔轰神兽的初始化效果部分代码:红色部分就是我们跟我们抽离出来的信息相吻合的部分,紫色的则是我们漏掉的信息,原来effect效果还有个属性叫做效果类别Category,而魔轰神兽的效果的效果类别是特殊召唤类。另外,明明这张卡没有作用于目标对象,为何要有Target,因为目标对象也可以是自己啊。而且触发型效果的Target跟Operation总是成对出现的。关于这个最后面会讲到。涉及到宣言。
2.3 effect脚本的基本格式说是基本格式其实只是为了让初学者有一个规范,不然乱七八糟的语句除了会产生各种各样的bug外还让脚本的编写困难重重。--效果属性的设置在initial_effect()函数里面 --效果的处理函数在下面定义 --有时候我们还需要自己定义一个卡片过滤函数filter用来反复调用过滤卡片。 --需要设置的基本属性值和设置方法请看下面第一部分. --需要定义的处理函数请看下面※一个卡片的效果可能由很多个效果组成,而每个效果的触发条件之类的属性都可能各不相同。而像永续魔法卡还需要一个独立的发动效果--Activate 该效果可能没有效果处理行为,作用仅仅是将卡片翻开发动而已。请回忆起我们的hello card。关于“各种卡片的效果的基本模板”,这个另外讲解。最初的时候我就讲过YGOCORE是如何创建卡片Card类型变量然后将效果注册给卡片card的:先根据卡组信息读入c+ID然后根据这个ID创建card对象,接着根据script目录下对应的脚本初始化效果e1 e2 e3……依次将效果注册给这个card变量(绑定)。这只是游戏开始时效果初始化的做法,我说过效果也是YGOCORE里的一种类型,也是变量,所以效果是可以动态创建和动态绑定(注册)的——“随时随地”按需要给卡片注册一个新效果。这个特性也经常会用到——全局效果和效果标记,这个以后会独立的讲到。 关于效果属性的设置可以直接去第一章effect类的基本属性表那里查看,接着到function.TXT里面查找effect类对应的Set函数,根据说明调用即可。这里我就不多讲了,因为有的查。
2.4 condition、cost、target、operation、value这五个函数的相关讲解。还记得上面魔轰神兽我们所抽离出的信息么,一般情况下抽离出来的信息都会涉及上面五个函数中的某几个。魔轰神兽就涉及到了condition前提条件、target目标对象和operation操作处理,这三个函数。魔轰神兽效果的具体的细节就在这三个函数里面编写。首先他们五个都有对应的Set函数。函数与参数列表※触发型效果跟永续型效果的参数略有出入※触发型效果condition最终需要返回一个boolean型数据,true表示满足条件,false表示不满足。Target,cost第一条语句必须if chk ==0 then return 条件 end这样,用于判断可行性,防止空发。(如果cost里面没有进行可行性判断,先判断能否支付代价的话,就会出现支付超出LP的代价把自己弄死的囧情况)如果三条函数不Set、留空则认为总是满足条件。operation中进行实际的效果处理,并且不需要返回值。※永续型效果的operation可能有返回值。永续型效果的target cost没有chk参数所以不用判断可行性。但是与此同时永续型效果的target和cost反而需要返回值。而这里target和cost跟condition一样成了operation的前提条件。※蓝色背景色部分表示这些参数描述了事件/时点的相关信息。※触发型和永续型的参数有所不同,c、g、gc,te_or_c是永续型效果才有的参数。
YGOCORE 游戏王CORE的自定义卡片教程(4)——第二章·进阶篇(下)为什么触发型和永续型的condition等函数的参数会有所不同?这是因为触发型和永续型他们所涉及的事件信息不一样。触发型的效果涉及的事件信息有:作用了哪个卡片组event group、作用了哪个玩家event player、事件的参数值value、因哪个效果reason effect、因什么原因reason、因哪个玩家reason player。就是蓝色的那几个参数。举例来说:玩家1发动某效果e1对玩家2造成了500的效果伤害,那么这时候就会产生事件信息。eg:空——没有作用于哪个卡片组ep:1 (1=玩家2)——作用于玩家2ev:500 ——事件有500的数值re: e1 ——因效果e1r: REASON_EFFECT(效果伤害)——因效果伤害rp: 0 (=玩家1)——因玩家1触发性效果的那几个函数就是将这几个值传入函数。而永续型效果由于只有影响作用所以它涉及的事件信息只有:作用的卡片card、作用的卡片组group、作用的卡片组数目group count、作用的效果effect或card、这个效果的玩家this player。※tp(this player)不是指该回合的玩家,而是指那个开了连锁的效果所属的玩家。例如在自己回合对方发动了陷阱卡,那么就开了个连锁,这时候事件信息里面的tp就是对方。※要注意,无论触发型还是永续型,operation的参数都是一样的。函数样板※有chk参数的函数都第一条语句都先判断chk,chk默认为0,意思是不可行,这个是用来设置门槛防止效果空发的。在target函数里,例如一个效果要选择场上一张卡破坏,那么场上就必须有卡,而且那卡是可破坏的,这时候我们才可以发动效果。在这里目标对象就是场上的一张卡,要是目标不存在的话就不发动。在target里Chk就是负责检查可操作对象是否存在。在cost函数里则是负责检查能否支付代价。他们的共同点就是检查可行性。例如我们只剩下1000LP这时候总不可能还能发动神警吧,难不成透支代价而死么?所以这里就有了这样一段语句:if chk == 0 return Duel.CheckLPCost(tp,2000)这位玩家能否支付2000LP作为cost。永续效果型的cost里面没有chk参数,所以不需要判断chk,但是永续型效果的cost有bool值,也就是说要 return条件 end 给他返回一个真假值。※如果触发型效果的operation带有某种类别如破坏会引发相应的事件、除外等等,那么target函数要为operation函数设定操作信息,调用函数Duel.SetOperationInfo(),其中一个参数是“操作的类别”,而cost函数不需要SetOperationInfo。 =====================================================================好了,知道了这5个函数的相关知识后,我们可以拿魔轰神兽了来练练手。怎么练?那就是自己分析魔轰神兽那张卡的效果然后写出伪代码(中文意思的代码),最后再去对比一下自己的代码跟原效果代码。以下是我们之前从效果说明中抽离出来的信息Code时点:进墓地时Type类型:只针对这张卡SINGLE+触发必发型TRIGGER_FCondition:进墓地前在手卡+被丢弃operation:发动效果的这张卡+表侧表示+特殊召唤+自己场上Target:好像没有试一下一伪代码的形式将上面的信息写成condition等函数的具体实现。Function condition(e,tp,eg,ep,ev,re,r,rp)return这张卡之前在手卡上and 事件原因是被丢弃endfunction Target(e,tp,eg,ep,ev,re,r,rp,chk) if chk ==0 return true end ——我们目标对象就是这张卡,所以无论如何都可行。※设置operation的信息:宣言特殊召唤,这张卡,1张……——这一句可暂时不用理解endfunction operation(e,tp,eg,ep,ev,re,r,rp)
发动效果的是这张卡then 表侧表示特殊召唤到自己场上endend上面就把伪代码写好了,接着只要根据伪代码去function.txt找对应的函数替换掉中文部分就行了。其实正式的代码跟伪代码已经相差不大,不信你自己看。function c.spcon(e,tp,eg,ep,ev,re,r,rp)
return e:GetHandler():IsPreviousLocation(LOCATION_HAND) and bit.band(r,REASON_DISCARD)==REASON_DISCARDendfunction c.sptg(e,tp,eg,ep,ev,re,r,rp,chk)
if chk==0 then return true end
Duel.SetOperationInfo(0,CATEGORY_SPECIAL_SUMMON,e:GetHandler(),1,0,0)endfunction c.spop(e,tp,eg,ep,ev,re,r,rp)
if e:GetHandler():IsRelateToEffect(e) then
Duel.SpecialSummon(e:GetHandler(),0,tp,tp,false,false,POS_FACEUP)
YGOCORE 游戏王CORE的自定义卡片教程(5)——第二章续第二章续从上一节的魔轰神的编写实践中,其实大家都已经知道效果是怎么具体实现出来的了。那么这时候又要再重新介绍一下YGOCORE的四个脚本函数库。因为写condition等函数内部的实现时要用到以下函数库里的函数。YGOCORE的脚本系统有四大部分组成(实质就是函数库)Duel
——决斗系统Card
——卡片系统Group
——卡片组系统Effect
——效果系统Duel决斗系统主要负责整个决斗环境,它相当于是“一双手“,拿起卡片,放下卡片,抽一张卡,选择卡片,擦看卡片,破坏卡片等等等等的这些“手操作”都是由duel中的函数实现的。也就是说想要让YGOCORE“动起来”,想要将那些卡片弄来弄去,就要靠这个。这四个系统里面与图形引擎最亲密的就是Duel,大部分我们能够看得见的操作都是duel函数的作用。而其他三个系统则比较隐性,一般我们察觉不到他们工作。同时效果的连锁也是由Duel来控制,效果1发动-》效果2连锁-》效果3连锁,这些连锁会被duel一一记录然后逆向处理。另外你还记得2.3常量介绍的REASON常量么?你有没有想过REASON值是谁写进card里的?其实是Duel写进去的。Duel函数处理card,让card位置产生变化时就会为card写入一个原因,而这个原因是我们指定的。Card卡片系统——对应card类型的函数它负责的是卡片的一些操作,大部分的参数是用来获取卡片的信息的,获取后用来逻辑判断。Group卡片组系统——对应Group类型的函数Effect效果系统——对应effect类型的函数基本Card卡片系统,大部分参数用来获取效果信息,另外他还能获取这个效果所属的那张卡片card。YGOCORE的效果就是调用上面的四个系统里的函数进行逻辑处理的。我们从模拟写魔轰神兽三头猫的效果那里就已经切身的感受到了这几个函数库要如何使用。这几个函数库已经被作者记录在function.TXT里面了,随时可以去查找。第二章我们了解YGOCORE效果运作机制和效果effect脚本的具体实现要如何编写,但是从中却遗留下了一些未解之谜。那个莫名其妙的filter卡片过滤函数和Duel.SetOperationInfo()函数是什么的干活。
关于卡片过滤函数filter(c。。。)这是我们自己创建定义的函数,系统不会自动调用,需要我们在target condition cost 或者 operation中自行调用,作用其实就是将重复使用的过滤代码给写成一个函数使用,让代码更美观简练。并且可以将此函数作为参数传入duel或者group的一些函数里面用作过滤之用。该函数返回的是 bool ,而第一个参数是c,值得注意的是filter的参数长度不固定,可以传入额外参数。也就是说c后面可以跟一连串参数,如 filter(c,atk,def……)这些额外参数怎么用呢?这里要提及lua的一些特性了,lua里面函数也是值,当作参数传进函数是为了被那个,但是lua函数用作参数传入时挺有特色。例如这个duel的函数,他的作用是将讲某个卡片组里面符合要求的卡片过滤出来以卡片组类型返回。Duel.IsExistingMatchingCard(functionf, integer player, integer s, integer o, integer count, Card ex, ...)我们不能这样传入filter函数Duel.IsExistingMatchingCard(c#####.filter(c,),tp,LOCATION_MZONE,0,1,nil)这是错误的。因为这样实际上就是将函数的运算结果(返回值)给传入了。我们要这样Duel.IsExistingMatchingCard(c#####.filter, tp, LOCATION_MZONE, 0, 1,nil,g,)Duel.IsExistingMatchingCard参数最后那里有“…“三个点,意思是额外参数。Lua里面允许传入函数进去运算但是只允许传入函数名,而该函数的参数则要在额外参数”…“后面传入。当duel函数处理的时候就会将额外参数那部分补到filter的参数表里面处理。下面是作者function.txt里面的说明。过滤条件函数是指第一个参数是Card类型,并且返回值是boolean的函数。此函数用于在一些获取满足条件的卡片组的过滤函数中重复调用。过滤条件函数可以有不定的参数,第二个开始的参数从过滤函数的额外参数获得。举例:function sample_filter(c, atk, def)return c:GetAttack()&=atk and c:GetDefence()&=defend此函数对于一张卡c,如果攻击力&=atk并且守备力&=def则返回true,否则返回falseg=Duel.GetFieldGroup(0,LOCATION_HAND,0) --获取玩家1的手卡fg=g:Filter(sample_filter, nil, ) --从g中筛选攻击力&=1000并且守备&=500的卡Group.Filter只需要3个参数,第4个参数开始为额外参数,额外的参数会传给sample_filter关于SetOperationInfo()函数在上一节,大家自己看condition、operation……函数模板那张图,会发现,effect里面有个属性是CATEGORY值的,而target函数里面的SetOperationInfo()也有CATEGORY值要设置给Operation函数。为什么会有两个地方都要有CATEGORY属性?effect有一个,operation又有一个。这里要说到“宣言”这个东西,有些效果的发动除了需要时点满足外,还需要判定某个连锁中是否带有某种“宣言”。例如星尘龙需要判定某个连锁里是否有“破坏宣言”,然后才能根据这个宣言发动和处理效果。请大家回顾一下YGOCORE的效果运作机制其中处理operation的那一步,系统根据OperationInfo发出了与operation的操作类别CATEGORY对应操作宣言,将这个宣言保存在连锁信息里面。当我们为某个operation设置了宣言类别后,那么那个operation处理的时候就会自动将宣言保存在连锁里。然后其他效果就可以从这个连锁里获取宣言信息判定发动效果。这就是我在上面Duel脚本系统那讲过的“操作是一双手“,它按照效果的说明做出具有效果类别的操作,并且对外宣言自己的这个操作具有什么类别。当操作执行的时候连锁里就带有了宣言信息。 宣言一旦发出!那么该效果的操作类别就被定性。”我要破坏你的卡片(宣言)“
于是乎小王的星尘龙就发动效果了。星尘龙正好接符合发动时点CHAINING。接着连锁的宣言里有破坏性质,那么星尘龙的效果就可以发动了。效果effect属性上面的类别属性(category)只有标识作用,是基本属性,没有发出宣言的能力。它只是被用来获取信息在别的地方作卡片属性判断用的。
例子 雪人食人怪与星尘龙雪人发动效果,执行效果处理操作operation函数,而在target函数里面就已经为operation写入了信息,其中就包含了它的操作具有CATEGORY_DESTROY类别,于是乎YGOCORE就根据operationInfo里的这个类别在当前连锁里面写入了破坏宣言。这时候这个时点刚好满足了星尘龙的效果,星尘龙接着判断那个连锁中是否带破坏宣言,然后再处理操作operation 无效并破坏雪人。--星尘龙与 潜行狙击手不得不说的秘密众所周知,潜行狙击手的破坏效果无法被星尘龙无效,按照游戏王卡片的规则来说,是因为潜行狙击手的破坏效果不确定,不知道是不是破坏,所以其效果不能定性为破坏效果。但是在YGOCORE里面却有另外一种角度的解释,这是从程序员的角度来看的。潜行狙击手效果属性CategoryCATEGORY_DESTROYTypeEFFECT_TYPE_IGNITIONPropertyEFFECT_FLAG_CARD_TARGETRangeLOCATION_MZONEOperationInfoCATEGORY_DICE以上是潜行狙击手的效果属性,效果的类别是破坏CATEGORY_DESTROY,但是操作operation的OperationInfo里类别确是扔色子CATEGORY_DICE。虽然operation函数里面确实也有Duel.Destroy()破坏卡片的函数但是由于operation被定性为扔骰子类别操作,所以它不会往当前连锁里写入破坏宣言,于是星尘龙也就无法针对连锁发动效果了。不过……operation会向系统发出扔色子宣言——“我扔骰子了!“举一反三如果要让潜行狙击手的操作能够触发星尘龙或我身作盾的效果,同时又具备CATEGORY_DICE的宣言该怎么做?很简单,只需要在target函数里再添加一条SetOperationInfo()语句就够了Duel.SetOperationInfo(0,CATEGORY_DESTROY,g,1,1-tp,LOCATION_MZONE)这个语句的意思是 --将当前操作的宣言设定为破坏类,作用的对象卡片为g,数目为1,对象玩家为对方,位置为怪兽区。这样潜行狙击手的效果就可以触发星尘龙的反击效果了。※同一个operation可以同时设置多个OperationInfo!
YGOCORE 游戏王CORE的自定义卡片教程(6)——实战演练!第三章前奏!第三章尚未正式开始,但是通过前两章的学习我们其实已经具备了基本的写卡能力,可以独立的完成一个卡片的效果编写了。下面我们通过实战演练巩固一下写卡的整个流程积累经验。这次就拿我们曾经分析过的卡来练,那就是第二章里分析过的三头猫“魔轰神兽 刻耳柏拉”。准备阶段:卡库录入:用DataEditor添加卡库信息,由于已经有三头猫的信息了所以我们额外添加一个新的id——c。卡图:可以准备也可以不准备。
分析阶段:分析卡片效果,从效果中抽离出各种信息。这张卡(EFFECT_TYPE_SINGLE)从手卡(condition:LOCATION_HAND)丢弃(condition:REASON_DISCARD)去墓地时(code:EVENT_TO_GRAVE),这张卡+在自己场上+特殊召唤(operation:这张卡+自己场上+特殊召唤+表侧表示)——额外得到的信息有 category:CATEGORY_SPECIAL_SUMMON,type 诱发必发型 EFFECT_TYPE_TRIGGER_F写成表Code:送去墓地时
EVENT_TO_GRAVEType:这张卡+诱发必发
EFFECT_TYPE_SINGLE+EFFECT_TYPE_TRIGGER_FCategory:特殊召唤类
CATEGORY_SPECIAL_SUMMONCondition:从手卡 被丢弃LOCATION_HAND,REASON_DISCARDOperation:这张卡+自己场上+特殊召唤OperationInfo:特殊召唤写成伪代码function c.condition(e,tp,eg,ep,ev,re,r,rp)
return 这张卡之前在手卡上 and 被丢弃 end function c.target(e,tp,eg,ep,ev,re,r,rp,chk)
if chk==0 then return true end
设置操作信息:特殊召唤宣言end function c.operation(e,tp,eg,ep,ev,re,r,rp)
if 发效果的是这张卡 then 表侧表示+特殊召唤+自己场上 endend接着就去写这个效果能发动的最基本代码function c.initial_effect(c)
local e1=Effect.CreateEffect(c)
e1:SetCode(EVENT_TO_GRAVE)
e1:SetType(EFFECT_TYPE_SINGLE+EFFECT_TYPE_TRIGGER_F)
e1:SetCategory(CATEGORY_SPECIAL_SUMMON)
c:RegisterEffect(e1)end 然后上去测试 恩!不错!进墓地成功诱发了效果。运作良好!接着就是把伪代码的condition函数们转换成真正的代码了!对着这些代码去function.txt里查找。
一、这张卡之前在手卡上①这张卡:“这张卡”要如何获得?condition参数表上只有代表这个效果的e而没有代表这张卡的参数。我们去effect的函数里找一找,还好effect的函数都不多,我们主要找Get函数。找啊找找到了这个函数Card Effect.GetHandler(Effect e),返回效果在哪一张卡上生效(通常是注册该效果的卡)。看来这个是我们要的函数。直接 e:GetHandler()就是这张卡自身了。②在手卡上:得到了“这张卡”接下来要获取这张卡的位置信息,又去function.TXT里面找card的函数,还是Get函数。找到了两个,integer Card.GetLocation(Card c)和integer Card.GetPreviousLocation(Card c)。前者是获得当前卡片的位置,后者是获得之前卡片的位置。明显后者是我们要的。我们可以这样写 e:GetHandler():GetPreviousLocation()==LOCATION_HAND。但是事实上除了这两个函数外还有另外两个专门用来干这种事情的函数。boolean Card.IsLocation(Card c, integer loc),该函数检查c当前位置是否是loc。boolean Card.IsPreviousLocation(Card c, integer loc),该函数用来检查c之前位置是不是loc。有了这个函数后我们可以改成这样 e:GetHandler():IsPreviousPLocation(LOCATION_HAND) 二、被丢弃这个就简单了,之前说过过YGOCOE会发出一系列的事件信息,这些事件信息就会传入condition target cost operation里面。REASON也是其中一个事件信息。参数里的r就是了。那么我们就可以写成 r==REASON_DISCARD。三、 设置操作信息:特殊召唤宣言设置操作信息要用duel里的SetOperationInfo函数。void Duel.SetOperationInfo(integer chainc, integer category, Card|Group targets, integer count, integer target_player, integertarget_param)设置当前处理的连锁的操作信息。此操作信息包含了效果处理中确定要处理的效果分类。比如潜行狙击手需要设置CATEGORY_DICE,但是不能设置CATEGORY_DESTROY,因为不确定。对于破坏效果,targets需要设置成发动时可能成为连锁的影响对象的卡,并设置count为发动时确定的要处理的卡的数量。比如黑洞发动时,targets需要设定为场上的所有怪物,count设置成场上的怪的数量。对于CATEGORY_SPECIAL_SUMMON,CATEGORY_TOHAND,CATEGORY_TODECK等分类,如果取对象则设置targets为对象,count为对象的数量;如果不取对象则设置targets为nil,count为预计要处理的卡的数量,并设置target_param为预计要处理的卡的位置。例如增援:SetOperationInfo(0,CATEGORY_TOHAND,nil,1,0,LOCATION_DECK)。操作信息用于很多效果的发动的检测,例如星尘龙,王家沉眠之谷等。看完上面一大堆后我们可以这样写Duel.SetOperationInfo(0,CATEGORY_SPECIAL_SUMMON,e:GetHandler(),1,0,0)四、发效果的是这张卡这里明显是只这张卡与这个效果是否有联系,而且一般“是xxx”这种说法的函数都是Is开头的。我们去function里面找一下card里有没有我们想要的函数。最后我找到了这个,boolean Card.IsRelateToEffect(Card c, Effect e) 检查c是否和效果e有联系。那么我们就可以写成这样 e:GetHandler():IsRelateToEffect(e)为什么要做出这样的判断呢?因为万一魔轰神兽进墓地被dd乌鸦连锁除外了,那么这个特殊召唤操作就明显要终止,因为发效果的怪已经不在了。但是在YGOCORE里面Duel可是“上帝之手”啊!只要他做出Duel.SpecialSummon(),就算那张卡除外了也给你特殊召唤回来(跟异次元苏生一样)。所以必须先判断一下那卡是否还跟着个效果有联系——也就是“还存不存在”——再处理特殊召唤。当然这里我们只是忠于效果的描述弄上去的,我们并没有考虑那么多。五、表侧表示+特殊召唤+自己场上这里要用到duel的SpecialSummon函数了,直接搜吧!integer Duel.SpecialSummon(Card|Group targets, integer sumtype, integer sumplayer, integer target_player, boolean nocheck,boolean nolimit, integer pos)让玩家player以sumtype方式,pos表示形式把targets特殊召唤到target_player场上。如果nocheck为true则无视卡的召唤条件。如果nolimit为true则无视卡的苏生限制。返回值是特殊召唤成功的卡的数量。里面有一个参数是sumtype,是个integer,直觉告诉我这是个常量标识,我们到constant.lua里找一找,发现真的有SUMMON_TYPE常量。同理pos的常量也发现了 POS_。我们需要的是SUMMON_TYPE_SPECIAL(特殊召唤)和POS_FACEUP(表侧表示)这两个。我们可以这样写Duel.SpecialSummon(e:GetHandler(),SUMMON_TYPE_SPECIAL,tp,tp,false,false,POS_FACEUP)OK最后把伪代码换成上面的代码!function c.condition(e,tp,eg,ep,ev,re,r,rp)
return e:GetHandler():IsLocation(LOCATION_HAND) and r==REASON_DISCARDendfunction c.target(e,tp,eg,ep,ev,re,r,rp,chk)
if chk==0 then return true end
Duel.SetOperationInfo(0,CATEGORY_SPECIAL_SUMMON,e:GetHandler(),1,0,0)end function c.operation(e,tp,eg,ep,ev,re,r,rp)
if e:GetHandler():IsRelateToEffect(e) then Duel.SpecialSummon(e:GetHandler(),SUMMON_TYPE_SPECIAL,tp,tp,false,false,POS_FACEUP) endend 然后在效果初始化那里Set上这些函数。function c.initial_effect(c)
local e1=Effect.CreateEffect(c)
e1:SetCode(EVENT_TO_GRAVE)
e1:SetType(EFFECT_TYPE_SINGLE+EFFECT_TYPE_TRIGGER_F)
e1:SetCategory(CATEGORY_SPECIAL_SUMMON)
e1:SetCondition(c.condition)
e1:SetTarget(c.target)
e1:SetOperation(c.operation)
c:RegisterEffect(e1)end 然后我们就屁颠屁颠的跑去测试。
嗯…………什么都没发生……怎么回事 ? 回想一下我的调试教程。查看一下error.log文件发现根本没有新error。看来代码没有错误。再说基本效果代码我们再第一阶段已经测试过了,可以诱发,肯定也没问题,那么问题出在哪里呢?问题这时候只能是出在condition那里。我们试一下将r==REASON_DISCARD去掉试试(包括前面的and)。发现居然诱发了。看来问题是出在REASON_DISCARD上。为什么r==REASON_DISCARD不起作用,不是原因“丢卡”吗?在这里我们要想想“八戒临死前三天说的话”了。还记得我在第一章续的常量那里讲过常量是可以用+号加起来的吧。而且那时候我用的例子刚好就是REASON_DISCARD啊!这里我就要更加详细的去讲解一下了!在常量里面!有些常量只能组合使用不能单独拿出来用!例如REASON_DISCARD,他单独一个的话没有任何意义,他要跟REASON_EFFECT、REASON_COST等连用才有意义。表明他是因具体哪种原因被丢弃的。我们试一下将代码改成r==REASON_EFFECT+REASON_DISCARD 看看。测试!嗯?效果出发了耶!看来真的是这样!看到这里我们就知道怎么做了,我们将REASON_DISCARD所有有可能的组合都写出来。r==REASON_EFFECT+REASON_DISCARD+REASON_COST+………………要写到猴年马月啊!这组合总共有n个那么多个啊!还记得第一章续里面我说过常量的过滤操作么?这里终于就大显神威了!我们用 bit.band(r,REASON_DISCARD) 抽出r跟REASON_DISCARD 里面相同的部分!如果r里面包含有REASON_DISCARD的话那么就会返回REASON_DISCARD。我们的代码就可以改写成这样bit.band(r,REASON_DISCARD)==REASON_DISCARD开机测试!现在这张卡无论什么原因被丢弃到墓地都会引发效果了!!!我们的第一场实战圆满结束。ps:关于常量组合。那些不能够单独拿出来使用的常量的一般都是 _PHASE _EVENT结尾的。他们必须分别跟PHASE_ EVENT_量组合使用。如RESET_PHASE RESET_EVENT。其中最特殊的是REASON_里面的值,具体那些必须组合使用我现在还没有绝对的经验。
全文完。感想:我猜这个火不了,毕竟大家时间有限、兴趣有限,有时间看教程还不如直接下个最新版的ygocore多大几盘,对吧?反正让有需要的人看到就行了。
我们合作写一个如何?我自己不够熟练
你也发现了,虽然都是LUA,但是AI和卡片脚本的最大区别是,AI之间重叠的部分很大,导致一个语句出错,可能全部AI卡组都会错了,我指的就是基本逻辑。灾亡兽就是一个例子。现在灾亡兽很可能没写全,缺了它在场上时对一些卡片类型的判断,导致一用就出错,而与之相对的,就是只命令某个AI卡组的语句了。比如巨神兵、翼神龙那种会特别写明要三个祭品。到时候写教程,要告诉新手,AI脚本会分为“基本逻辑”和“个别逻辑”,这是最简单的说法了,而且AI卡组本身也在AI文件夹里面,而不是在DECK里(这点中文版的反而在DECK里了)。另外,你那个刷屏的五行我改了,改成对AI作弊强度的中文提示,防止还有人问。总之这个写法就是从最基本的几个写法开始,比如“AI如何明白对面怪兽不被战斗破坏”、“AI如何不用旋风破坏自己的卡”、“AI如何判断该不该发动选发效果”等等,由浅入深,像学语言一样,先学普遍的写法,再学语法结构,那也是可以考虑的办法。
贴吧热议榜
使用签名档&&
保存至快速回贴}

我要回帖

更多关于 游戏王剧场版有哪些 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信