創作內容

6 GP

遊戲王YGOpro(ADS) Lua程式腳本撰寫教學 01

作者:true│2015-10-30 12:18:02│巴幣:12│人氣:4142
本教學將從Lua語法的基礎來教導你如何寫出自己卡片,而非是複製貼上。
適合有一定程式基礎且對自製卡片有相當熱忱的創作者閱讀。
若你在此之前從未接觸過Lua腳本,強烈建議先去觀看其他的基礎教學。
否則你可能會難以理解本文的內容。

首先是本次腳本的編寫範例:


使用DataEditorX新建腳本後你會看到以下畫面:


initial_effect代表的是初始化函數,括號裡面的c代表的即是這張卡片。
基本上所有效果的宣告都會在這個函數內完成。

接下來我們開始嘗試撰寫第一個效果:
①:此卡發動的回合的我方主要階段可以發動。從牌組將1體「PM 露力麗」加入手牌。


aux.AddPendlumProcedure(c)代表的是為c也就是這張卡片寫入擺動召喚的規則。
基本上是所有擺動怪獸都必須加入的一行。

接下來下方的即是我們的第一個效果。
效果的編寫規則如下:
local 效果名稱=Effect.CreateEffect(c)
X
X
X
X
c:RegisterEffect(效果名稱)

第一行代表的是宣告效果。類似於一般程式中的宣告變數。
最後一行則是將中間的XXX屬性寫入c也就是這張卡片。
以下是Effect裡面常見的屬性:
SetDescription:為此效果添加描述。常用於多個效果中給玩家做選擇時顯示。(EX:空氣人)
SetCategory:效果的分類。例如死蘇為特召效果,屬於CATEGORY_SPECIAL_SUMMON。
SetType:效果的觸發條件。例如魔法陷阱卡的發動屬於EFFECT_TYPE_ACTIVATE。SetCode:效果的種類或發動時機。例如被破壞時發動為EVENT_DESTROYED。
SetRange:效果的發動或適用的位置。例如永續魔陷通常為LOCATION_SZONE(魔陷區)。
SetTargetRange:效果的影響範圍。括號左邊為自己,右邊則代表對手。例如影響雙方怪獸區則為(LOCATION_MZONE,LOCATION_MZONE);只影響我方怪獸區不影響對手則為(LOCATION_MZONE,0)。其他的以此類推。
SetProperty:效果的性質。例如取對象的效果為EFFECT_FLAG_CARD_TARGET。
SetCountlimit:效果的發動次數限制。例如1回合1次就填入1。
SetCounterlimit:放置指示物的上限。例如0xee指示物最多只能放2個,則填入(0xee,2)
SetCondition:效果的發動條件。
SetTarget:效果的對象。
SetOperation:效果的處理。
SetReset:效果的重設條件。常用於到回合結束前適用XXX一類的效果。
SetValue:效果的數值。常用於攻守變化的效果。

接下來解說範例內的第一個效果。
local e1=Effect.CreateEffect(c)
e1:SetDescription(aux.Stringid(526,0))
e1:SetType(EFFECT_TYPE_ACTIVATE)
e1:SetCode(EVENT_FREE_CHAIN)
e1:SetOperation(c526.activate)
c:RegisterEffect(e1)

這個效果代表的是擺動怪獸設置於靈擺區的動作。
擺動怪獸的發動視為魔法卡的發動,所以SetType的屬性使用EFFECT_TYPE_ACTIVATE。
SetCode內的EVENT_FREE_CHAIN代表的是自由時機點。
意思是我可以在任何時機點發動此卡。但由於擺動怪獸視為通常魔法卡屬於一速效果,所以只限在自己回合的主要階段中發動。
SetOperation括號內代表的是則是此效果處理時執行的函數。
若發動時沒有要執行的動作,則可將此行刪除。

接下來撰寫效果處理時的函數:

範例內瑪力露的第一個擺動效果:
①:此卡發動的回合的我方主要階段可以發動。從牌組將1體「PM 露力麗」加入手牌。

為了判斷當前的回合是否為此卡發動的回合,我們在此卡發動時執行了activate這個函數。
我們可以看到activate後面括號內有各種回傳值。以下是常用的各項數值:
c:代表當前的卡片。
e :代表當前的效果。
tp:代表當前的玩家。
1-tp:代表敵方玩家。
eg:代表回傳的事件群組。
ep:代表回傳的事件所屬玩家。
ev:代表回傳的事件的數值。
re:代表造成事件原因的效果。
r :代表事件的原因。
rp :代表事件原因的所屬玩家。
chk:效果條件的檢查。
chkc:效果條件的卡片的檢查。

了解各項回傳值代表的意義後,我們繼續往下看。
if not e:GetHandler():IsRelateToEffect(e) then return end
這行代表的是若效果e的處理者與此效果失去關聯則結束處理。
GetHandler()代表的是回傳效果e的處理者,而當前效果的處理者就是這張卡瑪力露。
而我們知道當永續魔陷離場時視同無效。
所以後面的IsRelateToEffect(e) 即是用來判斷這張卡發動時是否還留在場上。
若因其他效果離場則視為和e失去關聯,後續的效果不處理。

若通過了上面的檢查確認此卡還留在場上後,將做以下的處理。
e:GetHandler():RegisterFlagEffect(526,RESET_EVENT+0x1fe0000+RESET_PHASE+PHASE_END,0,1)
這行代表的是為效果e的處理者寫入一個效果標記。
還記得我們寫這個函數是為了判斷當前的回合是否為此卡發動的回合嗎?
RegisterFlagEffect內的526代表的是識別的編號。而後面一長串則代表重設的時點。
簡單來說就是我寫入了一個編號526的標記。期限則是到回合結束前適用。
如此一來我們之後只要判斷這個標記是否存在,就知道當前的回合是否為此卡發動的回合了。



完成了判斷是否為發動回合的標記後,我們接著要來編寫加入手牌這個動作。
首先由於是檢索效果同時又包含加入手牌的效果,所以我們在SetCategory寫入CATEGORY_TOHAND+CATEGORY_SEARCH
有人大概會問CATEGORY_TOHAND和CATEGORY_SEARCH有什麼不同?
CATEGORY_TOHAND泛指所有包含加入手牌的效果。而CATEGORY_SEARCH則是限定從牌組加入手牌。例如雷王的封鎖檢索效果就是判斷效果分類是否包含CATEGORY_SEARCH。
接著因為是啟動效果,所以SetType寫入EFFECT_TYPE_IGNITION。
SetRange這邊由於是在擺動區發動,所以寫入LOCATION_PZONE。舉一反三,若是在怪獸區發動則寫入LOCATION_MZONE,魔陷區則是LOCATION_SZONE。
SetCountLimit代表發動次數。因為是1回合1次所以填入1。
若想仿照星因士這類的卡名1回合1次,則在次數後面填入編號。例如(1,526)則代表526這個效果整回合總共只能發動1次。
至於下方Condition、Target和Operation則對應條件、對象和處理時要執行的函數。



前面有提到condition代表的是效果的發動條件。而我們在前面所寫好e1效果在此派上了用場。
我們只需要加入一行 return e:GetHandler():GetFlagEffect(526)~=0 就能搞定。
此行代表回傳事件e的處理者是否有被寫入526這個標記。若沒有則等於0;反之則不等於0。
也就是說若回傳值不等於0,即能滿足當前回合為發動此卡的回合的條件。

當滿足condition函數內的條件後,程式接下來將判斷對象是否存在。
這時候target函數就會派上用場。
if chk==0 then return Duel.IsExistingMatchingCard(c526.thfilter,tp,LOCATION_DECK,0,1,nil) end
這裡的意思是若尚未進行條件檢查,則檢查在我方的LOCATION_DECK(牌組)裡面是否至少有1張卡片滿足c526.thfilter這個函數。
IsExistingMatchingCard這個函數的用法如下:
IsExistingMatchingCard(過濾函數,玩家,我方位置,敵方位置,最低標準張數,例外條件)
舉例,假如我要判斷敵方場上是不是至少有2體表側表示的怪獸,則可以這麼麼寫:
return Duel.IsExistingMatchingCard(Card.IsFaceup,tp,0,LOCATION_MZONE,2,nil) end
需要注意的是若為取對象的效果,必須使用Duel.IsExistingTarget。
由於從牌組加入手牌是非指定效果所以才使用Duel.IsExistingMatchingCard。

接著來看上面的c526.thfilter這個函數。
return c:IsCode(525) and c:IsAbleToHand()
代表的回傳c是不是編號525,且c可以加入手牌。編號525即是範例內提到露力麗。
假如你想檢索的是某個系列,則可以使用IsSetCard(系列編號)這個函數;判斷種族則使用IsRace(種族名稱);屬性則是IsAttribute(屬性)。

回到正題,假如我的牌組存在露力麗(編號525)這張卡,則這個函數就會回傳true
也就是剛才的if chk==0 then return Duel.IsExistingMatchingCard(c526.thfilter,tp,LOCATION_DECK,0,1,nil) end
這行的條件將會成立,接著就能繼續處理下面程式。
Duel.SetOperationInfo(0,CATEGORY_TOHAND,nil,1,tp,LOCATION_DECK)
這行用來設定效果處理時分類。假如你在效果處理時尚未確定效果的分類,則可將此行刪除。
(EX:次元魔法這類效果處理時還未確定是否會破壞的卡片,則免寫此行)

接著進入最後的效果處理階段。來看c526.operation內的第一行。
if not e:GetHandler():IsRelateToEffect(e) then return en
如果你前面有認真在看,一定會覺得這行異常熟悉。
沒錯,就和一開始的e1效果一樣,這行即是用來判斷效果處理時這張卡片是不是還留在場上。
如果被旋風這類的卡片破壞的話,當然效果也就不處理,因此將直接中斷函數的執行。反之則繼續進行以下程式。
Duel.Hint(HINT_SELECTMSG,tp,HINTMSG_ATOHAND)
這行就是跳出提示視窗,用來告訴玩家選擇要加入手牌的卡。
舉例,像是提示對手玩家選擇要破壞的卡片,則可以這麼寫:
Duel.Hint(HINT_SELECTMSG,1-tp,HINTMSG_DESTROY)
中間的tp代表的是我方玩家,1-tp則是敵方玩家。後面的HINTMSG_DESTROY則是要提示的訊息。這些訊息通常可以在ADS資料夾底下的string.conf檔案裡面找到。

接下來看到這行:
local g=Duel.SelectMatchingCard(tp,c526.thfilter,tp,LOCATION_DECK,0,1,1,nil)
SelectMatchingCard代表是選擇一個群組。一般用於不取對象的卡片效果。
若是指定對象的效果則使用SelectTarget。
用法基本上和前面的Duel.IsExistingMatchingCard大同小細。差別在於SelectMatchingCard回傳的是玩家選擇的卡片;IsExistingMatchingCard則是回傳true或false。
玩家的選擇結果將會回傳到g這個群組。
if g:GetCount()>0 then即是判斷g群組內是否至少有1張卡片。
滿足條件後就執行Duel.SendtoHand(g,nil,REASON_EFFECT)這個函數將g加入玩家手牌。
每次從牌組檢索結束後當然免不了要給對手確認,告訴對手自己沒有作弊。
這時就會用到最後的Duel.ConfirmCards(1-tp,g),向玩家1-tp也就是對手展示加入手牌的g。
完成後就大功告成。

以上的效果你也可以從EM琴鍵猴的Lua腳本內找到類似的程式。
是的,若你只單純想做個類似的效果,你可以直接複製貼上再做細微修改。
然而我相信並不是你想做的所有效果都能用這個方法取得。
本教學的用意在於讓使用者真正了解程式的意義與運作原理。
歡迎同好一起討論研究。礙於字數關係教學就先寫到這邊。有任何問題都可以在下方留言。

在此感謝真的有將以上文章從頭看到底的充滿耐心的您!



引用網址:https://home.gamer.com.tw/TrackBack.php?sn=3002761
All rights reserved. 版權所有,保留一切權利

相關創作

留言共 0 篇留言

我要留言提醒:您尚未登入,請先登入再留言

6喜歡★spadl 可決定是否刪除您的留言,請勿發表違反站規文字。

前一篇:【無言】淺談出版自由... 後一篇:《火雞傳說》RPG開發日...

追蹤私訊切換新版閱覽

作品資料夾

ilove487致一百光年外的你
【讀墨】2023台灣大眾小說人氣票選活動!!看更多我要大聲說昨天14:46


face基於日前微軟官方表示 Internet Explorer 不再支援新的網路標準,可能無法使用新的應用程式來呈現網站內容,在瀏覽器支援度及網站安全性的雙重考量下,為了讓巴友們有更好的使用體驗,巴哈姆特即將於 2019年9月2日 停止支援 Internet Explorer 瀏覽器的頁面呈現和功能。
屆時建議您使用下述瀏覽器來瀏覽巴哈姆特:
。Google Chrome(推薦)
。Mozilla Firefox
。Microsoft Edge(Windows10以上的作業系統版本才可使用)

face我們了解您不想看到廣告的心情⋯ 若您願意支持巴哈姆特永續經營,請將 gamer.com.tw 加入廣告阻擋工具的白名單中,謝謝 !【教學】