pro_on_0
|
分享:
▼
x12
|
[插件] [Amxx 製作] 簡單等級系統 [NVault 保存][血量][速度][重力]
(持續更新)
第一次發教學帖 如果有錯 多多包含 首先 寫一個 Amxx #include 是第一步啦 #include, 簡單一點來說 就是 讀取某個檔案 而檔案裡面有你的Amxx插件需要用到的東西
舉一個例子 複製程式
這是去 讀取 fakemeta 這檔案 < 及 > 只是把檔案名括住 沒有甚麼意思
而這些檔案的副檔名是 .inc, 放在 addons\amxmodx\scripting\include 這次的等級系統需要用 amxmodx amxmisc nvault fakemeta hamsandwich 複製程式
#include <amxmodx>
#include <amxmisc>
#include <nvault>
#include <fakemeta>
#include <hamsandwich> 接著, 就是弄幾個 variables (中文不懂怎樣解釋 -_-") 出來 要弄一個 variable 出來 我們用 new 舉一個例子 複製程式
這裡的大概解釋是 一個新variable 名為g_xp 33個位置 一般來說 如果你想暫時記錄的資料只有一個 你可以省略 [33] 不過我們需要儲存1 - 32玩家的資料 因為所有 variable 都是由 0 開始 , 不是由 1 開始 所以我們需要33 (不肯定是不是這樣 不過33就沒錯 -_-") 這次需要用到 玩家的經驗值 玩家的等級 玩家的累積傷害 儲存玩家資料的檔案 複製程式
new g_xp[33]
new g_level[33]
new g_damage[33]
new g_vault 跟著, 我們需要 註冊 一些東西 複製程式
複製程式
public plugin_init()
{
register_plugin("等級系統", "1.0", "oN.")
// register_plugin 是註冊插件的資料
// 依次序是 插件的名字 插年的版本 插件的作者
// 這是可以省略的
// register_clcmd 是註冊一個指令
// 當玩家輸入那指令便運行後面的 Function
// 依次序是 你要的指令 你要運行的 Function 的名字
register_clcmd( "say /save" ,"say_save")
register_clcmd( "say /xp" ,"say_xp")
register_forward(FM_PlayerPreThink, "fw_PlayerPreThink")
// register_forward 是註冊一個 forward (中文都是不懂得怎樣解釋 -_-")
// 依次序是 forward 的名字 (能在inc.中找到) 你所定的名字 (甚麼都可以)
// 這個 forward 十分有用 你的作用簡單來說是 監視玩家的一舉一動
RegisterHam(Ham_Killed, "player", "fw_PlayerKilled")
// RegisterHam 是一個 hamsandwich(inc.檔) 中的 Fucntion
// 它來註冊 hamsandwich 中的forward
// 依次序是 forward 的名字 (能在inc.中找到) 對象 你所定的名字 (甚麼都可以)
// 這是一個 玩家被殺 的 forward
RegisterHam(Ham_TakeDamage, "player", "fw_TakeDamage")
// 這是一個 玩家被傷害 的 forward
g_vault = nvault_open("n_xp")
// 這裡把 nvault_open("n_xp") 代入 g_vault
// nvault_open 是 nvault(inc.檔) 中的 Fucntion
// 這用來開啟一個 .vault 檔案, 用作儲存資料
// n_xp 是檔案的名稱
// 這種儲存方法是不可以直接打開檔案修改內容
// 檔案儲存在 addons\amxmodx\data\vault
// 還有另一種可以直接修改的儲存方法, 但那種較為複雜
} 下一步, 就是去寫上面所註冊的 forward 和 clcmd (玩家指令 - client command) 複製程式
// fw_TakeDamage 和上面的名字是一樣的
// (victim, inflictor, attacker, Float:damage, damage_type) 這是 forward 中所獲得的資料
// 上面的 victim attacker 這些名字可以改變的 只是把資料代入而已
// 依次是 受傷者 武器 攻擊者 傷害值 傷害種類
public fw_TakeDamage(victim, inflictor, attacker, Float:damage, damage_type)
{
// 首先在一些不適合的情況下 不運行下面的動作
// if 是 如果
// ( 及 ) 是必需的
// || 是 或者
// attacker == victim - 受傷者 是 攻擊者
// ! 是 相反意思
// is_user_connected 是 玩家連接著伺服器的
// 全句解作 如果 受傷者 是 攻擊者 或者 攻擊者不是連接著伺服器的
if (attacker == victim || !is_user_connected(attacker))
return HAM_IGNORED // 返回原來操作
// 其實 attacker 和 victim 都是數字來的
// 我們令用玩家的 id 去做我們想做的事
// g_damage[attacker] 是 攻擊者的g_damage
// += 是把 a 的數值加上 b
// 全句解作 把 攻擊者的g_damage 加上 傷害值
g_damage[attacker] += damage
// 這裡我們做一個檢查
// 如果 攻擊者的g_damage 大於或等於 150, 就會運行下面的動作
if (g_damage[attacker] >= 150)
{
// 把 攻擊者的g_damage 變回做 0
g_damage[attacker] -= 150
// 把 攻擊者的g_xp 加上 1
g_xp[attacker] += 1
}
// 上面的意思是 如果攻擊者的累積傷害大於150時, 就會加1經濟值和重設累積傷害
// 因為我們上面用過 return HAM_IGNORED 所以最後要多打一次
return HAM_IGNORED
}
// 依次是 受傷者 攻擊者 ??? (這個不太知道-_- 不過沒有太大作用)
public fw_PlayerKilled(victim, attacker, shouldgib)
{
// 和上面的一樣
if (attacker == victim || !is_user_connected(attacker))
return HAM_IGNORED
// 大家應該明白吧
g_xp[attacker] += 1
return HAM_IGNORED
// 這裡的意思是當玩家死亡事件發生 攻擊者經驗值增加
}
// 依次是 玩家
public fw_PlayerPreThink(id)
{
// 全句的意思是 如果 玩家的經驗值 大於或等於 ((玩家的等級 + 1) 乘 100)
if (g_xp[id] >= ((g_level[id] + 1) * 100))
g_level[id] ++ // 玩家的等級上升 (+1)
}
// 依次是 玩家
public say_save(id)
{
// 運行 SaveData 這個 Function, 而且把這裡的 id 連接 SaveData 那裡
SaveData(id)
// client_print 是給玩家彈出一段句子
// 依次序是 對象 類型 句子
// 給大家一個查詢 Function 的網站 (不是全部都有 !!)
// 大家可以打上client_print 然後就有佢的資訊 - 句子類型
// http://www.amxmodx.org/funcwiki.php
client_print(id, print_center, "保存記錄成功")
}
// 依次是 玩家
public say_rank(id)
client_print(id, print_center, "你目前的等級: %i 經驗值: %i ", g_level[id], g_xp[id])
// 我們可以在client_print入面代入可變的資料
// 由於g_level及g_xp是整數, 所以我們用 %i
// 如果玩家的 level 是 1, xp 是 103
// 句子就是 你目前的等級: 1 經驗值: 103
// client_putinserver 是一個inc檔入面包含的Fucntion
// 意思是玩家進入伺服時
public client_putinserver(id)
LoadData(id)
// client_disconnect 是一個inc檔入面包含的Fucntion
// 意思是玩家離開伺服時
public client_disconnect(id)
SaveData(id)
// 這是一個自定意 Function 名字甚麼都可以
public SaveData(id)
{
// variables
// 要注意的是 今次我們的variables是記錄 string (字串) 的
// 所以 [xx] 代表 字串 可以有多長
new name[32], vaultkey[64], vaultdata[256]
// 這是把玩家的名字代入 name 入面
get_user_name(id, name, 31)
// format 是把一個variable寫成一段句字
// 依次序是 variable 長度 ([xx] 中的 xx - 1) 句字 需要代入的variable
// 如果玩家的名字是oN. 累積傷害是50
// vaultkey 就是 oN.-mod
// vaultdata 就是 103#1#50#
format(vaultkey, 63, "%s-mod", name)
format(vaultdata, 255, "%i#%i#%i#", g_xp[id], g_level[id], g_damage[id])
// 這個是 nvault 中的 Function, 意思是把 vaultkey 及 vaultdata 寫入 g_vault
nvault_set(g_vault, vaultkey, vaultdata)
}
// 這是一個自定意 Function 名字甚麼都可以
public LoadData(id)
{
new name[32], vaultkey[64], vaultdata[256]
get_user_name(id,name,31)
format(vaultkey, 63, "%s-caxp", name)
format(vaultdata, 255, "%i#%i#%i#", g_xp[id], g_level[id], g_damage[id])
// 這個是 nvault 中的 Function, 意思從 g_vault 搜尋數據
nvault_get(g_vault, vaultkey, vaultdata, 255)
// replace_all 是把某string中的 a 變為 b
// 依次序是 字串 長度 a b
replace_all(vaultdata, 255, "#", " ")
new playerxp[32], playerlevel[32], playerdamage[32]
// 解釋 vaultdata, 把 vaultdata 中的資料 代入 以下 variables
// 依次序是 字串 variables 長度 variables1 長度 variables2 長度 (還可以有更多)
parse(vaultdata, playerxp, 31, playerlevel, 31, playerdamage, 31)
// str_to_num 是把字串轉變為數字
// 由於讀出來的是字串, 所以要轉變
g_xp[id] = str_to_num(playerxp)
g_level[id] = str_to_num(playerlevel)
g_damage[id] = str_to_num(playerdamage)
}
就那麼多先, 還有更新 那麼, 現在就說管理員的指令吧 第一步就是 註冊管理員指令 (在 plugin_init() 中) 複製程式
public plugin_init()
// 依次序是 指令 運行的Function 需要的權限 解釋
// 解釋打甚麼都行
// 權限的名字可以在 amxconst.inc 中找到
register_concmd("give_xp", "cmd_give_xp", ADMIN_KICK, "- givexp <name> <amount> : Give XP") 然後就是 cmd_give_xp 這個 Function 複製程式
public cmd_give_xp(id, level, cid)
{
// cmd_access 是檢查指令有沒有錯
// 當中的 3 是指指令一共有多少個參數
// 例如 testing oN. 20 90
// 上面就有 4 個參數 (指令計算在裡)
if (!cmd_access(id, level, cid, 3))
return PLUGIN_HANDLED // 返回
// 這裡我們或可寫成 new arg[2][4]
// 那我們就以 arg[0] 和 arg[1] 來表示
new arg_name[4], arg_amount
// read_argv 就是一個讀取參數的 Function
// 依次序是 參數的位置 代入的Variable 長度
read_argv(1, arg_name, 3)
read_argv(2, arg_amount, 3)
// cmd_target 是 從名字搜尋玩家
// 依次序是 指令者 名字 模式
// 模式可以在上述網址中查到
// 在下面的情況 target 已成為該名字的玩家 (如果名字不合 則是!target)
new target = cmd_target(id, arg_name, 2)
if (!target)
{
client_print(id, print_console, "Player not found")
return PLUGIN_HANDLED
}
g_xp[target] += str_to_num(arg_amount)
return PLUGIN_HANDLED
} 那麼, 現在就說怎麼改變玩家的血量 我們可以用到兩個Function, 一個是fun (inc.), 一個是fakemeta (inc.) (記住要#include 相應的inc.檔案)
[quote]set_user_health(玩家, 血量) set_pev(玩家, pev_health, 血量)
這兩個都是設定玩家的血量[/quote] 那我們該在那裡用到這兩個Function呢 ? 當然是在玩家出生的時間了 我們就先要在 註冊這個出生的時間 (在 plugin_init() 中)
複製程式
RegisterHam(Ham_Spawn, "player", "fw_PlayerSpawn_Post", 1)
整個來說了, 就是.... 複製程式
public plugin_init()
RegisterHam(Ham_Spawn, "player", "fw_PlayerSpawn_Post", 1)
// Ham Player Spawn Post Forward
public fw_PlayerSpawn_Post(id)
{
// 如果 玩家不是生存的
if (!is_user_alive(id))
return // 返回
// set_pev 是一個 fakemeta 的 Function, 作用是設定某些東西
// 而 pev_health 就是指定 set_pev 所設定的東西, 這個就是玩家的血量
// 而 float 呢, 這個就是把整數轉變成浮點數 (0.9, 1.2, 11.3, 100.0 這些)
// 全句解釋就是 先把 (玩家的血量 加上 玩家的等級) 變成 浮點數 (例如100 + 10 = 110 就是 110.0)
// 然後 設定 (set_pev) 玩家的血量 (pev_health) 變成 (玩家的血量 加上 玩家的等級[Float])
set_pev(id, pev_health, float(pev(id, pev_health) + g_level[id]))
} 這就好了 那麼, 現在就說怎麼改變玩家的速度 我們同樣可以用到兩個Function, 一個是 fun (inc.), 一個是 fakemeta (inc.) set_user_maxspeed(玩家, 速度) set_pev(玩家, pev_maxspeed, 速度) 速度必須是Float, 而正常速度值為 240.0
我們就先要在 註冊運作設定速度的時間 (在 plugin_init() 中) 我們今次就用回 FM_PlayerPreThink
複製程式
register_forward(FM_PlayerPreThink, "fw_PlayerPreThink")
整個來說了, 就是.... 複製程式
public plugin_init()
register_forward(FM_PlayerPreThink, "fw_PlayerPreThink")
public fw_PlayerPreThink(id)
{
// 如果 玩家不是生存的
if (!is_user_alive(id))
return // 返回
// 由於這裡的速度值必須是Float 所以g_level需要轉變成Float
set_pev(id, pev_maxspeed, 240.0 + float(g_level[id]))
} 那就再說 玩家的重力吧 都是 fun 和 fakemeta set_user_gravity(玩家, 重力) set_pev(玩家, pev_gravity, 重力) 重力必須是Float, 而正常速度值為 1.0 數值愈低 玩家就愈輕
如果要設定玩家的重力 可以運行在以上的兩個Forward 複製程式
RegisterHam(Ham_Spawn, "player", "fw_PlayerSpawn_Post", 1) 複製程式
register_forward(FM_PlayerPreThink, "fw_PlayerPreThink")
複製程式
set_pev(id, pev_gravity, 1.0 - (g_level[id] * 0.006)) 如果大家想改變能力的增加幅度 其實很容易 例如你想每級增加 3 HP
就把複製程式
set_pev(id, pev_health, float(pev(id, pev_health) + g_level[id]))
改成 複製程式
set_pev(id, pev_health, float(pev(id, pev_health) + (g_level[id] * 3))) 就是這樣了 待續....
[ 此文章被pro_on_0在2011-12-04 12:45重新編輯 ]
|