廣告廣告
  加入我的最愛 設為首頁 風格修改
首頁 首尾
 手機版   訂閱   地圖  簡體 
您是第 3433 個閱讀者
 
發表文章 發表投票 回覆文章
  可列印版   加為IE收藏   收藏主題   上一主題 | 下一主題   
xuqiang52133
個人文章 個人相簿 個人日記 個人地圖
初露鋒芒
級別: 初露鋒芒 該用戶目前不上站
推文 x1 鮮花 x32
分享: 轉寄此文章 Facebook Plurk Twitter 複製連結到剪貼簿 轉換為繁體 轉換為簡體 載入圖片
推文 x0
[插件] NPC不能自动判断攻击,带源码  (NPC不能自动判断攻击,带源码(求帮助啊))
#include <amxmodx>
#include <amxmisc>
#include <fakemeta>
#include <engine>
#include <hamsandwich>




//Boolean of when NPC spawned 
new bool: g_NpcSpawn[256]; 
//Boolean to check if NPC is alive or not 
new bool: g_NpcDead[256]; 
//Classname for our NPC 
new const g_NpcClassName[] = "ent_npc"; 
//Constant model for NPC 
new const g_NpcModel[] = "models/barney.mdl"; 


//List of sounds our NPC will emit when damaged 
new const g_NpcSoundPain[][] =  

    "barney/ba_pain1.wav", 
    "barney/ba_pain2.wav", 
    "barney/ba_pain3.wav" 



//Sounds when killed 
new const g_NpcSoundDeath[][] = 

    "barney/ba_die1.wav", 
    "barney/ba_die2.wav", 
    "barney/ba_die3.wav" 



//Sounds when we knife our flesh NPC
new const g_NpcSoundKnifeHit[][] = 
{
"weapons/knife_hit1.wav",
"weapons/knife_hit2.wav",
"weapons/knife_hit3.wav",
"weapons/knife_hit4.wav"
}


new const g_NpcSoundKnifeStab[] = "weapons/knife_stab.wav";


//List of idle animations 
new const NPC_IdleAnimations[] = { 0, 1, 2, 3, 11, 12, 18, 21, 39, 63, 65 };


//Sprites for blood when our NPC is damaged
new spr_blood_drop, spr_blood_spray


//Player cooldown for using our NPC 
new Float: g_Cooldown[32];


//Boolean to check if we knifed our NPC
new bool: g_Hit[32];


public plugin_init()
{
register_plugin("NPC Plugin", "1.1", "Mazza");
register_clcmd("say /npc", "ClCmd_NPC");

register_event("HLTV", "Event_NewRound", "a", "1=0", "2=0");

RegisterHam(Ham_TakeDamage, "info_target", "npc_TakeDamage");
RegisterHam(Ham_Killed, "info_target", "npc_Killed");
RegisterHam(Ham_Think, "info_target", "npc_Think");
RegisterHam(Ham_TraceAttack, "info_target", "npc_TraceAttack");
RegisterHam(Ham_ObjectCaps, "player", "npc_ObjectCaps", 1 );

register_forward(FM_EmitSound, "npc_EmitSound"); 
}


public plugin_precache()
{
spr_blood_drop = precache_model("sprites/blood.spr")
spr_blood_spray = precache_model("sprites/bloodspray.spr")

new i;
for(i = 0 ; i < sizeof g_NpcSoundPain ; i++)
precache_sound(g_NpcSoundPain);
for(i = 0 ; i < sizeof g_NpcSoundDeath ; i++)
precache_sound(g_NpcSoundDeath);


precache_model(g_NpcModel)
}


public plugin_cfg()
{
Load_Npc()
}


public ClCmd_NPC(id)
{
//Create a new menu
new menu = menu_create("NPC: 菜单", "Menu_Handler");

//Add some items to the newly created menu
menu_additem(menu, "建立NPC", "1");
menu_additem(menu, "删除NPC", "2");
menu_additem(menu, "保存所有NPC", "3");
menu_additem(menu, "删除所有NPC", "4");

//Let the menu have an 'Exit' option
menu_setprop(menu, MPROP_EXIT, MEXIT_ALL);

//Display our menu
menu_display(id, menu);
}


public Menu_Handler(id, menu, item)
{
//If user chose to exit menu we will destroy our menu
if(item == MENU_EXIT)
{
menu_destroy(menu);
return PLUGIN_HANDLED;
}

new info[6], szName[64];
new access, callback;

menu_item_getinfo(menu, item, access, info, charsmax(info), szName, charsmax(szName), callback);

new key = str_to_num(info);

switch(key)
{
case 1:
{
//Create our NPC
Create_Npc(id);
}
case 2:
{
//Remove our NPC by the users aim
new iEnt, body, szClassname[32];
get_user_aiming(id, iEnt, body);

if (is_valid_ent(iEnt)) 
{
entity_get_string(iEnt, EV_SZ_classname, szClassname, charsmax(szClassname));

if (equal(szClassname, g_NpcClassName)) 
{
remove_entity(iEnt);
}

}
}
case 3:
{
//Save the current locations of all the NPCs
Save_Npc();

client_print(id, print_chat, "[AMXX] 已经保存");
}
case 4:
{
//Remove all NPCs from the map
remove_entity_name(g_NpcClassName);

client_print(id, print_chat, "[AMXX] 已经删除");
}
}

//Keep the menu displayed when we choose an option
menu_display(id, menu);

return PLUGIN_HANDLED;
}


public npc_TakeDamage(iEnt, inflictor, attacker, Float:damage, bits)
{
//Make sure we only catch our NPC by checking the classname
new className[32];
entity_get_string(iEnt, EV_SZ_classname, className, charsmax(className))

if(!equali(className, g_NpcClassName))
return;

//Play a random animation when damanged
Util_PlayAnimation(iEnt, random_num(13, 17), 1.25);


//Make our NPC say something when it is damaged
//NOTE: Interestingly... Our NPC mouth (which is a controller) moves!! That saves us some work!!
emit_sound(iEnt, CHAN_VOICE, g_NpcSoundPain[random(sizeof g_NpcSoundPain)],  VOL_NORM, ATTN_NORM, 0, PITCH_NORM)

g_Hit[attacker] = true;
}


public npc_Killed(iEnt)
{
new className[32];
entity_get_string(iEnt, EV_SZ_classname, className, charsmax(className))

if(!equali(className, g_NpcClassName))
return HAM_IGNORED;


//Player a death animation once our NPC is killed
Util_PlayAnimation(iEnt, random_num(25, 30))


//Because our NPC may look like it is laying down. 
//The bounding box size is still there and it is impossible to change it so we will make the solid of our NPC to nothing
entity_set_int(iEnt, EV_INT_solid, SOLID_NOT);


//The voice of the NPC when it is dead
emit_sound(iEnt, CHAN_VOICE, g_NpcSoundDeath[random(sizeof g_NpcSoundDeath)],  VOL_NORM, ATTN_NORM, 0, PITCH_NORM)


//Our NPC is dead so it shouldn't take any damage and play any animations
entity_set_float(iEnt, EV_FL_takedamage, 0.0);
//Our death boolean should now be true!!
g_NpcDead[iEnt] = true;

//The most important part of this forward!! We have to block the death forward.
return HAM_SUPERCEDE
}


public npc_Think(iEnt)
{
if(!is_valid_ent(iEnt))
return;

static className[32];
entity_get_string(iEnt, EV_SZ_classname, className, charsmax(className))

if(!equali(className, g_NpcClassName))
return;

//We can remove our NPC here if we wanted to but I left this blank as I personally like it when there is a NPC coprse laying around
if(g_NpcDead[iEnt])
{
return;
}

//Our NPC just spawned
if(g_NpcSpawn[iEnt])
{
static Float: mins[3], Float: maxs[3];
pev(iEnt, pev_absmin, mins);
pev(iEnt, pev_absmax, maxs);


//Draw a box which is the size of the bounding NPC
message_begin(MSG_BROADCAST, SVC_TEMPENTITY)
write_byte(TE_BOX)
engfunc(EngFunc_WriteCoord, mins[0])
engfunc(EngFunc_WriteCoord, mins[1])
engfunc(EngFunc_WriteCoord, mins[2])
engfunc(EngFunc_WriteCoord, maxs[0])
engfunc(EngFunc_WriteCoord, maxs[1])
engfunc(EngFunc_WriteCoord, maxs[2])
write_short(100)
write_byte(random_num(25, 255))
write_byte(random_num(25, 255))
write_byte(random_num(25, 255))
message_end();

//Our NPC spawn boolean is now set to false
g_NpcSpawn[iEnt] = false;
}

//Choose a random idle animation
Util_PlayAnimation(iEnt, NPC_IdleAnimations[random(sizeof NPC_IdleAnimations)]);


//Make our NPC think every so often
entity_set_float(iEnt, EV_FL_nextthink, get_gametime() + random_float(5.0, 10.0));
}


public npc_TraceAttack(iEnt, attacker, Float: damage, Float: direction[3], trace, damageBits)
{
if(!is_valid_ent(iEnt))
return;

new className[32];
entity_get_string(iEnt, EV_SZ_classname, className, charsmax(className))

if(!equali(className, g_NpcClassName))
return;

//Retrieve the end of the trace
new Float: end[3]
get_tr2(trace, TR_vecEndPos, end);

//This message will draw blood sprites at the end of the trace
message_begin(MSG_BROADCAST,SVC_TEMPENTITY)
write_byte(TE_BLOODSPRITE)
engfunc(EngFunc_WriteCoord, end[0])
engfunc(EngFunc_WriteCoord, end[1])
engfunc(EngFunc_WriteCoord, end[2])
write_short(spr_blood_spray)
write_short(spr_blood_drop)
write_byte(247) // color index
write_byte(random_num(1, 5)) // size
message_end()
}


public npc_ObjectCaps(id)
{
//Make sure player is alive
if(!is_user_alive(id))
return;


//Check when player presses +USE key
if(get_user_button(id) & IN_USE)
{
//Check cooldown of player when using our NPC
static Float: gametime ; gametime = get_gametime();
if(gametime - 1.0 > g_Cooldown[id])
{
//Get the classname of whatever ent we are looking at
static iTarget, iBody, szAimingEnt[32];
get_user_aiming(id, iTarget, iBody, 75);
entity_get_string(iTarget, EV_SZ_classname, szAimingEnt, charsmax(szAimingEnt));

//Make sure our aim is looking at a NPC
if(equali(szAimingEnt, g_NpcClassName))
{
//Do more fancy stuff here such as opening a menu
//But for this tutorial I will only display a message to prove it works
client_print(id, print_chat, "嘿!老兄你看到我的朋友嘎登没有?他到那里去了");
}

//Set players cooldown to the current gametime
g_Cooldown[id] = gametime;
}
}
}


public npc_EmitSound(id, channel, sample[], Float:volume, Float:attn, flag, pitch)
{
//Make sure player is alive
if(!is_user_connected(id))
return FMRES_SUPERCEDE;


//Catch the current button player is pressing
new iButton = get_user_button(id);

//If the player knifed the NPC
if(g_Hit[id])
{
//Catch the string and make sure its a knife 
if (sample[0] == 'w' && sample[1] == 'e' && sample[8] == 'k' && sample[9] == 'n')
{
//Catch the file of _hitwall1.wav or _slash1.wav/_slash2.wav
if(sample[17] == 's' || sample[17] == 'w')
{
//If player is slashing then play the knife hit sound
if(iButton & IN_ATTACK)
{
emit_sound(id, CHAN_WEAPON, g_NpcSoundKnifeHit[random(sizeof g_NpcSoundKnifeHit)], volume, attn, flag, pitch);
}
//If player is tabbing then play the stab sound
else if(iButton & IN_ATTACK2)
{
emit_sound(id,CHAN_WEAPON, g_NpcSoundKnifeStab, volume, attn, flag, pitch);
}


//Reset our boolean as player is not hitting NPC anymore
g_Hit[id] = false;

//Block any further sounds to be played
return FMRES_SUPERCEDE
}
}
}

return FMRES_IGNORED
}


public Event_NewRound()
{
new iEnt = -1;

//Scan and find all of the NPC classnames
while( ( iEnt = find_ent_by_class(iEnt, g_NpcClassName) ) )
{
//If we find a NPC which is dead...
if(g_NpcDead[iEnt])
{
//Reset the solid box
entity_set_int(iEnt, EV_INT_solid, SOLID_BBOX);
//Make our NPC able to take damage again
entity_set_float(iEnt, EV_FL_takedamage, 1.0);
//Make our NPC instanstly think
entity_set_float(iEnt, EV_FL_nextthink, get_gametime() + 0.01);

//Reset the NPC boolean to false
g_NpcDead[iEnt] = false;
}

//Reset the health of our NPC
entity_set_float(iEnt, EV_FL_health, 250.0);
}
}


Create_Npc(id, Float:flOrigin[3]= { 0.0, 0.0, 0.0 }, Float:flAngle[3]= { 0.0, 0.0, 0.0 } )
{
//Create an entity using type 'info_target'
new iEnt = create_entity("info_target");

//Set our entity to have a classname so we can filter it out later
entity_set_string(iEnt, EV_SZ_classname, g_NpcClassName);

//If a player called this function
if(id)
{
//Retrieve the player's origin
entity_get_vector(id, EV_VEC_origin, flOrigin);
//Set the origin of the NPC to the current players location
entity_set_origin(iEnt, flOrigin);
//Increase the Z-Axis by 80 and set our player to that location so they won't be stuck
flOrigin[2] += 80.0;
entity_set_origin(id, flOrigin);

//Retrieve the player's  angle
entity_get_vector(id, EV_VEC_angles, flAngle);
//Make sure the pitch is zeroed out
flAngle[0] = 0.0;
//Set our NPC angle based on the player's angle
entity_set_vector(iEnt, EV_VEC_angles, flAngle);
}
//If we are reading from a file
else 
{
//Set the origin and angle based on the values of the parameters
entity_set_origin(iEnt, flOrigin);
entity_set_vector(iEnt, EV_VEC_angles, flAngle);
}


//Set our NPC to take damange and how much health it has
entity_set_float(iEnt, EV_FL_takedamage, 1.0);
entity_set_float(iEnt, EV_FL_health, 250.0);


//Set a model for our NPC
entity_set_model(iEnt, g_NpcModel);
//Set a movetype for our NPC
entity_set_int(iEnt, EV_INT_movetype, MOVETYPE_PUSHSTEP);
//Set a solid for our NPC
entity_set_int(iEnt, EV_INT_solid, SOLID_BBOX);


//Create a bounding box for oru NPC
new Float: mins[3] = {-12.0, -12.0, 0.0 }
new Float: maxs[3] = { 12.0, 12.0, 75.0 }


entity_set_size(iEnt, mins, maxs);

//Controllers for our NPC. First controller is head. Set it so it looks infront of itself
entity_set_byte(iEnt,EV_BYTE_controller1,125);
// entity_set_byte(ent,EV_BYTE_controller2,125);
// entity_set_byte(ent,EV_BYTE_controller3,125);
// entity_set_byte(ent,EV_BYTE_controller4,125);

//Drop our NPC to the floor
drop_to_floor(iEnt);

// set_rendering( ent, kRenderFxDistort, 0, 0, 0, kRenderTransAdd, 127 );

//We just spawned our NPC so it should not be dead
g_NpcSpawn[iEnt] = true;
g_NpcDead[iEnt] = false;

//Make it instantly think
entity_set_float(iEnt, EV_FL_nextthink, get_gametime() + 0.01)
}


Load_Npc()
{
//Get the correct filepath and mapname
new szConfigDir[256], szFile[256], szNpcDir[256];

get_configsdir(szConfigDir, charsmax(szConfigDir));

new szMapName[32];
get_mapname(szMapName, charsmax(szMapName));

formatex(szNpcDir, charsmax(szNpcDir),"%s/NPC", szConfigDir);
formatex(szFile, charsmax(szFile),  "%s/%s.cfg", szNpcDir, szMapName);

//If the filepath does not exist then we will make one
if(!dir_exists(szNpcDir))
{
mkdir(szNpcDir);
}

//If the map config file does not exist we will make one
if(!file_exists(szFile))
{
write_file(szFile, "");
}

//Variables to store when reading our file
new szFileOrigin[3][32]
new sOrigin[128], sAngle[128];
new Float:fOrigin[3], Float:fAngles[3];
new iLine, iLength, sBuffer[256];

//When we are reading our file...
while(read_file(szFile, iLine++, sBuffer, charsmax(sBuffer), iLength))
{
//Move to next line if the line is commented
if((sBuffer[0]== ';') || !iLength)
continue;

//Split our line so we have origin and angle. The split is the vertical bar character
strtok(sBuffer, sOrigin, charsmax(sOrigin), sAngle, charsmax(sAngle), '|', 0);

//Store the X, Y and Z axis to our variables made earlier
parse(sOrigin, szFileOrigin[0], charsmax(szFileOrigin[]), szFileOrigin[1], charsmax(szFileOrigin[]), szFileOrigin[2], charsmax(szFileOrigin[]));

fOrigin[0] = str_to_float(szFileOrigin[0]);
fOrigin[1] = str_to_float(szFileOrigin[1]);
fOrigin[2] = str_to_float(szFileOrigin[2]);

//Store the yawn angle
fAngles[1] = str_to_float(sAngle[1]);

//Create our NPC
Create_Npc(0, fOrigin, fAngles)

//Keep reading the file until the end
}
}


Save_Npc()
{
//Variables
new szConfigsDir[256], szFile[256], szNpcDir[256];

//Get the configs directory.
get_configsdir(szConfigsDir, charsmax(szConfigsDir));

//Get the current map name
new szMapName[32];
get_mapname(szMapName, charsmax(szMapName));

//Format 'szNpcDir' to ../configs/NPC
formatex(szNpcDir, charsmax(szNpcDir),"%s/NPC", szConfigsDir);
//Format 'szFile to ../configs/NPC/mapname.cfg
formatex(szFile, charsmax(szFile), "%s/%s.cfg", szNpcDir, szMapName);

//If there is already a .cfg for the current map. Delete it
if(file_exists(szFile))
delete_file(szFile);

//Variables
new iEnt = -1, Float:fEntOrigin[3], Float:fEntAngles[3];
new sBuffer[256];

//Scan and find all of my custom ents
while( ( iEnt = find_ent_by_class(iEnt, g_NpcClassName) ) )
{
//Get the entities' origin and angle
entity_get_vector(iEnt, EV_VEC_origin, fEntOrigin);
entity_get_vector(iEnt, EV_VEC_angles, fEntAngles);

//Format the line of one custom ent.
formatex(sBuffer, charsmax(sBuffer), "%d %d %d | %d", floatround(fEntOrigin[0]), floatround(fEntOrigin[1]), floatround(fEntOrigin[2]), floatround(fEntAngles[1]));

//Finally write to the mapname.cfg file and move on to the next line
write_file(szFile, sBuffer, -1);

//We are currentlying looping to find all custom ents on the map. If found another ent. Do the above till there is none.
}

}


stock Util_PlayAnimation(index, sequence, Float: framerate = 1.0)
{
entity_set_float(index, EV_FL_animtime, get_gametime());
entity_set_float(index, EV_FL_framerate,  framerate);
entity_set_float(index, EV_FL_frame, 0.0);
entity_set_int(index, EV_INT_sequence, sequence);
}



我要暴你头。。。。。
獻花 x0 回到頂端 [樓 主] From:遼寧 | Posted:2014-02-24 16:58 |
xuqiang52133
個人文章 個人相簿 個人日記 個人地圖
初露鋒芒
級別: 初露鋒芒 該用戶目前不上站
推文 x1 鮮花 x32
分享: 轉寄此文章 Facebook Plurk Twitter 複製連結到剪貼簿 轉換為繁體 轉換為簡體 載入圖片

这个NPC不能自动判断攻击,建立出来只是一个模型而已,这个求各位帮助我以下好吗,谢谢大家了,


我要暴你头。。。。。
獻花 x0 回到頂端 [1 樓] From:遼寧 | Posted:2014-02-24 17:00 |
a7811311622 手機
個人頭像
個人文章 個人相簿 個人日記 個人地圖
特殊貢獻獎 優秀管理員勳章 社區建設獎
頭銜:我…在工作了…我…在工作了…
版主
級別: 版主 該用戶目前不上站
版區: CS提問區
推文 x771 鮮花 x2152
分享: 轉寄此文章 Facebook Plurk Twitter 複製連結到剪貼簿 轉換為繁體 轉換為簡體 載入圖片

npc_Think 裡完全沒提到什麼自動判斷攻擊…當然不會有反應…
不過…就這點長度的程式碼你為何會期待 NPC 會有如此高明的功能?
你當 NST 的 NPC 寫那麼長寫心酸的?


尚無簽名,歡迎 [新增個性化簽名]
獻花 x0 回到頂端 [2 樓] From:臺灣中華電信股份有限公司 | Posted:2014-02-24 20:05 |
xuqiang52133
個人文章 個人相簿 個人日記 個人地圖
初露鋒芒
級別: 初露鋒芒 該用戶目前不上站
推文 x1 鮮花 x32
分享: 轉寄此文章 Facebook Plurk Twitter 複製連結到剪貼簿 轉換為繁體 轉換為簡體 載入圖片

你能 帮我 完成一下好吗 ,谢谢你了 ,我实在是 弄不明白了 。


我要暴你头。。。。。
獻花 x0 回到頂端 [3 樓] From:美國 | Posted:2014-02-24 21:39 |

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