﻿
一 编写脚本的前提条件：
1 了解了lua的相关知识（至少要知道语法，语句，基本的运算，Table和Metatable）
2 熟悉游戏王的规则，包含常见的和各种不常见的规则
3 一个文本编辑器。

二 关于脚本系统的简要架构说明
脚本系统中包含4个主函数库，Card，Effect，Group和Duel，这几个函数库包含了脚本中需要的所有的基本功能。另外还有一个简单的位操作库bit和辅助函数库Auxiliary，包含了一些辅助用的函数。具体的函数清参考函数手册。
脚本系统包含3种自定义类型（Userdata），包括Card，Effect，Group。这几个类型分别以相应的函数库作为Metatable来实现模拟的OOP功能。Effect和Group直接以上述的同名函数库作为Metatable，Card则多了一个中间的模板Metatable。
对于Card类型，系统每载入一张卡，首先会根据那张卡的唯一代号（8位密码）创建一个模板Table（'c'+8位密码），然后调用那张卡的脚本文件（即那些.lua文件）一次初始化模板。然后会生成一个Card的Userdata作为新卡的变量，并设置这个模板Table作为变量的Metatable。最后会将这个变量作为参数调用模板Table的initial_effect函数来对这张卡经行初始化工作。卡的静态效果都是在initial_effect函数中注册。对于通常怪物，此函数通常是一个空函数，不写这个函数也没问题，但是会报告一个“函数未找到”的错误。
对于Effect类型，此类型包含了卡的效果的信息，具体后面会详细介绍此类型的设置和说明。
Group类型即是卡片组，顾名思义就是存多张卡片使用的。此类型通常用于对多张卡片同时进行操作。Group库中提供了一些函数进行添加，删除，搜索特定的卡片。要注意的是：1、Group中卡片的排列顺序随机（但操作时会进行排序以满足replay的需要） 2、一个Group中同一张卡只能存在一次

三 脚本中的一些常量说明
--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可以通过两个函数来创建
●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。比如强欲谦虚之壶等不能特招，一回合只能发动一张的效果。
