廣告廣告
  加入我的最愛 設為首頁 風格修改
首頁 首尾
 手機版   訂閱   地圖  簡體 
您是第 4231 個閱讀者
 
發表文章 發表投票 回覆文章
  可列印版   加為IE收藏   收藏主題   上一主題 | 下一主題   
xhsu
個人文章 個人相簿 個人日記 個人地圖
路人甲
級別: 路人甲 該用戶目前不上站
推文 x2 鮮花 x6
分享: 轉寄此文章 Facebook Plurk Twitter 版主評分 複製連結到剪貼簿 轉換為繁體 轉換為簡體 載入圖片
推文 x1
[插件] 创造自己的事件(中高阶教程)
在AMXMODX1.80之後,似乎支持創建屬於自己的事件觸發接口了……
那好,我今天就帶大家學習一下怎麽創造一個事件。
(抱歉各位,我是大陸人,翻牆慕名而來,語法錯誤敬請諒解!謝謝!)
1.什麽是“事件”?
這裏說的不是指ham模塊或者fm模塊的register forward,也不是register ham
而是inc裏直接由forward xxxxxx(any:...)觸發的
最常見的是啥?當然是每個插件都看得到的forward plugin_init()了
當然,plugin_native, plugin_precache等等都是
這裏要教的就是,怎麽用插件創造一個這樣的事件。

2.Pre事件與Post事件。
這兩個對於大部分人都很熟悉,我也不多說,能看懂上面文字的,也一定能明白Pre和Post事件的區別。
(簡單提一下,Pre事件就是“預”,可以打斷阻止其發生,Post事件打斷了也沒用,因爲已經發生過了)
但是對於forward來說,創造pre事件或者post事件都差不多,甚至沒有區別。(後面說)

3.第一步
首先肯定要#include <amxmodx>不必多說
即使是一個事件,我們也需要一個“容器”來承接返回值。
所以像這樣:(先以Post事件爲例)
new g_fwDummyResult, Post_Gift
接下來,我們需要在plugin_init()裏面創造事件!
Post_Gift = CreateMultiForward("amx_event_head_shot", ET_IGNORE, FP_CELL, FP_CELL)
這就是我們需要詳解的部分了!
前面的Post_Gift = CreateMultiForward()自然不必多說,獲取事件返回編號值。
第一項:"amx_event_head_shot"這個字符串,就是相當於字符串plugin_init——子插件裏的回調函數名,也是forward xxx(any:...)那個xxx的內容
第二項的內容,可以說是關鍵。讓我們看看amxconst.inc裏給的:
#define ET_IGNORE                  0      //ignore return val
#define ET_STOP                  1      //stop on PLUGIN_HANDLED
#define ET_STOP2                  2      //same, except return biggest
#define ET_CONTINUE            3      //no stop, return biggest
一般來說,Post事件用ET_IGNORE,Pre事件用ET_CONTINUE
這裏我的例子是Post事件,故用ET_IGNORE
第三項,則是事件給的參數。例如這個,將來我要寫在子插件裏的是什麽?
forward amx_event_head_shot(iVictim, iAttacker)
玩家是屬於1-32區間內的整數,所以——我們要用FP_CELL
再看看amxconst.inc給的。
#define FP_CELL                  0 //整數
#define FP_FLOAT            1 //浮點數
#define FP_STRING            2 //字符串
#define FP_ARRAY            4 //數組
根據你的forward事件的需求,一個逗號一個逗號(據說可以無限延長)的填進這些FP_XXX
(注:如果要觸發浮點數組,例如pev獲取的坐標,向量,角度等等,怎麽辦呢?很簡單,用FP_FLOAT | FP_ARRAY。參見多種傷害類型並存應該怎麽做,原理一樣)
這樣,我們的事件就算注冊完了!

(抱歉,剛剛寫一半斷電了,趕緊先發第一部分。。)

此文章被評分,最近評分記錄
財富:200 (by amore12) | 理由: 讚..^^



獻花 x2 回到頂端 [樓 主] From:歐洲 | Posted:2014-07-29 11:03 |
xhsu
個人文章 個人相簿 個人日記 個人地圖
路人甲
級別: 路人甲 該用戶目前不上站
推文 x2 鮮花 x6
分享: 轉寄此文章 Facebook Plurk Twitter 複製連結到剪貼簿 轉換為繁體 轉換為簡體 載入圖片

4.第二步
事件注冊完了,但是我們並沒有規定什麽時候觸發啊?所以我們得觸發他。
(這裏我們以爆頭觸發爲例)
public plugin_init()
{
     register_plugin(PLUGIN_NAME, PLUGIN_VERSION, PLUGIN_AUTHOR);

     Post_Gift = CreateMultiForward("amx_event_head_shot", ET_IGNORE, FP_CELL, FP_CELL)
     
     register_event("DeathMsg","EventDeath","a","3=1","5=0") //這樣過濾,就會僅僅觸發爆頭
}

public EventDeath()
{
     new iVictim = read_data(2)
     new iAttacker = read_data(1)
     
     fm_set_user_money(iAttacker, get_pdata_int(iAttacker, m_pdata_iMoney)+1000, 1)
     
     ExecuteForward(Post_Gift, g_fwDummyResult, iVictim, iAttacker)
}
這樣,我們在給爆頭額外獎勵的同時,也會觸發一個事件。
(Post事件的特性也體現在這裏——所有東西都處理完畢,才觸發)
我們來講解一下ExecuteForward()
首先第一項,就是我們在注冊事件中的事件返回值了——Post_Gift = CreateMultiForward()
第二項……嗯,還記得我說過,即使一個事件也需要兩個變量嗎?就是這樣。即使你使用了ET_IGNORE,你也需要一個容器來盛放“0”這個沒用的返回值。
(g_fwDummyResult這個東西變成全局的其實也沒關係,因爲每觸發一個事件,就會被賦值一次,不會互相幹擾返回值)
然後第三項到第N項,就是我們的事件基本參數,也就是剛剛FP_CELL等等一一對應的數字。
(注意:剛剛你用了多少個FP_XXX,這裏就必須給滿所有參數,否則會出錯。)


獻花 x0 回到頂端 [1 樓] From:歐洲 | Posted:2014-07-29 11:11 |
xhsu
個人文章 個人相簿 個人日記 個人地圖
路人甲
級別: 路人甲 該用戶目前不上站
推文 x2 鮮花 x6
分享: 轉寄此文章 Facebook Plurk Twitter 複製連結到剪貼簿 轉換為繁體 轉換為簡體 載入圖片

5.結束了?沒有!Pre事件!
以上就是一個Post事件的來曆。
(以下部分選修~~)
那麽,有人要問,Pre事件呢?
其實對於插件來說,Pre事件和Post事件沒差多少。你讓不讓Pre事件打斷,都是你說了算的。
我們來看看:
new g_fwDummyResult, Post_Gift, Pre_Gift

public plugin_init()
{
     register_plugin(PLUGIN_NAME, PLUGIN_VERSION, PLUGIN_AUTHOR);
     
     Post_Gift = CreateMultiForward("amx_event_head_shot", ET_IGNORE, FP_CELL, FP_CELL)
     Pre_Gift = CreateMultiForward("amx_hook_head_shot", ET_CONTINUE)
     
     register_event("DeathMsg","EventDeath","a","3=1","5=0")
}

public EventDeath()
{
     ExecuteForward(Pre_Gift, g_fwDummyResult)      //執行Pre事件
     if(g_fwDummyResult) return                  //如果Pre事件存在返回值,那麽主插件也返回
     
     new iVictim = read_data(2)
     new iAttacker = read_data(1)
     
     fm_set_user_money(iAttacker, get_pdata_int(iAttacker, m_pdata_iMoney)+1000, 1)
     
     ExecuteForward(Post_Gift, g_fwDummyResult, iVictim, iAttacker)
}

這樣一來,大家都明白了吧?在g_fwDummyResult被賦予返回值了以後,一旦不爲0,那就取消主插件內事件的執行。
所以,返回值其實可以做很多事……比如你要在一個think刷速度的插件內控制速度,可以選擇把速度設定爲返回值最高的那個插件。
等等等等……但總而言之,如果你不寫上if(g_fwDummyResult) return 那麽你的Pre事件也打不斷。所以,Pre到底能不能打斷,全看你。
這就是forward事件的創造,學會了嗎?如果還不會,可以回複我~

以上


獻花 x0 回到頂端 [2 樓] From:歐洲 | Posted:2014-07-29 11:20 |
xhsu
個人文章 個人相簿 個人日記 個人地圖
路人甲
級別: 路人甲 該用戶目前不上站
推文 x2 鮮花 x6
分享: 轉寄此文章 Facebook Plurk Twitter 複製連結到剪貼簿 轉換為繁體 轉換為簡體 載入圖片

順便說一下對本論壇的看法(個人)
1.插件都不開源……Allied Modders 的插件都必須開源,不開源還可能刪帖……(而且也無權限)
2.教學文都要威望……我有點懷疑這幾位是否真心想讓新人學習插件(哪怕是教怎麽用if,else,new的教學文也是如此)
3.能下載的插件都有一行討厭的字飄來飄去,下載者如果要做版本會直接pass,如果個人娛樂玩也愉快不到哪去,最終很可能會沒人用……當初你寫這個插件是讓大家都不用,還是希望廣爲流傳?
4.似乎以上都是爲了防止盜文啊?嗯……無論各位怎麽珍愛自己的勞動成果,這毫無錯誤。但是我要表明我的態度:我的插件沒有版權,歡迎改PLUGIN_AUTHOR或者顯示一行字說是某某人寫的;我的文章沒有版權,歡迎四處轉載不標明出處……

以上


獻花 x3 回到頂端 [3 樓] From:歐洲 | Posted:2014-07-29 11:31 |
i-c0112
個人頭像
個人文章 個人相簿 個人日記 個人地圖
小有名氣
級別: 小有名氣 該用戶目前不上站
推文 x6 鮮花 x194
分享: 轉寄此文章 Facebook Plurk Twitter 複製連結到剪貼簿 轉換為繁體 轉換為簡體 載入圖片

要不要再補齊一下 提醒大家 要發布 forward 的 宣告標頭.inc??
如果能再稍微花時間排版 整齊點 讓有心學習的人能更快看懂

除此之外 這篇已經確實發揮教學效果了 真的感謝分享
願意花時間幫助他人~~

至於插件和教學文 存在不低的門檻 這樣的問題
說真的原因其實是缺乏正式管道讓創作人保護自己的權利
所以才會靠這種 不分好壞 一概把 有意獲得源碼的人 排擠在外 這種下下策
其實大家沒有一個不喜歡討論自己的成果 尤其各位應該都是滿腔熱血的在coding吧


獻花 x0 回到頂端 [4 樓] From:臺灣中華電信股份有限公司 | Posted:2014-08-01 20:49 |
xhsu
個人文章 個人相簿 個人日記 個人地圖
路人甲
級別: 路人甲 該用戶目前不上站
推文 x2 鮮花 x6
分享: 轉寄此文章 Facebook Plurk Twitter 複製連結到剪貼簿 轉換為繁體 轉換為簡體 載入圖片

抱歉忘了這一段~關於forward的,感謝樓上提醒~
6.在inc裡面:
既然事件已經存在了,那麼我們怎麼讓別的插件調用它呢?
當然就是我們最初提到的forward啦!
我們還是以上面為例!
(我原來還不會用code呢,感謝Nailaz教我!)
複製程式
forward amx_hook_head_shot()
forward amx_event_head_shot(iVictim, iAttacker)
這個怎麼來的呢?
還記得我們上面的CreateMultiForward("amx_hook_head_shot", ET_CONTINUE)嗎?
forward裡面的主要部分就是註冊事件時引號內的內容,括弧裡面的對應法則就是ExecuteForward裡面除了返回值以外的部分,按順序寫下來~
這樣,整個事件就算是完成了~
(注:forward可以放在inc里然後用#include;當然也可以放在插件頭!)


獻花 x0 回到頂端 [5 樓] From:歐洲 | Posted:2014-08-04 09:05 |
xuqiang52133
個人文章 個人相簿 個人日記 個人地圖
初露鋒芒
級別: 初露鋒芒 該用戶目前不上站
推文 x1 鮮花 x32
分享: 轉寄此文章 Facebook Plurk Twitter 複製連結到剪貼簿 轉換為繁體 轉換為簡體 載入圖片

我有一个代码,能帮我加个东西吗?我的 QQ373734484。加我可以吗/我想问你点问题


我要暴你头。。。。。
獻花 x0 回到頂端 [6 樓] From:沒有資料 | Posted:2014-11-26 21:51 |

首頁  發表文章 發表投票 回覆文章
Powered by PHPWind v1.3.6
Copyright © 2003-04 PHPWind
Processed in 0.019110 second(s),query:16 Gzip disabled
本站由 瀛睿律師事務所 擔任常年法律顧問 | 免責聲明 | 本網站已依台灣網站內容分級規定處理 | 連絡我們 | 訪客留言