上一期我们稍微介绍了一下YGO PRO以及制卡用的DataEditorX,这一期开始,我们就要正式开始我们的印卡大业了~
(注意:1、本章篇幅较长,没有耐心看下去的人可以跳过去了;2、之后的操作以YGO Pro 2为基准)
首先我们打开DataEditorX,按照上期的方法打开cdb库,先别点那些卡,我们在卡片密码那里输入一串数值,比如54998762啥的,注意不能含有字母,否则会提示“卡片密码不能为0”,在卡图上方的框框中填入卡片名字,选好卡片类型以及卡片属性(如果要做效果怪的话记得一定要勾选“怪兽”以及“效果”和“效果分类”一栏中你想做的效果,方便之后检索)后点击添加,我们的卡片信息就成功导入进数据库了。
这里以“特殊召唤”为例,下图:
我们点击“脚本”,就可以为卡片创造一个命名格式为“c卡片密码.lua”的lua脚本(在选择打开的数据库所在的目录下,会自动生成一个“script”文件夹,自建脚本就存放在那里),此脚本可以使用Notepade++等工具编写,编写前记得把编码改成“utf-8 无BOM”,否则编出来的脚本是无效的,记得一定要编写之前改,编写完了过后再改已经迟了(某位大大的教训)。在这里我使用的是DataEditorX自带的编写工具,就省掉了改编码的那一步了。
可以看到,最上面那里就是我们的卡名,下面则是正式的代码区。
在这里会调用到YGO Pro自建的函数以及数据类型,下面搬运卡鲁洛斯大大给出的表(虽然很长但是这些都是我们后面要用到的,没耐心的请拖动滚动条OWO):
--Locations LOCATION_DECK 卡组 LOCATION_HAND 手牌 LOCATION_MZONE 怪兽区域 LOCATION_SZONE 魔陷区域 LOCATION_GRAVE 墓地 LOCATION_REMOVED 除外区 LOCATION_EXTRA 额外 LOCATION_OVERLAY 叠放卡 --Positions POS_FACEUP_ATTACK 表侧攻击 POS_FACEDOWN_ATTACK 里侧攻击 POS_FACEUP_DEFENCE 表侧守备 POS_FACEDOWN_DEFENCE 里侧守备 POS_FACEUP 表侧 POS_FACEDOWN 里侧 POS_ATTACK 攻击 POS_DEFENCE 守备 --Phase PHASE_DRAW 抽卡阶段 PHASE_STANDBY 准备阶段 PHASE_MAIN1 主要阶段1 PHASE_BATTLE 战斗阶段 PHASE_DAMAGE 伤害阶段 PHASE_DAMAGE_CAL 伤害计算时 PHASE_MAIN2 主要阶段2 PHASE_END 结束阶段 --Player PLAYER_NONE 无玩家 PLAYER_ALL 双方 玩家的标识: 0=玩家1, 1=玩家2
Effect是实现各种效果的中心部分。在此系统中,根据一个效果是否有操作动作(比如破坏,伤害等),卡的效果主要被分成两种,一种是永续型,另一种是触发型。永续型一般是表示状态变化的效果,触发型一般是需要有动作或者需要执行特定的函数才能实现的效果。当然也有特例,具体参考效果说明文档。 Effect可以通过两个函数来创建 ●Effect.CreateEffect() 此函数将会建议一个新的空效果 ●Effect.Clone(e) 此函数将会创建一个已存在的效果e的副本 当然,Effect不注册是不能生效的。Effect可以通过以下两个函数注册给卡片或者全局环境 ●Card.RegisterEffect(c,e) 将效果e注册给卡片c ●Duel.RegisterEffect(e,player) 将效果e作为玩家player的效果注册给全局环境 Effect主要包含了以下需要设置的值: description,code,type,category,range,target range,count limit,reset,property,label, condition,target,cost,operation,value,owner player 这些属性基本都可以通过相关的Set和Get函数来设置和获取。具体参考Effect库的函数说明。 两种类型通用的属性: ●Description: 效果描述,大部分效果可不用,从多个效果中选择一个发动时才会用到这一属性 ●Code: 此属性表示效果的种类。效果列表清查阅效果手册。 ●Category: 效果分类。仅用于那些进入连锁的效果,用于标识该效果包含了那些分类。需要注意的是,只要包含了某个效果,即使效果处理时不会处理那个效果,也要把那个效果的分类加入此属性。举例:大宇宙和星光大道,这两张卡“包含”了特殊召唤的效果,即使不一定特殊召唤。此属性用于某些卡的发动的判定(如弹压)。 此属性可以是以下值的组合: CATEGORY_DESTROY 破坏效果 CATEGORY_RELEASE 解放效果 CATEGORY_REMOVE 除外效果 CATEGORY_TOHAND 送去手牌效果 CATEGORY_TODECK 送去卡组效果 CATEGORY_TOGRAVE 送去墓地效果 CATEGORY_DECKDES 卡组破坏效果 CATEGORY_HANDES 手牌破坏效果 CATEGORY_SUMMON 召唤效果 CATEGORY_SPECIAL_SUMMON 特殊召唤效果 CATEGORY_TOKEN 生成Token效果 CATEGORY_FLIP 反转效果 CATEGORY_POSITION 改变表示形式效果 CATEGORY_CONTROL 改变控制权效果 CATEGORY_DISABLE 无效效果的效果 CATEGORY_DISABLE_SUMMON 无效召唤,特殊召唤的效果 CATEGORY_DRAW 抽卡效果 CATEGORY_SEARCH 检索效果(一般是卡组) CATEGORY_EQUIP 装备效果 CATEGORY_DAMAGE 直接伤害效果 CATEGORY_RECOVER 回复效果 CATEGORY_ATKCHANGE 攻击变化效果 CATEGORY_DEFCHANGE 守备变化效果 CATEGORY_COUNTER 指示物相关效果 CATEGORY_COIN 需要扔硬币的效果 CATEGORY_DICE 需要扔骰子的效果 ●Type: 此属性用于表示效果的分类,可以是下面的值的组合。组合方法见下面的分类解释。 EFFECT_TYPE_SINGLE 单体 EFFECT_TYPE_FIELD 群体 EFFECT_TYPE_EQUIP 装备 EFFECT_TYPE_ACTIONS 触发型 EFFECT_TYPE_ACTIVATE 发动 EFFECT_TYPE_FLIP 反转 EFFECT_TYPE_IGNITION 启动 EFFECT_TYPE_TRIGGER_O 诱发(选发) EFFECT_TYPE_QUICK_O 诱发即使(选发) EFFECT_TYPE_TRIGGER_F 诱发(必发) EFFECT_TYPE_QUICK_F 诱发即时(必发) EFFECT_TYPE_CONTINUOUS 永续 ●Reset: 此属性用于标识效果被Reset的时机。此属性可以是以下值的组合: RESET_DRAW 抽卡阶段 RESET_STANDBY 准备阶段 RESET_MAIN1 主要阶段1 RESET_BATTLE 战斗阶段 RESET_DAMAGE 伤害阶段 RESET_DAMAGE_CAL 伤害计算阶段 RESET_MAIN2 主要阶段2 RESET_END 结束阶段 RESET_SELF_TURN 我方回合 RESET_OPPO_TURN 对方回合 RESET_PHASE 阶段结束时Reset,此flag需要配合以上值一起使用 RESET_LABEL 根据标签Reset RESET_EVENT 根据事件Reset,此flag需要配合从RESET_DISABLE开始的标志一起使用 RESET_USE 效果计数变成0之后Reset RESET_CODE 根据效果种类Reset RESET_COPY 复制效果Reset RESET_DISABLE 进入无效化状态时Reset RESET_TURN_SET 变成里侧表示时Reset RESET_TOGRAVE 送去墓地时Reset RESET_REMOVE 除外(永久)时Reset RESET_TEMP_REMOVE 除外(暂时)时Reset RESET_TOHAND 送去手牌时Reset RESET_TODECK 送去卡组时Reset RESET_LEAVE 离场时Reset RESET_TOFIELD 上场时Reset RESET_CONTROL 控制权转移时Reset 脚本中一般只需要使用RESET_PHASE和RESET_EVENT以及相关的值 ●Property: 此属性包含了此效果的一些额外的信息,可以是以下值的组合: EFFECT_FLAG_FUNC_VALUE 此效果的Value属性是函数 EFFECT_FLAG_COUNT_LIMIT 此效果有内置的次数限制 EFFECT_FLAG_FIELD_ONLY 此效果是注册给全局环境的 //以上3个属性为系统内置,无法在脚本中进行设置 EFFECT_FLAG_CARD_TARGET 此效果取对象 EFFECT_FLAG_IGNORE_RANGE 忽略Target Range属性, EFFECT_FLAG_ABSOLUTE_TARGET Target Range不会因为控制权的改变而改变 EFFECT_FLAG_IGNORE_IMMUNE 忽略免疫属性 EFFECT_FLAG_SET_AVAILABLE 影响里侧表示的卡 EFFECT_FLAG_AUXILIARY (预留) EFFECT_FLAG_CANNOT_DISABLE 不能无效化的效果 EFFECT_FLAG_PLAYER_TARGET 以玩家为对象 EFFECT_FLAG_BOTH_SIDE 双方都可以发动 EFFECT_FLAG_COPY_INHERIT 继承复制的效果的Reset属性 EFFECT_FLAG_DAMAGE_STEP 伤害阶段可以发动 EFFECT_FLAG_DAMAGE_CAL 伤害计算时可以发动 EFFECT_FLAG_DELAY 延迟处理 EFFECT_FLAG_SINGLE_RANGE 单体效果 EFFECT_FLAG_UNCOPYABLE 不可被黑豹,混沌幻影等卡复制 EFFECT_FLAG_OATH 契约效果 EFFECT_FLAG_SPSUM_PARAM 特殊召唤参数 一些特定的标志的使用见分类解释。 ●Label: 此属性不会被系统使用,通常用于脚本传递或者保存简单的整数参数使用 ●owner player: 此属性表示这个效果属于那个玩家。一般注册效果时,此属性会被自动设置成当前正在发动效果的那个玩家。当然也可以手动设置此值。 以下根据两种不同的类型解释需要设置的值 1 永续型 永续型效果主要表现状态的变化,首先Type属性只能是EFFECT_TYPE_SINGLE,EFFECT_TYPE_FIELD以及EFFECT_TYPE_EQUIP中的一个。其中EFFECT_TYPE_SINGLE表示效果只影响注册的卡本身,EFFECT_TYPE_FIELD表示效果影响某个区域的卡,EFFECT_TYPE_EQUIP表示效果影响注册的卡装备着的卡。 ●对于EFFECT_TYPE_FIELD效果需要设置Range和Target Range属性。其中Range表示注册的卡在什么地方生效,Target Range表示影响那个区域的卡。举例: local e=Effect.CreateEffect(c) e:SetType(EFFECT_TYPE_FIELD) e:SetRange(LOCATION_SZONE) 此效果在魔陷区生效 e:SetTargetRange(LOCATION_MZONE,LOCATION_MZONE) 此效果影响双方的怪兽区域 c:RegisterEffect(e) 如果Range属性被设置成怪兽区域或者魔陷区,那么那张卡必须是表侧表示这个效果才能生效。 一些额外的property说明 EFFECT_FLAG_IGNORE_RANGE: 当设置了这个标志时,target range属性将会被忽略,此时所有区域的卡收回收到影响 EFFECT_FLAG_PLAYER_TARGET: 设置了这个标志时 这个效果被视为影响玩家,此时需要通过类似以下的方式设定影响的范围 e:SetTargetRange(0,1) 只影响对方玩家 EFFECT_FLAG_PLAYER_TARGET: 设置了这个标志时,这个效果影响的区域不会随着卡的控制权的改变而改变。例子可参考“仪式魔人解放者”的不能特殊召唤的效果。 EFFECT_FLAG_SET_AVAILABLE: 此效果影响场上里侧的卡。默认情况下不会影响。比如“场地防护罩”的“不能破坏”的效果。 ●对于EFFECT_TYPE_SINGLE效果,一般情况下不需要设定Range和Target range。此时次效果被视为是暂时性的状态改变。如果设置了EFFECT_FLAG_SINGLE_RANGE属性,那么需要同时设置Range属性来注明这个单体效果在何处生效。使用了EFFECT_FLAG_SINGLE_RANGE标志的single效果视为永续型的效果。 ●EFFECT_TYPE_EQUIP无特定的Property标志 Condition表示这个效果生效的条件。如果不设置表示永久生效。此属性需要一个函数作为判定生效的依据。函数原型如下: function sample_condition(e) end 其中参数e是那个效果本身 Target表示这个效果影响的卡的具体要求。可视为是详细的过滤函数。如果不设置则表示影响区域的所有卡均适用。single和equip类型不需要设置此项。此属性同样需要需要一个函数作为判断卡是否受影响的依据。原型如下: function sample_condition(e,c) end 其中参数e是效果本身,c是需要判断的卡 Value用于设置效果的值,一般只用于数值变化效果和其他一些特定的效果。此属性可以直接填数值,也可以是一个函数,原型同target,用函数可以针对不同的卡设置不同的值。 2 触发型 触发型效果需要为Type设置EFFECT_TYPE_ACTIONS以下中的任意一个类型,并且设置的时候系统会自动为Type属性添加EFFECT_TYPE_ACTIONS标志。除此之外,对于EFFECT_TYPE_TRIGGER_O,EFFECT_TYPE_TRIGGER_F和EFFECT_TYPE_CONTINUOUS需要额外添加EFFECT_TYPE_SINGLE或者EFFECT_TYPE_FIELD。触发型的code一般指的是触发的事件,比如EVENT_DESTROY表示破坏时触发这一效果。某些类型不需要设定code。 ●EFFECT_TYPE_ACTIVATE: 卡片的发动都应使用设个类型。非魔法或者陷阱卡添加此效果没有任何作用。此类型不需要设定Range,code则是发动时点,如果是无发动时点的卡则将code设置成EVENT_FREE_CHAIN。 ●EFFECT_TYPE_FLIP: 反转效果,不需要设置code ●EFFECT_TYPE_IGNITION: 启动效果。此效果需要设置Range为发动启动效果所在的位置。比如亚特兰蒂斯的战士是手牌 ,成长的鳞茎是墓地。不需要设置code。 ●EFFECT_TYPE_TRIGGER_O和EFFECT_TYPE_TRIGGER_F: 诱发效果。前者表示选发,后者表示必发。诱发效果需要额外指明是single还是field类型,表示是卡本身的触发事件还是其它卡的触发事件。简单来说single类型表示“当这张卡XXX时”的效果,field类型是“当有卡XXXX时”的效果。举例:三眼怪的效果是“当这张卡从场上送去墓地时”的效果,所以是EFFECT_TYPE_TRIGGER_F+EFFECT_TYPE_SINGLE;王虎的效果是“当有卡特殊召唤时”的效果,所以是EFFECT_TYPE_TRIGGER_F+EFFECT_TYOE_FIELD。另外的区别是single类型不需要设置Range,而field类型需要设置成发动诱发效果的位置。 关于错时点的一些解释:EFFECT_TYPE_TRIGGER_F不会错时点,在当前连锁处理完之后会新开连锁;EFFECT_TYPE_TRIGGER_O一般来说如果之后进行了会中断的操作比如处理新连锁,召唤上场等行为就会错过时点。在Property的标志EFFECT_FLAG_DELAY可以让这个选发的诱发效果效果延迟发动而不会错时点,用来实现“XXXX的场合”“可以”发动的效果。加上此标志之后选发的效果也会等到当前的行为处理完之后新开连锁处理。 ●EFFECT_TYPE_QUICK_O: 绝大部分的诱发即时效果,设置和EFFECT_TYPE_ACTIVATE基本相同,唯一的不同点在于这个类型需要设置Range指明发动的位置,比如死灵守卫需要指定为墓地。 ●EFFECT_TYPE_QUICK_F: 只有极少数卡有此类型的效果(死灵骑士,光与暗之龙,青冰白夜龙等)。此效果会强制针对最后一个触发此效果的事件进行连锁。使用此类型的效果时要注意发动条件的判定避免形成无限连锁(比如光暗龙的自连锁,每次连锁中只能发动一次的原因)。 ●EFFECT_TYPE_CONTINUOUS: 和EFFECT_TYPE_TRIGGER_F基本相同,不同点在于此类型的效果会在触发事件后立刻处理并且不会进入连锁。常用来实现一些辅助效果。 触发型效果常会用到的一些Property值: EFFECT_FLAG_CARD_TARGET 此效果取对象,表示此效果取对象 EFFECT_FLAG_PLAYER_TARGET 以玩家为对象,通常用于抽卡效果。拥有这个标志的效果可以被精灵之镜连锁。 EFFECT_FLAG_BOTH_SIDE 双方都可以发动的效果。比如融合之门,王宫的弹压。 EFFECT_FLAG_DAMAGE_STEP 伤害阶段可以发动 EFFECT_FLAG_DAMAGE_CAL 伤害计算时可以发动 EFFECT_FLAG_DELAY 延迟处理 触发型效果的具体实现主要依赖于4个属性:Condition,Cost,Target和Operation。这4项必须是函数,或者留空。其中Condition用于发动条件判定,Cost用于发动cost的满足性判定和具体进行cost行为,Target用于发动对象判定(主要是判定是否满足对象的条件和空发判定)以及具体的指定对象等操作,Operation则是在效果处理时会执行的具体的效果操作。 函数原型分别为: function sample_condition(e,tp,eg,ep,ev,re,r,rp) end function sample_cost(e,tp,eg,ep,ev,re,r,rp,chk) end function sample_target(e,tp,eg,ep,ev,re,r,rp,chk,chkc) end function sample_operation(e,tp,eg,ep,ev,re,r,rp) end 这几个函数的前8个参数作用相同,具体解释如下: e: 该效果本身 tp: 发动或者准备发动该效果的玩家 eg: event group, 事件涉及卡片组 ep: event player, 事件涉及的玩家 ev: event value, 事件涉及参数 re: reason effect, 触发事件的效果 r: reason, 事件原因描述 rp: reason, 触发事件的玩家 第3-8个参数记录了触发事件的信息, 举例来说:玩家1发动某效果e1对玩家2造成了500的效果伤害,那么 eg:空 ep:1 (=玩家2) ev:500 re: e1 r: REASON_EFFECT(效果伤害) rp: 0 (=玩家1) 触发事件的哪些参数有用具体参考事件说明。 cost和target还有第9个参数chk。此参数是在效果发动之前对效果的发动可能性经行判定。判定时,chk会被设置成0传入函数,然后在具体经行cost操作或者指定目标等操作时,chk会被设置成1传入。举例: function c87910978.cost(e,tp,eg,ep,ev,re,r,rp,chk) if chk==0 then return Duel.CheckLPCost(tp,800) --检查阶段,检查是否能支付800LP的cost else Duel.PayLPCost(tp,800) end --非检查阶段,支付800LP的cost end 如果效果是指定目标的,那么target会有第10个参数chkc,用来判断某一张卡是否是正确的对象(主要用于六武众的影武者等转移对象的效果),并且检查是chk会被置0.举例: function c87910978.target(e,tp,eg,ep,ev,re,r,rp,chk,chkc) if chk==0 then if chkc then return chkc:GetLocation()==LOCATION_MZONE and chkc:GetControler()~=tp and c87910978.filter(chkc) end --如果存在第10个参数,则检查那张卡是否满足这个效果的对象的要求。非指定对象的效果不需要此判定。 return Duel.IsExistingTarget(c87910978.filter,tp,0,LOCATION_MZONE,1,nil) --否则进行对象的存在性判定 end --进行对象选择 local g=Duel.SelectTarget(tp,c87910978.filter,tp,0,LOCATION_MZONE,1,1,nil) Duel.SetOperationInfo(0,CATEGORY_CONTROL,g,1,0,0) end 要注意的是,即使是不指定对象的效果也要进行对象的判定,用于防止空发。比如黑洞需要检查场上是否存在可破坏的怪,抽卡系效果需要判断卡组中是否存在足够的卡。 condition, cost, target都需要返回一个boolean型数据,true表示满足条件,false表示不满足。如果留空则认为总是满足条件。operation中进行实际的效果处理,并且不需要返回值。 某些效果可能有更多的额外参数,具体参考效果分类说明。 ●关于契约效果的补充说明: 如果是在一个效果发动的cost和target阶段注册了一个契约效果(包含EFFECT_FLAG_OATH标志),那么当这个效果的发动被无效时,此契约效果将会被自动reset。比如强欲谦虚之壶等不能特招,一回合只能发动一张的效果。
现在,我们就可以给自己的卡片添加效果了,首先我们在
function c54998762.initial_effect(c)的下面输入:
local e1=Effect.CreateEffect(c)
这段代码就是为卡片创建一个空效果,接下来我们需要设置效果发动的时点(条件)、类型、以及效果分类。
以这张卡从手卡丢弃去墓地时,这张卡在自己场上特殊召唤这个效果为例,我们先来分析效果描述,从中获取有用的信息。
首先我们可以发现,这个效果发动的对象是这张卡本身(EFFECT_TYPE_SINGLE),时点(code)是在从手卡(condition:LOCATION_HAND
)送入墓地(code:EVENT_TO_GRAVE)的时候,这张卡在自己场上表侧表示特殊召唤(operation:这张卡+自己场上+特殊召唤+表侧表示),同时可知:这个效果是属于诱发必发型(不需要玩家选择是否发动),并且效果分类为特殊召唤( category:CATEGORY_SPECIAL_SUMMON)。
那么我们应该怎么写接下来的代码呢?
首先我们要设置这个效果的属性,具体的信息就是通过分析效果描述剥离出来的对应常量,从时点开始依次为:
e1=SetCode(EVENT_TO_GRAVE)–时点
e1=SetType(EFFECT_TYPE_SINGLE+EFFECT_TYPE_TRIGGER_F)–当此卡的卡片状态发生变化时,即时发动此效果
e1=SetCategory(CATEGORY_SPECIAL_SUMMON)–效果类型为特殊召唤型
c:RegisterEffect(e1)–将效果注册给此卡
end
完成后的脚本应该是这样的:
function c54998762.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
接下来把脚本放入YGO Pro 2根目录下的script文件夹里就可以开心的去测试了~
噫,卡片能够成功召唤没错,但是为什么效果没有发动?
检查脚本,似乎少了些什么?原来是没有写相关的检查以及操作信息,导致无法完成效果的发动。
在这里就需要用到一些固定的参数了,具体如下:
e: 该效果本身 tp: 发动或者准备发动该效果的玩家 eg: event group, 事件涉及卡片组 ep: event player, 事件涉及的玩家 ev: event value, 事件涉及参数 re: reason effect, 触发事件的效果 r: reason, 事件原因描述 rp: reason, 触发事件的玩家
首先,这个效果想要发动,就必须确认这张卡存在于你的手牌上,并且是“之前存在于你的手牌上”(因为效果是从手牌进墓地后发动的),对照信息查查函数,嗯, Card Effect.GetHandler(Effect e)–(这张卡在手卡上)和 integer Card.GetPreviousLocation(Card c)–(获得之前卡片的位置)这两个函数似乎满足我们想要的条件,但是,似乎还有一个函数也是专门用来干这种事的,Card.IsPreviousLocation(Card c, integer loc),该函数用来检查c之前位置是不是loc。那么这里的脚本就是:e:GetHandler():IsPreviousPLocation(LOCATION_HAND)。
那么位置判定解决以后,我们再来写发动效果的原因,由于是将卡片送入墓地后发动,那么原因就是卡从手牌放入墓地啦,那么脚本就是:r==REASON_DISCARD。但是似乎感觉有些地方怪怪的?再看一眼常量表,原来REASON_DISCARD要和REASON_EFFECT、REASON_COST等常量连用才有意义,改动之后的脚本应该是:r==REASON_EFFECT+REASON_DISCARD才对。两个常量之间用加号相连。
接下来我们来设置操作信息,这里要用duel里的SetOperationInfo函数,这类函数的格式是:
Duel.SetOperationInfo(integer chainc, integer category, Card|Group targets, integer count, integer target_player, integer target_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)。操作信息用于很多效果的发动的检测,例如星渣(星尘龙),印卡的时候必定会用到。
然后就是确认这个效果是由这张卡发出的(也就是这个效果和这张卡有联系),而boolean Card.IsRelateToEffect(Card c, Effect e)这个函数就可以用来检查c是否和效果e有联系。那么我们可以这么写:e:GetHandler():IsRelateToEffect(e)
建立联系后我们就可以开始写召唤的代码了~这里要用到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,是个intege,这是个常量标识,我们到YGO Pro2根目录下的scrip文件夹中的constant.lua中找找,发现真的有SUMMON_TYPE常量。同理pos的常量也发现了 POS_。我们需要的是SUMMON_TYPE_SPECIAL(特殊召唤)和POS_FACEUP(表侧表示)这两个。我们可以这样写:
Duel.SpecialSummon(e:GetHandler(),SUMMON_TYPE_SPECIAL,tp,tp,false,false,POS_FACEUP)
如果上面这些都完成了的话,我们就可以完善脚本了~
在原脚本的下面接着写:
function c54998762.condition(e,tp,eg,ep,ev,re,r,rp) return e:GetHandler():IsPreviousLocation(LOCATION_HAND) and r==RESON_EFFECT+RESON_DISCARD end function c54998762.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 c54998762.operation(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) end end
然后在效果初始化那里Set上这些函数,保存。
现在再去测试一下,是不是就成了呢?咦?怎么还没反应?再去检查一下代码,似乎没有什么地方有问题。但是不知道有没有人注意到REASON_DISCARD其实是要要求将所有能够令卡丢弃的原因给列出来,那么问题来了,这样的组合有很多个,总不能一个个的用加号连起来吧?这个时候我们就需要用到过滤操作了,我们用 bit.band(r,REASON_DISCARD) 抽出r跟REASON_DISCARD 里面相同的部分!如果r里面包含有REASON_DISCARD的话那么就会返回REASON_DISCARD。我们的代码就可以改写成这样:
bit.band(r,REASON_DISCARD)~=0
经过修改后的脚本:
function c54998762.initial_effect(c) local e1=Effect.CreateEffect(c) e1:SetDescription(aux.Stringid(54998762,0)) e1=SetCategory(CATEGORY_SPECIAL_SUMMON) e1=SetType(EFFECT_TYPE_SINGLE+EFFECT_TYPE_TRIGGER_F) e1=SetCode(EVENT_TO_GRAVE) e1:SetCondition(c54998762.condition) e1:SetTarget(c54998762.target) e1:SetOperation(c54998762.operation) c:RegisterEffect(e1) end function c54998762.condition(e,tp,eg,ep,ev,re,r,rp) return e:GetHandler():IsPreviousLocation(LOCATION_HAND) and bit.band(r,REASON_DISCARD)~=0 end function c54998762.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 c54998762.operation(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) end end
开机测试!
现在这张卡无论什么原因被丢弃到墓地都会引发效果,注意必须是要丢弃(效果或cost),“送入墓地”是不算的。
那么今天就先到这里,下一期我们就先讲解怎么做融合怪吧,后面同调、超量、灵摆都还等着呢~我们下期再见~
PS:事实上这篇文章里是有一个错误的,不过这个错误的原因是因为RT没有好好看效果造成的,是我的锅,想要自己制作卡片的同学在制作卡片的时候一定要明确自己想要达成的效果再动手哦。