Skocz do zawartości

Witamy w Nieoficjalnym polskim support'cie AMX Mod X

Witamy w Nieoficjalnym polskim support'cie AMX Mod X, jak w większości społeczności internetowych musisz się zarejestrować aby móc odpowiadać lub zakładać nowe tematy, ale nie bój się to jest prosty proces w którym wymagamy minimalnych informacji.
  • Rozpoczynaj nowe tematy i odpowiedaj na inne
  • Zapisz się do tematów i for, aby otrzymywać automatyczne uaktualnienia
  • Dodawaj wydarzenia do kalendarza społecznościowego
  • Stwórz swój własny profil i zdobywaj nowych znajomych
  • Zdobywaj nowe doświadczenia

Dołączona grafika Dołączona grafika

Guest Message by DevFuse
 

Wklejka myczzrxof1cg dodana przez Anty, 06.04.2012 20:30
Typ:



Pomoc
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
80.
81.
82.
83.
84.
85.
86.
87.
88.
89.
90.
91.
92.
93.
94.
95.
96.
97.
98.
99.
100.
101.
102.
103.
104.
105.
106.
107.
108.
109.
110.
111.
112.
113.
114.
115.
116.
117.
118.
119.
120.
121.
122.
123.
124.
125.
126.
127.
128.
129.
130.
131.
132.
133.
134.
135.
136.
137.
138.
139.
140.
141.
142.
143.
144.
145.
146.
147.
148.
149.
150.
151.
152.
153.
154.
155.
156.
157.
158.
159.
160.
161.
162.
163.
164.
165.
166.
167.
168.
169.
170.
171.
172.
173.
174.
175.
176.
177.
178.
179.
180.
181.
182.
183.
184.
185.
186.
187.
188.
189.
190.
191.
192.
193.
194.
195.
196.
197.
198.
199.
200.
201.
202.
203.
204.
205.
206.
207.
208.
209.
210.
211.
212.
213.
214.
215.
216.
217.
218.
219.
220.
221.
222.
223.
224.
225.
226.
227.
228.
229.
230.
231.
232.
233.
234.
235.
236.
237.
238.
239.
240.
241.
242.
243.
244.
245.
246.
247.
248.
249.
250.
251.
252.
253.
254.
255.
256.
257.
258.
259.
260.
261.
262.
263.
264.
265.
266.
267.
268.
269.
270.
271.
272.
273.
274.
275.
276.
277.
278.
279.
280.
281.
282.
283.
284.
285.
286.
287.
288.
289.
290.
291.
292.
293.
294.
295.
296.
297.
298.
299.
300.
301.
302.
303.
304.
305.
306.
307.
308.
309.
310.
311.
312.
313.
314.
315.
316.
317.
318.
319.
320.
321.
322.
323.
324.
325.
326.
327.
328.
329.
330.
331.
332.
333.
334.
335.
336.
337.
338.
339.
340.
341.
342.
343.
344.
345.
346.
347.
348.
349.
350.
351.
352.
353.
354.
355.
356.
357.
358.
359.
360.
361.
362.
363.
364.
365.
366.
367.
368.
369.
370.
371.
372.
373.
374.
375.
376.
377.
378.
379.
380.
381.
382.
383.
384.
385.
386.
387.
388.
389.
390.
391.
392.
393.
394.
395.
396.
397.
398.
399.
400.
401.
402.
403.
404.
405.
406.
407.
408.
409.
410.
411.
412.
413.
414.
415.
416.
417.
418.
419.
420.
421.
422.
423.
424.
425.
426.
427.
428.
429.
430.
431.
432.
433.
434.
435.
436.
437.
438.
439.
440.
441.
442.
443.
444.
445.
446.
447.
448.
449.
450.
451.
452.
453.
454.
455.
456.
457.
458.
459.
460.
461.
462.
463.
464.
465.
466.
467.
468.
469.
470.
471.
472.
473.
474.
475.
476.
477.
478.
479.
480.
481.
482.
483.
484.
485.
486.
487.
488.
489.
490.
491.
492.
493.
494.
495.
496.
497.
498.
499.
500.
501.
502.
503.
504.
505.
506.
507.
#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", ADMIN_IMMUNITY);
 
	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[i]);
	for(i = 0 ; i < sizeof g_NpcSoundDeath ; i++)
		precache_sound(g_NpcSoundDeath[i]);
 
	precache_model(g_NpcModel)
}
 
public plugin_cfg()
{
	Load_Npc()
}
 
public ClCmd_NPC(id)
{
	//Create a new menu
	new menu = menu_create("NPC: Main Menu", "Menu_Handler");
 
	//Add some items to the newly created menu
	menu_additem(menu, "Create NPC", "1");
	menu_additem(menu, "Delete NPC", "2");
	menu_additem(menu, "Save current NPC locations", "3");
	menu_additem(menu, "Delete all 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] NPC origin saved succesfully");
		}
		case 4:
		{
			//Remove all NPCs from the map
			remove_entity_name(g_NpcClassName);
 
			client_print(id, print_chat, "[AMXX] ALL NPC origin removed");
		}
	}
 
	//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, "Hello");
			}
 
			//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
			
		

Dodanych wklejek: 11179
Powered By (Pav32) Pastebin © 2011