Raised This Month: $ Target: $400
 0% 

Headcrab Spawner


  
 
 
Thread Tools Display Modes
Prev Previous Post   Next Post Next
Glaster
Junior Member
Join Date: Jan 2020
Location: Irkutsk, Russia
Old 03-12-2024 , 03:42   Re: Headcrab Spawner
Reply With Quote #30

Source code for GHW_Headcrab. I hope it'll be useful for someone


Code:
#include <amxmodx>
#include <amxmisc>
#include <chr_engine>

#define FL_PSYCHIC	(1<<32)
#define FL_FRIENDLY	(1<<33)
#define FL_IN_JUMP	(1<<34)
#define FL_IN_RIGHT	(1<<35)
#define FL_IN_LEFT	(1<<36)
#define FL_IN_FORWARD	(1<<37)
#define FL_IN_BACK	(1<<38)
#define FL_STOPPED	(1<<39)
#define FL_WANDER	(1<<40)
#define FL_EXPLODE	(1<<42)
#define FL_KAMIKAZE	(1<<43)
#define FL_FROZEN2	(1<<44)
#define FL_FRIENDLY_1	(1<<45)
#define FL_FRIENDLY_2	(1<<46)
#define FL_FRIENDLY_3	(1<<47)
#define FL_FRIENDLY_4	(1<<48)

#define SQ_IDLE		0
#define SQ_TURNLEFT	9
#define SQ_TURNRIGHT	8
#define SQ_RUN		3
#define SQ_DIE		7
#define SQ_IN_AIR	13
#define SQ_IN_JUMP	5

#define FR_IDLE		1.0
#define FR_TURNLEFT	0.5
#define FR_TURNRIGHT	0.5
#define FR_RUN		1.5
#define FR_DIE		1.0
#define FR_IN_AIR	1.0
#define FR_IN_JUMP	1.0

#define BLOOD_COLOR	204

#define HEALTH_OFFSET	100000.0

#define THINK_DELAY	0.0

new blood, blood2
new forward_hc_died = -1

public plugin_init()
{
	register_plugin("Headcrab AI","1.0","GHW_Chronic")

	forward_hc_died = CreateMultiForward("headcrab_killed",ET_STOP,FP_CELL)

	register_forward(FM_Think,"headcrab_think")
	register_forward(FM_Touch,"headcrab_touch")
}

public plugin_natives()
{
	register_native("create_headcrab","create_headcrab")
	register_native("set_headcrab_health","set_headcrab_health")
	register_native("kill_headcrab","kill_headcrab")

	register_library("headcrab")
}

public plugin_precache()
{
	precache_model("models/headcrab.mdl")

	precache_sound("headcrab/hc_pain1.wav")
	precache_sound("headcrab/hc_pain2.wav")
	precache_sound("headcrab/hc_pain3.wav")

	precache_sound("headcrab/hc_alert1.wav")
	precache_sound("headcrab/hc_alert2.wav")

	precache_sound("headcrab/hc_attack1.wav")
	precache_sound("headcrab/hc_attack2.wav")
	precache_sound("headcrab/hc_attack3.wav")

	precache_sound("headcrab/hc_die1.wav")
	precache_sound("headcrab/hc_die2.wav")

	precache_sound("headcrab/hc_headbite.wav")

	precache_sound("headcrab/hc_idle1.wav")
	precache_sound("headcrab/hc_idle2.wav")
	precache_sound("headcrab/hc_idle3.wav")
	precache_sound("headcrab/hc_idle4.wav")
	precache_sound("headcrab/hc_idle5.wav")

	precache_sound("squeek/sqk_blast1.wav")

	blood = precache_model("sprites/blood.spr")
	blood2 = precache_model("sprites/bloodspray.spr")
}

public create_headcrab()
{
	new ent = engfunc(EngFunc_CreateNamedEntity,engfunc(EngFunc_AllocString,"info_target"))

	set_pev(ent,pev_classname,"GHW_headcrab")
	engfunc(EngFunc_SetModel,ent,"models/headcrab.mdl")

	set_pev(ent,pev_mins,Float:{-16.0,-16.0,0.0})
	set_pev(ent,pev_maxs,Float:{16.0,16.0,36.0})
	set_pev(ent,pev_size,Float:{-16.0,-16.0,0.0,16.0,16.0,36.0})
	engfunc(EngFunc_SetSize,ent,Float:{-16.0,-16.0,0.0},Float:{16.0,16.0,36.0})

	set_pev(ent,pev_solid,SOLID_BBOX)
	set_pev(ent,pev_movetype,MOVETYPE_FLY)

	set_pev(ent,pev_sequence,SQ_IDLE)
	set_pev(ent,pev_gaitsequence,SQ_IDLE)
	set_pev(ent,pev_framerate,FR_IDLE)

	set_pev(ent,pev_health,100.0 + HEALTH_OFFSET)
	set_pev(ent,pev_takedamage,1.0)

	set_pev(ent,pev_dmg,1.0)

	set_pev(ent,pev_maxspeed,20.0)

	set_pev(ent,pev_flags,FL_MONSTER|FL_MONSTERCLIP)
	set_pev(ent,pev_nextthink,get_gametime())

	return ent;
}

public set_headcrab_health(ent,Float:health)
{
	set_pev(ent,pev_health,health + HEALTH_OFFSET)
	set_pev(ent,pev_max_health,health + HEALTH_OFFSET)
}

public headcrab_think(ent)
{
	static classname[32]
	pev(ent,pev_classname,classname,31)
	if(equali(classname,"GHW_headcrab"))
	{
		new flags = pev(ent,pev_flags)
		if(flags & FL_FROZEN2)
		{
			set_pev(ent,pev_velocity,Float:{0.0,0.0,0.0})
			set_pev(ent,pev_takedamage,0.0)
		}
		if(!(flags & FL_STOPPED))
		{
			new Float:health, Float:oldhealth
			pev(ent,pev_health,health)
			pev(ent,pev_max_health,oldhealth)

			if(health<HEALTH_OFFSET)
			{
				kill_headcrab(ent)
				return 0;
			}

			new enemy = pev(ent,pev_enemy)
			if(!is_user_alive(enemy)) enemy=0

			static Float:origin[3], Float:velocity[3]
			pev(ent,pev_origin,origin)
			pev(ent,pev_velocity,velocity)
			static Float:velocity2[3], Float:origin2[3]

			new Float:maxspeed
			pev(ent,pev_maxspeed,maxspeed)

			if(health < oldhealth)
			{
				switch(random_num(1,3))
				{
					case 1: emit_sound(ent,CHAN_VOICE,"headcrab/hc_pain1.wav",VOL_NORM, ATTN_NORM,0,PITCH_NORM)
					case 2: emit_sound(ent,CHAN_VOICE,"headcrab/hc_pain2.wav",VOL_NORM, ATTN_NORM,0,PITCH_NORM)
					case 3: emit_sound(ent,CHAN_VOICE,"headcrab/hc_pain3.wav",VOL_NORM, ATTN_NORM,0,PITCH_NORM)
				}
				message_begin(MSG_BROADCAST,SVC_TEMPENTITY)
				write_byte(TE_BLOODSPRITE)
				write_coord(floatround(origin[0]))
				write_coord(floatround(origin[1]))
				write_coord(floatround(origin[2]))
				write_short(blood2)
				write_short(blood)
				write_byte(BLOOD_COLOR)
				write_byte(10)
				message_end()
			}

			if(flags & FL_WANDER && !enemy)
			{
				if(flags & FL_IN_FORWARD || flags & FL_IN_BACK)
				{
					if(flags & FL_IN_FORWARD) get_offset_origin(ent,Float:{40.0,0.0,0.0},origin2)
					else get_offset_origin(ent,Float:{-40.0,0.0,0.0},origin2)

					get_speed_vector(origin,origin2,maxspeed,velocity2)

					new Float:diff = floatsqroot(maxspeed) - (floatsqroot(maxspeed) * 0.2236)
					if(!is_within_difference(velocity[0],velocity2[0],diff) || !is_within_difference(velocity[1],velocity2[1],diff) || random_num(1,2500)==1686)
					{
						static param[1]

						if(flags & FL_IN_FORWARD)
						{
							param[0] = FL_IN_FORWARD
							flags -= FL_IN_FORWARD
						}
						else
						{
							param[0] = FL_IN_BACK
							flags -= FL_IN_BACK
						}

						remove_flag(param,ent)

						switch(random_num(1,2))
						{
							case 1:
							{
								flags += FL_IN_LEFT
								param[0] = FL_IN_LEFT
							}
							case 2:
							{
								flags += FL_IN_RIGHT
								param[0] = FL_IN_RIGHT
							}
						}
						set_task(random_float(1.0,2.0) * (20.0 / maxspeed),"remove_flag",ent,param,1)
					}
				}
				else if(!(flags & FL_IN_RIGHT) && !(flags & FL_IN_LEFT))
				{
					set_pev(ent,pev_sequence,SQ_RUN)
					set_pev(ent,pev_gaitsequence,SQ_RUN)
					set_pev(ent,pev_framerate,FR_RUN * (maxspeed / 20.0))

					flags += FL_IN_FORWARD
					get_offset_origin(ent,Float:{40.0,0.0,0.0},origin2)

					get_speed_vector(origin,origin2,maxspeed,velocity2)
				}
			}
			else if(!enemy)
			{
				set_pev(ent,pev_sequence,SQ_IDLE)
				set_pev(ent,pev_gaitsequence,SQ_IDLE)
				set_pev(ent,pev_framerate,FR_IDLE * (maxspeed / 20.0))
				if(random_num(1,2500)==1686)
				{
					switch(random_num(1,5))
					{
						case 1: emit_sound(ent,CHAN_VOICE,"headcrab/hc_idle1.wav",VOL_NORM, ATTN_NORM,0,PITCH_NORM)
						case 2: emit_sound(ent,CHAN_VOICE,"headcrab/hc_idle2.wav",VOL_NORM, ATTN_NORM,0,PITCH_NORM)
						case 3: emit_sound(ent,CHAN_VOICE,"headcrab/hc_idle3.wav",VOL_NORM, ATTN_NORM,0,PITCH_NORM)
						case 4: emit_sound(ent,CHAN_VOICE,"headcrab/hc_idle4.wav",VOL_NORM, ATTN_NORM,0,PITCH_NORM)
						case 5: emit_sound(ent,CHAN_VOICE,"headcrab/hc_idle5.wav",VOL_NORM, ATTN_NORM,0,PITCH_NORM)
					}
				}
			}
			if(enemy && !(flags & FL_IN_JUMP))
			{
				static Float:angles[3]
				static Float:origin3[3]
				pev(enemy,pev_origin,origin3)

				new Float:hit[3]
				engfunc(EngFunc_TraceLine,origin,origin3,1,ent,0)
				get_tr2(0,TR_vecEndPos,hit)

				if(!task_exists(ent+5000))
				{
					if(hit[0]!=origin3[0] || hit[1]!=origin3[1] || hit[2]!=origin3[2])
					{
						set_task(5.0,"lose_enemy",ent+5000)
					}
				}
				else if(hit[0]==origin3[0] && hit[1]==origin3[1] && hit[2]==origin3[2])
				{
					remove_task(ent+5000)
				}

				pev(ent, pev_angles, angles)
				origin3[0] -= origin[0]
				origin3[1] -= origin[1]
				origin3[2] -= origin[2]

				new Float:v_length
				v_length = vector_length(origin3)

				static Float:aim_vector[3]
				aim_vector[0] = origin3[0] / v_length
				aim_vector[1] = origin3[1] / v_length
				aim_vector[2] = origin3[2] / v_length

				static Float:new_angles[3]
				vector_to_angle(aim_vector,new_angles)

				new_angles[0] *= -1

				if(new_angles[1]>180.0) new_angles[1] -= 360
				if(new_angles[1]<-180.0) new_angles[1] += 360
				if(new_angles[1]==180.0 || new_angles[1]==-180.0) new_angles[1]=-179.999999

				new_angles[1] += 180.0
				angles[1] += 180.0
				new Float:flabs = floatabs(new_angles[1]-angles[1])
				//new Float:flabs2
				//if(flabs>180.0) flabs2 = flabs - 180.0
				//else flabs2 = flabs
				new Float:flabs3 = floatabs(180-(new_angles[1]-angles[1]))
				if(!is_within_difference(flabs3,180.0,5.0))
				{
					new bool:opp
					if(flabs>180.0) opp=true
					if(flags & FL_IN_LEFT) flags -= FL_IN_LEFT
					if(flags & FL_IN_RIGHT) flags -= FL_IN_RIGHT
					if(!opp)
					{
						if(floatabs(180-(new_angles[1]-angles[1]))<180.0) flags += FL_IN_LEFT
						else flags += FL_IN_RIGHT
					}
					else
					{
						if(floatabs(180-(new_angles[1]-angles[1]))<180.0) flags += FL_IN_RIGHT
						else flags += FL_IN_LEFT
					}
				}
				else
				{
					if(flags & FL_IN_LEFT) flags -= FL_IN_LEFT
					if(flags & FL_IN_RIGHT) flags -= FL_IN_RIGHT
					flags += FL_IN_JUMP
					set_pev(ent,pev_sequence,SQ_IN_JUMP)
					set_pev(ent,pev_gaitsequence,SQ_IN_JUMP)
					set_pev(ent,pev_framerate,FR_IN_JUMP * (maxspeed / 20.0))
					set_task(0.3 * (20.0 / maxspeed),"perform_headjump",ent)
					set_pev(ent,pev_movetype,MOVETYPE_TOSS)
				}
			}
			else if(!enemy && !(flags & FL_FRIENDLY))
			{
				static players[32]
				players[0]=0
				new num
				static findflags[8]
				if(flags & FL_PSYCHIC) findflags = "ahj"
				else findflags = "ahj"

				get_players_distance(origin,players,num,findflags,ent)

				if(num)
				{
					new team
					for(new i=0;i<num;i++)
					{
						team = get_user_team(players[i])
						if((!(flags & FL_FRIENDLY_1) && team==1) || (!(flags & FL_FRIENDLY_2) && team==2) || (!(flags & FL_FRIENDLY_3) && team==3) || (!(flags & FL_FRIENDLY_4) && team==4))
						{
							switch(random_num(1,2))
							{
								case 1: emit_sound(ent,CHAN_VOICE,"headcrab/hc_alert1.wav",VOL_NORM, ATTN_NORM,0,PITCH_NORM)
								case 2: emit_sound(ent,CHAN_VOICE,"headcrab/hc_alert2.wav",VOL_NORM, ATTN_NORM,0,PITCH_NORM)
							}
							enemy = players[i]
							set_pev(ent,pev_enemy,players[i])
							if(flags & FL_IN_LEFT) flags -= FL_IN_LEFT
							if(flags & FL_IN_RIGHT) flags -= FL_IN_RIGHT
							set_task(20.0,"lose_enemy",ent+5000)
						}
					
					}
				}
			}
			if(flags & FL_IN_RIGHT || flags & FL_IN_LEFT)
			{
				velocity2[0] = 0.0
				velocity2[1] = 0.0
				static Float:angles[3]

				pev(ent,pev_angles,angles)

				if(flags & FL_IN_RIGHT)
				{
					angles[1] -= 0.5 * (maxspeed / 20.0)
					set_pev(ent,pev_sequence,SQ_TURNRIGHT)
					set_pev(ent,pev_gaitsequence,SQ_TURNRIGHT)
					set_pev(ent,pev_framerate,FR_TURNRIGHT * (maxspeed / 20.0))
				}
				else
				{
					angles[1] += 0.5 * (maxspeed / 20.0)
					set_pev(ent,pev_sequence,SQ_TURNLEFT)
					set_pev(ent,pev_gaitsequence,SQ_TURNLEFT)
					set_pev(ent,pev_framerate,FR_TURNLEFT * (maxspeed / 20.0))
				}

				if(angles[1]>=180.0) angles[1]=-179.0
				else if(angles[1]<=-180.0) angles[1]=179.0

				set_pev(ent,pev_angles,angles)
			}
			if(!(flags & FL_IN_JUMP))
			{
				engfunc(EngFunc_DropToFloor,ent)
				velocity2[2] = 20.0
				set_pev(ent,pev_velocity,velocity2)
				set_pev(ent,pev_movetype,MOVETYPE_FLY)
			}
			set_pev(ent,pev_enemy,enemy)
			set_pev(ent,pev_flags,flags)
			set_pev(ent,pev_max_health,health)
		}
		set_pev(ent,pev_nextthink,get_gametime()+THINK_DELAY)
	}
	return 1;
}

public perform_headjump(ent)
{
	if(pev_valid(ent))
	{
		new Float:origin[3], Float:origin2[3], Float:maxspeed, Float:velocity[3]
		pev(ent,pev_maxspeed,maxspeed)
		pev(ent,pev_origin,origin)
		new Float:blah[3]
		blah[0] = 40.0 * (maxspeed / 20.0)
		blah[1] = 0.0
		blah[2] = 40.0 * (20.0 / maxspeed)
		get_offset_origin(ent,blah,origin2)
		get_speed_vector(origin,origin2,maxspeed * 23,velocity)
		if(velocity[2]<200.0) velocity[2]=200.0
		set_pev(ent,pev_velocity,velocity)
		switch(random_num(1,3))
		{
			case 1: emit_sound(ent,CHAN_VOICE,"headcrab/hc_attack1.wav",VOL_NORM, ATTN_NORM,0,PITCH_NORM)
			case 2: emit_sound(ent,CHAN_VOICE,"headcrab/hc_attack2.wav",VOL_NORM, ATTN_NORM,0,PITCH_NORM)
			case 3: emit_sound(ent,CHAN_VOICE,"headcrab/hc_attack3.wav",VOL_NORM, ATTN_NORM,0,PITCH_NORM)
		}
		set_pev(ent,pev_sequence,SQ_IN_AIR)
		set_pev(ent,pev_gaitsequence,SQ_IN_AIR)
		set_pev(ent,pev_framerate,FR_IN_AIR)
		new param[1]
		param[0] = FL_IN_JUMP
		//set_task(1.0 * (20.0 / maxspeed),"remove_flag",ent,param,1)
		set_task(1.1,"remove_flag",ent,param,1)
	}
}

public headcrab_touch(headcrab,id)
{
	if(pev_valid(headcrab) && is_user_alive(id))
	{
		new classname[32]
		pev(headcrab,pev_classname,classname,31)
		new flags = pev(headcrab,pev_flags)
		new team = get_user_team(id)
		if(equali(classname,"GHW_headcrab") &&
		!(flags & FL_FRIENDLY) &&
		!(team==1 && (flags & FL_FRIENDLY_1)) &&
		!(team==2 && (flags & FL_FRIENDLY_2)) &&
		!(team==3 && (flags & FL_FRIENDLY_3)) &&
		!(team==4 && (flags & FL_FRIENDLY_4))
		)
		{
			new Float:damage
			pev(headcrab,pev_dmg,damage)

			if(damage)
			{
				new ent = engfunc(EngFunc_CreateNamedEntity,engfunc(EngFunc_AllocString,"trigger_hurt"))

				set_pev(ent,pev_classname,"Headcrab")

				set_pev(ent,pev_dmg,damage * 2.0)
				set_pev(ent,pev_dmgtime,0.0)
				set_pev(ent,pev_dmg_inflictor,DMG_BULLET)

				dllfunc(DLLFunc_Spawn,ent)
				dllfunc(DLLFunc_Touch,ent,id)
				engfunc(EngFunc_RemoveEntity,ent)

				set_pev(headcrab,pev_dmg,0.0)
				new param[1]
				param[0] = floatround(damage)
				set_task(2.0,"can_do_damage",headcrab,param,1)

				emit_sound(headcrab,CHAN_VOICE,"headcrab/hc_headbite.wav",VOL_NORM, ATTN_NORM,0,PITCH_NORM)
			}

			if(flags & FL_KAMIKAZE)
			{
				kill_headcrab(headcrab)
			}
		}
	}
}

public can_do_damage(param[1],ent)
{
	if(pev_valid(ent)) set_pev(ent,pev_dmg,float(param[0]))
}

public lose_enemy(ent)
{
	if(pev_valid(ent-5000)) set_pev(ent-5000,pev_enemy,0)
}

public remove_flag(flag[1],ent)
{
	if(pev_valid(ent))
	{
		new curflags = pev(ent,pev_flags)
		if(curflags & flag[0])
		{
			curflags -= flag[0]
			set_pev(ent,pev_flags,curflags)
		}
	}
}

public kill_headcrab(ent)
{
	if(pev_valid(ent))
	{
		new fwd_result
		ExecuteForward(forward_hc_died,fwd_result,ent)
		if(fwd_result!=PLUGIN_HANDLED)
		{
			new Float:origin[3]
			pev(ent,pev_origin,origin)
		
			new explosive
			if(pev(ent,pev_flags) & FL_EXPLODE) explosive=1
		
			engfunc(EngFunc_RemoveEntity,ent)
		
			headcrab_deatheffect(origin,explosive)
		}
	}
}

public headcrab_deatheffect(Float:origin[3],explosive)
{
	new ent = engfunc(EngFunc_CreateNamedEntity,engfunc(EngFunc_AllocString,"info_target"))
	set_pev(ent,pev_classname,"GHW_dead_headcrab")
	engfunc(EngFunc_SetModel,ent,"models/headcrab.mdl")

	set_pev(ent,pev_mins,Float:{-16.0,-16.0,0.0})
	set_pev(ent,pev_maxs,Float:{16.0,16.0,36.0})
	set_pev(ent,pev_size,Float:{-16.0,-16.0,0.0,16.0,16.0,36.0})
	engfunc(EngFunc_SetSize,ent,Float:{-16.0,-16.0,0.0},Float:{16.0,16.0,36.0})

	set_pev(ent,pev_solid,SOLID_BBOX)
	set_pev(ent,pev_movetype,MOVETYPE_FLY)

	set_pev(ent,pev_sequence,SQ_DIE)
	set_pev(ent,pev_gaitsequence,SQ_DIE)
	set_pev(ent,pev_framerate,FR_DIE)

	set_pev(ent,pev_origin,origin)

	emit_sound(ent,CHAN_VOICE,"headcrab/hc_die1.wav",VOL_NORM, ATTN_NORM,0,PITCH_NORM)

	new array[4]
	array[0] = explosive
	array[1] = floatround(origin[0])
	array[2] = floatround(origin[1])
	array[3] = floatround(origin[2])
	set_task(5.0,"headcrab_deatheffect2",ent,array,4)
}

public headcrab_deatheffect2(param[4],ent)
{
	if(pev_valid(ent))
	{
		if(param[0])
		{
			emit_sound(ent,CHAN_VOICE,"squeek/sqk_blast1.wav",VOL_NORM, ATTN_NORM,0,PITCH_NORM)
	
			message_begin(MSG_BROADCAST,SVC_TEMPENTITY)
			write_byte(TE_BLOODSPRITE)
			write_coord(param[1])
			write_coord(param[2])
			write_coord(param[3])
			write_short(blood2)
			write_short(blood)
			write_byte(BLOOD_COLOR)
			write_byte(10)
			message_end()
		}
		engfunc(EngFunc_RemoveEntity,ent)
	}
}
Glaster is offline
 



Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump


All times are GMT -4. The time now is 00:25.


Powered by vBulletin®
Copyright ©2000 - 2024, vBulletin Solutions, Inc.
Theme made by Freecode