husano896
|
分享:
▼
x18
|
[插件] NPC製作教學(最好有點插件基礎在進來!
(待續(?)
所謂NPC 基本上就是"非玩家控制"的角色 例如常見的ZBOT 人質都是 要做個NPC角色 我們需要用到<amxmodx>和<engine>這兩個模塊 就在sma上方加入(若有了就別再加了) 複製程式
#include <amxmodx>
#include <engine>
接著 要寫個製造NPC的function出來 並在plugin_init()裡面加入會調用到的指令 複製程式
public plugin_init()
{
register_clcmd("npc_create", "create_npc") //這個是只要玩家在控制台打npc_create這指令 就會讀取create_npc裡面的指令
}
複製程式
1.我們首先需要用到create_entity這個指令來建立一個物體 複製程式
new ent = create_entity("info_target") //創立一個物體出來 並讓"ent"指向他
2.設定NPC的位置 可以有很多種用法 這裡是將NPC建立在玩家的頭上 複製程式
new Float:origin[3]
entity_get_vector(id,EV_VEC_origin,origin)
origin[2] += 300.0
entity_set_origin(ent,origin);
3.設定血量 複製程式
entity_set_float(ent,EV_FL_takedamage,1.0) //這裡是讓它變成可被攻擊
entity_set_float(ent,EV_FL_health,100.0) //這裡是設定血量
有研究過NST原碼的玩家都會好奇 為什麼不要用DAMAGE_AIM呢 用過的人就會發現 攻擊npc時會lag 尤其是很多隻NPC在地圖上時會特別明顯 4.設定模組(範例是使用models/player/terror/terror.mdl) 複製程式
//※記得在plugin_precache()裡面加入你的模組噢!!
entity_set_model(ent, "models/player/terror/terror.mdl")
5.設定名稱(記住不要設中文!!) 複製程式
entity_set_string(ent,EV_SZ_classname,"npc_terror") //這裡可以隨便取 但是到後面會用到
6.設定大小(記住 不要調太大!! 不然會卡住) 複製程式
new Float:maxs[3] = {16.0,16.0,36.0} //這裡越大 NPC所佔的範圍越大
new Float:mins[3] = {-16.0,-16.0,-36.0} //這裡越小 NPC所佔的範圍越大
entity_set_size(ent,mins,maxs) //設定大小
entity_set_int(ent,EV_INT_solid, 2) //使NPC變為固體(不能穿透)
7.設定畫格 複製程式
entity_set_float(ent,EV_FL_animtime,2.0)
entity_set_float(ent,EV_FL_framerate,1.0) //動作速率 調太大動作會像瘋子...
entity_set_int(ent,EV_INT_sequence,0) //調用的動作序號
8.讓NPC會思考 複製程式
entity_set_float(ent,EV_FL_nextthink,halflife_time() + 0.01) //這裡是設定成下次思考的時間為遊戲時間+0.01秒時
9.丟到地上(就真的這樣翻..) 複製程式
10.設定NPC思考的東西 複製程式
在public plugin_init()裡面加入
register_think("npc_id","npc_think") //前面的npc_id換成你前面npc設的名字!!
隨意找個地方加入
public npc_think(id)
{
//看你要讓NPC幹嘛都扔在這裡
entity_set_float(id,EV_FL_nextthink,halflife_time() + 0.01)
}
※瘟腥提示(?):如果sma裡面有中文字的話 記得轉成UTF-8 No Bom的格式!! 進入遊戲後 測試看看吧!! 下面附件是做好的範例 有問題歡迎發問 參考來源: https://forums.alliedmods.net...php?t=11756
[ 此文章被husano896在2011-07-09 19:51重新編輯 ]
此文章被評分,最近評分記錄財富:100 (by Rubbish-Nec) | 理由: 發文獎勵!! | |
|
|
|
|
x8
[樓 主]
From:臺灣中華電信股份有限公司 | Posted:2011-07-03 11:32 |
|
|
husano896
|
分享:
▲
▼
HAM Forward
要使NPC能在被傷害/擊殺時有特殊效果 我們需要用到hamsandwich這模塊 在sma最上方加入 複製程式
#include <hamsandwich>
#include <fakemeta> //2011.12.28修正(真晚- -
在NPC創建的地方加入 為了確保傷害公式只會被讀一次 要記得加記錄項 像下面 複製程式
if (!g_hamnpc) //記住!!g_hamnpc只能被放在function外面!!
{
//這兩串是讓NPC讀到你的傷害公式
RegisterHamFromEntity(Ham_TakeDamage, ent, "fw_TakeDamage")
RegisterHamFromEntity(Ham_TraceAttack, ent, "fw_TraceAttack")
RegisterHamFromEntity(Ham_Killed, ent, "fw_Killed")
g_hamnpc = 1
}
※如果讀了好幾次的話 電腦當機恕不退費(? 不知道怎麼加歡迎PM我 並在plugin_init裡面加入 複製程式
//這兩串是讓玩家讀到你的傷害公式
RegisterHam(Ham_TakeDamage, "player", "fw_TakeDamage")
RegisterHam(Ham_TraceAttack, "player", "fw_TraceAttack")
//這裡就不需要加Killed了 不然會讀兩次
當然 我們還要在下面加入對應的function才行 複製程式
public fw_TakeDamage(victim, inflictor, attacker, Float:damage, damage_type)
{
if (victim==attacker)
return HAM_IGNORED;
if (!pev_valid(victim) || !pev_valid(attacker))
return HAM_IGNORED;
new classname[32]
pev(victim,pev_classname,classname,31)
if (equal(classname,"(你之前設的NPC名字)")) //這裡是檢查被打的人是不是NPC
{
//看你要加啥都加在這邊
//有一點要注意 "非"玩家使用的指令不能加在這邊 否則會有錯誤
//例如 被攻擊/攻擊者是NPC 就不能使用 cs_get_user_team(victim) 或 cs_set_user_money(victim, ...)
//當然 is_user_connected(回傳玩家是否連接)這類的指令可以用
//傷害的修改教學 可以看a78大的文章 http://bbs-mychat.com/reads.php?tid=829669
}
return HAM_IGNORED;
}
複製程式
#define DMG_HEGRENADE (1 << 24) //感謝fouury提醒
new cache_bloodspray, cache_blood //血的spr 等等會用到
public plugin_precache()
{
//讀取spr
cache_blood = precache_model("sprites/blood.spr")
cache_bloodspray = precache_model("sprites/bloodspray.spr")
}
public fw_TraceAttack(victim, attacker, Float:damage, Float:direction[3], tracehandle, damage_type)
{
if (victim==attacker)
return HAM_IGNORED;
if (!pev_valid(victim) || pev_valid(attacker))
return HAM_IGNORED;
new classname[32]
pev(victim,pev_classname,classname,31)
if (equal(classname,"(你之前設的NPC名字)")) //這裡是檢查被打的人是不是NPC
{
//注意事項跟上面一樣
//get_tr/set_tr這類指令可以使用 可用來判定傷害部位/噴血位置
//下面會有範例(飯粒?
new body = get_tr2(tracehandle,TR_iHitgroup) //取得NPC被傷害的部位
if (body == 1) //爆頭的情況下
{
damage *= 4.0 //傷害四倍
SetHamParamFloat(3, damage) //讀取修改過後的傷害
}
new Float:Fend[3],end[3]
get_tr2(tracehandle, TR_vecEndPos, Fend) //在開槍的位置和被擊中的位置畫條線(我不知道怎麼解釋..)
//This message will draw blood sprites at the end of the trace
if (!(damage_type & DMG_HEGRENADE)) //如果不是被芭樂炸的
{
end[0] = floatround(Fend[0])
end[1] = floatround(Fend[1])
end[2] = floatround(Fend[2])
create_block_sprites(end) //在該位置顯示噴血(不會有血跡)
}
}
return HAM_IGNORED;
}
create_block_sprites(const origin[3])
{
// Show some blood :)
message_begin(MSG_BROADCAST, SVC_TEMPENTITY)
write_byte(TE_BLOODSPRITE)
write_coord(origin[0])
write_coord(origin[1])
write_coord(origin[2])
write_short(cache_bloodspray)
write_short(cache_blood)
write_byte(75)
write_byte(5)
message_end()
}
複製程式
public fw_Killed(victim, attacker)
{
//※跟上上方的說明一樣 非玩家指令不能用 除非你能確定你用的人是玩家
new classname[32]
pev(victim,pev_classname,classname,31)
if (equal(classname,"(你之前設的NPC名字)")) //這裡是檢查被打的人是不是NPC
{
if (is_user_connected(attacker)) //當攻擊者是玩家時
{
//你可以在這裡加給玩家用的指令 例如加錢...加血
}
}
return HAM_IGNORED
}
有興趣的人 可以看下面從Ham_const裡面拿來的說明(英文) 複製程式
* Description: Usually called whenever an entity gets attacked by a hitscan (such as a gun) weapon.
* Use the get/set tr2 natives in fakemeta to handle the traceresult data.
* Do not use a handle of 0 as a traceresult in execution, use create_tr2() from Fakemeta
* to pass a custom handle instead. (Don't forget to free the handle when you're done.)
* Forward params: function(this, idattacker, Float:damage, Float:direction[3], traceresult, damagebits)
* Return type: None.
* Execute params: ExecuteHam(Ham_TraceAttack, this, idattacker, Float:damage, Float:direction[3], tracehandle, damagebits);
*/
Ham_TraceAttack,
/**
* Description: Usually called whenever an entity takes any kind of damage.
* Inflictor is the entity that caused the damage (such as a gun).
* Attacker is the entity that tirggered the damage (such as the gun's owner).
* Forward params: function(this, idinflictor, idattacker, Float:damage, damagebits);
* Return type: Integer.
* Execute params: ExecuteHam(Ham_TakeDamage, this, idinflictor, idattacker, Float:damage, damagebits);
*/
Ham_TakeDamage,
這次說明可能比較難懂 多觀察其他插件的使用方式吧 如果完全看不懂 建議你先學一點c++ 題外話: 這次的東西好多都忘了改為engine的用法><2011.12.28:還是改回fakemeta好了 問題好多..(汗尤其是get_tr2的部分根本不能用(汗顏
[ 此文章被husano896在2012-02-18 14:57重新編輯 ]
此文章被評分,最近評分記錄財富:50 (by Rubbish-Nec) | 理由: 追加獎勵!! | |
|
|
|
|
x4
[1 樓]
From:臺灣中華電信股份有限公司 | Posted:2011-07-03 11:33 |
|
|
|