/*
Для работы нового алгоритма AI необходимо указывать 
setactorvar[THISACTOR].enemy_ang при ai NO и setvarvar target_id PLAYERID, когда монстр увидел игрока
В тело монстра указывать 
setvar maxSpeed 100
setvar weight 1
setvar width 128 //Ширина монтра для огневых спрайтов от спрея
setvar height 8192 //высота монстра, определяется координата z для hitscan
	
state mainAI
 
Поставить hitag монстру, тогда он не будет проходить на территорию сектора с cstat 4096
Для мелких монстров нужно отключить слежение за целью по вертикали, для этого поставить setvar enemy_nohitscan_z 1

не использовать переменные invisible и  reflective!
*/


//state enemies_loadactor - sprites.con #33

define EFFECTIVE_DISTANCE 16384

define MOVETOTARGET 0
define SEARCHING 1
define EVASION 2
define BLOCK 3

define STAYPUT 0
define WALK 1
define ATTACK 2
define GETDAMAGE 3
define GETHEAVYDAMAGE 4
define BURNING 5
define VOODOO 6
define DYING 7
define DEAD  8
define USERAI 16384

include blcons/enemy_param.con

state facingstate

  	getactor[THISACTOR].x mx
	getactor[THISACTOR].y my
	getactor[PLAYERID].x x
	getactor[PLAYERID].y y
	getplayer[THISACTOR].kickback_pic perplayer
	ifvare perplayer 0
	{
		ifvarg akimboshotgunalt 0 { setvarvar perplayer akimboshotgunalt }
		ifvarg tommysweep 0 { setvarvar perplayer tommysweep } 
		ifvarg akimbotommysweep 0 { setvarvar perplayer akimbotommysweep } 
		ifvarg voodooalt 0 { setvarvar perplayer voodooalt }
		ifvarg tntalt 0 { setvarvar perplayer tntalt }
		ifvarg sprayalt 0 { setvarvar perplayer sprayalt }
		ifvarg akimboteslaalt 0 { setvarvar perplayer akimboteslaalt }
		ifvarg teslaalt 0 { setvarvar perplayer teslaalt }
		ifvarg voodoocount1 0 { setvarvar perplayer voodoocount1 }
		ifvarg voodoocount2 0 { setvarvar perplayer voodoocount2 }
		ifvarg voodoocount3 0 { setvarvar perplayer voodoocount3 }
		ifvarg voodoocount4 0 { setvarvar perplayer voodoocount4 }
		ifvarg voodoocount5 0 { setvarvar perplayer voodoocount5 }
		
	}
	subvarvar mx x
	subvarvar my y
	getangle mang mx my
	getactor[THISACTOR].ang ang
	getincangle mang mang ang
	
	
	getactor[THISACTOR].z z
	subvarvar z height
	setactor[THISACTOR].z z
	canseespr THISACTOR PLAYERID see
	addvarvar z height
	setactor[THISACTOR].z z
	ifvare see 0 ifcanseetarget setvar see 1
	
	ifvare see 1
	ifvare actorvar[PLAYERID].invisible 0 {
		ifvarg mang -384 ifvarl mang 384
		{
			ifpdistl 8192 ifvarg perplayer 0 setvar set 1 else 
			ifpdistl 1536 setvar set 1 else { setvar set 0 }
		} else setvar set 1
	} else setvar set 0
	
	/*
	ifvarvare HITSPRITE THISACTOR {
		ifvare actorvar[PLAYERID].invisible 0 {
			ifvarg mang -384 ifvarl mang 384 {
				ifpdistl 8192 ifvarg perplayer 0 setvar set 1
			} else setvar set 1
		}
	}
	*/
	
	ifvare active 1 ifvarg sprite[THISACTOR].extra 0 { setvar active 0 setvar set 1 }
ends

state zvelstate
	mulvarvar in2 3
	setvar damagez -32
	mulvarvar damagez htextra
	setvarvar in3 damagez
ends

state SATMethod
setvarvar in1 enemy_hitx
setvarvar in2 enemy_hity
subvarvar in1 enemy_hitx2
subvarvar in2 enemy_hity2

setvar penV -1
setvarvar len targetdist
getactorvar[target_id].width tmp
mulvar tmp 2
addvarvar tmp width

ifvarvarl len tmp {
	setvarvar nx in1
	setvarvar ny in2
	mulvar nx 100
	mulvar ny 100
	ifvarvarn len 0 {
		divvarvar nx len
		divvarvar ny len
	} else {
		setvar nx 0
		setvar ny 0
	}
	setvarvar tmp width
	mulvar tmp 2
	setvarvar penV tmp
	subvarvar penV len
	ifvarvarg penV 0 {
		setvarvar ejx penV
		mulvarvar ejx nx
		divvar ejx 100
		setvarvar ejy penV
		mulvarvar ejy ny
		divvar ejy 100
		getplayer[THISACTOR].posx x2
		getplayer[THISACTOR].posy y2
		subvarvar x2 ejx
		subvarvar y2 ejy
		setplayer[THISACTOR].posx x2
		setplayer[THISACTOR].posy y2
	}
}
ends

state enemyeffects
	ifvare VISION 1 ifvarg sprite[THISACTOR].extra 0 { setactor[THISACTOR].shade -127 }
	getactor[THISACTOR].htextra htextra
	getactor[THISACTOR].htang htang
	ifvarg htextra 0 
	{
		setvarvar in1 htang 
		setvarvar tmp htextra
		ifvarg addition_weight 0
			divvarvar tmp addition_weight
		ifinwater divvarvar tmp 4 else
			divvarvar tmp 8
		setvarvar in2 tmp 
		mulvarvar in2 24
		ifwasweapon RADIUSEXPLOSION 
		{ state	zvelstate } else
		ifwasweapon PR_NAPALM 
		{ state	zvelstate } else
		ifwasweapon ALTNAPALM
		{ state	zvelstate } else
		/*ifwasweapon ALTTESLA 
		{ state	zvelstate } else */
		setvarvar in3 0
		state physics_start
		state phys_reset_vel
		state phys_add_vel_ang
		state physics_end		
		
		setactorvar[THISACTOR].phys_air_damping_x 1110
		setactorvar[THISACTOR].phys_air_damping_y 1110
		setactorvar[THISACTOR].phys_air_damping_z 1050	
		setactorvar[THISACTOR].phys_wall_damping_x 2350 
		setactorvar[THISACTOR].phys_wall_damping_y 2350
		setactorvar[THISACTOR].phys_wall_damping_z 2050 		
			
		setactorvar[THISACTOR].phys_gravity_x 0 
		setactorvar[THISACTOR].phys_gravity_y 0
		randvar tmp 200
		addvar tmp 400
		setactorvar[THISACTOR].phys_gravity_z tmp
	}
	
	state physics_start
	state physics_interact_air
	
	ifinwater
		setvar phys_z_internal 0
	else {
		ifvare fly_enemy 1
			setvar phys_z_internal 0
	}
	
	state physics_move
	state physics_interact_walls
	state physics_end
		
ends

state hitscanstate 
	//вектор направления до цели
	
	setvarvar enemy_hittx target_x
	setvarvar enemy_hitty target_y
	subvarvar enemy_hittx enemy_x
	subvarvar enemy_hitty enemy_y
	
	//определение угла направления до цели
	getangle enemy_hita enemy_hittx enemy_hitty
	cos enemy_hitcos enemy_hita
	sin enemy_hitsin enemy_hita

	//уровень глаз объекта
	subvarvar enemy_z height
	/*
	
	//разница высот между объекта и целью //1024xy - 16384 z
	
	setvarvar tmp enemy_z
	subvarvar tmp target_z
	addvarvar tmp actorvar[target_id].height
	divvar tmp 16
	
	//определение вертикалного угла...приблизительно phoriz
	
	getangle enemy_zdist tmp targetdist
	subvar enemy_zdist 513
	mulvar enemy_zdist 896
	
	ifvare enemy_nohitscan_z 1 
		setvar enemy_zdist 0
	
	setvarvar deb_horiz enemy_zdist
	divvar deb_horiz -2048
	addvar deb_horiz 100
	*/
	
	setvarvar tmp enemy_z
	subvarvar tmp target_z
	
	ifvarvarl tmp 0 setvar enemy_scale -2048
			else setvar enemy_scale -1664

	addvarvar tmp actorvar[target_id].height
	//divvar tmp 10
	ldist enemy_zdist THISACTOR target_id  
	ifvarl enemy_zdist 1
		setvar enemy_zdist 1
	//mulvarvar tmp 100
	mulvarvar tmp 10
	divvarvar tmp enemy_zdist
	mulvarvar tmp enemy_scale
	setvarvar enemy_zdist tmp

	ifvare deb_menu 2 {
		setvarvar deb_horiz enemy_zdist
		divvarvar deb_horiz enemy_scale
		addvar deb_horiz 100
	}
	
	getactor[THISACTOR].sectnum enemy_hits
	
	ifvarn target_id -1 {
		getactor[THISACTOR].z z
		subvarvar z height
		setactor[THISACTOR].z z
		canseespr THISACTOR target_id see
		addvarvar z height
		setactor[THISACTOR].z z
		ifvare actorvar[target_id].invisible 1
			setvar see 0
	}

	ifvare see 1 {
		ifvarn enemy_hits -1
			hitscan enemy_x enemy_y enemy_z enemy_hits enemy_hitcos enemy_hitsin enemy_zdist RETURN enemy_wallid enemy_hittid enemy_hittx enemy_hitty enemy_hittz CLIPMASK1 //0x00010001h

	} else setvar enemy_hittid -1
	// определение цели на расстоянии до 6000 - 8000ед при вертикальном угле не более 200
	

ends

state start_coord
ifvarn target_id -1 {
dist targetdist THISACTOR target_id 
ifvarl targetdist EFFECTIVE_DISTANCE {

	// Определение начальных координат, координаты монстра
	getactor[THISACTOR].x enemy_x
	getactor[THISACTOR].y enemy_y
	getactor[THISACTOR].z enemy_z
	//координаты цели
	getactor[target_id].x target_x
	getactor[target_id].y target_y
	getactor[target_id].z target_z
	
	state hitscanstate 
	
	//определение поля видения врага
	getincangle anglefield enemy_hita enemy_ang
	
	// Определение конечных координат

	ifvare enemy_movtype SEARCHING {
		setvarvar target_hitx enemy_x
		addvar target_hitx 1024
		ifcount 55 { randvar randang 2048 resetcount }
		rotatepoint enemy_x enemy_y target_hitx enemy_y randang target_hitx target_hity
		setvar weight 3
		
		ifvarvare enemy_hittid target_id // Если цель в зоне видимости
			ifvarn enemy_invis 1 
				setvar enemy_movtype MOVETOTARGET
	}
	
	ifvare enemy_movtype MOVETOTARGET {
		setvarvar enemy_savetx target_x
		setvarvar enemy_savety target_y	
						
		setvarvar target_hitx enemy_hittx
		setvarvar target_hity enemy_hitty 
	}

	ifvare enemy_movtype EVASION { 
		setvarvar target_hitx evasion_x
		setvarvar target_hity evasion_y 
		addvar gotopoint 1
		addvar weight 2
		
		ifvarg gotopoint 15 { 
			setvar evasion_x -1
			setvar evasion_y -1
			
			setvarvar in1 enemy_x
			setvarvar in2 enemy_y
			subvarvar in1 startev_x 
			subvarvar in2 startev_y
			state vec2d_lenght
			ifvarl out1 64
				randvar enemy_ang 2048 //предотвращает застревание между спрайтами
			else {
				setvar startev_x -1
				setvar startev_y -1
			}
			setvar gotopoint 0 
		}
	}
	
	ifvare enemy_movtype BLOCK {
		setvarvar target_hitx block_x
		setvarvar target_hity block_y 
			
		
		ifvarl evasion_len 1536 
			setvar gotopoint 0 
		else { 
			addvar gotopoint 1
			ifvarg gotopoint 56 { 
				setvar block_x -1
				setvar block_y -1
				setvar gotopoint 0 
			}
		}
	}

	ifvare enemy_invis 1 { //Если цель невидимая (переменная из mainAI)
		ifvare gotopoint 0 
			setvar enemy_movtype SEARCHING 
	} else {
		ifvarvare enemy_hittid target_id { // Если цель в зоне видимости
			ifvare gotopoint 0 {
				setvar enemy_movtype MOVETOTARGET 
			}	
		} else { // Если цель ушла из поля видимости, монстр идет до места, где видел цель в последний раз
			ifvarn enemy_movtype BLOCK {
				ifvarg evasion_len 768 {
					ifvarn enemy_savetx -1 ifvarn enemy_savety -1 {
						setvarvar in1 enemy_x
						setvarvar in2 enemy_y
						subvarvar in1 enemy_savetx 
						subvarvar in2 enemy_savety 
						state vec2d_lenght
						ifvarl out1 768 {
							setvar enemy_savetx -1
							setvar enemy_savety -1
						}
						setvarvar evasion_x enemy_savetx
						setvarvar evasion_y enemy_savety
						setvar enemy_movtype EVASION
					}
				} else { 
					setvar enemy_movtype SEARCHING 
				}
			} else {
				ifvare gotopoint 0 {
					setvar enemy_savetx -1
					setvar enemy_savety -1
					setvar enemy_movtype SEARCHING 
				}
			}
		}
	}

	setvarvar phys_core_tmp1 enemyret
	andvar phys_core_tmp1 TOUCH_MASK
	ifvare phys_core_tmp1 TOUCH_WALL_FLAG {
		setvarvar phys_core_tmp1 enemyret
		andvar phys_core_tmp1 MAXWALLS_MASK
	
		// get wall vector
		getwall[phys_core_tmp1].x phys_core_tmp2
		getwall[phys_core_tmp1].y phys_core_tmp3
		
		ifvare wall[phys_core_tmp1].lotag 511 ifvarn enemy_type ATTACK
			ifvarvare enemy_wallid phys_core_tmp1 {
			setvar enemy_type ATTACK
			setvarvar change_ai enemy_type
		}
		
		
		ifcount 20 {
			getwall[phys_core_tmp1].nextwall wallid
			ifvarn wallid -1
			ifvarn wall[wallid].hitag 0  {
				getwall[phys_core_tmp1].nextsector tmp
				headspritesect spriteid tmp
				whilevarn spriteid -1 
				{
					ifvare sprite[spriteid].picnum TC_LOCKER ifvare sprite[spriteid].pal 0 {
						setactorvar[spriteid].enemy_opendr 1
					}
					nextspritesect spriteid spriteid
				}
			}
			resetcount
		}
		

		getwall[phys_core_tmp1].point2 phys_core_tmp1
		getwall[phys_core_tmp1].x phys_core_tmp4
		getwall[phys_core_tmp1].y phys_core_tmp5
		subvarvar phys_core_tmp4 phys_core_tmp2
		subvarvar phys_core_tmp5 phys_core_tmp3
		// ( phys_core_tmp4,phys_core_tmp5 ) - wall vector
		getangle phys_core_tmp2 phys_core_tmp4 phys_core_tmp5
		
		/*
		setvarvar phys_core_tmp3 enemy_ang
		shiftvarl phys_core_tmp2 1
		subvarvar phys_core_tmp2 phys_core_tmp3
		andvar phys_core_tmp2 2047
		
		setvarvar x2 enemy_x
		ifvarg sprite[THISACTOR].clipdist 30
			addvar x2 1024
		else addvar x2 512
		rotatepoint enemy_x enemy_y x2 enemy_y phys_core_tmp2 evasion_x evasion_y
		
		updatesectorz evasion_x evasion_y sprite[THISACTOR].z RETURN
		ifvare RETURN -1 { 
			setvarvar tmp enemy_ang
			addvar tmp 1024
			rotatepoint enemy_x enemy_y x2 enemy_y tmp evasion_x evasion_y
		}
		*/
		
		ifvare startev_x -1 ifvare startev_y -1 {
			setvarvar startev_x enemy_x
			setvarvar startev_y enemy_y
		}

		setvarvar ang phys_core_tmp2
		addvar ang 512
		setvarvar x2 enemy_x
		
		setvarvar tmp maxSpeed
		mulvar tmp 4
		ifvarg sprite[THISACTOR].clipdist 30 
			mulvar tmp 2
		addvarvar x2 tmp
		
		rotatepoint enemy_x enemy_y x2 enemy_y ang evasion_x evasion_y
		ifvarn enemy_movtype BLOCK setvar enemy_movtype EVASION	
	}
	
	ifvare phys_core_tmp1 TOUCH_SPRITE_FLAG {
		setvarvar phys_core_tmp1 enemyret
		andvar phys_core_tmp1 MAXWALLS_MASK
		
		ifvare actorvar[phys_core_tmp1].obj_statnum 15 ifvarand actorvar[phys_core_tmp1].obj_zvel 1 ifvarand sprite[phys_core_tmp1].cstat 16 {
			ifvarg anglefield -128 ifvarl anglefield 128 {
				setvar enemy_type ATTACK
				setvarvar change_ai enemy_type
			}
		}

		setvarvar evasion_x sprite[phys_core_tmp1].x
		setvarvar evasion_y sprite[phys_core_tmp1].y
		subvarvar evasion_x enemy_x
		subvarvar evasion_y enemy_y
		getangle mang evasion_x evasion_y
		getincangle mang mang enemy_ang //Угол между векторами до цели и направления
		setvarvar ang enemy_ang

		ifvarl mang 0 
			subvar ang 128 
		else 
			addvar ang 128
			
		ifvare startev_x -1 ifvare startev_y -1 {
			setvarvar startev_x enemy_x
			setvarvar startev_y enemy_y
		}
		
		setvarvar evasion_x enemy_x
		addvar evasion_x 1024
		rotatepoint enemy_x enemy_y evasion_x enemy_y ang evasion_x evasion_y
		setvar enemy_movtype EVASION
	}
  }
}
ends

state vectors_calc

	// Создание вектора направления до цели
	setvarvar vector_x enemy_x
	subvarvar vector_x target_hitx
	mulvar vector_x -1
	
	setvarvar vector_y enemy_y
	subvarvar vector_y target_hity
	mulvar vector_y -1
	
	setvarvar in1 vector_x
	setvarvar in2 vector_y
	state vec2d_lenght
	setvarvar evasion_len out1

	// Нормировка вектора до цели
	mulvarvar vector_x TRIG_MAX
	mulvarvar vector_y TRIG_MAX
	ifvarn out1 0 { 
		divvarvar vector_x out1 
		divvarvar vector_y out1 
	} else { setvar vector_x 0 setvar vector_y 0 }

	//Создание втрого вектора по направлению движения

	cos vector2_x enemy_ang
	sin vector2_y enemy_ang
	
ends


state seeker_calc

	// Третий единичный вектор - поправка на угол, как разница первого и второго

	setvarvar vector3_x vector_x
	setvarvar vector3_y vector_y
	subvarvar vector3_x vector2_x
	subvarvar vector3_y vector2_y //третий вектор

	setvarvar in1 vector3_x
	setvarvar in2 vector3_y
	state vec2d_lenght

	setvarvar vector_len out1 //длина 3го вектора, поправка на угол
	mulvarvar vector_len maxSpeed //скорость поворота за целью
	divvar vector_len TRIG_MAX

	getangle ang vector_x vector_y
	getangle mang vector2_x vector2_y
	getincangle mang mang ang //Угол между векторами до цели и направления
	divvarvar vector_len weight //поправка на массу тела при повороте

	ifvarg mang 0
		addvarvar enemy_ang vector_len
	else
		subvarvar enemy_ang vector_len
	setactor[THISACTOR].ang enemy_ang
	
ends

state fleer_calc
	// Третий единичный вектор - поправка на угол, как разница первого и второго

	setvarvar vector3_x vector_x
	setvarvar vector3_y vector_y
	mulvar vector3_x -1
	mulvar vector3_y -1
	subvarvar vector3_x vector2_x
	subvarvar vector3_y vector2_y //третий вектор

	setvarvar in1 vector3_x
	setvarvar in2 vector3_y
	state vec2d_lenght

	setvarvar vector_len out1 //длина 3го вектора, поправка на угол
	mulvarvar vector_len maxSpeed //скорость поворота за целью
	divvar vector_len TRIG_MAX

	getangle ang vector_x vector_y
	getangle mang vector2_x vector2_y
	getincangle mang mang ang //Угол между векторами до цели и направления
	divvarvar vector_len weight //поправка на массу тела при повороте

	ifvarg mang 0
		subvarvar enemy_ang vector_len
	else
		addvarvar enemy_ang vector_len
	setactor[THISACTOR].ang enemy_ang
ends

//тут идет движение врага к цели

state move_to_vector
getactor[THISACTOR].clipdist enemyclip
mulvarvar enemyclip 8

ifvare enemyret 0
{
	mulvarvar vector2_x maxSpeed
	mulvarvar vector2_y maxSpeed
	divvarvar vector2_x TRIG_MAX
	divvarvar vector2_y TRIG_MAX
} else { 
	ifvarand enemyret 16384 //touch sprite
	{
		mulvarvar vector2_x maxSpeed
		mulvarvar vector2_y maxSpeed
		divvarvar vector2_x TRIG_MAX
		divvarvar vector2_y TRIG_MAX	
	}
	else { setvar vector2_x 0 setvar vector2_y 0 addvar enemy_ang 361 }
}	

	getactor[THISACTOR].x x
	getactor[THISACTOR].y y
	getactor[THISACTOR].z z
	getflorzofslope enemy_hits x y mz
	subvarvar mz z
	ifvarl mz 0 { setvarvar zvel mz } else {
		ifinwater ifvare target_inwater 1 { 
			ifvare see 1 {
				getactor[THISACTOR].z enemy_z
				getactor[target_id].z target_z
				subvar target_z 4096
				subvarvar target_z enemy_z
				setvarvar zvel maxSpeed
				ifvarg target_z 0 { mulvar zvel 4 } else
					mulvar zvel -4
			} else setvar zvel 0
		} else setvar zvel 500
	}

	ifvarn fly_enemy 1
		movesprite THISACTOR 0 0 zvel CLIPMASK0 RETURN

ifvarvarg targetdist enemyclip {
	ifvarn enemy_movtype BLOCK
		movesprite THISACTOR vector2_x vector2_y 0 CLIPMASK0 enemyret //01010040h  //CLIPMASK1
	else ifvarl vector_len 5 
		movesprite THISACTOR vector2_x vector2_y 0 CLIPMASK0 enemyret //CLIPMASK1
} 
else { // Блокировка движения монстра, если уперся в спрайт (и блокирует игрока)
	/*
	ifvarn target_id -1 
		state SATMethod
	mulvarvar vector2_x -5
	mulvarvar vector2_y -5
	ifvare enemyret 0 movesprite THISACTOR vector2_x vector2_y 0 CLIPMASK0 enemyret
	*/
}

ifvarn target_id -1 {
	getactor[target_id].extra extra
	ifvarl extra 1 { 
		ifvarn sprite[THISACTOR].picnum 6290 //чтобы искали граждан
			setvarvar target_id PLAYERID
	}
}
ends

state shootblood
getactor[THISACTOR].htang blood_ang
ifvarg htextra 40
{
	randvar blood_rand 5
	getactor[THISACTOR].x blood_x
	getactor[THISACTOR].y blood_y
	getactor[THISACTOR].z blood_z
	subvarvar blood_z 8192
	randvar rand_x 512
	randvar rand_y 512
	randvar rand_z -4096
	randvar blood_xsize 14
	addvarvar blood_xsize 4
	ifrnd 128 mulvar rand_x -1 
	ifrnd 128 mulvar rand_y -1 
	addvarvar blood_x rand_x
	addvarvar blood_y rand_y
	addvarvar blood_z rand_z
	getactor[THISACTOR].sectnum blood_sect
	cos blood_cos blood_ang
	sin blood_sin blood_ang
	getplayer[THISACTOR].horiz phoriz
	subvar phoriz 100
	mulvar phoriz -2048
	ifvarn blood_sect -1 hitscan blood_x blood_y blood_z blood_sect blood_cos blood_sin phoriz RETURN blood_wall RETURN blood_x blood_y blood_z 1
	getactor[THISACTOR].x x
	getactor[THISACTOR].y y
	setvarvar blood_x2 blood_x
	setvarvar blood_y2 blood_y
	subvarvar blood_x2 x
	subvarvar blood_y2 y
	mulvarvar blood_x2 blood_x2
	mulvarvar blood_y2 blood_y2
	addvarvar blood_x2 blood_y2
	sqrt blood_x2 blood_dist 
	
	
	
	ifvarl blood_dist 2048
	ifvarg blood_wall -1
	{
		ifvarg wall[blood_wall].lotag 0 {
			setvar kill_blood 1
		}
		ifvarg wall[blood_wall].hitag 0 {
			setvar kill_blood 1
		}
		getwall[blood_wall].nextsector sectorid
		ifvarn sectorid -1
		{
			getsector[sectorid].lotag lotag
			ifvarn lotag 0 setvar kill_blood 1
			headspritesect spriteid sectorid
			whilevarn spriteid -1 
			{
				getactor[spriteid].picnum picnum
				switch picnum
				case ACTIVATOR
				case TC_LOCKER
				case SECTOREFFECTOR
					setvar kill_blood 1
				break
				endswitch
				nextspritesect spriteid spriteid
			}
		}
	ifvare kill_blood 0
	{	
		ifvare blood_rand 0 eqspawn BLOODSPLAT6 else eqspawn BLOODSPLAT5
		setactorvar[RETURN].wallblood 1
		getwall[blood_wall].x wallx
		getwall[blood_wall].y wally
		getwall[blood_wall].point2 blood_wall
		getwall[blood_wall].x wallx2
		getwall[blood_wall].y wally2
		subvarvar wallx2 wallx
		subvarvar wally2 wally
		getangle wallang wallx2 wally2
		addvar wallang 512
		setactor[RETURN].ang wallang
		setactor[RETURN].x blood_x
		setactor[RETURN].y blood_y
		setactor[RETURN].z blood_z
		setactor[RETURN].xrepeat blood_xsize
		divvar blood_xsize 4
		setactor[RETURN].yrepeat blood_xsize
	}
	}
}
ends

state enemyjibs_state
	setvar in1 2
	setvar in2 JIBS7
	state spawn_multiply
	setactorvar[RETURN].htangsaved htang
	setactorvar[RETURN].htextrasaved paextra
	ifwasweapon RADIUSEXPLOSION { setactorvar[RETURN].explosionvar 1 }

	setvar in1 20
	setvar in2 JIBS9
	state spawn_multiply
				
	setvar in1 2
	setvar in2 JIBS8
	state spawn_multiply
	setactorvar[RETURN].htangsaved htang
	setactorvar[RETURN].htextrasaved paextra
	ifwasweapon RADIUSEXPLOSION { setactorvar[RETURN].explosionvar 1 }
		
	setvar in1 2
	setvar in2 JIBS10
	state spawn_multiply
	setactorvar[RETURN].htangsaved htang
	setactorvar[RETURN].htextrasaved paextra
	ifwasweapon RADIUSEXPLOSION { setactorvar[RETURN].explosionvar 1 }
		
	setvar in1 2
	setvar in2 JIBS11
	state spawn_multiply
	setactorvar[RETURN].htangsaved htang
	setactorvar[RETURN].htextrasaved paextra
	ifwasweapon RADIUSEXPLOSION { setactorvar[RETURN].explosionvar 1 }
		
	setvar in1 2
	setvar in2 JIBS12
	state spawn_multiply
	setactorvar[RETURN].htangsaved htang
	setactorvar[RETURN].htextrasaved paextra
	ifwasweapon RADIUSEXPLOSION { setactorvar[RETURN].explosionvar 1 }
		
	ifrnd 64 { sound FLSHDOR1 } else ifrnd 64 { sound FLSHDOR2 }
	ifrnd 127 { sound FLSHSTP1 sound FLSHSTP2 }
	state bloodspraystate
	state bloodspraystate
ends

state mainAI

/*
espawn ACTOR2
setactor[RETURN].x enemy_hittx
setactor[RETURN].y enemy_hitty
setactor[RETURN].z enemy_hittz

espawn ACTOR2
setactor[RETURN].pal 1
setactor[RETURN].x block_x
setactor[RETURN].y block_y

espawn ACTOR2
setactor[RETURN].pal 2
setactor[RETURN].x evasion_x
setactor[RETURN].y evasion_y
*/

state enemyeffects

	getactor[THISACTOR].cstat tmp
	andvar tmp 1
	ifvarg sprite[THISACTOR].extra 0 ifvare tmp 1 {
		setvarvar cm_clipdist sprite[THISACTOR].clipdist
		shiftvarl cm_clipdist 4
		
		getactor[THISACTOR].z ztop
		subvarvar ztop height
		findnearspritevar APLAYER cm_clipdist spriteid
		ifvarn spriteid -1 ifvarvarl sprite[spriteid].z sprite[THISACTOR].z ifvarvarg sprite[spriteid].z ztop /*ifvarn sprite[THISACTOR].picnum GARGOYLE*/ {
			setvarvar in1 sprite[THISACTOR].x
			setvarvar in2 sprite[THISACTOR].y
			subvarvar in1 sprite[spriteid].x
			subvarvar in2 sprite[spriteid].y
			
			ldist len THISACTOR spriteid

			setvar penV -1
			setvarvar nx in1
			setvarvar ny in2
			mulvar nx 100
			mulvar ny 100
			ifvarvarn len 0 {
				divvarvar nx len
				divvarvar ny len
			} else {
				setvar nx 0
				setvar ny 0
			}
			setvarvar tmp width
			mulvar tmp 2
			setvarvar penV tmp
			subvarvar penV len
			ifvarvarg penV 0 {
				setvarvar ejx penV
				mulvarvar ejx nx
				divvar ejx 100
				setvarvar ejy penV
				mulvarvar ejy ny
				divvar ejy 100
				getplayer[THISACTOR].posx x2
				getplayer[THISACTOR].posy y2
				subvarvar x2 ejx
				subvarvar y2 ejy
				updatesector x2 y2 RETURN
							
				ifvarn RETURN -1 ifvare phitobj 0 {
					setplayer[THISACTOR].posx x2
					setplayer[THISACTOR].posy y2
				}
			}
		}
	}
	
ifvarg flamedamage 0 { 
	ifvare enemy_type STAYPUT {
		setvar enemy_type WALK
		setvarvar change_ai enemy_type
	}
	addvar COUNTER 1 state newfirestate 
} 
ifvare pfire 1 {
	ifvare enemy_type STAYPUT {
		setvar enemy_type GETDAMAGE
		setvar change_ai GETDAMAGE
	}
}
ifinwater setvar COUNTER 0
ifvarvare COUNTER flamedamage { setvar flamedamage 0 setvar COUNTER 0 }
	
ifvarn target_id -1 {
getactor[target_id].sectnum tmp
ifvarn tmp -1 ifvarl tmp 4096 {
	getsector[tmp].lotag lotag
	ifvare lotag 2 setvar target_inwater 1 
		else setvar target_inwater 0
	}
}
	
ifvarn enemy_type DEAD {
	getplayer[THISACTOR].i PLAYERID

	ifvarn target_id -1 {
	getactorvar[target_id].invisible enemy_invis
	getactorvar[target_id].reflective enemy_refl
	ifp pdead setvar enemy_invis 1
	ifvare cantseetarget 1 setvar enemy_invis 1
	state start_coord
	state vectors_calc
	}
	
	ifvare enemy_invis 1 {
		ifvare enemy_type ATTACK {
			setvar enemy_type WALK
			setvarvar change_ai enemy_type 
		}
	}

	ifhitweapon	{
		
		setvarvar enemy_htpic sprite[THISACTOR].htpicnum
		ifvare enemy_htpic ALTTESLA {
			setvar teslahitenable 1
			setvar change_ai -1
		}
		
		ifvarn sprite[THISACTOR].htpicnum STAFFALTPROJ {
			getactor[THISACTOR].htang ang
			addvar ang 1024
			setvarvar enemy_ang ang
		}
		getactor[THISACTOR].htowner spriteid
		ifvarg spriteid 0 { 
			getactor[THISACTOR].picnum picnum
			getactor[spriteid].picnum tmp
			ifvarvarn tmp picnum { 
			switch tmp
			case ZOMBIE
			case HERETIC
			case FISH
			case SPIDER
			case PHANTASM
			case HELLDOG
			case GILLBEAST
			case GARGOYLE
			case BUTCHER
			case FATRAT
			case BOSSSPIDER
			case APLAYER
				ifrnd 64
					setvarvar target_id spriteid 
			break 
			endswitch
			}
		} 
		state shootblood 
		state shootblood 
		state shootblood 
		ifvarg htextra 12
			state bloodspraystate
		else ifrnd 64 state bloodspraystate
		
		ifwasweapon STAFFALTPROJ {
			ifvarg sprite[THISACTOR].extra 0 {
				setvar enemy_type GETDAMAGE
				setvar change_ai GETDAMAGE
			} else setvar voodoohitenemy 1
		} else
		ifwasweapon PR_NAPALM { 
			ifvarg sprite[THISACTOR].extra 0 {
				setvar enemy_type GETDAMAGE
				setvarvar change_ai enemy_type 
			} else {
				setvar enemy_type GETHEAVYDAMAGE 
				setvarvar change_ai enemy_type 
			}
		} else
		ifwasweapon RADIUSEXPLOSION {
			ifvarg sprite[THISACTOR].extra 0 {
				setvar enemy_type GETDAMAGE
				setvarvar change_ai enemy_type 
			} else {
				setvar enemy_type GETHEAVYDAMAGE 
				setvarvar change_ai enemy_type 
			}	
		} else {
			ifvarg sprite[THISACTOR].extra 0 {
				ifvare sprite[THISACTOR].picnum ZOMBIE {
					ifvarg htextra 12 {
						ifvarn change_ai USERAI
						setvar enemy_type GETDAMAGE
					}
				} else ifvarn change_ai USERAI
					setvar enemy_type GETDAMAGE
			} else {
				ifvare change_ai USERAI { 
						ifvare zombie_lay 1 {
							setactor[THISACTOR].extra 1 //для падающего зомби, чтобы не умирал раньше времени
						} else {
							setvar enemy_type DYING
							setvar change_ai DYING
						}
				} else 
					setvar enemy_type DYING
					
			}
		}

		ifvarn change_ai USERAI
			setvarvar change_ai enemy_type
	}

	ifsquished 
	ifvarg sprite[THISACTOR].extra 0
	{
		setactor[THISACTOR].extra 0
		setvar enemy_type GETHEAVYDAMAGE 
		setvarvar change_ai enemy_type 
	}
	
	ifvarn fly_enemy 1
	ifvare sector[THISACTOR].lotag 1 {	
		movesprite THISACTOR 0 0 512 CLIPMASK0 RETURN
	}
	

	ifvarn change_ai USERAI {
	
		ifvare enemy_type STAYPUT ifvare change_ai WALK {
			setvar enemy_type WALK
			setvarvar change_ai enemy_type
		}
		
		ifvare enemy_type WALK {
			setvar teslahitenable 0
			
			ifvare target_id -1 
				setvarvar target_id PLAYERID
		
			state seeker_calc
			state move_to_vector
			
			setvarvar scan_x enemy_x
			setvarvar tmp maxSpeed
			mulvar tmp 6 
			addvarvar scan_x tmp //384
			rotatepoint enemy_x enemy_y scan_x enemy_y enemy_ang scan_x2 scan_y2
			updatesectorz scan_x2 scan_y2 enemy_z scan_return
			ifvarn scan_return -1 {
				getactor[THISACTOR].sectnum enemy_hits
				ifinwater 
					nullop 
				else
					ifvare fly_enemy 1
						nullop
				else ifvarn enemy_nohitscan_z 1 ifvarvarn scan_return enemy_hits {
					getsector[scan_return].floorz enemy_scanz
					subvarvar enemy_scanz sprite[THISACTOR].z
					ifvarg enemy_scanz 8192 ifvare sector[scan_return].floorslope 0 {
						ifvarn enemy_movtype BLOCK { 
							setvarvar ang enemy_ang
							addvar ang 1024
							setvarvar block_x enemy_x
							addvarvar block_x 1536
							rotatepoint enemy_x enemy_y block_x enemy_y ang block_x block_y
							setvar enemy_movtype BLOCK
						}
					}

					ifvarg sector[scan_return].hitag 39 
					ifvarl sector[scan_return].hitag 42 {
						ifvarn enemy_movtype BLOCK { 
							setvarvar ang enemy_ang
							addvar ang 1024
							setvarvar block_x enemy_x
							addvarvar block_x 1536
							rotatepoint enemy_x enemy_y block_x enemy_y ang block_x block_y
							setvar enemy_movtype BLOCK
						}
					}

					ifvare sector[scan_return].hitag 666 {
						ifvarn enemy_movtype BLOCK { 
							setvarvar ang enemy_ang
							addvar ang 1024
							setvarvar block_x enemy_x
							addvarvar block_x 1536
							rotatepoint enemy_x enemy_y block_x enemy_y ang block_x block_y
							setvar enemy_movtype BLOCK
						}
					}
					
				}
			}
			
			ifvarn enemy_invis 1 {
				randvar enemyroam 512
				ifvarn target_id -1 
					getactor[target_id].extra extra

				ifvarl targetdist 550 ifvarg extra 0 
				ifvarg anglefield -128 ifvarl anglefield 128 {
					ifvarvare enemy_hittid target_id {
						setvar enemy_type ATTACK
						setvarvar change_ai enemy_type
					}
				}
				setvar invis_count 0
			} else {
				setvar enemyroam -1
				addvar invis_count 1
				ifvarg invis_count 390 { 
					setvar enemy_type STAYPUT
					setvarvar change_ai enemy_type
					setvar invis_count 0				
				}
			}
		}
		
		ifvare enemy_type ATTACK {
			ifvare change_ai -1 {
				setvar enemy_type WALK
				setvarvar change_ai enemy_type
			}
		}
		
		ifvare enemy_type GETDAMAGE {
			setvar invis_count 0
			ifvare change_ai -1 {
				setvar enemy_type WALK
				setvarvar change_ai enemy_type
			}
		}
		
		ifvare enemy_type GETHEAVYDAMAGE {
			setvar invis_count 0
			addvar haha_enabled 1	
			ifvare change_ai -1 {
				setvar enemy_type WALK
				setvarvar change_ai enemy_type
			}
		}
		
		ifvare enemy_type DYING {
			ifvare change_ai -1 {
				setvar enemy_type DEAD
				setvarvar change_ai enemy_type
			}
		}
	}
	ifvarn enemy_type DYING 
	ifvarn enemy_type DEAD {
	
		ifinwater setvar enemy_falling 0 else 
		ifvare fly_enemy 1 setvar enemy_falling 0 else {
		iffloordistl 192 nullop else
			addvar enemy_falling 1 }
		
		ifvarg enemy_falling 15 iffloordistl 10 {
			ifvarn sector[enemy_hits].lotag 1 {
				setvar enemy_type DYING 
				setvarvar change_ai enemy_type
			}
			setvar enemy_falling 0	
		}
	
		ifvarn enemy_hits -1 {
			getactor[THISACTOR].extra extra
			getflorzofslope enemy_hits enemy_x enemy_y enemy_floordist
			subvarvar enemy_floordist sprite[THISACTOR].z
			ifvarg sector[enemy_hits].hitag 39 
			ifvarl sector[enemy_hits].hitag 42 {
				ifvarl enemy_floordist 257 {
					ifvarg extra 0 {
						addvar lavasp_count 1
						ifvarn sprite[THISACTOR].picnum HELLDOG
						ifvarn sprite[THISACTOR].picnum CERBERUS {
							subvar extra 1
							setactor[THISACTOR].extra extra
						}
						ifvarg lavasp_count 8 { spawn LAVASPARK setvar lavasp_count 0 }
					} else ifvarn sprite[THISACTOR].picnum HELLDOG
					ifvarn sprite[THISACTOR].picnum CERBERUS 
						setvar burningguyactive 1
				}		
			} else ifvare sector[enemy_hits].hitag 666 {
				ifvarl enemy_floordist 257 {
					ifvarg extra 0 {
						addvar lavasp_count 1
						subvar extra 33
						setactor[THISACTOR].extra extra
					} else {
						setvar enemy_type DYING 
						setvarvar change_ai enemy_type
					}
				}
			}
		}
	}
			
	ifvarn enemy_type BURNING
	ifvare burningguyactive 1 { 
		setvar enemy_type BURNING 
		setvarvar change_ai enemy_type
		setvar burningguyactive 0
	}
	
	ifvare voodootouchenemy 1 {
		setvar enemy_type GETDAMAGE
		setvarvar change_ai enemy_type 
		state shootblood 
		state shootblood 
		state shootblood 
		state bloodspraystate
		setvar voodootouchenemy 0
	}
	
	ifvare voodoohitenemy 1 {
		setvar enemy_type VOODOO
		setvarvar change_ai enemy_type
		setvar voodoohitenemy 0
	}
	
	ifvarn enemy_type DYING 
	ifvarn enemy_type DEAD 
	ifvarn enemy_type GETHEAVYDAMAGE 
	ifvarl sprite[THISACTOR].extra 0
	{
		setactor[THISACTOR].extra 0
		setvar enemy_type DYING 
		setvarvar change_ai enemy_type 
	}
} else {
	
	ifvare change_ai DEAD {
		ifvarn sprite[THISACTOR].picnum CIVILIAN 
		ifvarn sprite[THISACTOR].picnum FATRAT 
			addkills 1
			
		setactor[THISACTOR].extra -1
		state rx_cansetactive
		setvar enemy_tesla 0
		state enemykill_trigger
		setvar change_ai -1
	}
}

ends

include blcons/enemies/bat.con
include blcons/enemies/boneell.con
include blcons/enemies/burningguy.con
include blcons/enemies/civil.con
include blcons/enemies/cultist.con
include blcons/enemies/evilhand.con
include blcons/enemies/fatrat.con
include blcons/enemies/fatzombie.con
include blcons/enemies/gargoyle.con
include blcons/enemies/gillbeast.con
include blcons/enemies/hellhound.con
include blcons/enemies/spider.con
include blcons/enemies/phantasm.con
include blcons/enemies/zombie.con
include blcons/enemies/good_doggy.con
include blcons/enemies/tchernobog.con
include blcons/enemies/pod.con
include blcons/enemies/tentacle.con
include blcons/enemies/beast.con