
/*
	ChebMaster's note:
	I strongly encourage re-using my code in other mods
	-- but, PRETTY PLEASE, invent your own prefix and search-and-replace "FBD_"
	   with that prefix of yours everywhere in the borrowed code.
	Because when someone *else* goes a step further building something
		even more awesome by cros-breeeding the mods they'd have a *colossal pain*
		if identifiers in those mods are the same.
	I encountered this problem when trying to run Franken Brutal Doom Monsters-only	
		on top of Project Brutality. It went pear-shaped because PB copies *tons*
		of BD code verbatim, with class names staying *the same* - and GZDoom 
		fucks class inheritance up *hard* when it tries resolving two PK3s
		that declare identical class names.
*/

#include MARINES_deth.txt


//***Che this class encapsulates the synthetic state machine
// common for both the evil marines and the NPC marines. 


// The ancestors have to define the following states:
// Triumph - after fatality on an enemy they killed in melee. Evil marines may laugh, NPCs may say a witty one-liner like "Eat shit and die, motherfucker".
// OnBeingUsed - Active or Inactive had been called. NPCs switch between following and staying put, evil marines ignore.
// OnDeath - the final death state. *must* only use "----" A not to break animation and MUST end in a -1 frame. Giving thhe killer soul ammo and unsubscribing NPCs from the party go here.


// The Idle and See states *must* maintain user_wp_cooldown ticking it down appropriate amount of tics:
//			TNT1 A 0 A_JumpIf(user_wp_cooldown <= 0, 2)
//			TNT1 A 0 A_SetUserVar("user_wp_cooldown", user_wp_cooldown - <tics>)


// NOTE: I use A_LookEx(user_head_type ? 0 : LOF_NOSOUNDCHECK | LOF_NOSEESOUND, 0,0,0,0, "SeeEnemy")
//  because NPCs must be utterly deaf to avoid Leroying into the thicket
//  (the +AMBUSH flag doesnt cut it!)
//  The universal code tells NPCs from evil marines by not having a headbox type set!

//  0.005493164 = 360 / 65536, ACS to DECORATE angle
//	182.0444 = 65536 / 360, DECORATE to ACS angle

ACTOR Marine_AbstractSynth: Marine_AbstractDeath  // both Marine_Base and EvilMarine_Base inherit from this
{
	
	Game Doom
	
	MONSTER
	-FRIENDLY	
	
	Radius 14 //***Che NOTE: NPC's radius is 12 (see the descendant class), I keep it for backward compatibility withh BD21 !
	Height 56
	Speed 5
	FastSpeed 4
	MaxStepHeight 32
	MaxDropoffHeight 64
	
	PainChance 200
	PainChance "Argent", 255
	DamageFactor "Argent", 1.0 // a healing/enraging buff inflicted by ghost souls summoned by super archviles
	DamageFactor "FireInTheHole", 1.0 // AOE inflicted by grenades that fall to the ground
	PainChance "FireInTheHole", 255
	DamageFactor "HurrDurrMeHazGrenaed", 1.0 // AOE inflicted by imps who chatch a grenade
	PainChance "HurrDurrMeHazGrenaed", 255
	DamageFactor "Use", 0.0 //1.0 // inflicted by BD player pressing Use (implemented through weapons)
	PainChance "Use", 0 //255	
	PainChance "Ice", 20
	
	// subsscribed to rocket dodging
	PainChance "Avoid", 255
	DamageFactor "Avoid", 1.0
	
	
	+FLOORCLIP
	+QUICKTORETALIATE
	+DONTHURTSPECIES
	+MTHRUSPECIES
	+MISSILEMORE	
	
	+NODROPOFF // can *only* go over the edge if kicked. Too much usage of A_Recoil otherwise.

	// Script error, "brutalv21.5franken.pk3:marines_syn.txt" line 54:
	// "AVOIDHAZARDS" is an unknown flag
	//+AVOIDHAZARDS // The monster will actively try to avoid being harmed by crushing ceilings. Note: This flag ONLY works for crushing ceilings ! It will not make the actor react to other level hazards.

	
	var int user_aggro_at_head; // required for the ACS script "FBD_TryReAggroAtHead"
	
	var int user_player_num; // contains PlayerNumber() + 1, to make zero mean ownerless instead of player 0
	var int user_npc_type;
	
	var int user_x;
	var int user_y;
	var int user_z;
	var int user_angle;
	var int user_pathfind_fail;
	
/*	
	//OBSOLETED
	// For getting out of player's line of fire. Maintained by the ACS script MoveNPCClearPlayersLOF
	// the script marks a cylindrical volume in front of the player, we simply backpedal 
	// away from our *target* if we are inside as if we were too close to our target.
	// Thus NPCs fighting the same monster as the player would naturally clump behind the player.
	var int user_avoid_x;
	var int user_avoid_y;
	var int user_avoid_z;
	var int user_avoid_r; //zero means dont bother
*/	
	
	var int user_in_air; 
	var int user_has_los; // used by the weapon phase, updated by the movement phase
	var int user_wp_cooldown; // remaining cooldown tics 
	var int user_notarget_cooldown; 
	var int user_strafe; // strafing speed x1 (absolute value, would match actual speed to this randomly)
	var int user_backpedal; // x1, may be negative for bumrushing or being too far
	// moved this declaration to EvilMarinePlasma
	var int user_shots; // shots remaining in sequence
	var int user_shot_cooldown; // between shots in a burst
	//var int user_ccp_cooldown; // circle strafing probes cooldown
	var int user_charge;  // weapon charge (for snipers: their sniping delay)
	
	var int user_anim_frame_time;
	var int user_anim_frame; 
	
	// controlling variables, are set in the weapon switching state:
	var int user_ambush_chance; // when finishes charging and finds there is no LOS. 
		// Is checked at blindfire attempt for the first shot. Not applicable to bfg.
	var int user_ambush_duration; // tics without LOS and not firing before going back to See
	var int user_burst_length;
	var int user_fire_period; // cooldown before the next shot in the burst
	var int user_weapon_cooldown_time;  // in effect after all shots were fired, can't fire again NOR switch weapon until this many tics pass
	var int user_charge_time; // set if weapons requires charging. 
	
	// Ignored while in the air *unless* user_stand_still is set
	// Angle adjustment is disabled while charging (bfg9000, minigun).
	// The rocket launcher also has a very small charging time, to lessen aiming into walls
	var int user_stand_still; // Stop moving when charging -- also disables shooting in air. For BFG.
	var int user_melee_range;
	var int user_too_close_range; // if closer and facing the target, will switch to the synth attack state
		// regardless of target's visibility and begin backpedaling/circle-strafing
	var int user_forgetfulness; // full chase cycles of no LOS after which clears target. Only NPCs set this. Zero means never.	
	//var int user_maradeur; // maradeur tier, 1..3. // moved to MARINES_fat.txt
	
	var int user_enemy_memory; // used to forget target
	
	var int user_muzzle_z; // controls the firing point
	
	var int user_guarding; // NPC guard position
	var int user_guard_x;
	var int user_guard_y;
	
	//var int user_head_tid; // moved to MARINES_fat.txt
	
	// moved to MARINES_fat.txt
	//var int user_head_type; // 6 - evil marine headbox, or 0 for NPCs
		//***Che: this is IMPORTANT, the algos use this to apply appropiate behavior
	
	var int user_sleeping;
	var int user_item_no;
	var int user_serverside_sfchk;
	
	// *actual* velocities calculated from delta x/y between tics 
	//   (momx/momy cannot be relied on to check if actor is stuck 
	//    trying to push through a wall via ThingThrust)
	var int user_rightward_vel; // lateral (rightward) velocity *100
	var int user_forward_vel;	// dilatational (forward) *actual* velocity *100

	var int user_head_tic; // descendants may use this to decrease headbox adjust frequency
	var int user_sfx_tic; // used by various weapon animations
	
	var int user_awakened; // had a target at least once. 
		// Without this, Idle jumps to Stand instead of wandering.
		// Used to invoke WeaponSwitch after Spawn
	
	var int user_weapon; // set this before jumping to WeaponSwitch 
		// to switch to a weapon other than default (e.g. melee)
		// The caller is responsible for making sure the weapon is not in the process of charging or firing.
		
		// 1 - fist // weak by design
		// 2 - berserk (also fist) -- they inflict *identical* damage, only differing in attack cooldown!
		// 3 - chainsaw // doomed index = +14 = weak chainsaw
		// 4 - rifle // doomed index +0 = weak rifle
		// 5 - shotgun // doomed index = +15 = weak shotgun
		// 6 - ssg
		// 7 - minigun // weak by design
		// 8 - rocket launcher
		// 9 - plasma // doomed index = +16 = weak plasma
		// 10 - railgun
		// 11 - bfg 9k
		// 12 - bfg 10k, not supported by NPCs
		// 13 - unmaker, not supported by NPCs
		// 14 - dragonslayer, maradeur only
		// 15 - hellhound summoning, maradeur only
		// 16 - mg-42, maradeur only
		// 17 - dragonslayer, maradeur only
		// 18 - axe // doomed index +17 = weak axe
	var int user_default_weapon; // used if user_weapon is zero. 
		// All descendants except the Maradeur rely on this exclusively
		//  to swap between melee and ranged!
	var int user_melee_weapon;	// may be 1, 2, 3, or 4 (since rifle marines hit with the stock of their gun instead of punching) 
	var int user_maradeur_weapon; // switched from the threat sense phase, depending on opponent + fuzzy logic
	
	// var int	user_old_x;
	//var int	user_old_y;
	var int	user_old_z; // used in dodge-rolling
	
	var int	user_wander; // countdown for wandering in the idle state
	
	var int user_probed_angle; // to discard probes cast in radically different directions
	// -- yet another reason they kept jumping like rabbits on steroids in the original BD. 
	// He turns to walk away, casts a probe -- it signals he has to jump,
	// makes a 180-degree turn towards a wall, the probing result arrives,
	// he jumps while facing a solid wall.

	var int user_roll_check; // used in dodge-roll wall checking	
	
	var int user_jump_power; // spawn sets this to 50, then calls an ACS script that reduces it to 37 for EDAY mars maps
	// to be passed to thrust thing z in Jump
	
	var int user_thr_acc; // current threat assessment, 0 to 256
	var int user_thr_cooldown; // to make it run every 6 tics, not every tic (every 3 tics for the maradeur)
	
	var int user_thr_mul; // target's danger level, 1 and up
	
	var int user_thr_hrr; // target's Horrible Rape Radius, in parallel to user_too_close_range
	var int user_thr_chaaarge; // boolean, rush the target to close in quickly (say, we have chainsaw while he has rocket launcher)
	
	var int user_ddgrll_cldwn; // dodge roll in reaction to being 
		// in targets aim on cooldown -- in chase loops (2 tics)
	var int user_ddgrll_chance; // chance to dodge-roll on pain. 0 = always (maradeur). Default 192. Negative values *disable*, even for Maradeur
	
	var int user_prev_x; // unfortunately, momx & momy *cannot* be relied upon, 
		// these do not zero out on collision and cannot represent actual speed
	var int user_prev_y;
	var int user_dx;
	var int user_dy;
	
	var int user_ambush; // boolean
	//var int user_see_after_wp_sw; // moved to MARINES_fat.txt
	
	var int user_summon_cooldown; // in tics, maradeur's hellhound summoning

	// moved to MARINES_fat.txt
	//var int user_syn_mode;	// 1 normal missile 2 backpedaling, 3 npc clearing player line of fire
	
	var int user_strafing_angle; // to use A_Wander in a sideways direction for strafing
	var int user_swander_cd; // to regulate A_Wander-based strafing, this slows it down to once in N tics
	var int user_stuck_det; // accumulates while not movilg while trying to. Until it decays back to zero, use A_Wander based strafing.
	var int user_move_wander; // only 0 or 1 allowed, otherwise multiplayer sync scripts fail!
		// movement method: using A_Wander to move, otherwise ThrustThing	
	var int user_loiter_count; // to timeout syn modes 2. 3 and 4 after 90 tics.
	
	var int user_nag_period;
	var int user_nag_cooldown; // after nagging, will set it to Random(user_nag_period / 2, user_nag_period)
	
	var int user_prev_wpn; // used by weapobn switching to avoid making a sound when switching to the same weapon
	
	var int user_thr_min; // floor for user_thr_acc
	
	var int user_noplayercansee; // accumulator of NPC being out of sight of all players. 
		// When reaches 350 (10 seconds) would teleport behind his party leader	
		
	var int user_npc_sas; // standing animation set
	var int user_npc_mode; // general mode
		// 0 - standing
		// 1 - follow player or guard position
		// 2 - chasing the enemy, has LOS
		// 3 - moving towards the enemy's last known position
		// 4 - standing near the player
		// 5 - following a patrol point
	var int user_npc_tgt_x; // coordinates where last seen target
	var int user_npc_tgt_y;
	var int user_npc_tgt_valid;	

	var int user_just_dodge_rolled;
	var int user_speed_limit;
	
	var int user_dist_to_player; // NPCs only, filled by ACS scripts	
	var int user_dang_to_player; // -- " --, delta angle
	
	var int user_aggro_cooldown; // tics. Until this runs out, will use A_Wander 
		//   instead of A_Chase for movement (only applicable to the synthetic See state)
		// The key reason for this is that the actor stops acquiring targets, just ignores any hostiles. 
		// Designed for NPCs who have their custom steering.	
		
	// used by the bunch of probes that adjust blindfire direction *and* finely adjust firing angle to avoid corners
	var int user_best_d;
	var int user_best_a;
	var int user_best_p;  // is considered invalid if user_best_d is zero - e.g. use autoaimed pitch instead
	var int user_best_cd; // to fire every 4 tics while charging the weapon, continuing adjusting
	
	var int user_marad_wpsw_cdn; // maradeur's weapon switching cooldown (2 seconds after the last switch)
	
	var int user_onspawn; // used by NPCs to suppress their random turning algo until leave spawn
	
	States
	{
/*		
		Pain.Use:
			"----" A 0 HealThing(1)
		Active: // from SwitchableDecoration, this is what lets NPCs react to pressing Use on them
		Inactive:
			"----" A 1 A_JumpIf(true, "OnBeingUsed")
			Wait
*/			
		OnBeingUsed:
			"----" A 1
			Goto See
			
		Jump:
			"----" A 0 A_TakeInventory("evmarinecanjump", 1)
			
			// Encountered  a curious bug: they kept double-jumping mid-air 
			// until they reached stratosphere. Then splattered on landing.
			"----" A 0 A_JumpIf(user_syn_mode && (user_in_air || z - floorz > 32), "SynthContinue")
			
			Goto SynthJump // takes care of jumping and landing -- in parallel to shooting. 
				// Can start shooting if acquires target LOS while in jump
				
		Pain.Ice:
			"----" A 10 A_Pain
		Pain:
		Pain.Argent:
			"----" A 0
			"----" A 0 A_SetUserVar("user_aggro_cooldown", 0)
			"----" A 0 A_JumpIfInventory("IsDown", 1, "PainIsDown") // see ancestor class
			
			"----" A 0 A_JumpIf(user_ddgrll_chance < 0 || user_ddgrll_cldwn > 0, "PainActually")
			
			// if maradeur, ignore the dodge roll cooldown and roll always!
			"----" A 0 A_JumpIf(user_maradeur && !(user_charge && user_stand_still), "PainDodgeRoll") //"DodgeRoll")
			
			"----" A 0 A_Jump(user_ddgrll_chance ? user_ddgrll_chance : 256, "PainDodgeRoll")
			Goto PainActually	
		PainActually:
			"----" A 0 A_JumpIf(user_maradeur, "MaradeurPainContinue")
			"----" A 0 A_JumpIf(user_weapon == 3, "Pain_Chainsaw")
			"----" A 0 A_JumpIf(user_weapon == 4, "Pain_Rifle")
			"----" A 0 A_JumpIf(user_weapon == 5, "Pain_Shotgun")
			"----" A 0 A_JumpIf(user_weapon == 6, "Pain_SSG")
			"----" A 0 A_JumpIf(user_weapon == 7, "Pain_Minugun")
			"----" A 0 A_JumpIf(user_weapon == 8, "Pain_RL")
			"----" A 0 A_JumpIf(user_weapon == 9, "Pain_Plasma")
			"----" A 0 A_JumpIf(user_weapon == 10, "Pain_Railgun")
			"----" A 0 A_JumpIf(user_weapon == 11, "Pain_BFG")
			"----" A 0 A_JumpIf(user_weapon == 12, "Pain_10K")
			"----" A 0 A_JumpIf(user_weapon == 13, "Pain_Unmaker")
			"----" A 0 A_JumpIf(user_weapon == 16, "Pain_MG42")
			"----" A 1 A_JumpIf(true, "Pain_Fists")
			Wait
				
		PainContinue: // weapon-specific pain animations (see descendant classes) return here
			"----" A 3
			"----" A 0 A_JumpIf(user_syn_mode != 1 && user_in_air || z - floorz > 32, "SynthContinue")
			Goto ShuffleFromPain
			
		MaradeurPainContinue: 
			"----" A 0 A_JumpIf(user_syn_mode != 1 && user_in_air || z - floorz > 32, "SynthContinue")
			Goto ShuffleFromPain	
			
		PainDodgeRoll:
			"----" A 0 A_Pain
			Goto DodgeRoll
		
		Pain.Avoid:
		Pain.RailAvoid: // only works on those subscribed - e.g. the high tir maradeur
		Pain.FireInTheHole:
		Pain.HurrDurrMeHazGrenaed:
		
			"----" A 0
			"----" A 0 A_SetUserVar("user_aggro_cooldown", 0)
			"----" A 0 HealThing(1)
			"----" A 0 A_SetUserVar("user_thr_acc", user_thr_acc < 155 ? user_thr_acc + 100 : 255) // threat assessment increase
			"----" A 0 A_JumpIfInventory("IsDown", 1, "PainIsDown")
			
			// Maradeur dodge-rolls mid-air, the motherfrakker.
			"----" A 0 A_JumpIf(user_maradeur && !(user_charge && user_stand_still), "DodgeRoll")
			
			// regular evil marines: just circle-strafe really fast. Do NOT interrupt bfg charging.
			"----" A 0 A_JumpIf(user_syn_mode == 1 && (user_charge && user_stand_still), "ShuffleFromPain")
			
			"----" A 0 A_Jump(user_ddgrll_chance < 0, "ShuffleFromPain")
			
			"----" A 0 A_Jump(user_ddgrll_chance ? user_ddgrll_chance : 256, "DodgeRoll")
			"----" A 1 A_Jump(256, "Jump")
			Wait

		Pain.Kick:
		Pain.Extremepunches:
		Pain.BlackHole: // ancient arachnotron
			"----" A 0
			"----" A 0 A_JumpIfInventory("IsDown", 1, "PainIsDown")
			"----" A 0 A_ChangeFlag("NODROPOFF", 0) // the *only* case he could be thrown off a cliff!			
			"----" A 0 A_Pain
			"----" A 0 A_SetUserVar("user_charge", 0)
			"----" A 0 A_SetUserVar("user_shots", 0)
			"----" A 0 A_SetUserVar("user_ambush", 0)
			"----" A 0 A_SetUserVar("user_shot_cooldown", 0)
			"----" A 0 A_JumpIf(!user_head_tid, 2)
			"----" A 0 ACS_NamedExecuteWithResult("DeleteHeadboxMkII")
			"----" A 0 A_FaceTarget
			"----" A 0 A_Recoil(5)
			"----" A 0 ThrustThingZ(0, 30, 0, 1)
			"----" A 0 A_GiveInventory("IsDown", 1)
			PNKI AABC 4
			PNKI D 30
			"----" A 0 A_ChangeFlag("NODROPOFF", 1)
			"----" A 0 A_TakeInventory("IsDown", 1)
			PNKI CDA 4
			Goto See
			
		Pain.Slide: // player backslide
			"----" A 0 A_Pain
			"----" A 0 A_SetUserVar("user_charge", 0)
			"----" A 0 A_SetUserVar("user_shots", 0)
			"----" A 0 A_SetUserVar("user_ambush", 0)
			"----" A 0 A_SetUserVar("user_shot_cooldown", 0)
			"----" A 0 A_JumpIf(!user_head_tid, 2)
			"----" A 0 ACS_NamedExecuteWithResult("DeleteHeadboxMkII")	
			"----" A 0 ThrustThingZ(0,50,0,1)			
			PNKI A 1 A_FaceTarget
			PNKI A 3 A_Recoil (-6)
			PNKI B 4
			PROL ABCDE 3
			PROL ABCDEABCDEABCDEABCDE 5 A_CheckFloor("MissileOnLanding") //"Missile")
			Goto See
			
		MissileOnLanding:
			"----" A 0 A_JumpIfTargetInLOS("Missile", 0, JLOSF_DEADNOJUMP)
			Goto See
			
		PainIsDown:
			"----" A 0 A_Pain
			PNKI C 4
			PNKI D 30
			"----" A 0 A_TakeInventory("IsDown", 1)
			PNKI CBA 4
			"----" A 0 A_ChangeFlag("NODROPOFF", 1)
			Goto See
			
		ForgetTarget:
			"----" A 0 A_ClearTarget
			"----" A 0 A_ChangeFlag("FRIENDLY", 0) // to aggro at a nearest player to re-target him
			"----" A 0 A_SetUserVar("user_enemy_memory", 0)
			Goto See

		SeeEnemy: // overrideable by the NPC class
			"----" A 0 
			Goto See			

		FollowPatrolPoint:
			"----" A 0 A_SetUserVar("user_syn_mode", 0)
			"----" A 0 A_SetUserVar("user_awakened", 1)
			Goto ChaseLoop
			
		See:
		SeeProper: // to allow overriding the see state
//"----" A 0 ACS_NAMedExecuteWithResult("FBD_DebugNPCTarget", 0)				
		
			// The See state is another quasi-synthetic state!
			"----" A 0
			"----" A 0 A_JumpIf(!user_syn_mode, 3)
			"----" A 0 A_SetUserVar("user_syn_mode", 0)
			"----" A 0 ACS_NamedExecuteAlways("SkulltagTransmitSynStateToClient") // the Zandronum game engine does never sync user variables nor monsters' inventories
			
			"----" A 0 A_JumpIf(user_awakened, 2)
			"----" A 0 A_SetUserVar("user_awakened", 1)
			"----" A 0 A_ChangeFlag("NODROPOFF", 1)
			
			// just in case some weird shit happens
			"----" A 0 A_CheckFlag("SHOOTABLE", 3, AAPTR_DEFAULT) // do not set if already shootable
			"----" A 0 A_ChangeFlag("SHOOTABLE", 1)
			"----" A 0 A_ChangeFlag("INVULNERABLE", 0)
/*			
			// slaughtermap manage - warming the headbox up
			"----" A 0 A_JumpIf(!user_head_type, 5) // n/a, NPCs do not have headboxes.
			"----" A 0 A_JumpIf(!user_sleeping, 4) // forgo the expensive sight check if already awake
			"----" A 0 A_JumpIfInTargetInventory("IsPlayer", 1, 2) // bypass the sight check 
			"----" A 0 A_CheckSight(2) // out of sight of any player, AND attacking another monster, keep slumbering
			"----" A 0 A_SetUserVar("user_sleeping", 0)				
*/			
			"----" A 0 A_JumpIf(!user_head_type, 2) // skip this for NPCs
			"----" A 0 A_JumpIfInTargetInventory("PlayerIsDead", 1, "Triumph")
			
			"----" A 0 A_JumpIf(user_guarding, "StandLoop") // defined in MARINES_npcs.txt
			"----" A 0 A_JumpIf(!user_head_type && user_onspawn && !CheckClass("PatrolPoint", AAPTR_TARGET, true), "StandLoop") // prevents stationary NPCs from resetting their angle
			
			
			Goto ChasePlayer			
			
		ChasePlayer:
		
			"----" A 0 A_JumpIf(!user_head_tid, 4) // n/a, NPCs do not have headboxes and do not support sfest optimizations.
			// slaughtermap manage
			"----" A 0 A_JumpIf(!user_sleeping, 3) // forgo the expensive sight check if already awake
			"----" A 0 A_CheckSight(2) // do not consider ourselves awake if none of the players can see us
			"----" A 0 A_SetUserVar("user_sleeping", 0)
/*
			"----" A 0 A_JumpIf(user_serverside_sfchk != -1, 3) // -1 means ACS commands us to do the radiusgive
			"----" A 0 A_RadiusGive("SfestCounterServerside", 500, RGF_MONSTERS | RGF_CUBE | RGF_NOSIGHT, 1)			
			"----" A 0 A_SetUserVar("user_serverside_sfchk", 1) // reply that we did the deed	
*/			
			"----" A 0 A_ChangeFlag("NOPAIN", 0)
			"----" A 0 A_SetUserVar("user_anim_frame", 0)
			"----" A 0 A_SetUserVar("user_anim_frame_time", 0)
			
			// Switch to the synth state to begin backpedaling -- *without* line of sight.
			//  Results in evil marines ambushing player at proper distances for each specific weapon.
			//  Also prevents NPC marines from walking too close to monster around a doorframe edge.
			
			// All hail A_Warp and A_JumpIfTargetInLOS, the indispensable tools of incredible might!
			
			"----" A 0 A_JumpIf(!CallACS("IsSynthMarineTargetValid"), "ChaseLoop")
			
			//P.S. Also results in both evil and npc marines staying da fug out of the bosses' Horrible Rape Radius.
			// If you fight a helicopter or a super cyberdemon, your npcs will keep huddling in cover.
			//  note user_thr_chaaarge does not affect this, charging is made as a part of the missile state
			"----" A 0 A_JumpIf(user_head_type, 2) // jump over the next frame if we are not an NPC
			"----" A 0 A_JumpIfInventory("IsPlayer", 1, 2, AAPTR_TARGET) // NPCs should *not* react this way to players
			
			// without sight it is the same as A_jumpifcloser EXCEPT it won't jump if target is dead
			"----" A 0 A_JumpIfTargetInLOS("SynthBackpedal", 0, JLOSF_DEADNOJUMP | JLOSF_NOSIGHT, user_thr_hrr > user_too_close_range ? user_thr_hrr : user_too_close_range)
			"----" A 0 // an empty frame to jump to
			
			
			Goto ChaseLoop
			
			//***Che this code here is weird because I emulate the original jump checking code
			//  to the best of my ability.
			// It was quirky but worked *extremely* well after I tweaked it fixing a couple minor issues.
			// As usual for Mark-sensei: a genius solution abandoned on the cusp of working properly :(
		
		ChaseLoop:
			// manage weapon cooldown
			"----" A 0 A_JumpIf(!user_wp_cooldown, 2)
			"----" A 0 A_SetUserVar("user_wp_cooldown", (user_wp_cooldown < 2 ? 0 : user_wp_cooldown - 2))
			
			"----" A 0 A_SetUserVar("user_just_dodge_rolled", 0)
			
			// NPC logic is ignored when following patrol points!
			
			"----" A 0 A_JumpIf(!user_head_type, "ChaseLoopNPCLogic")
			Goto ChaseLoopMovement
			
		ChaseLoopNPCLogic: // a stub -- see the descendant class that implements this
			"----" A 0
			Goto ChaseLoopMovement
		
		ChaseLoopMovement:
			"----" A 0 A_JumpIf (user_anim_frame_time > 0, 2)
			"----" A 0 A_Recoil(-2) // once per 4 tics while ChaseLoop loops every 2 tics
		ChaseLoopMoveSkipRecoil:	
			"----" A 0 A_JumpIf(user_aggro_cooldown, "ChaseLoopWanderInstead")
			
			"----" A 0 A_JumpIf(user_anim_frame == 2, "ChaseFrame2") // all return to ChaseLoopContinue
			"----" A 0 A_JumpIf(user_anim_frame == 3, "ChaseFrame3")
			"----" A 0 A_JumpIf(user_anim_frame == 4, "ChaseFrame4")
			"----" A 1 A_JumpIf(true, "ChaseFrame1")
			Wait
		
		ChaseLoopWanderInstead:
			"----" A 0 A_SetUserVar("user_aggro_cooldown", user_aggro_cooldown > 2 ? user_aggro_cooldown - 2 : 0)
			"----" A 0 A_JumpIf(user_anim_frame == 2, "WanderFrame2") // all, likewise, return to ChaseLoopContinue
			"----" A 0 A_JumpIf(user_anim_frame == 3, "WanderFrame3")
			"----" A 0 A_JumpIf(user_anim_frame == 4, "WanderFrame4")
			"----" A 1 A_JumpIf(true, "WanderFrame1")
			Wait
			
		ChaseLoopContinue:
		
			"----" A 0 A_JumpIf(user_aggro_cooldown || user_wp_cooldown, 3) // do *not* initiate going into the Missile syn mode 1 until weapon cooldown is over!			
			"----" A 0 A_SetUserVar("user_angle", angle * 100.0) 
			// discovered (surprise, moterfracker! says the game engine) that A_Chase with CHF_DONTMOVE often resets angle to zero
			"----" AA 0 A_Chase("Missile", "Missile", CHF_DONTMOVE) // a (double) chance to jump to the Missile state as per normal monster behavior
			"----" A 0 A_SetAngle(user_angle / 100.0)
			
			"----" A 0 A_JumpIf(!user_anim_frame_time && user_anim_frame == 0, "ChaseFireJumpCheck")
			"----" A 0 A_JumpIf(!user_anim_frame_time && user_anim_frame == 1, "ChaseCheckJump")
		ChaseLoopContinue2:
			"----" A 0 A_SetUserVar("user_ddgrll_cldwn", user_ddgrll_cldwn > 0 ? user_ddgrll_cldwn - 1 : 0)
			//"----" A 0 A_SetUserVar("user_anim_frame_time", user_anim_frame_time + 1) //((momx * momx) + (momy * momy) < 20 ? 1 : 2))
			//"----" A 0 A_JumpIf(user_anim_frame_time >= 2, 1)
			//Goto ChaseLoop
			//"----" A 0 A_SetUserVar("user_anim_frame_time", 0)
			//"----" A 0 A_SetUserVar("user_anim_frame", user_anim_frame + 1)
			"----" A 0 A_SetUserVar("user_anim_frame", user_anim_frame_time >= 2 ? user_anim_frame + 1 : user_anim_frame)
			"----" A 0 A_SetUserVar("user_anim_frame_time", user_anim_frame_time >= 2 ? 0 : user_anim_frame_time + 1)
			
			
			
			// clientside trap
			"----" A 0 A_JumpIf(user_anim_frame_time, 1) // clientside jumps never work
			Goto ChaseLoop
			
			// NPCs make footstep sounds
			"----" A 0 A_JumpIf(user_head_type || (user_anim_frame != 2 && user_anim_frame != 4), 2)
			"----" A 0 A_SpawnItemEx("FootStep6", 0, 0, 8, 0, 0, 0, 0, SXF_SETMASTER )
			
			"----" A 0 A_JumpIf(user_anim_frame < 4, "ChaseLoop")
			
			"----" A 0 A_SetUserVar("user_nag_cooldown", user_nag_cooldown > 16 ? user_nag_cooldown - 16 : 0)
			"----" A 0 A_JumpIf(!user_nag_cooldown && (user_head_type || user_dist_to_player < 150), "Nag") // NPCs only nag when close to the player
			
			//"----" A 0 A_JumpIf(!user_head_type, "ChaseLookNPC") // only look after the animation cycle finishes!!!
			
			"----" A 0 A_JumpIf(user_maradeur > 1, 1)
			Goto ChasePlayer
			"----" A 0 A_SetUserVar("user_summon_cooldown", user_summon_cooldown > 8 ? user_summon_cooldown - 8 : 0)
			"----" A 0 A_JumpIf(!user_summon_cooldown, "SummonHellhounds")
			Goto ChasePlayer
			
		ChaseFireJumpCheck:
			"----" A 0 A_JumpIf(z - floorz > 16, "ChaseJumpCancel")
			"----" A 0 A_JumpIfInTargetLOS("ChaseLoopFinish", 180, 0, 100) // a certain fix for close distances
			"----" A 0 A_JumpIf(!CallAcs("FBD_RequestExoticManeuver", 3), "ChaseLoopFinish")
			"----" A 0  A_SetUserVar("user_probed_angle", angle) // so that probes are invalidated if we turn around in those 4 tics
				// P.S. Also if no LOS forces facing in this direction while in jump!
			"----" A 0 A_CustomMissile("EvilMarineCheckFront", 32, 0, 0, 2, 0)
			"----" A 0 A_CustomMissile("EvilMarineCheckJump", 64, 0, 0, CMF_AIMDIRECTION, 35)
			//"----" A 0 A_CustomMissile("FBD_CheckIfTargetIsAbove60") // to prevent melee attacks
			Goto ChaseLoopFinish
		ChaseCheckJump:
			"----" A 0 A_JumpIfInventory("evmarinenoway", 1, "ChaseJumpCheck2")
			"----" A 0 A_JumpIf(CallAcs("GetZDeltaToTarget") > 40, "ChaseJumpCheck2") //A_JumpIfInventory("TargetIsAbove", 1, "ChaseJumpCheck2")
			Goto ChaseLoopFinish
		ChaseJumpCheck2:
			"----" A 0 A_JumpIf(z - floorz > 16, "ChaseJumpCancel")
			"----" A 0 A_FaceTarget
			"----" A 0 A_TakeInventory("evmarinenoway", 1)
			
			//***Che: argh, why doesnt't DECORATE have abs() :( 
			//  (no, in Zandronum it does not)
			// Making sure the angle haven't deviated for more than 45 degrees:
			//  (fix for them relying on a probe launched before they made a 180 U-turn)
			//"----" A 0 A_JumpIf(((angle - user_probed_angle < -360) && (angle - user_probed_angle + 360 > 50 || angle - user_probed_angle + 360 < -50)) || ((angle - user_probed_angle > 360) && (angle - user_probed_angle - 360 > 50 || angle - user_probed_angle - 360 < -50)) || ((angle - user_probed_angle <= 360) && (angle - user_probed_angle >= -360) && (angle - user_probed_angle > 50 || angle - user_probed_angle < -50)), "ChaseLoopFinish")
			"----" A 0 A_JumpIf(CallACS("GetAngleDelta360iAbs", angle, user_probed_angle) > 50, "ChaseLoopFinish") 
			"----" A 0 A_JumpIfInventory("evmarinecanjump", 1, "Jump")
			Goto ChaseLoopFinish
			
		ChaseJumpCancel:
			"----" A 0 A_TakeInventory("evmarinenoway", 1)
			"----" A 0 A_TakeInventory("evmarinecanjump", 1)
			//"----" A 0 A_TakeInventory("TargetIsAbove", 1)
			Goto ChaseLoopFinish
			
		ChaseLoopFinish:
			"----" A 0 A_JumpIf(!user_head_type || user_aggro_cooldown || user_wp_cooldown, "ChaseLoopContinue2")//"ChaseLookNPC")
			
			"----" A 0 A_SetUserVar("user_angle", angle * 100.0) 
			// discovered (surprise, moterfracker! says the game engine) that A_Chase with CHF_DONTMOVE often resets angle to zero
			"----" AA 0 A_Chase("Missile", "Missile", CHF_DONTMOVE) // attack visible targets
			"----" A 0 A_SetAngle(user_angle / 100.0)			
			Goto ChaseLoopContinue2
/*		
		ChaseLookNPC: // a stub, see MARINES_npcs.txt
			"----" A 0
			Goto ChasePlayer
*/
/*		
		LostTarget:
			"----" A 0 A_SetUserVar("user_ddgrll_cldwn", 0)
			"----" A 0 A_SetUserVar("user_thr_acc", 0)
			"----" A 0 A_SetUserVar("user_thr_mul", 0)
			"----" A 0 A_SetUserVar("user_thr_hrr", 0)
			"----" A 0 A_SetUserVar("user_thr_chaaarge", 0)
			
			//"----" A 0 A_SetUserVar("user_wp_cooldown", 0)
			"----" A 0 A_SetUserVar("user_shots", 0)
			"----" A 0 A_SetUserVar("user_ambush", 0)
			"----" A 0 A_SetUserVar("user_shot_cooldown", 0)
			Goto Idle
*/			
	
		KilledMyTarget:
			"----" A 0 A_JumpIf(!user_head_type, 2) // skip this for NPCs
			"----" A 0 A_JumpIfInTargetInventory("PlayerIsDead", 1, "Triumph")
			"----" A 0
			Goto Idle			
		
		NpcFollowPlayer: // stub, state is defined in a descendant class
		Idle:
			// a fix for the infinitesimal probability of landing here from dodge-rolling backward or forward
			// if we lose target in the process (those rolls are based on fast chase)
			// P.S. *what* fast chase?! I replaced that with custom mechanics *ages* ago!
			"----" A 0 A_CheckFlag("SHOOTABLE", 3, AAPTR_DEFAULT) // do not set if already shootable
			"----" A 0 A_ChangeFlag("SHOOTABLE", 1)
			"----" A 0 A_ChangeFlag("INVULNERABLE", 0)
			

			//"----" A 0 A_SetUserVar("user_syn_mode", 0)
			// do not clear it for NPCs that have a party leader:
			"----" A 0 A_SetUserVar("user_syn_mode", !user_head_type && user_player_num ? user_syn_mode : 0)
			
			"----" A 1 // crash guard protection frame against infinite zero-time loops
			
			"----" A 0 A_JumpIf(!user_head_type && user_player_num, "NpcFollowPlayer")
			
			// clear the target knowledge -- but not the threat accumulator!
			"----" A 0 A_SetUserVar("user_thr_chaaarge", 0)
			"----" A 0 A_SetUserVar("user_thr_mul", 0)
			"----" A 0 A_SetUserVar("user_thr_hrr", 0)
			
			
			"----" A 0 A_SetUserVar("user_wander", Random(1, 3))
			
			// switch to ranged weapon if we have one
			// also clears a shitton of variables
			"----" A 0 A_JumpIf(user_sleeping, "IdleLoop") // non-conventional use of this variable, to prevent weapon switching repeatedly (which makes sound)
			"----" A 0 A_JumpIf(user_maradeur, "IdleLoop")
			"----" A 0 A_SetUserVar("user_see_after_wp_sw", 2) // go to idle loop afterwards
			"----" A 0 A_SetUserVar("user_weapon", user_default_weapon < 4 ? user_melee_weapon : user_default_weapon)
			Goto WeaponSwitch
			
		IdleLoop:	
			"----" A 0 A_JumpIf(user_guarding, "SeeGuarding") // NPCs only
			"----" A 4 // non-zero duration -- just in case
			
			// A hack: let weapon cooldown stay undecayed on idle. This gives a random emergent 
			//   extra pre-fire delay to the first shot after acquiring a target
			//"----" A 0 A_SetUserVar("user_wp_cooldown", 0)
			
			"----" A 0 A_LookEx(user_head_type ? 0 : LOF_NOSOUNDCHECK | LOF_NOSEESOUND, 0,0,0,0, "SeeEnemy")

			"----" A 0 A_JumpIf(user_wander > 0, "WanderCycle")
			
			"----" A 0 A_JumpIf(!user_head_type, "SeeGuarding") // no headbox means NPC
				// SeeGuarding would spend at least 4 tics in standing weapon at ready animation, before jumping back to Idle
				
			"----" A 0 A_SetUserVar("user_sleeping", 0)	// headbox slaughtermap optimization
			"----" A 0 A_Jump(16, "RandomWander")
			Loop
		
		RandomWander:
			"----" A 0 A_SetUserVar("user_wander", Random(3, 9))
			Goto IdleLoop

		DodgeRoll:
			
			//***Che: using the immensely powerful tool of A_Warp
			//  to check if there is space in selected direction.
			// Unlike probing missiles (and I wanted to replace the jump check
			//   as well, but... "Don't fix it if it ain't broken"), the result is
			//   *immediate*. You can probe around all you want with zero-duration states
			//   before committing to a course of action.
			// In situations like dodging where even one tic is a sizable time 
			//   (1/35th of a second is nothing for a modern player's reflexes)
			//   there is practically no alternative to this method.
			// A_Warp has a built-in jump on success (just specify the state to jump to),
			//   and you can just warp right back, by specifying opposite offsets.
			// Just don't go storing x and y in user variables -- they are *rounded down*
			//   because x and y are floats while user variables are integer,
			//   so you *will* get stuck in a wall you were hugging.
			
			"----" A 0 A_SetUserVar("user_just_dodge_rolled", 1)
			"----" A 0 A_SetUserVar("user_aggro_cooldown", 0)
			
			"----" A 0 A_FaceTarget
			
			// disabled
			"----" A 0 A_JumpIf(user_ddgrll_chance < 0, "ShuffleFromPain")
			
			// totally disabled while bfg is charging
			"----" A 0 A_JumpIf(user_charge && user_shots && user_stand_still && user_syn_mode == 1, "ShuffleFromPain")
			
			"----" A 0 A_SetUserVar("user_angle", angle * 100.0)
			"----" A 0 A_SetUserVar("user_ddgrll_cldwn", Random(0, 8)) // in chase loops
		
			"----" A 0  A_TakeInventory("MeleeMiss", 3)
			"----" A 0 A_SetUserVar("user_roll_check", 0)
			"----" A 0 A_SetUserVar("user_old_z", z)
			
			// Dodge-roll means invulnerability!
			"----" A 0 A_JumpIf(!user_head_tid, 2)
			"----" A 0 ACS_NamedExecuteWithResult("DeleteHeadboxMkII")
			"----" A 0 A_ChangeFlag("SHOOTABLE", 0)
			"----" A 0 A_ChangeFlag("INVULNERABLE", 1)
			
			"----" A 1 A_Jump(256, "RollLeft", "RollRight")
			Wait
			
			/*
			Trying to warp in chosen direction and checking for success.
			On success, warping back to the initial position
			   the NPC/evil marine radii are 12/14
			   so warping 16 map units away should, in theory,
			   bring our center over the edge if there was a drop
			   we can then detect using floorz
			Doesn't actually roll straight right or left 
			   but at 60 degree angle from the view direction
			This is for both avoiding walls we may be hugging with our back
				(due to backpedaling, a very high chance)
				and for making us closer to the player, possibly into melee range
				(right in yer face!)
			*/	
			
		RollLeft:
		
			// Before we roll, we try teleporting in that direction.
			// If we are blocked, we try rolling in the other direction.
			// If both are blocked, we roll backwards.
			"----" A 0 A_JumpIf(user_roll_check >= 2, "RollBackward")
			"----" A 0 A_SetUserVar("user_roll_check", user_roll_check + 1)
			"----" A 0 A_Warp(AAPTR_DEFAULT, 8, -14, 16, 0, 0, "RollLeftContinue")
			Goto RollRight // teleport failed, try the other direction
			
		RollLeftContinue:
			// A_Warp *can* and *will* warp you hundreds of map units up a cliff!
			// Checking the resulting z is a must.
			// Also checking for sheer drops.
			"----" A 0 A_JumpIf(z - floorz > 32 || z - user_old_z > 32, "RollLeftCancel")
			
			// Warp back to our original position before proceeding.
			// Note: imma exploiting the fact that game engine force-aligns any actors vertically
			//   to fit above the floor and below the ceiling -- unless that actor
			//   has collision turned off completely.
			// So there is no risk of getting stuck due to z being rounded.
			// Again, *don't* try this at home with x or y!
			"----" A 0 A_Warp(AAPTR_DEFAULT, -8, 14, user_old_z - z, 0, WARPF_NOCHECKPOSITION)	
			
			"----" A 0 A_SetAngle(angle + 90)			
			Goto ProceedRolling

		RollLeftCancel:
			// Warp back to whence we came from before trying another direction
			"----" A 0 A_Warp(AAPTR_DEFAULT, -8, 14, user_old_z - z, 0, WARPF_NOCHECKPOSITION)
			Goto RollRight
			
		RollRight:
			"----" A 0 A_JumpIf(user_roll_check >= 2, "RollBackward")
			"----" A 0 A_SetUserVar("user_roll_check", user_roll_check + 1)
			"----" A 0 A_Warp(AAPTR_DEFAULT, 8, 14, 16, 0, 0, "RollRightContinue")
			Goto RollLeft
			
		RollRightContinue:	
			"----" A 0 A_JumpIf(z - floorz > 32 || z - user_old_z > 32, "RollRightCancel")
			"----" A 0 A_Warp(AAPTR_DEFAULT, -8, -14, user_old_z - z, 0, WARPF_NOCHECKPOSITION)
			
			"----" A 0 A_SetAngle(angle - 90)			
			Goto ProceedRolling
			
		RollRightCancel:
			"----" A 0 A_Warp(AAPTR_DEFAULT, -8, -14, user_old_z - z, 0, WARPF_NOCHECKPOSITION)
			Goto RollLeft
			
		RollBackward:
			// this is it, the end of the line. Roll where wall deflection dictates!
			"----" A 0 A_SetAngle(angle + 180 + Random(-60,60))
			Goto ProceedRolling
			
		ProceedRolling:	
			// A_Wander takes care of any obstacles automatically, the patient bouncing off walls to roll along them!
			// Our speed 5 is per call, we need ~25 movement per tic
			
			//***Che: please note, I modified the PROL sprites mirroring them horizontally
			//  now a normal movement using them results in player rolling forward..ish
			// they only have *two* actual directions: 1,2,8,3,7, and 4,6,5
			
			// The original BD sprites won't work well (the marine will look rotating in the wrong direction)
			
			"----" A 0 A_JumpIf(user_maradeur == 3, "RollLikeSonicTheHedgehog")
			"----" A 0 A_JumpIf(user_weapon == 2 || user_maradeur, "RollSuper")
			Goto RollNormally
			
		RollNormally:
			"----" AA 0 A_Wander
			PROL A 1 A_Wander 
			"----" A 0 A_Wander 
			PROL A 1 A_Wander 
			"----" A 0 A_Wander 
			PROL A 1 A_Wander 
			"----" A 0 A_Wander 
			PROL B 1 A_Wander 
			"----" A 0 A_Wander 
			PROL B 1 A_Wander 
			"----" A 0 A_Wander 
			PROL B 1 A_Wander  
			"----" A 0 A_Wander 
			PROL C 1 A_Wander 
			"----" A 0 A_Wander 
			PROL C 1 A_Wander 
			"----" A 0 A_Wander 
			PROL C 1 A_Wander 
			PROL DDDEEE 1 A_Wander 
			Goto RollFinish			
		
		RollSuper:
			"----" AA 0 A_Wander
			PROL A 1 A_Wander 
			"----" AA 0 A_Wander 
			PROL A 1 A_Wander 
			"----" AA 0 A_Wander 
			PROL A 1 A_Wander 
			"----" AA 0 A_Wander 
			PROL B 1 A_Wander 
			"----" AA 0 A_Wander 
			PROL B 1 A_Wander 
			"----" A 0 A_Wander 
			PROL B 1 A_Wander  
			"----" A 0 A_Wander 
			PROL C 1 A_Wander 
			"----" A 0 A_Wander 
			PROL C 1 A_Wander 
			"----" A 0 A_Wander 
			PROL C 1 A_Wander 
			"----" A 0 A_Wander 
			PROL D 1 A_Wander 
			"----" A 0 A_Wander 
			PROL DEEE 1 A_Wander 
			Goto RollFinish			
		
		RollLikeSonicTheHedgehog:
			"----" AAA 0 A_Wander 
			PROL A 1 A_Wander 
			"----" AAAA 0 A_Wander 
			PROL A 1 A_Wander 
			"----" AAAA 0 A_Wander 
			PROL A 1 A_Wander 
			"----" AAAA 0 A_Wander 
			PROL B 1 A_Wander 
			"----" AAA 0 A_Wander 
			PROL B 1 A_Wander 
			"----" AAA 0 A_Wander 
			PROL B 1 A_Wander 			
			"----" AAA 0 A_Wander 
			PROL C 1 A_Wander 
			"----" AAA 0 A_Wander 
			PROL C 1 A_Wander 
			"----" AA 0 A_Wander 
			PROL C 1 A_Wander 
			"----" AA 0 A_Wander 
			PROL D 1 A_Wander 
			"----" AA 0 A_Wander 
			PROL D 1 A_Wander 
			"----" AA 0 A_Wander 
			PROL D 1 A_Wander 			
			"----" A 0 A_Wander 
			PROL E 1 A_Wander 
			"----" A 0 A_Wander 
			PROL E 1 A_Wander 
			"----" A 0 A_Wander 
			PROL E 1 A_Wander 
			Goto RollFinish			
			
		RollFinish:
			"----" A 0 A_SetAngle(user_angle / 100.0) // restore our initial facing direction
			"----" A 0 A_SetUserVar("user_wp_cooldown", user_wp_cooldown > 15 ? user_wp_cooldown - 15 : 0)
			"----" A 0 A_ChangeFlag("SHOOTABLE", 1)
			"----" A 0 A_ChangeFlag("INVULNERABLE", 0)
			"----" A 0  A_JumpIf(!user_head_tid, 2) // NPCs have no headbox
			"----" A 0 ACS_NamedExecuteAlways("FrankenHeadForceCreate", 0, 5, 0, 44)
			"----" A 0 A_JumpIf(user_syn_mode == 1, "RollSwitchToMissile") // One of the synth state entry points, 
				// we just return after the missile state made us roll -- may result in ambush if we rolled out of sight.
				// melee weapons are exempt
			//"----" A 0 A_JumpIf(!user_head_type && user_weapon > 3 && !CallAcs("NPC_CanOpenFireFilter"), "ChaseLoopWanderInstead") // NPCs are subject to the Ninjustsu Conservation Law
			"----" A 0 A_JumpIfTargetInLOS("RollSwitchToMissile", 0, JLOSF_DEADNOJUMP) //"Missile")
			Goto See

		RollSwitchToMissile: 
			// includes obligatory facetarget, otherwise he could dodge-roll *before* "See" and be facing in a completely random direction!
			"----" A 0 A_FaceTarget
			Goto MissileAfterDodgeRoll
			
		CancelMissileTargetInvalid: // NPC base class overrides
			"----" A 1
			Goto ChaseLoopWanderInstead
			
		
		Missile:
			// because of-fucking-course the game engine puts then into their Missile state with patrol points as their target!
			
//"----" A 0 ACS_NAMedExecuteWithResult("FBD_DebugNPCTarget", 1)	
			

			"----" A 0 A_JumpIf(!CallACS("IsSynthMarineTargetValid"), "CancelMissileTargetInvalid")
			
			//"----" A 0 A_JumpIf(!user_head_type && user_syn_mode != 1 && user_weapon > 3 && !CallAcs("NPC_CanOpenFireFilter"), "ChaseLoopWanderInstead") // NPCs are subject to the Ninjustsu Conservation Law
			
			"----" A 0 A_SetUserVar("user_onspawn", 0) // NPC been in combat, spawn angle no longer applicable
			
			// slaughtermap manage - warming the headbox up
			"----" A 0 A_JumpIf(!user_head_type, 5) // skip if no headbox (NPC)
			"----" A 0 A_JumpIf(!user_sleeping, 4) // forgo the expensive sight check if already awake
			"----" A 0 A_JumpIfInTargetInventory("IsPlayer", 1, 2) // bypass the sight check 
			"----" A 0 A_CheckSight(2) // out of sight of any player, AND attacking another monster, keep slumbering
			"----" A 0 A_SetUserVar("user_sleeping", 0)

			"----" A 0 A_JumpIf(user_head_type, 2)
			"----" A 0 A_JumpIfInventory("IsPlayer", 1, "NpcFollowPlayer", AAPTR_TARGET)
			
			
			"----" A 0 A_JumpIfInTargetLOS(3, 60, JLOSF_DEADNOJUMP)
			"----" A 0 A_JumpIf(true, 3)
			"----" A 0 A_SetUserVar("user_syn_mode", 1) // makes DodgeRoll jump to MissileAfterDodgeRoll after it finishes
			"----" A 0 A_JumpIf("user_just_dodge_rolled", 2)
			"----" A 0 A_Jump(user_thr_acc > 50, "DodgeRoll") // if in target's sight
			"----" A 0 A_SetUserVar("user_just_dodge_rolled", 0)
			
			"----" A 0 A_JumpIf(user_wp_cooldown, "See")
			// this was STUPID, making them helpless :(
			//"----" A 0 A_JumpIf(!user_head_type && !CallAcs("NPC_CanOpenFireFilter"), "See") // NPCs are subject to the Ninjustsu Conservation Law
			
			"----" A 0 A_Recoil(-4)
			"----" A 0 A_FaceTarget
			//"----" A 0 A_JumpIfCloser(user_melee_range, "MeleeAttack") // see the threat assessment phase
			
			
		
			// weapon cooldown is always retained 
			"----" A 0 A_SetUserVar("user_wp_cooldown", user_wp_cooldown > 2 ? user_wp_cooldown - 2 :  0)

			"----" A 0 A_SetUserVar("user_anim_frame", 0)	
			"----" A 0 A_SetUserVar("user_anim_frame_time", 0)

			// Kinslayer check for evil marines:	
			// true means check along the class inheritance chain
			"----" A 0 A_JumpIf(!CheckClass("EvilMarine_Base", AAPTR_DEFAULT, true) || !CheckClass("EvilMarine_Base", AAPTR_TARGET, true), 2) 
			"----" A 0 ACS_NamedExecuteWithResult("FBD_InfightFriendlyFireOn") // only gets called if both us and our target are evil marines
			
						
		MissileAfterDodgeRoll:	
		
			"----" A 0 A_JumpIf(!CallACS("IsSynthMarineTargetValid"), "See")
			
			"----" A 0 A_JumpIf(user_head_type, 4)
			"----" A 0 A_JumpIfInventory("IsPlayer", 1, "NpcFollowPlayer", AAPTR_TARGET)
			"----" A 0 A_JumpIfInventory("TargetIsAMarine", 1, "NpcFollowPlayer", AAPTR_TARGET)
			"----" A 0 A_CheckFlag("FRIENDLY", "NpcFollowPlayer", AAPTR_TARGET)
			
			"----" A 0 A_SetUserVar("user_syn_mode", 1) // just in case
			"----" A 0 A_SetUserVar("user_notarget_cooldown", 0)
			"----" A 0 A_SetUserVar("user_shots", user_burst_length) // to vary burst length, add more during firing			
			
			"----" A 0 ACS_NamedExecuteAlways("SkulltagTransmitSynStateToClient") // the Zandronum game engine does never sync user variables nor monsters' inventories

			"----" A 0 A_SetUserVar("user_ambush", 0)
			"----" A 0 A_SetUserVar("user_shot_cooldown", 0)
			"----" A 0 A_SetUserVar("user_loiter_count", 0)
			"----" A 0 A_SetUserVar("user_strafe", user_strafe < 5 ? 5 : user_strafe)
			"----" A 0 A_SetUserVar("user_backpedal", 0)
			
			"----" A 0 A_SetUserVar("user_charge", 0)
		
			"----" A 0 A_TakeInventory("MeleeMiss", 3)
			
			// Always assuming we have LOS on entering the missile state -- and *always* calling A_FaceTarget.
			// If there is no actually LOS or the target is invisible, will register losing LOS in the Move phase.
			"----" A 0 A_SetUserVar("user_has_los", 1)
			"----" A 0 A_FaceTarget
			"----" A 0 A_SetUserVar("user_best_a", angle * 182.0444) // 360.0 => 65536 = 1.0 in ACS fixed
			//"----" A 0  A_JumpIfTargetInLOS(2)
			//"----" A 0 A_SetUserVar("user_has_los", 0)

			"----" A 0 A_SetUserVar("user_prev_x", x)
			"----" A 0 A_SetUserVar("user_prev_y", y)
			"----" A 1 // wait one tic to make actual velocities accumulate into delta x, y
			
			Goto SynthLoop
			
	
		//***Che SynthLoop is a synthetic attack state
		// made of four semi-independent layers:
		// MovePhase -> AnimPhase -> WeaponPhase -> ThreatSensePhase -> to the beginning	
		
		// where move and weapon phases have zero duration
		// and the anim phase always takes 1 tic
		
		ShuffleFromPain: //<- The custom pain state must redirect here if weapon is charging
			// Circle-strafe sharply instead of dodge-rolling
			"----" A 0 A_SetUserVar("user_strafe", user_strafe > 10 + user_maradeur * 3 ? user_strafe : 10 + user_maradeur * 3)
			
			"----" A 0 A_JumpIf(user_maradeur && (user_weapon <= 3 || user_weapon == 17 || user_weapon == 15), "MaradeurAdjustMeleeStrategyFromPain") 
			
			"----" A 0 A_JumpIf(user_syn_mode, "SynthContinue")
			Goto SynthBackpedal
			
		MaradeurAdjustMeleeStrategyFromPain:
			// berserk charge chance:
			//   summon hellhound - zero
			//   dragonslayer - 66%
			//   chainsaw - 25%
			"----" A 0 A_Jump(user_weapon == 15 ? 0 : (user_weapon == 17 ? 160 : 64), "MaradeurBerserkChargeFromPain")
			"----" A 0 A_SetUserVar("user_maradeur_weapon", Random(0, 100) < 40 ? 9 : 6) // plasma / ssg
			"----" A 0 A_SetUserVar("user_weapon", user_maradeur_weapon)
			Goto WeaponSwitch
			
		MaradeurBerserkChargeFromPain:
			"----" A 0 A_SetUserVar("user_chaaarge", 1)
			"----" A 0 A_SetUserVar("user_backpedal", -20)
			"----" A 0 A_JumpIf(user_syn_mode, "SynthContinue")
			Goto SynthBackpedal
		
		SynthContinue: // return from pain state and so on
			"----" A 0 // retain previous syn mode
			"----" A 0 A_JumpIf(!user_syn_mode, "SynthBackpedal")
			Goto WeaponPhase
			
		SynthBackpedal:
			"----" A 0 A_SetUserVar("user_syn_mode", user_syn_mode == 1 || user_shots ? 1 : 2)
			"----" A 0 A_SetUserVar("user_just_dodge_rolled", 0)
			"----" A 0 A_SetUserVar("user_loiter_count", 0)
			"----" A 0 A_FaceTarget
			"----" A 0 A_SetUserVar("user_angle", angle * 100.0)
			"----" A 0 A_SetUserVar("user_strafe", user_strafe > 3 + user_maradeur * 3 ? user_strafe : 3 + user_maradeur * 3)
			"----" A 0 ACS_NamedExecuteAlways("SkulltagTransmitSynStateToClient") // the Zandronum game engine does never sync user variables nor monsters' inventories
			Goto MovePhase
			
		SynthNPCGetClear:
			"----" A 0 A_SetUserVar("user_syn_mode", 3)
			"----" A 0 A_SetUserVar("user_just_dodge_rolled", 0)
			"----" A 0 A_SetUserVar("user_loiter_count", 0)
			
			"----" A 0 A_JumpIf(user_nag_cooldown > user_nag_period / 4, 3)
			//"----" A 0 A_PlaySound("npc/watchit", CHAN_VOICE)
			"----" A 0 ACS_NamedExecuteWithResult("FBD_SynthMarineVoice", CHE_WATCHIT)
			"----" A 0 A_SetUserVar("user_nag_cooldown", Random(user_nag_period / 2, user_nag_period))
			
			"----" A 0 ACS_NamedExecuteAlways("SkulltagTransmitSynStateToClient") // the Zandronum game engine does never sync user variables nor monsters' inventories
			Goto MovePhase
			
		SynthJump:
			"----" A 0 A_SetUserVar("user_syn_mode", 4)
			"----" A 0 A_SetUserVar("user_just_dodge_rolled", 0)
			"----" A 0 A_SetUserVar("user_loiter_count", 0)
			"----" A 0 ACS_NamedExecuteAlways("SkulltagTransmitSynStateToClient") // the Zandronum game engine does never sync user variables nor monsters' inventories
			"----" A 0 A_SetUserVar("user_in_air", 1)
			Goto MovePhase
			
		ExitSynthLoop:
			"----" A 0 A_SetUserVar("user_notarget_cooldown", 0)
			"----" A 0 A_SetUserVar("user_syn_mode", 0)
			"----" A 0 ACS_NamedExecuteAlways("SkulltagTransmitSynStateToClient")
			
			"----" A 0 A_SetUserVar("user_see_after_wp_sw", 1) // go to see afterwards
			
			"----" A 0 A_JumpIf(user_maradeur, "WeaponSwitch") // maradeurs don't switch
			
			"----" A 0 A_JumpIf(user_weapon == user_default_weapon, "See")
			"----" A 0 A_SetUserVar("user_weapon", user_default_weapon) // switch to ranged
			
			Goto WeaponSwitch
			
			
		SynthLoop: // NEVER jump here directly, use entry points!
			// using "----" (retain previous) to respect the quirks of the Zandronum multiplayer client
			// -- we may return here from pain, which is unique per descendant class
			
			"----" A 0 A_SetUserVar("user_nag_cooldown", user_nag_cooldown > 1 ? user_nag_cooldown - 1 : 0)
			
		MovePhase: 
			// hard cancel for the missile mode for NPCs targeting a player
			"----" A 0 A_JumpIf(user_head_type || user_syn_mode != 1, 2)
			"----" A 0 A_JumpIfInventory("IsPlayer", 1, "NpcFollowPlayer", AAPTR_TARGET) 
			
			"----" A 0 A_JumpIf(CheckClass("PatrolPoint", AAPTR_TARGET, true), "ExitSynthLoop")
		
			// in all modes except 1 (missile) and 4 (jump), forced face target every tic!
			"----" A 0 A_JumpIf(user_syn_mode == 1 || user_syn_mode == 4, 3)
			"----" A 0 A_FaceTarget
			"----" A 0 A_SetUserVar("user_best_a", angle * 182.0444)
		
			// they get rounded down to integers in the process
			"----" A 0 A_SetUserVar("user_dx", x - user_prev_x < -64 || x - user_prev_x > 64 ? 0 : x - user_prev_x)
			"----" A 0 A_SetUserVar("user_dy", y - user_prev_y < -64 || y - user_prev_y > 64 ? 0 : y - user_prev_y)
			//***Che: wtf is this? It breaks the entire algo! "----" A 0 A_JumpIf(!user_prev_x && !user_prev_y, 3)
			"----" A 0 A_SetUserVar("user_prev_x", x)
			"----" A 0 A_SetUserVar("user_prev_y", y)
			// map: x east, y north, 0 angle east, 90 angle north
			// actor: x forward, y rightward 
			// -- note in this system y is *flipped* compared to the map's system!
			//    where y, momy use map's
			//    and SpawnItemEx's y, yvel use actor's, relative to the actor
			//    Quoting a comment from Zandronum's source code implementing A_SpawnItemEx
			//    (thingdef_codeptr.cpp, line 2604):
			//        in relative mode negative y values mean 'left' and positive ones mean 'right'
			//        This is the inverse orientation of the absolute mode!
			//        ...
			//        x = self->x + FixedMul(xofs, finecosine[ang]) + FixedMul(yofs, finesine[ang]);
			//        y = self->y + FixedMul(xofs, finesine[ang]) - FixedMul(yofs, finecosine[ang]);
			
			// here user_dx and user_dy are in the map system where user_rightward_vel is in the actor system
			"----" A 0 A_SetUserVar("user_rightward_vel", !user_dx && !user_dy ? 0 : 100.0 * ( user_dx * sin(angle) - user_dy * cos(angle)))
			"----" A 0 A_SetUserVar("user_forward_vel", !user_dx && !user_dy ? 0 : 100.0 * (user_dx * cos(angle) + user_dy * sin(angle)))
			
			
			"----" A 0 A_JumpIf(user_syn_mode == 1 && ((user_charge && user_shots) || user_ambush), 2)
			// In syn mode 1 (missile), loiter count is used for a mode exit cooldown,
			//   cannot switch out until at least 5 tics are spent in it
			"----" A 0 A_SetUserVar("user_loiter_count", user_loiter_count + 1)
		
			// За такое хочется убивать. Себя.
			// Left here as a burning shame of an example HOW NOT TO DO it.
			//"----" A 0 A_JumpIf(!user_charge && user_shots <= 0 && user_notarget_cooldown > user_ambush_duration && !user_in_air, "See") // before los check: some states set this var manually
			
			// Line of sight is cached in a variable to avoid spamming it (the threat evaluation phase 
			//   calls it on its own anyway, but it is throttled by doing the evaluation once in 5 tics)
			"----" A 0 A_JumpIf(CallAcs("FBD_TargetIsInvisible"), "MoveNoLOS")
			"----" A 0 A_JumpIfTargetInLOS("MoveHasLOS", 130, JLOSF_DEADNOJUMP)
			Goto MoveNoLOS
		MoveNoLOS:
			"----" A 0 A_SetAngle(user_best_a  * 0.005493164) // face the best angle
			"----" A 0 A_JumpIf(user_has_los, "MoveLostLOS")
			Goto MoveMove
		
		MoveHasLOS:	
			"----" A 0 A_FaceTarget
			"----" A 0 A_JumpIf(user_syn_mode == 1, 2) // in the Missile mode, user_best_a 
				// is subject to repeated corrections using probes
				// - so direct angle to target may not be the best firing angle
				//  (probes resolve corners and stuff)
			"----" A 0 A_SetUserVar("user_best_a", angle * 182.0444) 
			"----" A 0 A_JumpIf(!user_has_los, "MoveRegainedLOS")
			Goto MoveMove
			
		MoveRegainedLOS:
			"----"  A 0 A_SetUserVar("user_has_los", 1)
			Goto MoveMove
			
		MoveLostLOS:
			"----" A 0 A_SetUserVar("user_has_los", 0)
			"----" A 0 A_JumpIf(user_syn_mode == 1 && !user_in_air && user_stand_still && (user_ambush || user_charge < user_charge_time || user_shots >= user_burst_length), "MoveLostLOSWhileCharging")
			Goto MoveMove

		MoveLostLOSWhileCharging:
			// currently, you only get here while charging your bfg
			"----" A 0 A_SetUserVar("user_strafe", user_strafe / 2) // cut strafing speed in half
			"----" A 0 A_Stop
			
			// now reverse direction by force-switching to wander mode:
			// a partial clone of MoveSwitchToWander
			"----" A 0 A_SetUserVar("user_swander_cd", 0)
			"----" A 0 A_SetUserVar("user_move_wander", 1)
			"----" A 0 A_SetUserVar("user_angle", angle * 100.0)
			
			// now reverse our lateral movement
			
			"----" A 0 A_JumpIf(user_rightward_vel > 300, "MoveSTWLeft") 
			"----" A 0 A_JumpIf(user_rightward_vel < -300, "MoveSTWRight") 
			"----" A 1 A_Jump(256, "MoveSTWLeft", "MoveSTWRight")
			Wait
			
		MoveMove:
			// Note: in my previous implementation I was using circle-strafing checks
			//   in this move phase. 
			// Unneeded.
			// Because random strafing generates enough emergent behavior 
			//   to give reliable and lifelike surprising around corners.
		
			"----" A 0 A_JumpIf(user_in_air, "MoveInAir") // jumping allows no other movement
			
			// max (abs(user_backpedal), user_strafe) implemented using trinary operators
			// because OF COURSE Zandronum doesn't know such functions
			"----" A 0 A_SetUserVar("user_swander_cd", user_swander_cd + (user_backpedal > 0 ? (user_backpedal > user_strafe ? user_backpedal : user_strafe) : (- user_backpedal > user_strafe ? - user_backpedal : user_strafe)))			
			
			
			"----" A 0 A_JumpIf(user_move_wander, "MoveWander")
			Goto MoveThrust
		
		MoveInAir:
			"----" A 0 A_SetUserVar("user_in_air", user_in_air + 1) // the Jump state sets to 1, we begin at 2!
			"----" A 0 A_JumpIf(user_has_los || angle == user_probed_angle, 2)
			"----" A 0 A_SetAngle(user_probed_angle) // cancel any turning aroud we may have made since the probe was fired
			"----" A 0 A_JumpIf(user_in_air == 2, "MoveInAirActuallyJump")
			// !user_syn_mode == 1 because if we are firing it means we had performed A_FaceTarget 
			//   and should continue on our trajectory. No sudden turns in air.
			"----" A 0 A_JumpIf(user_in_air >= 3 && user_forward_vel < 1000 && !user_syn_mode == 1, "MoveInAirJumpAccel") // after one tic spent in jump (moving upwards), accelerate forward
			"----" A 0 A_CheckFloor("MoveLand")
			//"----" A 0 A_JumpIf(user_in_air > 8 && user_in_air < 17 && z - floorz >= 64, "MoveTryWarpForward")
			"----" A 0 A_JumpIf(user_in_air > 60 && momz == 0, "MoveLand") // assume we landed on someone's head
			Goto MoveFinish
			
	
			
		MoveInAirActuallyJump:	
			"----" A 0 A_TakeInventory("evmarinecanjump", 1)
			"----" A 0 ThrustThingZ(0, user_jump_power ? user_jump_power : 50, 0, 1)
				//***Che: adjust aim *early* if target is invisible
				"----" A 0 A_JumpIf(CallAcs("FBD_TargetIsInvisible"), 2)
				"----" A 0 A_JumpIfTargetInLOS(2)
				"----" A 0 A_FaceTarget
				"----" A 0 // obligatory empty frame to jump to
			Goto MoveFinish
			
		MoveInAirJumpAccel:
			"----" A 0 A_Recoil(-3) //-6)
			"----" A 0 A_CheckFloor("MoveLand")
			Goto MoveFinish

/*			
		MoveTryWarpForward:
			"----" A 0 A_SetUserVar("user_old_z", z)
			"----" A 0 A_Warp(AAPTR_DEFAULT, 22, 0, 16, 0, 0, "MoveWarp1Succ")
			Goto MoveFinish 
			
		MoveWarp1Succ:
			"----" A 0 A_Warp(AAPTR_DEFAULT, 22, 0, 0, 0, 0, "MoveWarp2Succ")
			"----" A 0 A_Warp(AAPTR_DEFAULT, -22, 0, user_old_z - z, 0, WARPF_NOCHECKPOSITION)	
			Goto MoveFinish 

		MoveWarp2Succ:
			"----" A 0 A_JumpIf(z - floorz <= 24, "MoveWarpAccel")
			// failure, we failed to land on a ledge. Roll back both warps.
			"----" A 0 A_Warp(AAPTR_DEFAULT, -44, 0, user_old_z - z, 0, WARPF_NOCHECKPOSITION)
			Goto MoveFinish
			
		MoveWarpAccel:	
			// success, a suitable ledge ahead. Roll back both warps and accelerate sharply.
			"----" A 0 A_Warp(AAPTR_DEFAULT, -44, 0, user_old_z - z, 0, WARPF_NOCHECKPOSITION)
			"----" A 0 A_Recoil(-10)
			Goto MoveFinish
*/			
			
		MoveLand:
			"----" A 0 A_SetUserVar("user_in_air", 0)
			
			//P.S. Frak, they were driving themselves into walls and getting stuck
			//"----" A 0 A_Warp(AAPTR_DEFAULT, 10, 0, 0) // to hopefully push us away from the edge 
				// of the ledge we just jumped onto. Ignore failures.

			// let's try recoil instead... :(		
			"----" A 0 A_Recoil(-10)	
				
			"----" A 0 A_SpawnItemEx("FootStepStrong", 0, 0, 8, 0, 0)
			"----" A 0 A_JumpIf(user_syn_mode == 1, "MoveFinish") // continue our firing sequance
			Goto ExitSynthLoop // we are done here
			
			
		MoveThrust:	
			// the old movement mode using ThingThrust. Can get stuck on walls
			
			// in this mode user_swander_cd is used to determine if we want moving at all
			// (see MoveThrustFinish ) and is cleared each tic afterwards
			
			"----" A 0 A_JumpIf(user_strafe < 1, "MoveThrustBackOrForth") // no we do NOT wantt o move
			
			//DAFUG? Goto MoveThrustBackOrForth			

		MoveThrustSideways:
			"----" A 0 A_JumpIf(user_rightward_vel > (user_speed_limit * 90.0) || user_rightward_vel < (user_speed_limit * -90),"MoveThrustCoast")
			
			// if moving faster than 3 map units per tic, keep moving in that direction
			"----" A 0 A_JumpIf(user_rightward_vel > 300, "MoveThrustRight") // corresponds to 3 map units per tic
			"----" A 0 A_JumpIf(user_rightward_vel < -300, "MoveThrustLeft")
			
			// if speed is low, move randomly (would get unstuck unless in a corner)
			"----" A 1 A_Jump(256, "MoveThrustRight", "MoveThrustLeft")
			Wait // Zandronum client freezes and waits for an update from the server
			
		MoveThrustCoast:	
			 // decay the controlling value over time
			"----" A 0 A_SetUserVar("user_strafe", user_strafe > 0 ? user_strafe - 1 : 0)
			Goto MoveThrustBackOrForth			
			
		MoveThrustLeft:
			 // decay the controlling value over time
			"----" A 0 A_SetUserVar("user_strafe", user_strafe > 0 ? user_strafe - 1 : 0)
			"----" A 0 A_JumpIf(user_rightward_vel < -100 * user_strafe, "MoveThrustBackOrForth")//, 2)
			"----" A 0 ThrustThing((angle*256/360)+64, 1, 0, 0)
			Goto MoveThrustBackOrForth			
			
		MoveThrustRight:
			 // decay the controlling value over time
			"----" A 0 A_SetUserVar("user_strafe", user_strafe > 0 ? user_strafe - 1 : 0)
			"----" A 0 A_JumpIf(user_rightward_vel > 100 * user_strafe, "MoveThrustBackOrForth")//***Che !!!This was fouled up because it was jumping *into* the next state!!!!, 2)
			"----" A 0 ThrustThing((angle*256/360)+192, 1, 0, 0)
			Goto MoveThrustBackOrForth			
			
		MoveThrustBackOrForth:
			"----" A 0 A_JumpIf(user_backpedal > 1 && user_forward_vel > -100 * user_backpedal, "MoveThrustBackpedal")
			"----" A 0 A_JumpIf(user_backpedal < -1 && user_forward_vel < -100 * user_backpedal, "MoveThrustBumrush")
			Goto MoveThrustFinish
			
		MoveThrustBackpedal:
			"----" A 0 A_SetUserVar("user_backpedal", user_backpedal - 1)
			"----" A 0 ThrustThing(angle*256/360+128, 2, 0, 0)
			Goto MoveThrustFinish
		
		MoveThrustBumrush:
			"----" A 0 A_SetUserVar("user_backpedal", user_backpedal + 1)
			"----" A 0 ThrustThing(angle*256/360+128, -2, 0, 0)	
			Goto MoveThrustFinish
			
		MoveThrustFinish:
			// if all velocities are less than half of the largest desired velocity, count that as being stuck in a corner
			
			// note: user_swander_cd is 1x while user_rightward_vel, user_forward_vel are 100x
			
			"----" A 0 A_JumpIf(user_swander_cd > 1 && user_rightward_vel / 100 > - user_swander_cd / 2 && user_rightward_vel / 100 < user_swander_cd / 2 && user_forward_vel / 100 > - user_swander_cd / 2 && user_forward_vel / 100 < user_swander_cd / 2, "MoveThrustStuck")
			
			"----" A 0 A_SetUserVar("user_swander_cd", 0)
			Goto MoveAdjustSpeeds
			
		MoveThrustStuck:
			"----" A 0 A_SetUserVar("user_stuck_det", user_stuck_det + 1)
			"----" A 0 A_SetUserVar("user_swander_cd", 0)
			"----" A 0 A_JumpIf(user_stuck_det > 15, "MoveSwitchToWander")			
			Goto MoveAdjustSpeeds			
			
			
		MoveWander:
			// the new movement mode using A_Wander and a stored angle
			// only get here due to getting stuck while pushing
			// P.S. *or* an NPC returning to guard position
			"----" A 0 A_SetUserVar("user_stuck_det", user_stuck_det > 0 ? user_stuck_det - 1 : 0)
			"----" A 0 A_JumpIf(!user_stuck_det, "MoveSwitchToThrust")
			
			// in this mode user_swander_cd is an accumulator retaining leftover values 
			// from previous loops to dither speed (can only move in whole A_Wander calls)
			
			"----" A 0 A_JumpIf(user_swander_cd < 2, "MoveAdjustSpeeds")
			"----" A 0 A_SetUserVar("user_angle", angle * 100.0)
			"----" A 0 A_SetAngle(user_strafing_angle)
			Goto MoveWanderPerformMovement
			
		MoveWanderPerformMovement:
			
			"----" A 0 A_Wander // moves Speed map units forward per this function call
			
			// assumes Speed 5
			"----" A 0 A_SetUserVar("user_swander_cd", user_swander_cd - 5) // may go negative!
			"----" A 0 A_JumpIf(user_swander_cd > 0, "MoveWanderPerformMovement")
			Goto MoveWanderAfterMovement
			
		MoveWanderAfterMovement:
			"----" A 0 A_SetUserVar("user_strafing_angle", angle)
			"----" A 0 A_SetAngle(user_angle / 100.0)
			Goto MoveAdjustSpeeds
			
		MoveSwitchToThrust:
			"----" A 0 A_SetUserVar("user_move_wander", 0)
			"----" A 0 ACS_NamedExecuteAlways("SkulltagTransmitSynStateToClient")
			Goto MoveThrust
		
		MoveSwitchToWander:
			"----" A 0 A_SetUserVar("user_swander_cd", 0)
			"----" A 0 A_SetUserVar("user_move_wander", 1)
			
			"----" A 0 A_JumpIf(user_syn_mode == 1 && (user_charge || user_ambush), 2)
			//"----" A 0 A_FaceTarget
			"----" A 0 A_SetUserVar("user_angle", angle * 100.0)
			
			// now select the initial strafing angle according the desired movement direction
			// (will change from hitting obstacles anyway)
			//"----" A 0 A_FaceTarget
			"----" A 0 A_JumpIf(user_backpedal < -2, "MoveSTWBumrush")
			"----" A 0 A_JumpIf(user_backpedal > 2, 2)
			"----" A 0 A_Jump(256, "MoveSTWLeft", "MoveSTWRight")
			// backpedal:
			"----" A 0 A_SetAngle(angle + 180 + Random(-3 * user_strafe, 3 * user_strafe))
			Goto MoveSTWFinish
		MoveSTWLeft:
			"----" A 0 A_SetAngle(angle + 90)
			Goto MoveSTWFinish
		MoveSTWRight:
			"----" A 0 A_SetAngle(angle - 90)
			Goto MoveSTWFinish
		MoveSTWBumrush:	
			"----" A 0 A_SetAngle(angle + Random(-3 * user_strafe, 3 * user_strafe))
			Goto MoveSTWFinish
		MoveSTWFinish:	
			"----" A 0 A_SetUserVar("user_strafing_angle", angle)
			"----" A 0 A_SetAngle(user_angle * 0.01)
			"----" A 0 ACS_NamedExecuteAlways("SkulltagTransmitSynStateToClient")
			Goto MoveWander
			
		MoveAdjustSpeeds:
			// calculates desired speeds from the current threat factor and distance to target
			// NPC player avoidance logic also goes here
			
			"----" A 0 A_SetUserVar("user_strafe", user_strafe < user_thr_acc / 10 ? user_thr_acc / 10 : user_strafe) // sideways dodge from threat sense
			"----" A 0 A_SetUserVar("user_strafe", user_strafe < user_speed_limit ? user_strafe : user_speed_limit)
			
			"----" A 0 A_JumpIf((user_syn_mode == 3 || user_syn_mode == 1) && user_player_num, "MoveNPCSpecific")
			
		MoveAdjustSpeedsContinue:	
			// user_thr_acc is capped at 255, thus speed is capped at 25 -- VERY fast
			// but each dodge-roll eats 100 off user_thr_acc (and each flinch adds 100)
			
			"----" A 0 A_JumpIf(user_thr_chaaarge, "MoveAdjSpForw")
			"----" A 0 A_JumpIfCloser(user_thr_hrr, "MoveAdjSpFleeHRR") // *no* sight check
			"----" A 0 A_JumpIfCloser(user_too_close_range, "MoveAdjSpBack")
			
			Goto MoveFinish
		
		MoveAdjSpForw:
			// fists, chainsaw: 150% speed. Berserk: 200% speed.
			"----" A 0 A_SetUserVar("user_backpedal", - ((user_weapon == 2 ? 8 : (user_weapon == 1 || user_weapon == 3 ? 6 : 4)) + user_maradeur))
			Goto MoveFinish	
			
		MoveAdjSpBack:
			// max (user_thr_acc / 10, 4 + user_maradeur)
			"----" A 0 A_SetUserVar("user_backpedal", user_thr_acc / 10 > 4 + user_maradeur ? user_thr_acc / 10 : 4 + user_maradeur)
			Goto MoveFinish
			
		MoveAdjSpFleeHRR:
			// max (user_thr_acc / 10, 10)
			"----" A 0 A_SetUserVar("user_backpedal", user_thr_acc / 10 > 10 ? user_thr_acc / 10 : 10)
			Goto MoveFinish
		
		MoveNPCSpecific:
			/*
			"----" A 0 ACS_NamedExecuteWithResult("FBD_NPCWatchPlayersLOF") 
			"----" A 0 A_JumpIf(user_avoid_r <= 0, 2) // disabled: maybe that player is dead or missing - making xyz meaningles
			
			// the cylindrical avoidance zone if front of the player we are a follower of:
			"----" A 0 A_JumpIf(!(z > user_avoid_z - 48 && z < user_avoid_z + 96 && user_avoid_r * user_avoid_r > ((x - user_avoid_x) * (x - user_avoid_x) + (y - user_avoid_y) * (y - user_avoid_y))), 2)
			*/
			
			"----" A 0 A_JumpIf(!CallAcs("FBD_NPCCheckIfShouldGetClear"), 2)
			
			// clearing player's line of fire overrides all other forms of forward/back movement:
			"----" A 0 A_SetUserVar("user_backpedal", 7)
			Goto MoveFinish
			
			
			
			
			"----" A 0 A_JumpIfInTargetInventory("IsPlayer", 1, 1)
			Goto MoveAdjustSpeedsContinue
			
			// NPC's target is player, meaning there are no monsters left:
			//"----" A 0 A_JumpIf(user_guarding && ((x - user_guard_x) * (x - user_guard_x) + (y - user_guard_y) * (y - user_guard_y)) > 4096, "MoveReturnToPosition")
			"----" A 0 A_JumpIf(user_guarding && user_syn_mode != 1 && (x - user_guard_x < - 400 || x - user_guard_x > 400 || y - user_guard_y < -400 || y - user_guard_y > 400), "StopGuardingAndFollow")
			
			// Slow down.
			"----" A 0 A_SetUserVar("user_strafe", user_strafe > 3 ? 3 : user_strafe)
			"----" A 0 A_SetUserVar("user_backpedal", user_backpedal > 2 ? user_backpedal - 2 : 0)
			Goto MoveFinish
		
		MoveReturnToPosition:
			"----" A 0 A_SetUserVar("user_strafe", 0)
			"----" A 0 A_SetUserVar("user_backpedal", 0)
			"----" A 0 A_Stop
			"----" A 0 A_JumpIf((user_dx * user_dx) + (user_dy * user_dy) < 10, "MoveFinish") // horizontal speed must be 3 or less
			"----" A 0 A_SetUserVar("user_swander_cd", 10)
			"----" A 0 A_SetUserVar("user_move_wander", 1)
			"----" A 0 A_SetUserVar("user_stuck_det", 1)
			"----" A 0 ACS_NamedExecuteAlways("FBD_NudgeNPCBackToGuardPosition") // easier to code the math in ACS	
			Goto MoveFinish
			
		MoveFinish:	
			"----" A 0
			Goto AnimPhase
			
		



		
			

		AnimPhase:  // must have the duration of exactly 1 tic.
			"----" A 0 A_JumpIf(user_in_air, "AnimJump")

			"----" A 0 A_JumpIf((user_dx * user_dx) + (user_dy * user_dy) > 20, "AnimFastWalk")
			"----" A 0 A_JumpIf(user_dx || user_dy, "AnimSlowWalk")
			// standing still
			//"----" A 0 A_SetUserVar("user_anim_frame", 0)
			//"----" A 0 A_SetUserVar("user_anim_frame_time", 0)
			// standing still:
			"----" A 1 A_Jump(256, "AnimFrame1")
			Wait
		AnimSlowWalk:
			"----" A 0 A_SetUserVar("user_anim_frame_time", user_anim_frame_time + 1)
			"----" A 0 A_JumpIf(user_anim_frame_time >= 4, "AnimNextFrame")
			Goto AnimFrame
		AnimFastWalk:
			"----" A 0 A_SetUserVar("user_anim_frame_time", user_anim_frame_time + 2)
			"----" A 0 A_JumpIf(user_anim_frame_time >= 4, "AnimNextFrame")
			Goto AnimFrame
		AnimNextFrame:
			"----" A 0 A_SetUserVar("user_anim_frame_time", 0)
			"----" A 0 A_SetUserVar("user_anim_frame", user_anim_frame + 1)
			"----" A 0 A_JumpIf(user_anim_frame < 4, "AnimFrame")
			"----" A 0 A_SetUserVar("user_anim_frame", 0)
		AnimFrame:
			"----" A 0 A_JumpIf(user_anim_frame <= 0, "AnimFrame1")
			"----" A 0 A_JumpIf(user_anim_frame == 1, "AnimFrame2")
			"----" A 0 A_JumpIf(user_anim_frame == 2, "AnimFrame3")
			"----" A 0 A_JumpIf(user_anim_frame == 3, "AnimFrame4")
			"----" A 1 // emergency fallback (Zandronum client WILL reach here, it ignores jumps)
			Goto WeaponPhase
		AnimJump:
			"----" A 0 A_SetUserVar("user_anim_frame", 0)
			"----" A 0 A_SetUserVar("user_anim_frame_time", 0)
			"----" A 0 A_Jump(256, "AnimFrameJ")
			"----" A 1 // emergency fallback (Zandronum client WILL reach here, it ignores jumps)
			Goto WeaponPhase
	





			
			
		WeaponPhase: // must have zero duration
		
//"----" A 0 ACS_NAMedExecuteWithResult("FBD_DebugNPCTarget", 2)	

			"----" A 0 A_JumpIf(CheckClass("PatrolPoint", AAPTR_TARGET, true), "ExitSynthLoop")
		
			"----" A 0 A_JumpIf(!user_head_type, 2) // npc
			"----" A 0 A_JumpIfInTargetInventory("TargetIsAChaosMarine", 1, "WeaponClearTarget") // infighting is verboten
		
			// manage weapon cooldown -- independent of syn mode
			"----" A 0 A_JumpIf(!user_wp_cooldown, 2)
			"----" A 0 A_SetUserVar("user_wp_cooldown", user_wp_cooldown > 0 ? user_wp_cooldown - 1 : 0)
		
			"----" A 0 A_JumpIf(user_syn_mode == 1, "WeaponMissile")
			"----" A 0 A_JumpIf(user_has_los && (user_syn_mode == 2 || user_syn_mode == 3) && !user_wp_cooldown, "Missile") // insta-switch to firing
			"----" A 0 A_JumpIf((user_syn_mode == 2 || user_syn_mode == 3) && !user_wp_cooldown, "WeaponLoiter")
			"----" A 0 A_JumpIf(user_syn_mode == 2 || user_syn_mode == 4, "WeaponJumping")
			Goto ThreatSensePhase // Error, unknown syn state. Do nothing.
			

		WeaponLoiter: // the synth state used purely for movement purposes. 
			//  Employs A_Chase to switch to the missile state.
			
			"----" A 0 A_SetUserVar("user_angle", angle * 100.0) 
			// discovered (surprise, moterfracker! says the game engine) that A_Chase with CHF_DONTMOVE often resets angle to zero
			"----" A 0 A_Chase("Missile", "Missile", CHF_DONTMOVE) // Standard missile chance. 
				// Will jump to Missile, which may cause a dodge-roll before proceeding to syn mode 1
			"----" A 0 A_SetAngle(user_angle / 100.0)								
			Goto WeaponFinish	
		
		
		WeaponJumping: // a unique hack for managing the jumping animation. 
			// May fire a snap shot by switching to syn mode 1 (missile)
		
			"----" A 0 A_JumpIf(user_wp_cooldown > 0 || user_syn_mode == 1, "WeaponFinish") // no further action needed
			"----" A 0 A_JumpIfTargetInLOS(1, 130, JLOSF_DEADNOJUMP)
			Goto WeaponFinish
			// user_in_air is managed in the Movement phase
			// no snap shots if melee
			// no snap shots for bfg9k
			"----" A 0 A_JumpIf(user_in_air > 6 && user_weapon > 3 && !user_stand_still, 1) 
		
			Goto WeaponFinish //<-- jumps over this goto here (which is not a frame but rather between the frames)
			
			// An instaneous snap cheat shot the moment we ascend
			// 	 over that 64-high crate on the apex of our arch,
			//   our deadly super shotgun in hand, 
			//   to rain death on the hapless player.
			
			"----" A 0 A_JumpIf(user_head_type, 4)
			"----" A 0 A_JumpIfInventory("IsPlayer", 1, "WeaponFinish", AAPTR_TARGET) // npcs ignore player
			"----" A 0 A_CheckFlag("FRIENDLY", "WeaponFinish", AAPTR_TARGET) // npcs ignore friendlies
			
			"----" A 0 A_JumpIf(true, 2)
			"----" A 0 A_JumpIfInTargetInventory("TargetIsAChaosMarine", 1, "WeaponClearTarget") 
			// chaos marines cannot aggro at each other because there is no kinslayer support (by design!)
			
			"----" A 0 A_SetUserVar("user_syn_mode", 1) // switch to syn mode 1, Missile. Will proceed charging, firing and so on.
			"----" A 0 A_FaceTarget
			"----" A 0 ACS_NamedExecuteAlways("SkulltagTransmitSynStateToClient") // the Zandronum game engine does never sync user variables nor monsters' inventories
			"----" A 0 A_SetUserVar("user_shots", user_burst_length)
			"----" A 0 A_SetUserVar("user_notarget_cooldown", 0)
			"----" A 0 A_SetUserVar("user_shot_cooldown", 0)
			"----" A 0 A_SetUserVar("user_charge", user_charge_time)
			"----" A 0 A_SetUserVar("user_best_d", 0) // invalidate user_best_p
			"----" A 0 A_FaceTarget
			"----" A 0 A_SetUserVar("user_best_a", angle * 182.0444)
			Goto WeaponFinish
			
		WeaponClearTarget:
			"----" A 0 A_ClearTarget
			Goto WeaponFinish

		
		WeaponMissile: // our equivalent of the Missile state. Consists of charging, firing and ambushing
			// If we got here it means we are committed to firing.
			// No dawdling, no loitering, only cooldown can delay us and only ambushing can divert us.
			
			"----" A 0 A_JumpIf(user_wp_cooldown > 0, "WeaponFinish") // do nothing
			
			"----" A 0 A_JumpIf(user_shots <= 0, "WeaponFinish") // we are done.
			// After all shots are fired, the ball is on the Threat Sense phase's side, 
			//   which exits the synth loop to See -- maybe, via a parting dodge-roll.
			
			// For *all* weapons except the bfg, "charge" is actually a pre-fire pause
			//   to give the marines survivable reaction times
			
			"----" A 0 A_JumpIf(user_ambush > 0, "WeaponAmbushing") // assumes charge is full
			
			"----" A 0 A_JumpIf(user_charge < user_charge_time, "WeaponCharging")
			
			Goto WeaponFiring
			
		WeaponCharging:
			"----" A 0 A_SetUserVar("user_charge", user_charge + 1)
			"----" A 0 A_JumpIf(user_charge % 4 == 1, "WpnPobeForTheBest") // every 4 tics (because has to reset d before each probing)
			Goto WeaponChargingFinish
			
		WpnPobeForTheBest:
			"----" A 0 A_JumpIf(!user_has_los, 2)
			"----" A 0 A_SetUserVar("user_best_a", angle * 182.0444)
			"----" A 0 A_SetUserVar("user_best_d", 0) // also invalidates user_best_p

			// Probes take at least one tic to launch and run their script
			
			// P.S. This should save the father of Russian democracy:
			"----" A 0 A_JumpIf(!CallAcs("FBD_RequestExoticManeuver", 2), "WeaponChargingFinish")
			// note duration 2, not 4 - meaning there could be up to 50 synth marines using this
			// at the same time, not 25!
			// But also must not hog it if, say, a ton of minigun evil marines fire at one.
			//  .. whom am I kidding, you die instantly if that many evil marines fire at once.
			
			"----" A 0 A_CustomMissile("SynthMarinesBestAngleProbeCentral", user_muzzle_z - 6, 0, user_best_a * 0.005493164, CMF_ABSOLUTEANGLE |  (user_best_d ? CMF_ABSOLUTEPITCH : CMF_OFFSETPITCH) | CMF_SAVEPITCH, user_best_d ? user_best_p * 0.005493164 : 0) 
			// 0.005493164 = 65536 (= 1.0 fixed) => 360.0
			"----" AAAAA 0 A_CustomMissile("SynthMarinesBestAngleProbe", user_muzzle_z - 6, 0, user_best_a * 0.005493164 + Random(-100, 100) * 0.01 * (1.0 + 0.003 * (user_rightward_vel < 0 ? - user_rightward_vel : user_rightward_vel)), CMF_ABSOLUTEANGLE | (user_best_d ? CMF_ABSOLUTEPITCH : CMF_OFFSETPITCH) | CMF_SAVEPITCH, (user_best_d ? user_best_p * 0.005493164 : 0) + Random(-100, 100) * 0.03) 
			//Screw. Pitch. Random(-30, 30) * 0.01 * (1.0 + 0.01 * (user_forward_vel < 0 ? - user_forward_vel : user_forward_vel)))
			Goto WeaponChargingFinish
		WeaponChargingFinish:
			"----" A 0
			Goto WeaponChargingSFX	// will proceed to weapon-specific effect states that jump to WeaponFinish
			
		WeaponFiring:
			"----" A 0 A_JumpIf(!user_shot_cooldown, 2)
			"----" A 0 A_SetUserVar("user_shot_cooldown", user_shot_cooldown > 0 ? user_shot_cooldown - 1 : 0)
			"----" A 0 A_JumpIf (user_shots > 0 && user_shot_cooldown > 0, "WeaponFinish") // pause between shots of a burst
			Goto WeaponFire
			
		WeaponFire:	
			//"----" A 0 A_SetUserVar("user_ambush", 0) // need keep it to prevent double-ambushing. Cleared in WeaponFireReally.
			"----" A 0 A_SetUserVar("user_shots", user_shots > 0 ? user_shots - 1 : 0)
			"----" A 0 A_SetUserVar("user_shot_cooldown", user_shots > 0 ? user_fire_period : 0)
			"----" A 0 A_JumpIfInTargetInventory("ChainguyguyContinue", 1, "WeaponFireAutoaimed") // otherwise they migrate due to circle-strafing and then fire at a random wall because their firing direction stays locked
			"----" A 0 A_JumpIf(CallAcs("FBD_TargetIsInvisible"), "WeaponBlindfire")
			"----" A 0 A_JumpIf(!user_has_los, "WeaponBlindfire") 
			"----" A 0 A_JumpIfTargetInLOS("WeaponFireAutoaimed")
		WeaponBlindfire:
			"----" A 0 A_SetAngle(user_best_a  * 0.005493164)// / 100.0) //user_angle / 100.0)
			
			// in case of having LOS but target being invisible, updating til the end ofthe current loop
			"----" A 0 A_JumpIf(!user_has_los, 2)
			"----" A 0 A_SetUserVar("user_has_los", 0) 
			
			// Ambush is not applicable for bfg nor for melee weapons.
			// And, of course, this check is only valid before firing the first shot!
			"----" A 0 A_JumpIf(user_ambush || user_stand_still || user_weapon <= 3 || user_shots < user_burst_length, "WeaponFireReally") 
			
			//"----" A 0 A_Jump(user_ambush_chance, "WeaponAmbushInstead")
			Goto WeaponFireReally	
			
		WeaponFireAutoaimed:
			"----" A 0 A_FaceTarget
			"----" A 0 A_SetUserVar("user_best_a", angle * 182.0444)
			"----" A 0 A_JumpIf(user_shots > 0, "WeaponKeepProbing")
			Goto WeaponFireReally
			
		WeaponKeepProbing:
		
			"----" A 0 A_JumpIf(!CallAcs("FBD_RequestExoticManeuver", 2), "WeaponFireReally")
		
			//An EPIC blunder: the firing states downstream use this to determine is best pitch is valid
			// so it *never* got used. Argh.
			// Moved this to WeaponAfterFiring
			//"----" A 0 A_SetUserVar("user_best_d", 0) // also invalidates user_best_p
		
			// these probes will come bearing gifts when it is time to fire the next shot in the burst
			// aim mode zero, won't fire if has no target.
			"----" A 0 A_CustomMissile("SynthMarinesBestAngleProbeCentral", user_muzzle_z - 6, 0, user_best_a * 0.005493164, CMF_ABSOLUTEANGLE | CMF_OFFSETPITCH | CMF_SAVEPITCH, 0)
			"----" AAAAA 0 A_CustomMissile("SynthMarinesBestAngleProbe", user_muzzle_z - 6, 0, user_best_a * 0.005493164 + Random(-100, 100) * 0.01 * (1.0 + 0.003 * (user_rightward_vel < 0 ? - user_rightward_vel : user_rightward_vel)), CMF_ABSOLUTEANGLE | (user_best_d ? CMF_ABSOLUTEPITCH  : CMF_OFFSETPITCH) | CMF_SAVEPITCH, (user_best_d ? user_best_p * 0.005493164 : 0) + Random(-100, 100) * 0.03) 
			
			Goto WeaponFireReally
			
		WeaponAmbushInstead:
			"----" A 0 A_SetUserVar("user_ambush", 1)
			Goto WeaponFinish			
			
		WeaponAmbushing: // freeze, ready to fire a snap shot
			"----" A 0 A_JumpIfTargetInLOS(3, 0, JLOSF_DEADNOJUMP)
			"----" A 0 A_SetUserVar("user_notarget_cooldown", user_notarget_cooldown + 1)
			"----" A 0 A_JumpIf(user_notarget_cooldown > user_ambush_duration && !user_in_air, "WeaponCancelAmbush")
			Goto WeaponFinish
			
			// snap shot from ambush - 8 tics of LOS, very fast
			"----" A 0 A_JumpIfTargetInLOS(3, 0, JLOSF_DEADNOJUMP)
			"----" A 0 A_SetUserVar("user_ambush", user_ambush + 1)
			"----" A 0 A_JumpIf(user_ambush > 8 - user_maradeur , "WeaponFire")
			
			// special effects, only applicable to minigun (spinning sound)
			"----" A 0 A_JumpIf(user_weapon != 7, "WeaponFinish")
			"----" A 0 A_PlaySound("CHAINSPI", CHAN_WEAPON, 1, 1)
			Goto WeaponFinish
			
		WeaponCancelAmbush:
//"----" A 0 A_Log("cancel ambush")
			"----" A 0 A_SetUserVar("user_ambush", 0)
			"----" A 0 A_SetUserVar("user_shots", 0)
			"----" A 0 A_SetUserVar("user_charge", 0)
			"----" A 0 A_SetUserVar("user_syn_mode", 2)
			Goto WeaponFinish

		WeaponFireReally: 
			"----" A 0 A_SetUserVar("user_ambush", 0)
			
			// the states themselves are defined separately for chaos marines and for NPCs
			// because of course they fire different projectiles!
			"----" A 0 A_JumpIf(user_weapon == 4, "WpnFire_Rifle")
			"----" A 0 A_JumpIf(user_weapon == 5, "WpnFire_Shotgun")
			"----" A 0 A_JumpIf(user_weapon == 6, "WpnFire_SSG")
			"----" A 0 A_JumpIf(user_weapon == 7, "WpnFire_Minugun")
			"----" A 0 A_JumpIf(user_weapon == 8, "WpnFire_RL")
			"----" A 0 A_JumpIf(user_weapon == 9, "WpnFire_Plasma")
			"----" A 0 A_JumpIf(user_weapon == 10, "WpnFire_Railgun")
			"----" A 0 A_JumpIf(user_weapon == 11, "WpnFire_BFG")
			"----" A 0 A_JumpIf(user_weapon == 12, "WpnFire_10K")
			"----" A 0 A_JumpIf(user_weapon == 13, "WpnFire_Unmaker")
			
			"----" A 0 A_JumpIf(user_weapon == 15, "SummonAttack")
			"----" A 0 A_JumpIf(user_weapon == 16, "WpnFire_MG42")
			//"----" A 0 A_JumpIf(user_weapon == 17, "WpnFire_Dragonslayer")
			
			
			"----" A 0 A_SetUserVar("user_prev_wpn", 0) // forces knuckles crackle sound on weapon switch afterwards
			
			"----" A 1 A_Jump(256, "MeleeAttack") // inheritance-aware jump
			Wait // Zandronum client will ignore jumps and keep repeating the last frame
		
		OneMoreShot: // can be used by weapon fire states to increase burst length
			"----" A 0 A_JumpIf(user_shots < user_burst_length, 1)
			Goto WeaponAfterFiring
			"----" A 0 A_SetUserVar("user_shots", user_shots + 1)
			Goto WeaponAfterFiring
			
		WeaponAfterFiring:
			
			"----" A 0 A_SetUserVar("user_best_d", 0) // also invalidates user_best_p
			
			// A specific hack, after original BD chaingun guys, to keep firing the minigun at a killed player to splatter him
			// This shit goes on for 200 tics! See player.txt, Death.MonsterMinigun
			"----" A 0 A_JumpIf(user_weapon != 7 || user_shots >= user_burst_length, 3)
			"----" A 0 A_JumpIfInventory("ChainguyguyContinue", 1, "OneMoreShot", AAPTR_TARGET) 
			// if minigun *and* target in LOS, keep firing non-stop!
			"----" A 0 A_SetUserVar("user_shots", user_has_los ? user_burst_length : user_shots)
			
			// randomizing burst length
			// only when one shot in burst is left -- to minimize parasitic recursion by making sure 
			// one more shot is called no more than one time per loop
			"----" A 0 A_JumpIf(user_burst_length < 2 || user_shots != 1, 2) 
			"----" A 0 A_Jump(user_weapon == 7 && user_has_los ? 224 : (user_has_los ? 160 : 64), "OneMoreShot") // Beware of recursion!
			
			"----" A 0 A_JumpIf(user_shots, "WeaponFinish")
			"----" A 0 A_SetUserVar("user_charge", 0)
			"----" A 0 A_SetUserVar("user_wp_cooldown", user_weapon_cooldown_time)
			
			"----" A 0 A_JumpIf(CallAcs("GetIsTargetDead"), "KilledMyTarget") // exits the synth loop
			
			"----" A 0 A_SetUserVar("user_syn_mode", 2)
			
		WeaponFinish:
			"----" A 0
			"----" A 0 A_JumpIf(user_syn_mode == 1 && !user_ambush && user_nag_cooldown < user_nag_period / 3, "BattleCry")
			Goto ThreatSensePhase
			
			
		BattleCry:
			"----" A 0 A_SetUserVar("user_nag_cooldown", Random(user_nag_period / 2, user_nag_period))
			"----" A 0 ACS_NamedExecuteWithResult("FBD_SynthMarineVoice", CHE_HAVEATTHEE)
			Goto ThreatSensePhase
/*			
			"----" A 0 A_JumpIf(!user_head_type, "NpcBattleCry")
			"----" A 0 A_JumpIf(user_maradeur == 1, "Maradeur1BattleCry")
			"----" A 0 A_JumpIf(user_maradeur == 2, "Maradeur2BattleCry")
			"----" A 0 A_JumpIf(user_maradeur == 3, "Maradeur3BattleCry")
			"----" A 0 A_PlaySound("zombiemarine/sight", CHAN_VOICE)
			Goto ThreatSensePhase
			
		Maradeur1BattleCry:
			"----" A 0 A_PlaySound("maradeur/1/sight", CHAN_VOICE)
			Goto ThreatSensePhase
		
		Maradeur2BattleCry:
			"----" A 0 A_PlaySound("maradeur/2/sight", CHAN_VOICE)
			Goto ThreatSensePhase			
			
		Maradeur3BattleCry:
			"----" A 0 A_PlaySound("maradeur/3/sight", CHAN_VOICE)
			Goto ThreatSensePhase			
			
		NpcBattleCry:
			"----" A 0 A_PlaySound("npc/battlecry", CHAN_VOICE)
			Goto ThreatSensePhase
*/			
			
			
			
		
		ThreatSensePhase:  // must have zero duration
			"----" A 0 A_JumpIf(user_thr_cooldown, "ThreatCooldown")
			"----" A 0 A_SetUserVar("user_ddgrll_cldwn", user_ddgrll_cldwn > 2 ? user_ddgrll_cldwn - 2 : 0)
			"----" A 0 A_SetUserVar("user_thr_chaaarge", user_default_weapon <= 3 && !user_maradeur ? 1 : 0)
			
			// Step 1: who is our target? How powerful is he?
			
			"----" A 0 A_JumpIfInTargetInventory("TargetIsAGreatTerribleBoss", 1, "Threat_OhCrap")
			"----" A 0 A_JumpIfInTargetInventory("IsPlayer", 1, "Threat_Player")
			"----" A 0 A_JumpIfInTargetInventory("TargetIsABoss", 1, "Threat_Boss")
			"----" A 0 A_JumpIfInTargetInventory("IsInATank", 1, "Threat_Boss")
			
			"----" A 0 A_JumpIfInTargetInventory("TargetIsAMiniBoss", 1, "Threat_Miniboss")
			
			"----" A 0 A_JumpIfInTargetInventory("TargetIsAChaosMarine", 1, "Threat_Fellow")
			"----" A 0 A_JumpIfInTargetInventory("TargetIsAMarine", 1, "Threat_Fellow")
			
			// take mancubi very seriously, we are critically vulnerable to their flame spam:
			"----" A 0 A_JumpIfInTargetInventory("TargetIsAMancubus", 1, "Threat_Boss") 
			// knights and barons only because higher forms trigger boss checks above:
			"----" A 0 A_JumpIfInTargetInventory("TargetIsABruiser", 1, "Threat_Bruiser") 
			Goto Threat_Lame
			
			
		Threat_Lame:
			"----" A 0 A_SetUserVar("user_thr_mul", 0)
			"----" A 0 A_SetUserVar("user_thr_hrr", 0)
			"----" A 0 A_SetUserVar("user_thr_min", 0)
			"----" A 0 A_JumpIfCloser(650, 2)
			"----" A 0 A_SetUserVar("user_maradeur_weapon", Random(0,100) < 30 ? 8 : 7) // rocket launcher / minigun
			Goto ThreatCalc
			"----" A 0 A_SetUserVar("user_maradeur_weapon", Random(0,100) < 30 ? 3 : 6) // chainsaw / ssg
			Goto ThreatCalc
		Threat_Player: 
			
			
			"----" A 0 A_JumpIf(user_player_num || !user_head_type, "ThreatClearNPC")
			
			// player's threat varies greatly with the weapon he holds:
			
			// only re-evaluate when we can see him:
			"----" A 0 A_JumpIfTargetInLOS(1, 0, JLOSF_DEADNOJUMP)
			Goto ThreatCalc		
// todo:
// --DONE Unmaker is counted as a revenant launcher (? probably for the sake of animation)
// 1. Revolver is counted as a shotgun	-- which is fine		
			
			"----" A 0 A_JumpIfInventory("QPowerQuadDamage",1,"Threat_OhCrap",AAPTR_TARGET)
			"----" A 0 A_JumpIfInventory("PowerTransformBaron",1,"Threat_Player_SSG",AAPTR_TARGET)
			"----" A 0 A_JumpIfInventory("PowerTransformRevenant",1,"Threat_Player_Explo",AAPTR_TARGET)
			"----" A 0 A_JumpIfInventory("FistsSelected",1,"Threat_Player_Fists",AAPTR_TARGET)
			"----" A 0 A_JumpIfInventory("HasBarrel",1,"Threat_Player_Explo",AAPTR_TARGET)
			
			
			// Now, if facing away or if facing sideways and aiming down iron sights or firing,
			//  threat this as player being distracted And BUMRUSH MERCILESSLY
			"----" A 0 A_JumpIf(CallAcs("GetDistanceToTarget") > 500, 4)
			"----" A 0 A_JumpIf(CallAcs("GetTargetsDeltaAngleAtMe") > 120, "Threat_PlayerDistracted") 
			"----" A 0 A_JumpIf(CallAcs("GetTargetsDeltaAngleAtMe") < 60, 2)
			"----" A 0 A_JumpIfInventory("PlayerIsFighting",1,"Threat_PlayerDistracted",AAPTR_TARGET)			
			
			"----" A 0 A_JumpIfInventory("RevenantLauncherSelected",1,"Threat_Player_Explo",AAPTR_TARGET)
			"----" A 0 A_JumpIfInventory("RocketLauncherSelected",1,"Threat_Player_Explo",AAPTR_TARGET)
			"----" A 0 A_JumpIfInventory("GrenadeLauncherSelected",1,"Threat_Player_Explo",AAPTR_TARGET)
			
			// alt shotolver and sniper rifle are slow firing, powerful single-bullet weapons, 
			// so bumrushing if close is a viable tactic
			"----" A 0 A_JumpIfInventory("Shotolver2Selected",1,"Threat_Player_Sniper",AAPTR_TARGET)
			"----" A 0 A_JumpIfInventory("SniperRifleSelected",1,"Threat_Player_Sniper",AAPTR_TARGET)
			
			"----" A 0 A_JumpIfInventory("BFG10kSelected",1,"Threat_Player_BFG10k",AAPTR_TARGET)
			"----" A 0 A_JumpIfInventory("BFGSelected",1,"Threat_Player_BFG",AAPTR_TARGET)
			"----" A 0 A_JumpIfInventory("UnmakerSelected",1,"Threat_Player_Unmaker",AAPTR_TARGET)
			"----" A 0 A_JumpIfInventory("RailGunSelected",1,"Threat_Player_Railgun",AAPTR_TARGET)
			"----" A 0 A_JumpIfInventory("SSGSelected",1,"Threat_Player_SSG",AAPTR_TARGET)
			"----" A 0 A_JumpIfInventory("ShotolverSelected",1,"Threat_Player_SSG",AAPTR_TARGET)
			"----" A 0 A_JumpIfInventory("sawSelected",1,"Threat_Player_Stayback",AAPTR_TARGET)
			"----" A 0 A_JumpIfInventory("AxeSelected",1,"Threat_Player_Stayback",AAPTR_TARGET)
			"----" A 0 A_JumpIfInventory("DragonslayerSelected",1,"Threat_Player_Dragonslayer",AAPTR_TARGET)
			"----" A 0 A_JumpIfInventory("MG42Selected",1,"Threat_Player_MG42",AAPTR_TARGET)
			"----" A 0 A_JumpIfInventory("HasCuttingWeapon",1,"Threat_Player_Stayback",AAPTR_TARGET)
			"----" A 0 A_JumpIfInventory("FlameCannonSelected",1,"Threat_Player_Flameth",AAPTR_TARGET)
			
			//"----" A 0 A_JumpIfInventory("",1,"Threat_Player_",AAPTR_TARGET)
			
			// default (all other weapons):
			"----" A 0 A_SetUserVar("user_thr_mul", 9) // dangerous like a mini-boss but no hrr
			"----" A 0 A_SetUserVar("user_thr_hrr", 0)
			"----" A 0 A_SetUserVar("user_thr_min", 50)
			"----" A 0 A_JumpIfCloser(2000, 2)
			"----" A 0 A_SetUserVar("user_maradeur_weapon", 8) // rocket launcher 
				// This was TOO brutal, unplayable!
				// Only ever use railgun as a mirror
				//Random(0,100) < 80 ? 8 : 10) // rocket launcher / railgun
			Goto ThreatCalc
			"----" A 0 A_JumpIfCloser(1000, 2)
			"----" A 0 A_SetUserVar("user_maradeur_weapon", Random(0,100) < 50 ? 8 : 9) // rocket launcher / plasma
			Goto ThreatCalc
			"----" A 0 A_JumpIfCloser(650, 2)
			"----" A 0 A_SetUserVar("user_maradeur_weapon", Random(0,100) < 70 ? 8 : 6) // rocket launcher / ssg
			Goto ThreatCalc
			"----" A 0 A_JumpIfCloser(350, 2)
			"----" A 0 A_SetUserVar("user_maradeur_weapon", Random(0,100) < 70 ? 6 : 3) // ssg / chainsaw
			Goto ThreatCalc
			"----" A 0 A_SetUserVar("user_maradeur_weapon", Random(0,100) < 70 ? 3 : 6) // ssg / chainsaw
			Goto ThreatCalc
		Threat_PlayerDistracted:
			"----" A 0 A_SetUserVar("user_thr_mul", 0)
			"----" A 0 A_SetUserVar("user_thr_hrr", 0)
			"----" A 0 A_SetUserVar("user_thr_min", 0)
			"----" A 0 A_SetUserVar("user_thr_chaaarge", 1)	
			"----" A 0 A_SetUserVar("user_maradeur_weapon", CallAcs("GetTargetHealth") < 33 ? 2 : 3) // berserk / chainsaw
			Goto ThreatCalc
		Threat_Player_Fists:
			"----" A 0 A_JumpIfInventory("PowerStrength",1,"Threat_Player_Stayback",AAPTR_TARGET) // yikes, he has berserk
			"----" A 0 A_SetUserVar("user_thr_mul", 4) // meh
			"----" A 0 A_SetUserVar("user_thr_hrr", 0)
			"----" A 0 A_SetUserVar("user_thr_min", 0)
			"----" A 0 A_JumpIfCloser(400, 2)
			"----" A 0 A_SetUserVar("user_maradeur_weapon", 4) // rifle, to show you aren't worth using anything better
			Goto ThreatCalc
			"----" A 0 A_SetUserVar("user_maradeur_weapon", 3) // chainsaw
			Goto ThreatCalc
		Threat_Player_SSG:
			"----" A 0 A_SetUserVar("user_thr_mul", 49)
			"----" A 0 A_SetUserVar("user_thr_min", 98)
			"----" A 0 A_SetUserVar("user_thr_hrr", 450)
			"----" A 0 A_JumpIfTargetInLOS(2, 0, JLOSF_DEADNOJUMP, 400) // up close, hes DEDLI
			"----" A 0 A_SetUserVar("user_maradeur_weapon", Random(0,100) < 80 ? 8 : 9) // rocket launcher / plasma
			Goto ThreatCalc	
			"----" A 0 A_SetUserVar("user_thr_mul", 29)
			"----" A 0 A_SetUserVar("user_maradeur_weapon", Random(0,100) < 50 ? 9 : 3) // plasma / chainsaw
			Goto ThreatCalc				
		Threat_Player_Railgun:
			"----" A 0 A_SetUserVar("user_thr_mul", 99)
			"----" A 0 A_SetUserVar("user_thr_min", 202)
			"----" A 0 A_SetUserVar("user_thr_hrr", 0)
			"----" A 0 A_JumpIfTargetInLOS(2, 0, JLOSF_DEADNOJUMP, 300) // rush player if closer than 300
			"----" A 0 A_SetUserVar("user_maradeur_weapon", 10) // railgun -- like with BFGs, mirror!
			Goto ThreatCalc
			"----" A 0 A_SetUserVar("user_thr_chaaarge", 1)	
			"----" A 0 A_SetUserVar("user_maradeur_weapon", 3) // chainsaw
			Goto ThreatCalc
		Threat_Player_Unmaker:	
			"----" A 0 A_SetUserVar("user_thr_mul", 99)
			"----" A 0 A_SetUserVar("user_thr_min", 202)
			"----" A 0 A_SetUserVar("user_thr_hrr", 600) // No. Exceptions. The only way to survive the unmaker
				// is to be far enough for the spread's random gods to spare you.
			"----" A 0 A_SetUserVar("user_maradeur_weapon", 13) // mirror with an Unmaker -- let's test whose Kung Fu is stronger!
			Goto ThreatCalc			
		Threat_Player_BFG10k:	
			// Up close it's explosive, bumrush. Far away it's a bfg 9000.
			"----" A 0 A_JumpIfTargetInLOS("Threat_Player_Explo", 0, JLOSF_DEADNOJUMP, 400)
			"----" A 0 A_SetUserVar("user_thr_mul", 99)
			"----" A 0 A_SetUserVar("user_thr_min", 202)
			"----" A 0 A_SetUserVar("user_thr_hrr", user_weapon <= 3 && !user_maradeur ? 0 : 1200)
			"----" A 0 A_SetUserVar("user_maradeur_weapon", 12) // mirror with a bfg 10k -- let's test whose Kung Fu is stronger!
			Goto ThreatCalc
		Threat_Player_Dragonslayer: 
			"----" A 0 A_SetUserVar("user_thr_mul", 99)
			"----" A 0 A_SetUserVar("user_thr_min", 202)
			"----" A 0 A_SetUserVar("user_thr_hrr", !user_maradeur ? 0 : 400)
			"----" A 0 A_SetUserVar("user_maradeur_weapon", 11) // ***TODO: this is a temporary stub, use bfg9k. When animation ready, change to 17, a Dragonslayer mirror!
			Goto ThreatCalc
		Threat_Player_MG42:
			"----" A 0 A_SetUserVar("user_thr_mul", 99)
			"----" A 0 A_SetUserVar("user_thr_min", 202)
			"----" A 0 A_SetUserVar("user_thr_hrr", 1200)
			"----" A 0 A_SetUserVar("user_maradeur_weapon", 16) // mirror it!
			Goto ThreatCalc
		Threat_Player_BFG:
			"----" A 0 A_SetUserVar("user_thr_mul", 99)
			"----" A 0 A_SetUserVar("user_thr_min", 202)
			"----" A 0 A_SetUserVar("user_thr_hrr", user_weapon == 3 && !user_maradeur ? 0 : 1200) // but not if we have chainsaw selected
			"----" A 0 A_SetUserVar("user_maradeur_weapon", 11) // let's test whose Kung Fu is stronger!
			Goto ThreatCalc
		Threat_Player_Stayback:
			//has berserk or chainsaw! ignore aim but keep distance of at least 400
			"----" A 0 A_SetUserVar("user_thr_mul", 9)
			"----" A 0 A_SetUserVar("user_thr_min", 0)
			"----" A 0 A_SetUserVar("user_thr_hrr", 400)
			"----" A 0 A_SetUserVar("user_maradeur_weapon", 6) // ssg
			Goto ThreatCalc
		Threat_Player_Flameth: //has flame cannon or flamethrower
			"----" A 0 A_SetUserVar("user_thr_mul", 29)
			"----" A 0 A_SetUserVar("user_thr_min", 60)
			"----" A 0 A_SetUserVar("user_thr_hrr", 500)
			"----" A 0 A_JumpIfCloser(500, 2)
			"----" A 0 A_SetUserVar("user_maradeur_weapon", 8) // rocket launcher
			Goto ThreatCalc
			"----" A 0 A_SetUserVar("user_maradeur_weapon", Random(0,100) < 50 ? 6 : 9) // ssg / plasma
			"----" A 0 A_SetUserVar("user_thr_min", 198)
			Goto ThreatCalc			
		Threat_Player_Explo: // has a rocket launcher, grenade launcher, bfg 10k, revenant launcher or a barrell.
			"----" A 0 A_SetUserVar("user_thr_mul", 19)
			"----" A 0 A_SetUserVar("user_thr_min", 98)
			
			"----" A 0 A_JumpIfTargetInLOS(3, 0, JLOSF_DEADNOJUMP, 900) // if closer than 500, rush player instead
			"----" A 0 A_SetUserVar("user_thr_hrr", 0)
			"----" A 0 A_SetUserVar("user_maradeur_weapon", Random(0,100) < 80 ? 9 : 4) // plasma / rifle
			Goto ThreatCalc
			// fall further back if distance, close in aggressively if close enough
			"----" A 0 A_JumpIfTargetInLOS(3, 0, JLOSF_DEADNOJUMP, 500) // if closer than 500, rush player instead
			"----" A 0 A_SetUserVar("user_thr_hrr", 650)
			"----" A 0 A_SetUserVar("user_maradeur_weapon", Random(0,100) < 80 ? 9 : 5) // plasma / shotgun
			Goto ThreatCalc
			// close up quickly
			"----" A 0 A_SetUserVar("user_thr_hrr", 0)
			"----" A 0 A_SetUserVar("user_thr_chaaarge", 1)	
			"----" A 0 A_SetUserVar("user_thr_min", 102)
			"----" A 0 A_SetUserVar("user_maradeur_weapon", Random(0,100) < 80 ? 3 : 6) // chainsaw / ssg
			Goto ThreatCalc
		Threat_Player_Sniper: // has a sniper rifle or alt shotolver, preferred distance is very close
			"----" A 0 A_SetUserVar("user_thr_hrr", 0) // keep closing in, at any distance!
			"----" A 0 A_SetUserVar("user_thr_chaaarge", 1)	
						
			"----" A 0 A_JumpIfTargetInLOS(4, 0, JLOSF_DEADNOJUMP, 900) // if closer than 500, rush player instead
			"----" A 0 A_SetUserVar("user_maradeur_weapon", Random(0,100) < 80 ? 8 : 9) // rocket launcher / plasma
			"----" A 0 A_SetUserVar("user_thr_mul", 19)
			"----" A 0 A_SetUserVar("user_thr_min", 98)
			Goto ThreatCalc
			
			"----" A 0 A_JumpIfTargetInLOS(4, 0, JLOSF_DEADNOJUMP, 500) // if closer than 500, rush player instead
			"----" A 0 A_SetUserVar("user_maradeur_weapon", Random(0,100) < 50 ? 9 : 5) // plasma / shotgun
			"----" A 0 A_SetUserVar("user_thr_mul", 7) // much less dangerous at this distance
			"----" A 0 A_SetUserVar("user_thr_min", 50)	
			Goto ThreatCalc
			
			"----" A 0 A_SetUserVar("user_thr_mul", 5) // meh
			"----" A 0 A_SetUserVar("user_thr_min", 102)
			"----" A 0 A_SetUserVar("user_maradeur_weapon", Random(0,100) < 80 ? 3 : 6) // chainsaw / ssg
			Goto ThreatCalc		
		
		Threat_Fellow:
			"----" A 0 A_SetUserVar("user_thr_mul", 9) // dangerous like a mini-boss but no hrr
			"----" A 0 A_SetUserVar("user_thr_min", 70)
			"----" A 0 A_SetUserVar("user_thr_hrr", 0)
			"----" A 0 A_JumpIfCloser(400, 2)
			"----" A 0 A_SetUserVar("user_maradeur_weapon", Random(0,100) < 30 ? 8 : 9) // rocket launcher / plasma
			Goto ThreatCalc
			"----" A 0 A_SetUserVar("user_maradeur_weapon", Random(0,100) < 30 ? 3 : 6) // chainsaw / ssg
			Goto ThreatCalc
		Threat_Bruiser:
			"----" A 0 A_SetUserVar("user_thr_mul", 19)
			"----" A 0 A_SetUserVar("user_thr_min", 98)
			"----" A 0 A_SetUserVar("user_thr_hrr", user_weapon <= 3 && !user_maradeur ? 0 : 400)
			"----" A 0 A_JumpIfCloser(700, 2)
			"----" A 0 A_SetUserVar("user_maradeur_weapon", Random(0,100) < 70 ? 8 : 9) // rocket launcher / plasma
			Goto ThreatCalc
			"----" A 0 A_SetUserVar("user_maradeur_weapon", Random(0,100) < 70 ? 6 : 8) // ssg / rocket launcher
			Goto ThreatCalc
		Threat_Miniboss:
			"----" A 0 A_SetUserVar("user_thr_mul", 29)
			"----" A 0 A_SetUserVar("user_thr_min", 98)
			"----" A 0 A_SetUserVar("user_thr_hrr", user_weapon == 3 ? 0 : 650) // cannot set higher, hexen dodging stops working
			"----" A 0 A_JumpIfCloser(700, 2)
			"----" A 0 A_SetUserVar("user_maradeur_weapon", 8) // rocket launcher
			Goto ThreatCalc			
			"----" A 0 A_SetUserVar("user_maradeur_weapon", Random(0,100) < 30 ? 6 : 8) // ssg / rocket launcher
			Goto ThreatCalc
		Threat_Boss:
			"----" A 0 A_SetUserVar("user_thr_mul", 39)
			"----" A 0 A_SetUserVar("user_thr_min", 102)
			"----" A 0 A_SetUserVar("user_thr_hrr", 1200) // want to be as far from him as possible
			"----" A 0 A_SetUserVar("user_maradeur_weapon", Random(0,100) < 70 ? 8 : 10) // rocket launcher / railgun
			Goto ThreatCalc
		Threat_OhCrap:
			"----" A 0 A_SetUserVar("user_thr_mul", 49)
			"----" A 0 A_SetUserVar("user_thr_min", 198)
			"----" A 0 A_SetUserVar("user_thr_hrr", 2000) // stay in cover fearfully
			"----" A 0 A_SetUserVar("user_maradeur_weapon", Random(0,100) < 30 ? 10 : 11) // railgun / bfg
			Goto ThreatCalc
		ThreatClearNPC:
			"----" A 0 A_SetUserVar("user_thr_mul", 0)
			"----" A 0 A_SetUserVar("user_thr_min", 0)
			"----" A 0 A_SetUserVar("user_thr_hrr", 0) 
			Goto ThreatCalc			
		
		ThreatCalc:
			// Step 2: is he aiming in our direction? (accumulate threat factor over time)
			
			"----" A 0 A_JumpIfInTargetInventory("IsPlayer", 1, "ThreatCalc_Player")
			
			// monsters' facing is disregarded because it is cosmetic anyway
			"----" A 0 A_SetUserVar("user_thr_acc", (user_thr_min > user_thr_acc ? user_thr_min : user_thr_acc) + 1 + user_thr_mul)
			Goto ThreatWpnSwitch
			
			
		ThreatCalc_Player:	
		
			// the threat accumulator will degrade over time if no los or the target is facing away from us			
			"----" A 0 A_JumpIf(CallAcs("GetTargetsDeltaAngleAtMe") > 90, "ThreatWpnSwitch") 
			
			// horizontal only: checking for vertical aim is beyond this scripting language
			"----" A 0 A_JumpIfInTargetLOS("ThreatCalcAimingAtUs", 5, JLOSF_DEADNOJUMP | JLOSF_CLOSENOSIGHT, user_thr_hrr > 1200 ? user_thr_hrr : 1200, user_melee_range)
			
			"----" A 0 A_JumpIfInTargetLOS("ThreatCalcLookingAtUs", 25, JLOSF_DEADNOJUMP | JLOSF_CLOSENOSIGHT, user_thr_hrr > 700 ? user_thr_hrr : 700, user_melee_range)
			
			"----" A 0 A_JumpIf(user_thr_acc > user_thr_min, "ThreatWpnSwitch")
			"----" A 0 A_SetUserVar("user_thr_acc",	user_thr_min)				
			
			Goto ThreatWpnSwitch 
			
		ThreatCalcAimingAtUs:	
			"----" A 0 A_SetUserVar("user_thr_acc", (user_thr_min > user_thr_acc ? user_thr_min : user_thr_acc) + 2 + user_thr_mul * 2)
			Goto ThreatWpnSwitch
			
		ThreatCalcLookingAtUs:
			// if the player has fired his weapon in the last 5 seconds or is aiming down iron sights, increase his danger rating:
			"----" A 0 A_JumpIfInTargetInventory("PlayerIsFighting", 1, "ThreatCalcAimingAtUs")
			"----" A 0 A_SetUserVar("user_thr_acc", (user_thr_min > user_thr_acc ? user_thr_min : user_thr_acc) + 1 + user_thr_mul)
			Goto ThreatWpnSwitch
		
		ThreatWpnSwitch:
			"----" A 0 A_JumpIf(user_maradeur, "ThreatMaradeurLogic")
			
			// Step 3: do we need to switch our weapon ?
			
			// This state can only choose between default and melee.
			// Maradeur's is *much* more sophisticated.
			
			// not legible for weapon switch
			"----" A 0 A_JumpIf(user_wp_cooldown || user_in_air || (user_syn_mode == 1 && (user_shots || (user_charge && user_stand_still))), "ThreatFinish")
				
			"----" A 0 A_JumpIf(user_weapon >= 4, "ThrWeHaveRangedWeaponSelected")
			Goto ThrWeHaveMeleeWeaponSelected
		ThrWeHaveMeleeWeaponSelected:
			"----" A 0 A_JumpIf(user_default_weapon <= 3, "ThreatFinish") // do nothing 
				// if we only have a melee weapon (the fist, berserk and chainsaw marines)
			//Five melee misses force a switch to ranged weapon
			"----" A 0 A_JumpIfInventory("MeleeMiss", 5, "ThrSwitchToRanged")
			
			// If the opponent has a Horrible Rape Radius defined, that forces a switch to ranged:
			"----" A 0 A_JumpIf(user_thr_hrr, "ThrSwitchToRanged")
			"----" A 0 A_JumpIfCloser(user_melee_range + 96, "ThreatFinish") // don't switch while in the melee range
			Goto ThrSwitchToRanged
			
		ThrWeHaveRangedWeaponSelected:
			"----" A 0 A_JumpIf(user_thr_hrr, "ThreatFinish") // NEVER switch to melee 
				// if the opponent has a Horrible Rape Radius defined!
			"----" A 0 A_JumpIfInventory("MeleeMiss", 1, "ThreatFinish") // do not switch to melee 
				// until we forget the trauma of not hitting out target (decreased with each attack)
				// Even a single miss prevents us from switching to melee
				//  but 5 are required to force switch to our ranged weapon 
				//  regardless of distance - such a nice histeresis loop.
			"----" A 0 A_JumpIfTargetInLOS("ThrSwitchToMelee", 130, JLOSF_DEADNOJUMP, user_melee_range)
			Goto ThreatFinish
			
		ThrSwitchToRanged:
			"----" A 0 A_SetUserVar("user_see_after_wp_sw", 0) // return to the synth loop afterwards
			"----" A 0 A_SetUserVar("user_weapon", user_default_weapon)
			Goto WeaponSwitch

		ThrSwitchToMelee:
			"----" A 0 A_SetUserVar("user_see_after_wp_sw", 0) // return to the synth loop afterwards
			"----" A 0 A_SetUserVar("user_weapon", user_melee_weapon)
			Goto WeaponSwitch
			
	
		ThreatFinish:
			"----" A 0 A_SetUserVar("user_thr_cooldown", 5)
			"----" A 0 A_SetUserVar("user_thr_acc", user_thr_acc > 255 ? 255 : user_thr_acc - 10)
			"----" A 0 A_JumpIf(!user_wp_cooldown, "MaybeEndSynthLoop")
			
			// if the targeit is aiming at us, and our weapon is on cooldown (we just fired, then dodge-roll 
			// with probability matching the threat level:
			"----" A 0 A_JumpIfInTargetLOS(1, 18, JLOSF_DEADNOJUMP, user_thr_hrr > 1200 ? user_thr_hrr : 1200)
			Goto MaybeEndSynthLoop
			"----" A 0 A_Jump(user_thr_acc, "ThreatDodgeRollOnWpCldwn")
			Goto MaybeEndSynthLoop
			
		ThreatDodgeRollOnWpCldwn:
			"----" A 0 A_SetUserVar("user_thr_acc", user_thr_acc > 100 ? user_thr_acc - 100 : 0)	
			Goto DodgeRoll	
			
		ThreatCooldown:
			"----" A 0 A_SetUserVar("user_thr_cooldown", user_thr_cooldown - 1)
			Goto MaybeEndSynthLoop
			
		ThreatMaradeurLogic: 
			"----" A 0 A_SetUserVar("user_marad_wpsw_cdn", user_marad_wpsw_cdn > 3 ? user_marad_wpsw_cdn - 3 : 0)
			"----" A 0 A_SetUserVar("user_thr_acc", user_thr_acc > 255 ? 255 : user_thr_acc - 10)
			"----" A 0 A_SetUserVar("user_summon_cooldown", user_summon_cooldown > 3 ? user_summon_cooldown - 3 : 0)
			
			"----" A 0 A_JumpIf(user_maradeur < 2 || user_summon_cooldown, 2)
			"----" A 0 A_SetUserVar("user_maradeur_weapon", 15) // he *also* goes into summoning from his chase state
			
			// user_loiter_count here prevents premature switching after just initiating the missile state
			"----" A 0 A_JumpIf(user_maradeur_weapon != user_weapon && (user_syn_mode == 1 ? (user_loiter_count > 2 && (!user_shots || user_wp_cooldown)) : !user_marad_wpsw_cdn), "MaradThinkOfSwitching")
			//: user_loiter_count > 45), "MaradThinkOfSwitching")
			//***TODO: investigate, switches too little
			Goto ThreatMaradFinish

		MaradThinkOfSwitching:
			// railgun, bfgs and summoning are excluded from probability checking, jump immediately:
			"----" A 0 A_Jump((user_maradeur_weapon == 10 || user_maradeur_weapon == 11 || user_maradeur_weapon == 12 || user_maradeur_weapon == 13 || user_maradeur_weapon == 15) ? 256 : user_maradeur * 24, "MaradSwitch")
			Goto ThreatMaradFinish
			
		MaradSwitch:
			"----" A 0 A_SetUserVar("user_marad_wpsw_cdn", 70)
			"----" A 0 A_SetUserVar("user_see_after_wp_sw", 0) // return to the synth loop afterwards
			"----" A 0 A_SetUserVar("user_weapon", user_maradeur_weapon)
			Goto WeaponSwitch
			
		ThreatMaradFinish:
		
			"----" A 0 A_SetUserVar("user_thr_cooldown", 3) // rather than 5 for regular marines
			
			//"----" A 0 A_JumpIf(user_maradeur > 1&& !user_summon_cooldown && !(user_stand_still && user_shots && user_syn_mode == 1), "SummonHellhounds")

			"----" A 0 A_JumpIf(!user_wp_cooldown, "MaybeEndSynthLoop")
			
			// if the target is aiming at us, and our weapon is on cooldown (we just fired), then dodge-roll 
			// with probability matching the threat level:
			"----" A 0 A_JumpIfInTargetLOS(1, 18, JLOSF_DEADNOJUMP, user_thr_hrr > 1200 ? user_thr_hrr : 1200)
			Goto MaybeEndSynthLoop
			"----" A 0 A_Jump(user_thr_acc, "ThreatDodgeRollOnWpCldwn")
			Goto MaybeEndSynthLoop
			
		

		MaybeEndSynthLoop:
			
			// missile mode: stay another 6 tics to assure animation consistency
			"----" A 0 A_JumpIf(user_syn_mode == 1 && !user_shots && user_loiter_count > 5 && !user_ambush && user_wp_cooldown <= (user_weapon_cooldown_time > 6 ? user_weapon_cooldown_time - 6 : 0), "ExitSynthLoop")
			"----" A 0 A_JumpIf(user_syn_mode == 3 && user_loiter_count > 30, "ExitSynthLoop")
			"----" A 0 A_JumpIf(user_syn_mode >= 2 && user_syn_mode <= 4 && user_loiter_count > 90, "ExitSynthLoop")
			"----" A 0 A_JumpIf(user_syn_mode == 5 && (!user_guarding || ((x - user_guard_x) * (x - user_guard_x) + (y - user_guard_y) * (y - user_guard_y)) < 4096), "ExitSynthLoop")
			Goto SynthLoop
			
		SummonGoesIntoCooldown:
			"----" A 0 A_SetUserVar("user_summon_cooldown", 350) // 10 seconds
			Goto See			
			
		SummonHellhounds: // maradeur only
			"----" A 0 A_JumpIf(user_maradeur < 2, "SummonGoesIntoCooldown")
			// alive summons limit:
			"----" A 0 A_JumpIfInventory("SummonsCount", user_maradeur == 3 ? 5 : 2, "SummonGoesIntoCooldown") // 1 => none, 2 => 2, 3 => 5
			"----" A 0 A_SetUserVar("user_weapon", 15)
			"----" A 0 A_SetUserVar("user_see_after_wp_sw", 0)
			Goto WeaponSwitch // leads to the synth Missile state to actually fire the dog
			
		WeaponSwitch:
			// does NOT affect weapon cooldown
			//"----" A 0 A_SetUserVar("user_wp_cooldown", 0)
			
			"----" A 0 A_SetUserVar("user_charge", 0)
			"----" A 0 A_SetUserVar("user_shots", 0)
			"----" A 0 A_SetUserVar("user_ambush", 0)
			"----" A 0 A_SetUserVar("user_shot_cooldown", 0)
			"----" A 0 A_SetUserVar("user_anim_frame", 0)	
			"----" A 0 A_SetUserVar("user_anim_frame_time", 0)
			"----" A 0 A_JumpIf(user_weapon, 2)
			"----" A 0 A_SetUserVar("user_weapon", user_default_weapon)
			
			"----" A 0 A_JumpIf(user_weapon >= 4, 3)
			"----" A 0 A_TakeInventory("MeleeMiss", 99)
			"----" A 0 A_TakeInventory("MeleeHitSuccess", 99)
			
			// If this is Zandronum client-server multiplayer, and this is running on the server,
			//   will rlay this via running SkulltagClientsideWeaponSwitch, which command would be
			//   transmitted to the client over the network thus syncing this user variable
			//   (the clientside script then forces the clientside instance of this monster into
			//   this WeaponSwitch state)
			// Otherwise, user variables on the server and the client are independent
			"----" A 0 ACS_NamedExecuteAlways("SkulltagTransmitWeaponSwitchToClient", 0, user_weapon,0,0)
			
			"----" A 0 A_JumpIf(user_weapon == 2, "WeaponSwitch_Berserk")
			"----" A 0 A_JumpIf(user_weapon == 3, "WeaponSwitch_Chainsaw")
			"----" A 0 A_JumpIf(user_weapon == 4, "WeaponSwitch_Rifle")
			"----" A 0 A_JumpIf(user_weapon == 5, "WeaponSwitch_Shotgun")
			"----" A 0 A_JumpIf(user_weapon == 6, "WeaponSwitch_SSG")
			"----" A 0 A_JumpIf(user_weapon == 7, "WeaponSwitch_Minugun")
			"----" A 0 A_JumpIf(user_weapon == 8, "WeaponSwitch_RL")
			"----" A 0 A_JumpIf(user_weapon == 9, "WeaponSwitch_Plasma")
			"----" A 0 A_JumpIf(user_weapon == 10, "WeaponSwitch_Railgun")
			"----" A 0 A_JumpIf(user_weapon == 11, "WeaponSwitch_BFG")
			"----" A 0 A_JumpIf(user_weapon == 12, "WeaponSwitch_10K")
			"----" A 0 A_JumpIf(user_weapon == 13, "WeaponSwitch_Unmaker")
			
			"----" A 0 A_JumpIf(user_weapon == 15, "WeaponSwitch_Summon")
			"----" A 0 A_JumpIf(user_weapon == 16, "WeaponSwitch_MG42")
					
		//***Che Please note that meleee attacks are separate states OUTSIDE the synth loop!
		//  all melee attacks are leap attacks with very high speed and very large distance
		//  that fire actual attacks when both momx and momy drop below 2
		
		WeaponSwitch_Fists:
			"----" A 0 A_JumpIf(user_prev_wpn == 1, 2)
			"----" A 0 A_PlaySound("Knuckled", CHAN_WEAPON)
			"----" A 0 A_SetUserVar("user_ambush_duration", 0)
			"----" A 0 A_SetUserVar("user_ambush_chance", 0)
			"----" A 0 A_SetUserVar("user_fire_period", 0)
			"----" A 0 A_SetUserVar("user_burst_length", 1)
			"----" A 0 A_SetUserVar("user_weapon_cooldown_time", 18)
			"----" A 0 A_SetUserVar("user_muzzle_z", 35) 
			"----" A 0 A_SetUserVar("user_charge_time", 0)
			"----" A 0 A_SetUserVar("user_melee_range", 200) // 
			"----" A 0 A_SetUserVar("user_too_close_range", 50) // makes him backpedal after each attack, which involves circle-strafing
			"----" A 0 A_SetUserVar("user_stand_still", 0) // can instafire during a jump		
			Goto WeaponSwitchFinish
			
		WeaponSwitch_Berserk:
			"----" A 0 A_JumpIf(user_prev_wpn == 2, 2)
			"----" A 0 A_PlaySound("Knuckled", CHAN_WEAPON)	
			"----" A 0 A_SetUserVar("user_ambush_duration", 0)
			"----" A 0 A_SetUserVar("user_ambush_chance", 0)
			"----" A 0 A_SetUserVar("user_fire_period", 0)
			"----" A 0 A_SetUserVar("user_burst_length", 1)
			"----" A 0 A_SetUserVar("user_weapon_cooldown_time", 6)
			"----" A 0 A_SetUserVar("user_muzzle_z", 35) 
			"----" A 0 A_SetUserVar("user_charge_time", 0) 
			"----" A 0 A_SetUserVar("user_melee_range", 300) // 
			"----" A 0 A_SetUserVar("user_too_close_range", 50) // makes him backpedal after each attack, which involves circle-strafing
			"----" A 0 A_SetUserVar("user_stand_still", 0) // can instafire during a jump		
			Goto WeaponSwitchFinish

		WeaponSwitch_Chainsaw:
			"----" A 0 A_JumpIf(user_prev_wpn == 3, 2)
			"----" A 0 A_PlaySound("weapons/chainsaw/draw", CHAN_WEAPON)	
			"----" A 0 A_Giveinventory("HasCutingWeapon",1)
			"----" A 0 A_SetUserVar("user_ambush_duration", 0)
			"----" A 0 A_SetUserVar("user_ambush_chance", 0)
			"----" A 0 A_SetUserVar("user_fire_period", 0)
			"----" A 0 A_SetUserVar("user_burst_length", 1) 
			"----" A 0 A_SetUserVar("user_weapon_cooldown_time", 3)
			"----" A 0 A_SetUserVar("user_muzzle_z", 35) 
			"----" A 0 A_SetUserVar("user_charge_time", 0)
			"----" A 0 A_SetUserVar("user_melee_range", 300) // 
			"----" A 0 A_SetUserVar("user_stand_still", 0) // can instafire during a jump	
			"----" A 0 A_SetUserVar("user_wp_cooldown", user_wp_cooldown < 15 ? 15 : user_wp_cooldown) // before can use the selected weapon
			"----" A 0 A_SetUserVar("user_too_close_range", 50) // makes him backpedal after each attack, which involves circle-strafing			
			Goto WeaponSwitchFinish
		WeaponSwitch_Rifle:
			"----" A 0 A_JumpIf(user_prev_wpn == 4, 2)
			"----" A 0 A_PlaySound("CLIPIN", CHAN_WEAPON)	
			"----" A 0 A_SetUserVar("user_ambush_duration", 75)
			"----" A 0 A_SetUserVar("user_ambush_chance", 64)
			"----" A 0 A_SetUserVar("user_fire_period", 5)
			"----" A 0 A_SetUserVar("user_burst_length", 7)
			"----" A 0 A_SetUserVar("user_weapon_cooldown_time", 20)
			"----" A 0 A_SetUserVar("user_muzzle_z", 39) // NOTE: varies when in jump, the animation phase constantly overwrites this!
			"----" A 0 A_SetUserVar("user_charge_time", 8) // very sharp reflexes
			"----" A 0 A_SetUserVar("user_melee_range", 150) // rather close
			"----" A 0 A_SetUserVar("user_too_close_range", 300) // prefers medium distances		
			"----" A 0 A_SetUserVar("user_stand_still", 0) // can instafire during a jump
			Goto WeaponSwitchFinish
		WeaponSwitch_Shotgun:
			"----" A 0 A_JumpIf(user_prev_wpn == 5, 2)
			"----" A 0 A_PlaySound("weapons/sgpump", CHAN_WEAPON)	
			"----" A 0 A_SetUserVar("user_ambush_duration", 75)
			"----" A 0 A_SetUserVar("user_ambush_chance", 128)
			"----" A 0 A_SetUserVar("user_fire_period", 0) // not applicable, coodown takes this role
			"----" A 0 A_SetUserVar("user_weapon_cooldown_time", 30) //like player's
			"----" A 0 A_SetUserVar("user_burst_length", 1)
			"----" A 0 A_SetUserVar("user_muzzle_z", 33) 
			"----" A 0 A_SetUserVar("user_charge_time", 12) // half a second charge time -- forewarn the player!
			"----" A 0 A_SetUserVar("user_melee_range", 90) // only very, very close
			"----" A 0 A_SetUserVar("user_too_close_range", 200) // results in ambushes
			"----" A 0 A_SetUserVar("user_stand_still", 0) // can instafire during a jump
			Goto WeaponSwitchFinish
		WeaponSwitch_SSG:
			"----" A 0 A_JumpIf(user_prev_wpn == 6, 2)
			"----" A 0 A_PlaySound("weapons/sshotc", CHAN_WEAPON)	
			"----" A 0 A_SetUserVar("user_ambush_duration", 250) // 8 seconds, results in deadly ambushes
			"----" A 0 A_SetUserVar("user_ambush_chance", 192)
			"----" A 0 A_SetUserVar("user_fire_period", 0)
			"----" A 0 A_SetUserVar("user_weapon_cooldown_time", 60) //a bit longer than player's
			"----" A 0 A_SetUserVar("user_burst_length", 1)
			"----" A 0 A_SetUserVar("user_muzzle_z", 31) // NOTE: varies when in jump, the animation phase constantly overwrites this!
			"----" A 0 A_SetUserVar("user_charge_time", 8) // dedli sharp reflexes
			"----" A 0 A_SetUserVar("user_melee_range", 1) // never
			"----" A 0 A_SetUserVar("user_too_close_range", 100) // prefers close range, results in ambushes
			"----" A 0 A_SetUserVar("user_wp_cooldown", user_wp_cooldown < 15 ? 15 : user_wp_cooldown)  // before can use the selected weapon
			Goto WeaponSwitchFinish
		WeaponSwitch_Minugun:
			"----" A 0 A_JumpIf(user_prev_wpn == 7, 2)
			"----" A 0 A_PlaySound("CHGNPKUP", CHAN_WEAPON)	
			"----" A 0 A_SetUserVar("user_ambush_duration", 75)
			"----" A 0 A_SetUserVar("user_ambush_chance", 128)
			"----" A 0 A_SetUserVar("user_fire_period", 3)
			"----" A 0 A_SetUserVar("user_burst_length", 6) // this is *minimum*! Can add randomly
			"----" A 0 A_SetUserVar("user_weapon_cooldown_time", 10)
			"----" A 0 A_SetUserVar("user_muzzle_z", 33) 
			"----" A 0 A_SetUserVar("user_charge_time", 15) // half a second
			"----" A 0 A_SetUserVar("user_melee_range", 120) // rather close
			"----" A 0 A_SetUserVar("user_too_close_range", 300) // prefers short distances		
			"----" A 0 A_SetUserVar("user_stand_still", 0) // can instafire during a jump
			Goto WeaponSwitchFinish
		WeaponSwitch_RL:
			"----" A 0 A_JumpIf(user_prev_wpn == 8, 2)
			"----" A 0 A_PlaySound("RLANDRAW", CHAN_WEAPON)	
			"----" A 0 A_SetUserVar("user_ambush_duration", 75)
			"----" A 0 A_SetUserVar("user_ambush_chance", 48)
			"----" A 0 A_SetUserVar("user_fire_period", 15)
			"----" A 0 A_SetUserVar("user_weapon_cooldown_time", 15)
			"----" A 0 A_SetUserVar("user_burst_length", 1)
			"----" A 0 A_SetUserVar("user_muzzle_z", 44) 
			"----" A 0 A_SetUserVar("user_charge_time", 35) // a whole second -- not actually charging, just aiming
			"----" A 0 A_SetUserVar("user_melee_range", 300) // very far, no firing up close
			"----" A 0 A_SetUserVar("user_too_close_range", 600) // prefers far distances		
			"----" A 0 A_SetUserVar("user_stand_still", 0) // can instafire during a jump
			"----" A 0 A_SetUserVar("user_wp_cooldown", user_wp_cooldown < 30 ? 30 : user_wp_cooldown)
			Goto WeaponSwitchFinish
		WeaponSwitch_Plasma:
			"----" A 0 A_JumpIf(user_prev_wpn == 9, 2)
			"----" A 0 A_PlaySound("PLSDRAW", CHAN_WEAPON)	
			"----" A 0 A_SetUserVar("user_ambush_duration", 45) // short
			"----" A 0 A_SetUserVar("user_ambush_chance", 96)
			"----" A 0 A_SetUserVar("user_fire_period", 5) // between shots
			"----" A 0 A_SetUserVar("user_weapon_cooldown_time", 25)
			"----" A 0 A_SetUserVar("user_burst_length", 6)
			"----" A 0 A_SetUserVar("user_muzzle_z", 35) 
			"----" A 0 A_SetUserVar("user_charge_time", 0) // no charge required
			"----" A 0 A_SetUserVar("user_melee_range", 150) 
			"----" A 0 A_SetUserVar("user_too_close_range", 300) // prefers short-ish distances
			"----" A 0 A_SetUserVar("user_stand_still", 0) // can start firing during a jump
			"----" A 0 A_SetUserVar("user_wp_cooldown", user_wp_cooldown < 15 ? 15 : user_wp_cooldown)
			Goto WeaponSwitchFinish
		WeaponSwitch_Railgun:
			"----" A 0 A_JumpIf(user_prev_wpn == 10, 2)
			"----" A 0 A_PlaySound("BEPBEP", CHAN_WEAPON)	
			"----" A 0 A_SetUserVar("user_ambush_duration", 75)
				// Normally chance is 0 but this applies to other paths of activating the synth loop that bypass the Missile state.
			"----" A 0 A_SetUserVar("user_ambush_chance", 0)
			"----" A 0 A_SetUserVar("user_fire_period", 0)
			"----" A 0 A_SetUserVar("user_weapon_cooldown_time", 35)
			"----" A 0 A_SetUserVar("user_burst_length", 1)
			"----" A 0 A_SetUserVar("user_muzzle_z", 44) 
			"----" A 0 A_SetUserVar("user_charge_time", 35) // a whole second -- not actually charging, just aiming
			"----" A 0 A_SetUserVar("user_melee_range", 300) // very far, no firing up close
			"----" A 0 A_SetUserVar("user_too_close_range", 1200) // prefers extreme distances		
			Goto WeaponSwitchFinish
		WeaponSwitch_BFG:
			"----" A 0 A_JumpIf(user_prev_wpn == 11, 2)
			"----" A 0 A_PlaySound("BFGREADY", CHAN_WEAPON)
			"----" A 0 A_SetUserVar("user_ambush_duration", 120) // veeeery long ambushes
			"----" A 0 A_SetUserVar("user_ambush_chance", 0)//  normally, n/a. Cannot snap shoot.
			"----" A 0 A_SetUserVar("user_fire_period", 0) // no pause between shots
			"----" A 0 A_SetUserVar("user_weapon_cooldown_time", 35) //3) // to prevent algorithmically locking him in a firing sequence.
			"----" A 0 A_SetUserVar("user_burst_length", 1)
			"----" A 0 A_SetUserVar("user_muzzle_z", 34) 
			"----" A 0 A_SetUserVar("user_charge_time", 35) // a whole second
			"----" A 0 A_SetUserVar("user_melee_range", 1) // will NOT engage in meelee
			"----" A 0 A_SetUserVar("user_too_close_range", 400) // prefers medium distances
			"----" A 0 A_SetUserVar("user_stand_still", 1) // cannot skip charging in a jump or interrupt charging
			"----" A 0 A_SetUserVar("user_wp_cooldown", user_wp_cooldown < 15 ? 15 : user_wp_cooldown)
			Goto WeaponSwitchFinish
		WeaponSwitch_10K:
			"----" A 0 A_JumpIf(!user_head_type, "WeaponSwitchNPCsCant10K")
			"----" A 0 A_JumpIf(user_prev_wpn == 12, 2)
			"----" A 0 A_PlaySound("BFGREADY", CHAN_WEAPON)
			"----" A 0 A_SetUserVar("user_ambush_duration", 120) // veeeery long ambushes
			"----" A 0 A_SetUserVar("user_ambush_chance", 0)//  normally, n/a. Cannot snap shoot.
			"----" A 0 A_SetUserVar("user_fire_period", 8) // terrifyingly devastating fire rate, this one has
			"----" A 0 A_SetUserVar("user_weapon_cooldown_time", 35) //3) // to prevent algorithmically locking him in a firing sequence.
			"----" A 0 A_SetUserVar("user_burst_length", 3) // subject to random increase during firing
			"----" A 0 A_SetUserVar("user_muzzle_z", 30) 
			"----" A 0 A_SetUserVar("user_charge_time", 35) // a whole second
			"----" A 0 A_SetUserVar("user_melee_range", 300) // the 10k chaos marine has super shotgun set as his melee weapon
			"----" A 0 A_SetUserVar("user_too_close_range", 700) // prefers far distances
			"----" A 0 A_SetUserVar("user_stand_still", 1) // cannot skip charging in a jump or interrupt charging
			"----" A 0 A_SetUserVar("user_wp_cooldown", user_wp_cooldown < 15 ? 15 : user_wp_cooldown)
			Goto WeaponSwitchFinish	

		WeaponSwitch_Unmaker:
			"----" A 0 A_JumpIf(!user_head_type, "WeaponSwitchNPCsCant10K")
			"----" A 0 A_JumpIf(user_prev_wpn == 13, 2)
			"----" A 0 A_PlaySound("UNMREADY", CHAN_WEAPON)
			"----" A 0 A_SetUserVar("user_ambush_duration", 10) // zilch
			"----" A 0 A_SetUserVar("user_ambush_chance", 0)//  normally, n/a. Cannot snap shoot.
			"----" A 0 A_SetUserVar("user_fire_period", 4) 
				// The damage is the same as player's (50) but fire rate is 1/4th
				//   thus making it only inflict 50% of what it should.
				//   still "you are dead" tier.
			"----" A 0 A_SetUserVar("user_weapon_cooldown_time", 15)
			"----" A 0 A_SetUserVar("user_burst_length", 2) // with a very high chance of it continuing if target is in sight
			"----" A 0 A_SetUserVar("user_muzzle_z", 34) 
			"----" A 0 A_SetUserVar("user_charge_time", 15) // still longer than the player's 4 tics!
			"----" A 0 A_SetUserVar("user_melee_range", 1) // will NOT engage in meelee
			"----" A 0 A_SetUserVar("user_too_close_range", 400) // prefers medium distances (because spread)
			"----" A 0 A_SetUserVar("user_stand_still", 1) // cannot skip charging in a jump or interrupt charging
			"----" A 0 A_SetUserVar("user_wp_cooldown", user_wp_cooldown < 35 ? 35 : user_wp_cooldown) // simply a grace period
			Goto WeaponSwitchFinish	

		WeaponSwitch_MG42:
			"----" A 0 A_JumpIf(!user_head_type, "WeaponSwitchNPCsCant10K")
			"----" A 0 A_JumpIf(user_prev_wpn == 16, 2)
			"----" A 0 A_PlaySound("CLIPIN", CHAN_WEAPON)
			"----" A 0 A_SetUserVar("user_ambush_duration", 300) // extreme
			"----" A 0 A_SetUserVar("user_ambush_chance", 128)
			"----" A 0 A_SetUserVar("user_fire_period", 2) // n-sane fire rate
			"----" A 0 A_SetUserVar("user_burst_length", 12) // this is a machinegun! Can add randomly
			"----" A 0 A_SetUserVar("user_weapon_cooldown_time", 15)
			"----" A 0 A_SetUserVar("user_muzzle_z", 36) 
			"----" A 0 A_SetUserVar("user_charge_time", 15) // half a second
			"----" A 0 A_SetUserVar("user_melee_range", 1) // will NOT engage in meelee
			"----" A 0 A_SetUserVar("user_too_close_range", 800) // prefers far distances		
			"----" A 0 A_SetUserVar("user_stand_still", 1) // canNOT instafire during a jump			
			Goto WeaponSwitchFinish
			
		//		
			
		WeaponSwitchNPCsCant10K:
			"----" A 0 A_Log("ERROR: NPCs cannot use BFG 10, Unmaker or MG-42. Switched to BFG 9K.")
			"----" A 0 A_SetUserVar("user_weapon", 11)
			Goto WeaponSwitch // switch to bfg 9k instead

		WeaponSwitch_Summon:
			"----" A 0 A_JumpIf(user_prev_wpn == 15, 2)
			"----" A 0 A_PlaySound("Knuckled", CHAN_WEAPON)	
			"----" A 0 A_SetUserVar("user_ambush_duration", 0)
			"----" A 0 A_SetUserVar("user_ambush_chance", 0)
			"----" A 0 A_SetUserVar("user_fire_period", 0)
			"----" A 0 A_SetUserVar("user_burst_length", 1)
			"----" A 0 A_SetUserVar("user_weapon_cooldown_time", 6)
			"----" A 0 A_SetUserVar("user_muzzle_z", 35) 
			"----" A 0 A_SetUserVar("user_charge_time", 0) 
			"----" A 0 A_SetUserVar("user_melee_range", 1) 
			"----" A 0 A_SetUserVar("user_too_close_range", 300) 
			"----" A 0 A_SetUserVar("user_stand_still", 0) 
			Goto WeaponSwitchFinish
			
		WeaponSwitchFinish:
			"----" A 0 A_SetUserVar("user_prev_wpn", user_weapon)
			"----" A 0 A_JumpIf(!user_head_type && (!user_npc_mode || user_onspawn) && !CheckClass("PatrolPoint", AAPTR_TARGET, true), "StandLoop") // NPCs
			
			"----" A 0 A_JumpIf(!user_awakened, "Stand")
			"----" A 0 A_JumpIf(user_see_after_wp_sw == 1 && CheckClass("PatrolPoint", AAPTR_TARGET, true), "FollowPatrolPoint")
			"----" A 0 A_JumpIf(user_see_after_wp_sw == 1, "See")
			"----" A 0 A_JumpIf(user_see_after_wp_sw == 2, "CheckForFatality") //"IdleLoop")
			Goto Missile //SynthLoop

		WanderCycle:
			"----" A 0 A_SetUserVar("user_wander", user_wander > 0 ? user_wander - 1 : 0)
			"----" A 0 A_SetUserVar("user_ddgrll_cldwn", user_ddgrll_cldwn > 0 ? user_ddgrll_cldwn - 1 : 0)
			"----" A 0 A_JumpIf(user_weapon == 3, "Wander_Chainsaw")
			"----" A 0 A_JumpIf(user_weapon == 4, "Wander_Rifle")
			"----" A 0 A_JumpIf(user_weapon == 5, "Wander_Shotgun")
			"----" A 0 A_JumpIf(user_weapon == 6, "Wander_SSG")
			"----" A 0 A_JumpIf(user_weapon == 7, "Wander_Minugun")
			"----" A 0 A_JumpIf(user_weapon == 8, "Wander_RL")
			"----" A 0 A_JumpIf(user_weapon == 9, "Wander_Plasma")
			"----" A 0 A_JumpIf(user_weapon == 10, "Wander_Railgun")
			"----" A 0 A_JumpIf(user_weapon == 11, "Wander_BFG") 
			"----" A 0 A_JumpIf(user_weapon == 12, "Wander_10K")
			"----" A 0 A_JumpIf(user_weapon == 13, "Wander_Unmaker")
			"----" A 0 A_JumpIf(user_weapon == 16, "Wander_MG42")
			Goto Wander_Fists	

		Wander_Fists:
			"----" A 0 A_JumpIf(!user_head_type, 2) // npc, no headbox
			"----" A 0 ACS_NamedExecuteWithResult("AdjustHeadboxMkII", 5, 0, 46) 
			"----" A 0 A_Recoil(-2)
			PLA1 BBBB 2 A_Wander
			"----" A 0 A_LookEx(user_head_type ? 0 : LOF_NOSOUNDCHECK | LOF_NOSEESOUND, 0,0,0,0, "SeeEnemy")
			
			"----" A 0 A_JumpIf(!user_head_type, 2) // npc, no headbox
			"----" A 0 ACS_NamedExecuteWithResult("AdjustHeadboxMkII", 5, 0, 42)
			"----" A 0 A_Recoil(-2)
			PLA1 CCCC 2 A_Wander
			"----" A 0 A_LookEx(user_head_type ? 0 : LOF_NOSOUNDCHECK | LOF_NOSEESOUND, 0,0,0,0, "SeeEnemy")

			"----" A 0 A_JumpIf(!user_head_type, 2) // npc, no headbox
			"----" A 0 ACS_NamedExecuteWithResult("AdjustHeadboxMkII", 5, 0, 44)
			"----" A 0 A_Recoil(-2)
			PLA1 DDDD 2 A_Wander
			"----" A 0 A_LookEx(user_head_type ? 0 : LOF_NOSOUNDCHECK | LOF_NOSEESOUND, 0,0,0,0, "SeeEnemy")
			
			"----" A 0 A_JumpIf(!user_head_type, 2) // npc, no headbox
			"----" A 0 ACS_NamedExecuteWithResult("AdjustHeadboxMkII", 5, 0, 43)
			"----" A 0 A_Recoil(-2)
			PLA1 AAAA 5 A_LookEx(user_head_type ? 0 : LOF_NOSOUNDCHECK | LOF_NOSEESOUND, 0,0,0,0, "SeeEnemy")
			"----" A 0 A_LookEx(user_head_type ? 0 : LOF_NOSOUNDCHECK | LOF_NOSEESOUND, 0,0,0,0, "SeeEnemy")
			
			Goto Idle
		Wander_Chainsaw:
			"----" A 0 A_JumpIf(!user_head_type, 2) // npc, no headbox
			"----" A 0 ACS_NamedExecuteWithResult("AdjustHeadboxMkII", 0, 0, 45)
			"----" A 0 A_Recoil(-2)
			MAR1 QQQQ 2 A_Wander
			"----" A 0 A_LookEx(user_head_type ? 0 : LOF_NOSOUNDCHECK | LOF_NOSEESOUND, 0,0,0,0, "SeeEnemy")
			
			"----" A 0 A_JumpIf(!user_head_type, 2) // npc, no headbox
			"----" A 0 ACS_NamedExecuteWithResult("AdjustHeadboxMkII", 0, -1, 43)
			"----" A 0 A_Recoil(-2)
			MAR1 RRRR 2 A_Wander
			"----" A 0 A_LookEx(user_head_type ? 0 : LOF_NOSOUNDCHECK | LOF_NOSEESOUND, 0,0,0,0, "SeeEnemy")		
		
			"----" A 0 A_JumpIf(!user_head_type, 2) // npc, no headbox
			"----" A 0 ACS_NamedExecuteWithResult("AdjustHeadboxMkII", 0, -2, 44)
			"----" A 0 A_Recoil(-2)
			MAR1 SSSS 2 A_Wander
			"----" A 0 A_LookEx(user_head_type ? 0 : LOF_NOSOUNDCHECK | LOF_NOSEESOUND, 0,0,0,0, "SeeEnemy")
			
			"----" A 0 A_JumpIf(!user_head_type, 2) // npc, no headbox
			"----" A 0 ACS_NamedExecuteWithResult("AdjustHeadboxMkII", 7, 3, 43)
			"----" A 0 A_Recoil(-2)
			MAR1 PPPP 5 A_LookEx(user_head_type ? 0 : LOF_NOSOUNDCHECK | LOF_NOSEESOUND, 0,0,0,0, "SeeEnemy")
			"----" A 0 A_LookEx(user_head_type ? 0 : LOF_NOSOUNDCHECK | LOF_NOSEESOUND, 0,0,0,0, "SeeEnemy")
			Goto Idle
		Wander_Rifle:
			"----" A 0 A_JumpIf(!user_head_type, 2) // npc, no headbox
			"----" A 0 ACS_NamedExecuteWithResult("AdjustHeadboxMkII", 3, 4, 45)
			PLAY BBBB 2 A_Wander
			"----" A 0 A_LookEx(user_head_type ? 0 : LOF_NOSOUNDCHECK | LOF_NOSEESOUND, 0,0,0,0, "SeeEnemy")
			
			"----" A 0 A_JumpIf(!user_head_type, 2) // npc, no headbox
			"----" A 0 ACS_NamedExecuteWithResult("AdjustHeadboxMkII", 4, 1, 43)
			PLAY CCCC 2 A_Wander
			"----" A 0 A_LookEx(user_head_type ? 0 : LOF_NOSOUNDCHECK | LOF_NOSEESOUND, 0,0,0,0, "SeeEnemy")
			
			"----" A 0 A_JumpIf(!user_head_type, 2) // npc, no headbox
			"----" A 0 ACS_NamedExecuteWithResult("AdjustHeadboxMkII", 6, -1, 44)
			PLAY DDDD 2 A_Wander
			"----" A 0 A_LookEx(user_head_type ? 0 : LOF_NOSOUNDCHECK | LOF_NOSEESOUND, 0,0,0,0, "SeeEnemy")
			
			"----" A 0 A_JumpIf(!user_head_type, 2) // npc, no headbox
			"----" A 0 ACS_NamedExecuteWithResult("AdjustHeadboxMkII", 7, 3, 43)
			PLAY AAAA 2 A_Wander
			"----" A 0 A_LookEx(user_head_type ? 0 : LOF_NOSOUNDCHECK | LOF_NOSEESOUND, 0,0,0,0, "SeeEnemy")
			Goto Idle
		Wander_Shotgun:
			"----" A 0 A_JumpIf(!user_head_type, 2) // npc, no headbox
			"----" A 0 ACS_NamedExecuteWithResult("AdjustHeadboxMkII", 4, 1, 43)
			"----" A 0 A_Recoil(-2)
			PLA3 BBBB 2 A_Wander
			"----" A 0 A_LookEx(user_head_type ? 0 : LOF_NOSOUNDCHECK | LOF_NOSEESOUND, 0,0,0,0, "SeeEnemy")
			
			"----" A 0 A_Recoil(-2)
			PLA3 CCCC 2 A_Wander
			"----" A 0 A_LookEx(user_head_type ? 0 : LOF_NOSOUNDCHECK | LOF_NOSEESOUND, 0,0,0,0, "SeeEnemy")
			
			"----" A 0 A_Recoil(-2)
			PLA3 DDDD 2 A_Wander
			"----" A 0 A_LookEx(user_head_type ? 0 : LOF_NOSOUNDCHECK | LOF_NOSEESOUND, 0,0,0,0, "SeeEnemy")
			
			"----" A 0 A_Recoil(-2)
			PLA3 AAAA 2 A_Wander
			"----" A 0 A_LookEx(user_head_type ? 0 : LOF_NOSOUNDCHECK | LOF_NOSEESOUND, 0,0,0,0, "SeeEnemy")
			Goto Idle
		Wander_SSG:
			"----" A 0 A_JumpIf(!user_head_type, 2) // npc, no headbox
			"----" A 0 ACS_NamedExecuteWithResult("AdjustHeadboxMkII", 4, 0, 43)
			"----" A 0 A_Recoil(-2)
			PLA9 BBBB 2 A_Wander
			"----" A 0 A_LookEx(user_head_type ? 0 : LOF_NOSOUNDCHECK | LOF_NOSEESOUND, 0,0,0,0, "SeeEnemy")
			
			"----" A 0 A_Recoil(-2)
			PLA9 CCCC 2 A_Wander
			"----" A 0 A_LookEx(user_head_type ? 0 : LOF_NOSOUNDCHECK | LOF_NOSEESOUND, 0,0,0,0, "SeeEnemy")
			
			"----" A 0 A_Recoil(-2)
			PLA9 DDDD 2 A_Wander
			"----" A 0 A_LookEx(user_head_type ? 0 : LOF_NOSOUNDCHECK | LOF_NOSEESOUND, 0,0,0,0, "SeeEnemy")
			
			"----" A 0 A_Recoil(-2)
			PLA9 AAAA 2 A_Wander
			"----" A 0 A_LookEx(user_head_type ? 0 : LOF_NOSOUNDCHECK | LOF_NOSEESOUND, 0,0,0,0, "SeeEnemy")
			Goto Idle
		Wander_Minugun:
			"----" A 0 A_JumpIf(!user_head_type, 2) // npc, no headbox
			"----" A 0 ACS_NamedExecuteWithResult("AdjustHeadboxMkII", 4, 0, 43)
			"----" A 0 A_Recoil(-2)
			PL42 BBBB 2 A_Wander
			"----" A 0 A_LookEx(user_head_type ? 0 : LOF_NOSOUNDCHECK | LOF_NOSEESOUND, 0,0,0,0, "SeeEnemy")
			
			"----" A 0 A_Recoil(-2)
			PL42 CCCC 2 A_Wander
			"----" A 0 A_LookEx(user_head_type ? 0 : LOF_NOSOUNDCHECK | LOF_NOSEESOUND, 0,0,0,0, "SeeEnemy")

			"----" A 0 A_Recoil(-2)
			PL42 DDDD 2 A_Wander
			"----" A 0 A_LookEx(user_head_type ? 0 : LOF_NOSOUNDCHECK | LOF_NOSEESOUND, 0,0,0,0, "SeeEnemy")
			
			"----" A 0 A_Recoil(-2)
			PL42 AAAA 2 A_Wander
			"----" A 0 A_LookEx(user_head_type ? 0 : LOF_NOSOUNDCHECK | LOF_NOSEESOUND, 0,0,0,0, "SeeEnemy")
			Goto Idle
		Wander_RL:
			"----" A 0 A_JumpIf(!user_head_type, 2) // npc, no headbox
			"----" A 0 ACS_NamedExecuteWithResult("AdjustHeadboxMkII", -10, 1, 44)
			"----" A 0 A_Recoil(-2)
			PL5S BBBB 2 A_Wander
			"----" A 0 A_LookEx(user_head_type ? 0 : LOF_NOSOUNDCHECK | LOF_NOSEESOUND, 0,0,0,0, "SeeEnemy")
			
			"----" A 0 A_Recoil(-2)
			PL5S CCCC 2 A_Wander
			"----" A 0 A_LookEx(user_head_type ? 0 : LOF_NOSOUNDCHECK | LOF_NOSEESOUND, 0,0,0,0, "SeeEnemy")
			
			"----" A 0 A_Recoil(-2)
			PL5S DDDD 2 A_Wander
			"----" A 0 A_LookEx(user_head_type ? 0 : LOF_NOSOUNDCHECK | LOF_NOSEESOUND, 0,0,0,0, "SeeEnemy")
			
			"----" A 0 A_Recoil(-2)
			PL5S AAAA 2 A_Wander
			"----" A 0 A_LookEx(user_head_type ? 0 : LOF_NOSOUNDCHECK | LOF_NOSEESOUND, 0,0,0,0, "SeeEnemy")
			Goto Idle
		Wander_Plasma:
			"----" A 0 A_JumpIf(!user_head_type, 2) // npc, no headbox
			"----" A 0 ACS_NamedExecuteWithResult("AdjustHeadboxMkII", 2, 4, 45)
			"----" A 0 A_Recoil(-2)
			PLA6 BBBB 2 A_Wander
			"----" A 0 A_LookEx(user_head_type ? 0 : LOF_NOSOUNDCHECK | LOF_NOSEESOUND, 0,0,0,0, "SeeEnemy")
			
			"----" A 0 A_JumpIf(!user_head_type, 2) // npc, no headbox
			"----" A 0 ACS_NamedExecuteWithResult("AdjustHeadboxMkII", 2, 1, 43)
			"----" A 0 A_Recoil(-2)
			PLA6 CCCC 2 A_Wander
			"----" A 0 A_LookEx(user_head_type ? 0 : LOF_NOSOUNDCHECK | LOF_NOSEESOUND, 0,0,0,0, "SeeEnemy")			
			
			"----" A 0 A_JumpIf(!user_head_type, 2) // npc, no headbox
			"----" A 0 ACS_NamedExecuteWithResult("AdjustHeadboxMkII", 7, -1, 44)
			"----" A 0 A_Recoil(-2)
			PLA6 DDDD 2 A_Wander
			"----" A 0 A_LookEx(user_head_type ? 0 : LOF_NOSOUNDCHECK | LOF_NOSEESOUND, 0,0,0,0, "SeeEnemy")
			
			"----" A 0 A_JumpIf(!user_head_type, 2) // npc, no headbox
			"----" A 0 ACS_NamedExecuteWithResult("AdjustHeadboxMkII", 7, 3, 43)
			"----" A 0 A_Recoil(-2)
			PLA6 AAAA 2 A_Wander
			"----" A 0 A_LookEx(user_head_type ? 0 : LOF_NOSOUNDCHECK | LOF_NOSEESOUND, 0,0,0,0, "SeeEnemy")
			
			Goto Idle
		Wander_Railgun:
			"----" A 0 A_JumpIf(!user_head_type, 2) // npc, no headbox
			"----" A 0 ACS_NamedExecuteWithResult("AdjustHeadboxMkII", -11, 1, 44)
			
			"----" A 0 A_Recoil(-2)
			MRRG BBBB 2 A_Wander
			"----" A 0 A_LookEx(user_head_type ? 0 : LOF_NOSOUNDCHECK | LOF_NOSEESOUND, 0,0,0,0, "SeeEnemy")
			
			"----" A 0 A_Recoil(-2)
			MRRG CCCC 2 A_Wander
			"----" A 0 A_LookEx(user_head_type ? 0 : LOF_NOSOUNDCHECK | LOF_NOSEESOUND, 0,0,0,0, "SeeEnemy")

			"----" A 0 A_Recoil(-2)
			MRRG DDDD 2 A_Wander
			"----" A 0 A_LookEx(user_head_type ? 0 : LOF_NOSOUNDCHECK | LOF_NOSEESOUND, 0,0,0,0, "SeeEnemy")
			
			"----" A 0 A_Recoil(-2)
			MRRG AAAA 2 A_Wander
			"----" A 0 A_LookEx(user_head_type ? 0 : LOF_NOSOUNDCHECK | LOF_NOSEESOUND, 0,0,0,0, "SeeEnemy")

			Goto Idle
		Wander_BFG:
			"----" A 0 A_JumpIf(!user_head_type, 2) // npc, no headbox
			"----" A 0 ACS_NamedExecuteWithResult("AdjustHeadboxMkII", 5, 0, 43)
			
			"----" A 0 A_Recoil(-2)
			PLA7 BBBB 2 A_Wander
			"----" A 0 A_LookEx(user_head_type ? 0 : LOF_NOSOUNDCHECK | LOF_NOSEESOUND, 0,0,0,0, "SeeEnemy")
			
			"----" A 0 A_Recoil(-2)
			PLA7 CCCC 2 A_Wander
			"----" A 0 A_LookEx(user_head_type ? 0 : LOF_NOSOUNDCHECK | LOF_NOSEESOUND, 0,0,0,0, "SeeEnemy")
			
			"----" A 0 A_Recoil(-2)
			PLA7 DDDD 2 A_Wander
			"----" A 0 A_LookEx(user_head_type ? 0 : LOF_NOSOUNDCHECK | LOF_NOSEESOUND, 0,0,0,0, "SeeEnemy")
			
			"----" A 0 A_Recoil(-2)
			PLA7 AAAA 2 A_Wander
			"----" A 0 A_LookEx(user_head_type ? 0 : LOF_NOSOUNDCHECK | LOF_NOSEESOUND, 0,0,0,0, "SeeEnemy")

			Goto Idle
		Wander_10K:
			"----" A 0 A_JumpIf(!user_head_type, 2) // npc, no headbox
			"----" A 0 ACS_NamedExecuteWithResult("AdjustHeadboxMkII", -4, -1, 44)
			
			"----" A 0 A_Recoil(-2)
			M10K BBBB 2 A_Wander
			"----" A 0 A_LookEx(user_head_type ? 0 : LOF_NOSOUNDCHECK | LOF_NOSEESOUND, 0,0,0,0, "SeeEnemy")
			
			"----" A 0 A_Recoil(-2)
			M10K CCCC 2 A_Wander
			"----" A 0 A_LookEx(user_head_type ? 0 : LOF_NOSOUNDCHECK | LOF_NOSEESOUND, 0,0,0,0, "SeeEnemy")
			
			"----" A 0 A_Recoil(-2)
			M10K DDDD 2 A_Wander
			"----" A 0 A_LookEx(user_head_type ? 0 : LOF_NOSOUNDCHECK | LOF_NOSEESOUND, 0,0,0,0, "SeeEnemy")
			
			"----" A 0 A_Recoil(-2)
			M10K AAAA 2 A_Wander
			"----" A 0 A_LookEx(user_head_type ? 0 : LOF_NOSOUNDCHECK | LOF_NOSEESOUND, 0,0,0,0, "SeeEnemy")

			Goto Idle
		Wander_Unmaker:
			"----" A 0 A_JumpIf(!user_head_type, 2) // npc, no headbox
			"----" A 0 ACS_NamedExecuteWithResult("AdjustHeadboxMkII", 0, 0, 46)
			
			"----" A 0 A_Recoil(-2)
			P7UM BBBB 2 A_Wander
			"----" A 0 A_LookEx(user_head_type ? 0 : LOF_NOSOUNDCHECK | LOF_NOSEESOUND, 0,0,0,0, "SeeEnemy")
			
			"----" A 0 A_Recoil(-2)
			P7UM CCCC 2 A_Wander
			"----" A 0 A_LookEx(user_head_type ? 0 : LOF_NOSOUNDCHECK | LOF_NOSEESOUND, 0,0,0,0, "SeeEnemy")
			
			"----" A 0 A_Recoil(-2)
			P7UM DDDD 2 A_Wander
			"----" A 0 A_LookEx(user_head_type ? 0 : LOF_NOSOUNDCHECK | LOF_NOSEESOUND, 0,0,0,0, "SeeEnemy")
			
			"----" A 0 A_Recoil(-2)
			P7UM AAAA 2 A_Wander
			"----" A 0 A_LookEx(user_head_type ? 0 : LOF_NOSOUNDCHECK | LOF_NOSEESOUND, 0,0,0,0, "SeeEnemy")

			Goto Idle

		Wander_MG42:
			"----" A 0 A_JumpIf(!user_head_type, 2) // npc, no headbox
			"----" A 0 ACS_NamedExecuteWithResult("AdjustHeadboxMkII", 0, 0, 46)
			
			"----" A 0 A_Recoil(-2)
			P842 BBBB 2 A_Wander
			"----" A 0 A_LookEx(user_head_type ? 0 : LOF_NOSOUNDCHECK | LOF_NOSEESOUND, 0,0,0,0, "SeeEnemy")
			
			"----" A 0 A_Recoil(-2)
			P842 CCCC 2 A_Wander
			"----" A 0 A_LookEx(user_head_type ? 0 : LOF_NOSOUNDCHECK | LOF_NOSEESOUND, 0,0,0,0, "SeeEnemy")
			
			"----" A 0 A_Recoil(-2)
			P842 DDDD 2 A_Wander
			"----" A 0 A_LookEx(user_head_type ? 0 : LOF_NOSOUNDCHECK | LOF_NOSEESOUND, 0,0,0,0, "SeeEnemy")
			
			"----" A 0 A_Recoil(-2)
			P842 AAAA 2 A_Wander
			"----" A 0 A_LookEx(user_head_type ? 0 : LOF_NOSOUNDCHECK | LOF_NOSEESOUND, 0,0,0,0, "SeeEnemy")

			Goto Idle					
		
		ChaseFrame1:
			// the a_chase in animation doesn't jump to missile, only moves -- while a_chase afterwards jumps but doesn't move

			"----" A 0 A_JumpIf(user_weapon == 3, "ChaseFrame1_Chainsaw")
			"----" A 0 A_JumpIf(user_weapon == 4, "ChaseFrame1_Rifle")
			"----" A 0 A_JumpIf(user_weapon == 5, "ChaseFrame1_Shotgun")
			"----" A 0 A_JumpIf(user_weapon == 6, "ChaseFrame1_SSG")
			"----" A 0 A_JumpIf(user_weapon == 7, "ChaseFrame1_Minugun")
			"----" A 0 A_JumpIf(user_weapon == 8, "ChaseFrame1_RL")
			"----" A 0 A_JumpIf(user_weapon == 9, "ChaseFrame1_Plasma")
			"----" A 0 A_JumpIf(user_weapon == 10, "ChaseFrame1_Railgun")
			"----" A 0 A_JumpIf(user_weapon == 11, "ChaseFrame1_BFG") 
			"----" A 0 A_JumpIf(user_weapon == 12, "ChaseFrame1_10K") 
			"----" A 0 A_JumpIf(user_weapon == 13, "ChaseFrame1_Unmaker") 
			"----" A 0 A_JumpIf(user_weapon == 16, "ChaseFrame1_MG42") 
		ChaseFrame1_Fists:
			"----" A 0 A_JumpIf(!user_head_type, 2) // npc, no headbox
			"----" A 0 ACS_NamedExecuteWithResult("AdjustHeadboxMkII", 5, 0, 44)
			"----" A 0 A_JumpIf(user_weapon != 2, 2)
			"----" A 0 A_Wander //200% speed with berserk
			PLA1 D 1 A_Chase("", "")
			"----" A 0 A_Wander //150% speed with fists			
			PLA1 D 1 A_Chase("", "")
			Goto ChaseLoopContinue
		ChaseFrame1_Chainsaw:
			"----" A 0 A_PlaySound("weapons/chainsaw/idle", CHAN_WEAPON)
			"----" A 0 A_JumpIf(!user_head_type, 2) // npc, no headbox
			"----" A 0 ACS_NamedExecuteWithResult("AdjustHeadboxMkII", 0, -2, 44)
			"----" A 0 A_Wander //150% speed with chainsaw
			MAR1 SS 1 A_Chase("", "")
			Goto ChaseLoopContinue
		ChaseFrame1_Rifle:
			"----" A 0 A_JumpIf(!user_head_type, 2) // npc, no headbox
			"----" A 0 ACS_NamedExecuteWithResult("AdjustHeadboxMkII", 6, -1, 44)
			PLAY DD 1 A_Chase("", "")
			Goto ChaseLoopContinue
		ChaseFrame1_Shotgun:
			"----" A 0 A_JumpIf(!user_head_type, 2) // npc, no headbox
			"----" A 0 ACS_NamedExecuteWithResult("AdjustHeadboxMkII", 4, 1, 43)
			PLA3 DD 1 A_Chase("", "")
			Goto ChaseLoopContinue
		ChaseFrame1_SSG:
			"----" A 0 A_JumpIf(!user_head_type, 2) // npc, no headbox
			"----" A 0 ACS_NamedExecuteWithResult("AdjustHeadboxMkII", 4, 0, 43)
			PLA9 DD 1 A_Chase("", "")
			Goto ChaseLoopContinue
		ChaseFrame1_Minugun:
			"----" A 0 A_JumpIf(!user_head_type, 2) // npc, no headbox
			"----" A 0 ACS_NamedExecuteWithResult("AdjustHeadboxMkII", 4, 0, 43)
			PL42 DD 1 A_Chase("", "")
			Goto ChaseLoopContinue
		ChaseFrame1_RL:
			"----" A 0 A_JumpIf(!user_head_type, 2) // npc, no headbox
			"----" A 0 ACS_NamedExecuteWithResult("AdjustHeadboxMkII", -10, 1, 44)
			PL5S DD 1 A_Chase("", "")
			Goto ChaseLoopContinue
		ChaseFrame1_Plasma:
			"----" A 0 A_JumpIf(!user_head_type, 2) // npc, no headbox
			"----" A 0 ACS_NamedExecuteWithResult("AdjustHeadboxMkII", 7, -1, 44)
			PLA6 DD 1 A_Chase("", "")
			Goto ChaseLoopContinue
		ChaseFrame1_Railgun:
			"----" A 0 A_JumpIf(!user_head_type, 2) // npc, no headbox
			"----" A 0 ACS_NamedExecuteWithResult("AdjustHeadboxMkII", -11, 1, 44)
			MRRG DD 1 A_Chase("", "")
			Goto ChaseLoopContinue
		ChaseFrame1_BFG:
			"----" A 0 A_JumpIf(!user_head_type, 2) // npc, no headbox
			"----" A 0 ACS_NamedExecuteWithResult("AdjustHeadboxMkII", 5, 0, 43)
			PLA7 DD 1 A_Chase("", "")
			Goto ChaseLoopContinue	
		ChaseFrame1_10K:
			"----" A 0 A_PlaySound("10KIDLE", CHAN_WEAPON)
			"----" A 0 A_JumpIf(!user_head_type, 2) // npc, no headbox
			"----" A 0 ACS_NamedExecuteWithResult("AdjustHeadboxMkII", -4, -1, 44)
			M10K DD 1 A_Chase("", "")
			Goto ChaseLoopContinue	
		ChaseFrame1_Unmaker:
			"----" A 0 A_JumpIf(!user_head_type, 2) // npc, no headbox
			"----" A 0 ACS_NamedExecuteWithResult("AdjustHeadboxMkII", 0, 0, 46)
			P7UM DD 1 A_Chase("", "")
			Goto ChaseLoopContinue
		ChaseFrame1_MG42:
			"----" A 0 A_JumpIf(!user_head_type, 2) // npc, no headbox
			"----" A 0 ACS_NamedExecuteWithResult("AdjustHeadboxMkII", 0, 0, 46)
			P842 DD 1 A_Chase("", "")
			Goto ChaseLoopContinue				

		WanderFrame1:
			"----" A 0 A_JumpIf(user_weapon == 3, "WanderFrame1_Chainsaw")
			"----" A 0 A_JumpIf(user_weapon == 4, "WanderFrame1_Rifle")
			"----" A 0 A_JumpIf(user_weapon == 5, "WanderFrame1_Shotgun")
			"----" A 0 A_JumpIf(user_weapon == 6, "WanderFrame1_SSG")
			"----" A 0 A_JumpIf(user_weapon == 7, "WanderFrame1_Minugun")
			"----" A 0 A_JumpIf(user_weapon == 8, "WanderFrame1_RL")
			"----" A 0 A_JumpIf(user_weapon == 9, "WanderFrame1_Plasma")
			"----" A 0 A_JumpIf(user_weapon == 10, "WanderFrame1_Railgun")
			"----" A 0 A_JumpIf(user_weapon == 11, "WanderFrame1_BFG") 
			"----" A 0 A_JumpIf(user_weapon == 12, "WanderFrame1_10K") 
			"----" A 0 A_JumpIf(user_weapon == 13, "WanderFrame1_Unmaker") 
			"----" A 0 A_JumpIf(user_weapon == 16, "WanderFrame1_MG42") 
		WanderFrame1_Fists:
			"----" A 0 A_JumpIf(!user_head_type, 2) // npc, no headbox
			"----" A 0 ACS_NamedExecuteWithResult("AdjustHeadboxMkII", 5, 0, 44)
			"----" A 0 A_JumpIf(user_weapon != 2, 2)
			"----" A 0 A_Wander //200% speed with berserk
			PLA1 D 1 A_Wander
			"----" A 0 A_Wander //150% speed with fists			
			PLA1 D 1 A_Wander
			Goto ChaseLoopContinue
		WanderFrame1_Chainsaw:
			"----" A 0 A_PlaySound("weapons/chainsaw/idle", CHAN_WEAPON)
			"----" A 0 A_JumpIf(!user_head_type, 2) // npc, no headbox
			"----" A 0 ACS_NamedExecuteWithResult("AdjustHeadboxMkII", 0, -2, 44)
			"----" A 0 A_Wander //150% speed with chainsaw
			MAR1 SS 1 A_Wander
			Goto ChaseLoopContinue
		WanderFrame1_Rifle:
			"----" A 0 A_JumpIf(!user_head_type, 2) // npc, no headbox
			"----" A 0 ACS_NamedExecuteWithResult("AdjustHeadboxMkII", 6, -1, 44)
			PLAY DD 1 A_Wander
			Goto ChaseLoopContinue
		WanderFrame1_Shotgun:
			"----" A 0 A_JumpIf(!user_head_type, 2) // npc, no headbox
			"----" A 0 ACS_NamedExecuteWithResult("AdjustHeadboxMkII", 4, 1, 43)
			PLA3 DD 1 A_Wander
			Goto ChaseLoopContinue
		WanderFrame1_SSG:
			"----" A 0 A_JumpIf(!user_head_type, 2) // npc, no headbox
			"----" A 0 ACS_NamedExecuteWithResult("AdjustHeadboxMkII", 4, 0, 43)
			PLA9 DD 1 A_Wander
			Goto ChaseLoopContinue
		WanderFrame1_Minugun:
			"----" A 0 A_JumpIf(!user_head_type, 2) // npc, no headbox
			"----" A 0 ACS_NamedExecuteWithResult("AdjustHeadboxMkII", 4, 0, 43)
			PL42 DD 1 A_Wander
			Goto ChaseLoopContinue
		WanderFrame1_RL:
			"----" A 0 A_JumpIf(!user_head_type, 2) // npc, no headbox
			"----" A 0 ACS_NamedExecuteWithResult("AdjustHeadboxMkII", -10, 1, 44)
			PL5S DD 1 A_Wander
			Goto ChaseLoopContinue
		WanderFrame1_Plasma:
			"----" A 0 A_JumpIf(!user_head_type, 2) // npc, no headbox
			"----" A 0 ACS_NamedExecuteWithResult("AdjustHeadboxMkII", 7, -1, 44)
			PLA6 DD 1 A_Wander
			Goto ChaseLoopContinue
		WanderFrame1_Railgun:
			"----" A 0 A_JumpIf(!user_head_type, 2) // npc, no headbox
			"----" A 0 ACS_NamedExecuteWithResult("AdjustHeadboxMkII", -11, 1, 44)
			MRRG DD 1 A_Wander
			Goto ChaseLoopContinue
		WanderFrame1_BFG:
			"----" A 0 A_JumpIf(!user_head_type, 2) // npc, no headbox
			"----" A 0 ACS_NamedExecuteWithResult("AdjustHeadboxMkII", 5, 0, 43)
			PLA7 DD 1 A_Wander
			Goto ChaseLoopContinue	
		WanderFrame1_10K:
			"----" A 0 A_PlaySound("10KIDLE", CHAN_WEAPON)
			"----" A 0 A_JumpIf(!user_head_type, 2) // npc, no headbox
			"----" A 0 ACS_NamedExecuteWithResult("AdjustHeadboxMkII", -4, -1, 44)
			M10K DD 1 A_Wander
			Goto ChaseLoopContinue	
		WanderFrame1_Unmaker:
			"----" A 0 A_JumpIf(!user_head_type, 2) // npc, no headbox
			"----" A 0 ACS_NamedExecuteWithResult("AdjustHeadboxMkII", 0, 0, 46)
			P7UM DD 1 A_Wander
			Goto ChaseLoopContinue
		WanderFrame1_MG42:
			"----" A 0 A_JumpIf(!user_head_type, 2) // npc, no headbox
			"----" A 0 ACS_NamedExecuteWithResult("AdjustHeadboxMkII", 0, 0, 46)
			P842 DD 1 A_Wander
			Goto ChaseLoopContinue				


		ChaseFrame2:
			"----" A 0 A_JumpIf(user_weapon == 3, "ChaseFrame2_Chainsaw")
			"----" A 0 A_JumpIf(user_weapon == 4, "ChaseFrame2_Rifle")
			"----" A 0 A_JumpIf(user_weapon == 5, "ChaseFrame2_Shotgun")
			"----" A 0 A_JumpIf(user_weapon == 6, "ChaseFrame2_SSG")
			"----" A 0 A_JumpIf(user_weapon == 7, "ChaseFrame2_Minugun")
			"----" A 0 A_JumpIf(user_weapon == 8, "ChaseFrame2_RL")
			"----" A 0 A_JumpIf(user_weapon == 9, "ChaseFrame2_Plasma")
			"----" A 0 A_JumpIf(user_weapon == 10, "ChaseFrame2_Railgun")
			"----" A 0 A_JumpIf(user_weapon == 11, "ChaseFrame2_BFG") 
			"----" A 0 A_JumpIf(user_weapon == 12, "ChaseFrame2_10K")
			"----" A 0 A_JumpIf(user_weapon == 13, "ChaseFrame2_Unmaker")
			"----" A 0 A_JumpIf(user_weapon == 16, "ChaseFrame2_MG42")
		ChaseFrame2_Fists:
			"----" A 0 A_JumpIf(!user_head_type, 2) // npc, no headbox
			"----" A 0 ACS_NamedExecuteWithResult("AdjustHeadboxMkII", 5, 0, 43)
			"----" A 0 A_JumpIf(user_weapon != 2, 2)
			"----" A 0 A_Wander //200% speed with berserk
			PLA1 A 1 A_Chase("", "")
			"----" A 0 A_Wander //150% speed with fists			
			PLA1 A 1 A_Chase("", "")
			Goto ChaseLoopContinue
		ChaseFrame2_Chainsaw:
			"----" A 0 A_JumpIf(!user_head_type, 2) // npc, no headbox
			"----" A 0 ACS_NamedExecuteWithResult("AdjustHeadboxMkII", 7, 3, 43)
			"----" A 0 A_Wander //150% speed with chainsaw
			MAR1 PP 1 A_Chase("", "")
			Goto ChaseLoopContinue
		ChaseFrame2_Rifle:
			"----" A 0 A_JumpIf(!user_head_type, 2) // npc, no headbox
			"----" A 0 ACS_NamedExecuteWithResult("AdjustHeadboxMkII", 7, 3, 43)
			PLAY AA 1 A_Chase("", "")
			Goto ChaseLoopContinue
		ChaseFrame2_Shotgun:
			PLA3 AA 1 A_Chase("", "")
			Goto ChaseLoopContinue
		ChaseFrame2_SSG:
			PLA9 AA 1 A_Chase("", "")
			Goto ChaseLoopContinue
		ChaseFrame2_Minugun:
			PL42 AA 1 A_Chase("", "")
			Goto ChaseLoopContinue
		ChaseFrame2_RL:
			PL5S AA 1 A_Chase("", "")
			Goto ChaseLoopContinue
		ChaseFrame2_Plasma:
			"----" A 0 A_JumpIf(!user_head_type, 2) // npc, no headbox
			"----" A 0 ACS_NamedExecuteWithResult("AdjustHeadboxMkII", 7, 3, 43)
			PLA6 AA 1 A_Chase("", "")
			Goto ChaseLoopContinue
		ChaseFrame2_Railgun:
			MRRG AA 1 A_Chase("", "")
			Goto ChaseLoopContinue
		ChaseFrame2_BFG:
			PLA7 AA 1 A_Chase("", "")
			Goto ChaseLoopContinue			
		ChaseFrame2_10K:
			M10K AA 1 A_Chase("", "")
			Goto ChaseLoopContinue	
		ChaseFrame2_Unmaker:
			P7UM AA 1 A_Chase("", "")
			Goto ChaseLoopContinue	
		ChaseFrame2_MG42:
			P842 AA 1 A_Chase("", "")
			Goto ChaseLoopContinue				

		WanderFrame2:
			"----" A 0 A_JumpIf(user_weapon == 3, "WanderFrame2_Chainsaw")
			"----" A 0 A_JumpIf(user_weapon == 4, "WanderFrame2_Rifle")
			"----" A 0 A_JumpIf(user_weapon == 5, "WanderFrame2_Shotgun")
			"----" A 0 A_JumpIf(user_weapon == 6, "WanderFrame2_SSG")
			"----" A 0 A_JumpIf(user_weapon == 7, "WanderFrame2_Minugun")
			"----" A 0 A_JumpIf(user_weapon == 8, "WanderFrame2_RL")
			"----" A 0 A_JumpIf(user_weapon == 9, "WanderFrame2_Plasma")
			"----" A 0 A_JumpIf(user_weapon == 10, "WanderFrame2_Railgun")
			"----" A 0 A_JumpIf(user_weapon == 11, "WanderFrame2_BFG") 
			"----" A 0 A_JumpIf(user_weapon == 12, "WanderFrame2_10K")
			"----" A 0 A_JumpIf(user_weapon == 13, "WanderFrame2_Unmaker")
			"----" A 0 A_JumpIf(user_weapon == 16, "WanderFrame2_MG42")
		WanderFrame2_Fists:
			"----" A 0 A_JumpIf(!user_head_type, 2) // npc, no headbox
			"----" A 0 ACS_NamedExecuteWithResult("AdjustHeadboxMkII", 5, 0, 43)
			"----" A 0 A_JumpIf(user_weapon != 2, 2)
			"----" A 0 A_Wander //200% speed with berserk
			PLA1 A 1 A_Wander
			"----" A 0 A_Wander //150% speed with fists			
			PLA1 A 1 A_Wander
			Goto ChaseLoopContinue
		WanderFrame2_Chainsaw:
			"----" A 0 A_JumpIf(!user_head_type, 2) // npc, no headbox
			"----" A 0 ACS_NamedExecuteWithResult("AdjustHeadboxMkII", 7, 3, 43)
			"----" A 0 A_Wander //150% speed with chainsaw
			MAR1 PP 1 A_Wander
			Goto ChaseLoopContinue
		WanderFrame2_Rifle:
			"----" A 0 A_JumpIf(!user_head_type, 2) // npc, no headbox
			"----" A 0 ACS_NamedExecuteWithResult("AdjustHeadboxMkII", 7, 3, 43)
			PLAY AA 1 A_Wander
			Goto ChaseLoopContinue
		WanderFrame2_Shotgun:
			PLA3 AA 1 A_Wander
			Goto ChaseLoopContinue
		WanderFrame2_SSG:
			PLA9 AA 1 A_Wander
			Goto ChaseLoopContinue
		WanderFrame2_Minugun:
			PL42 AA 1 A_Wander
			Goto ChaseLoopContinue
		WanderFrame2_RL:
			PL5S AA 1 A_Wander
			Goto ChaseLoopContinue
		WanderFrame2_Plasma:
			"----" A 0 A_JumpIf(!user_head_type, 2) // npc, no headbox
			"----" A 0 ACS_NamedExecuteWithResult("AdjustHeadboxMkII", 7, 3, 43)
			PLA6 AA 1 A_Wander
			Goto ChaseLoopContinue
		WanderFrame2_Railgun:
			MRRG AA 1 A_Wander
			Goto ChaseLoopContinue
		WanderFrame2_BFG:
			PLA7 AA 1 A_Wander
			Goto ChaseLoopContinue			
		WanderFrame2_10K:
			M10K AA 1 A_Wander
			Goto ChaseLoopContinue	
		WanderFrame2_Unmaker:
			P7UM AA 1 A_Wander
			Goto ChaseLoopContinue
		WanderFrame2_MG42:
			P842 AA 1 A_Wander
			Goto ChaseLoopContinue			
		
		ChaseFrame3:
			"----" A 0 A_JumpIf(user_weapon == 3, "ChaseFrame3_Chainsaw")
			"----" A 0 A_JumpIf(user_weapon == 4, "ChaseFrame3_Rifle")
			"----" A 0 A_JumpIf(user_weapon == 5, "ChaseFrame3_Shotgun")
			"----" A 0 A_JumpIf(user_weapon == 6, "ChaseFrame3_SSG")
			"----" A 0 A_JumpIf(user_weapon == 7, "ChaseFrame3_Minugun")
			"----" A 0 A_JumpIf(user_weapon == 8, "ChaseFrame3_RL")
			"----" A 0 A_JumpIf(user_weapon == 9, "ChaseFrame3_Plasma")
			"----" A 0 A_JumpIf(user_weapon == 10, "ChaseFrame3_Railgun")
			"----" A 0 A_JumpIf(user_weapon == 11, "ChaseFrame3_BFG") 
			"----" A 0 A_JumpIf(user_weapon == 12, "ChaseFrame3_10K") 
			"----" A 0 A_JumpIf(user_weapon == 13, "ChaseFrame3_Unmaker") 
			"----" A 0 A_JumpIf(user_weapon == 16, "ChaseFrame3_MG42") 
		ChaseFrame3_Fists:
			"----" A 0 A_JumpIf(!user_head_type, 2) // npc, no headbox
			"----" A 0 ACS_NamedExecuteWithResult("AdjustHeadboxMkII", 5, 0, 46)
			"----" A 0 A_JumpIf(user_weapon != 2, 2)
			"----" A 0 A_Wander //200% speed with berserk
			PLA1 B 1 A_Chase("", "")
			"----" A 0 A_Wander //150% speed with fists			
			PLA1 B 1 A_Chase("", "")
			Goto ChaseLoopContinue
		ChaseFrame3_Chainsaw:
			"----" A 0 A_JumpIf(!user_head_type, 2) // npc, no headbox
			"----" A 0 ACS_NamedExecuteWithResult("AdjustHeadboxMkII", 0, 0, 45)
			"----" A 0 A_Wander //150% speed with chainsaw
			MAR1 QQ 1 A_Chase("", "")
			Goto ChaseLoopContinue
		ChaseFrame3_Rifle:
			"----" A 0 A_JumpIf(!user_head_type, 2) // npc, no headbox
			"----" A 0 ACS_NamedExecuteWithResult("AdjustHeadboxMkII", 3, 4, 45)
			PLAY BB 1 A_Chase("", "")
			Goto ChaseLoopContinue
		ChaseFrame3_Shotgun:
			PLA3 BB 1 A_Chase("", "")
			Goto ChaseLoopContinue
		ChaseFrame3_SSG:
			PLA9 BB 1 A_Chase("", "")
			Goto ChaseLoopContinue
		ChaseFrame3_Minugun:
			PL42 BB 1 A_Chase("", "")
			Goto ChaseLoopContinue
		ChaseFrame3_RL:
			PL5S BB 1 A_Chase("", "")
			Goto ChaseLoopContinue
		ChaseFrame3_Plasma:
			"----" A 0 A_JumpIf(!user_head_type, 2) // npc, no headbox
			"----" A 0 ACS_NamedExecuteWithResult("AdjustHeadboxMkII", 2, 4, 45)
			PLA6 BB 1 A_Chase("", "")
			Goto ChaseLoopContinue
		ChaseFrame3_Railgun:
			MRRG BB 1 A_Chase("", "")
			Goto ChaseLoopContinue
		ChaseFrame3_BFG:
			PLA7 BB 1 A_Chase("", "")
			Goto ChaseLoopContinue	
		ChaseFrame3_10K:
			M10K BB 1 A_Chase("", "")
			Goto ChaseLoopContinue	
		ChaseFrame3_Unmaker:
			P7UM BB 1 A_Chase("", "")
			Goto ChaseLoopContinue
		ChaseFrame3_MG42:
			P842 BB 1 A_Chase("", "")
			Goto ChaseLoopContinue

		WanderFrame3:
			"----" A 0 A_JumpIf(user_weapon == 3, "WanderFrame3_Chainsaw")
			"----" A 0 A_JumpIf(user_weapon == 4, "WanderFrame3_Rifle")
			"----" A 0 A_JumpIf(user_weapon == 5, "WanderFrame3_Shotgun")
			"----" A 0 A_JumpIf(user_weapon == 6, "WanderFrame3_SSG")
			"----" A 0 A_JumpIf(user_weapon == 7, "WanderFrame3_Minugun")
			"----" A 0 A_JumpIf(user_weapon == 8, "WanderFrame3_RL")
			"----" A 0 A_JumpIf(user_weapon == 9, "WanderFrame3_Plasma")
			"----" A 0 A_JumpIf(user_weapon == 10, "WanderFrame3_Railgun")
			"----" A 0 A_JumpIf(user_weapon == 11, "WanderFrame3_BFG") 
			"----" A 0 A_JumpIf(user_weapon == 12, "WanderFrame3_10K") 
			"----" A 0 A_JumpIf(user_weapon == 13, "WanderFrame3_Unmaker") 
			"----" A 0 A_JumpIf(user_weapon == 16, "WanderFrame3_MG42") 
		WanderFrame3_Fists:
			"----" A 0 A_JumpIf(!user_head_type, 2) // npc, no headbox
			"----" A 0 ACS_NamedExecuteWithResult("AdjustHeadboxMkII", 5, 0, 46)
			"----" A 0 A_JumpIf(user_weapon != 2, 2)
			"----" A 0 A_Wander //200% speed with berserk
			PLA1 B 1 A_Wander
			"----" A 0 A_Wander //150% speed with fists			
			PLA1 B 1 A_Wander
			Goto ChaseLoopContinue
		WanderFrame3_Chainsaw:
			"----" A 0 A_JumpIf(!user_head_type, 2) // npc, no headbox
			"----" A 0 ACS_NamedExecuteWithResult("AdjustHeadboxMkII", 0, 0, 45)
			"----" A 0 A_Wander //150% speed with chainsaw
			MAR1 QQ 1 A_Wander
			Goto ChaseLoopContinue
		WanderFrame3_Rifle:
			"----" A 0 A_JumpIf(!user_head_type, 2) // npc, no headbox
			"----" A 0 ACS_NamedExecuteWithResult("AdjustHeadboxMkII", 3, 4, 45)
			PLAY BB 1 A_Wander
			Goto ChaseLoopContinue
		WanderFrame3_Shotgun:
			PLA3 BB 1 A_Wander
			Goto ChaseLoopContinue
		WanderFrame3_SSG:
			PLA9 BB 1 A_Wander
			Goto ChaseLoopContinue
		WanderFrame3_Minugun:
			PL42 BB 1 A_Wander
			Goto ChaseLoopContinue
		WanderFrame3_RL:
			PL5S BB 1 A_Wander
			Goto ChaseLoopContinue
		WanderFrame3_Plasma:
			"----" A 0 A_JumpIf(!user_head_type, 2) // npc, no headbox
			"----" A 0 ACS_NamedExecuteWithResult("AdjustHeadboxMkII", 2, 4, 45)
			PLA6 BB 1 A_Wander
			Goto ChaseLoopContinue
		WanderFrame3_Railgun:
			MRRG BB 1 A_Wander
			Goto ChaseLoopContinue
		WanderFrame3_BFG:
			PLA7 BB 1 A_Wander
			Goto ChaseLoopContinue	
		WanderFrame3_10K:
			M10K BB 1 A_Wander
			Goto ChaseLoopContinue	
		WanderFrame3_Unmaker:
			P7UM BB 1 A_Wander
			Goto ChaseLoopContinue
		WanderFrame3_MG42:
			P842 BB 1 A_Wander
			Goto ChaseLoopContinue			

		ChaseFrame4:
			"----" A 0 A_JumpIf(user_weapon == 3, "ChaseFrame4_Chainsaw")
			"----" A 0 A_JumpIf(user_weapon == 4, "ChaseFrame4_Rifle")
			"----" A 0 A_JumpIf(user_weapon == 5, "ChaseFrame4_Shotgun")
			"----" A 0 A_JumpIf(user_weapon == 6, "ChaseFrame4_SSG")
			"----" A 0 A_JumpIf(user_weapon == 7, "ChaseFrame4_Minugun")
			"----" A 0 A_JumpIf(user_weapon == 8, "ChaseFrame4_RL")
			"----" A 0 A_JumpIf(user_weapon == 9, "ChaseFrame4_Plasma")
			"----" A 0 A_JumpIf(user_weapon == 10, "ChaseFrame4_Railgun")
			"----" A 0 A_JumpIf(user_weapon == 11, "ChaseFrame4_BFG") 
			"----" A 0 A_JumpIf(user_weapon == 12, "ChaseFrame4_10K") 
			"----" A 0 A_JumpIf(user_weapon == 13, "ChaseFrame4_Unmaker") 
			"----" A 0 A_JumpIf(user_weapon == 16, "ChaseFrame4_MG42") 
		ChaseFrame4_Fists:
			"----" A 0 A_JumpIf(!user_head_type, 2) // npc, no headbox
			"----" A 0 ACS_NamedExecuteWithResult("AdjustHeadboxMkII", 5, 0, 42)
			"----" A 0 A_JumpIf(user_weapon != 2, 2)
			"----" A 0 A_Wander //200% speed with berserk
			PLA1 C 1 A_Chase("", "")
			"----" A 0 A_Chase("", "") //150% speed with fists			
			PLA1 C 1 A_Chase("", "")
			Goto ChaseLoopContinue
		ChaseFrame4_Chainsaw:
			"----" A 0 A_JumpIf(!user_head_type, 2) // npc, no headbox
			"----" A 0 ACS_NamedExecuteWithResult("AdjustHeadboxMkII", 0, -1, 43)
			"----" A 0 A_Wander //150% speed with chainsaw
			MAR1 RR 1 A_Chase("", "")
			Goto ChaseLoopContinue
		ChaseFrame4_Rifle:
			"----" A 0 A_JumpIf(!user_head_type, 2) // npc, no headbox
			"----" A 0 ACS_NamedExecuteWithResult("AdjustHeadboxMkII", 4, 1, 43)
			PLAY CC 1 A_Chase("", "")
			Goto ChaseLoopContinue
		ChaseFrame4_Shotgun:
			PLA3 CC 1 A_Chase("", "")
			Goto ChaseLoopContinue
		ChaseFrame4_SSG:
			PLA9 CC 1 A_Chase("", "")
			Goto ChaseLoopContinue
		ChaseFrame4_Minugun:
			PL42 CC 1 A_Chase("", "")
			Goto ChaseLoopContinue
		ChaseFrame4_RL:
			PL5S CC 1 A_Chase("", "")
			Goto ChaseLoopContinue
		ChaseFrame4_Plasma:
			"----" A 0 A_JumpIf(!user_head_type, 2) // npc, no headbox
			"----" A 0 ACS_NamedExecuteWithResult("AdjustHeadboxMkII", 2, 1, 43)
			PLA6 CC 1 A_Chase("", "")
			Goto ChaseLoopContinue
		ChaseFrame4_Railgun:
			MRRG CC 1 A_Chase("", "")
			Goto ChaseLoopContinue
		ChaseFrame4_BFG:
			PLA7 CC 1 A_Chase("", "")
			Goto ChaseLoopContinue
		ChaseFrame4_10K:
			M10K CC 1 A_Chase("", "")
			Goto ChaseLoopContinue
		ChaseFrame4_Unmaker:
			P7UM CC 1 A_Chase("", "")
			Goto ChaseLoopContinue
		ChaseFrame4_MG42:
			P842 CC 1 A_Chase("", "")
			Goto ChaseLoopContinue			

		WanderFrame4:
			"----" A 0 A_JumpIf(user_weapon == 3, "WanderFrame4_Chainsaw")
			"----" A 0 A_JumpIf(user_weapon == 4, "WanderFrame4_Rifle")
			"----" A 0 A_JumpIf(user_weapon == 5, "WanderFrame4_Shotgun")
			"----" A 0 A_JumpIf(user_weapon == 6, "WanderFrame4_SSG")
			"----" A 0 A_JumpIf(user_weapon == 7, "WanderFrame4_Minugun")
			"----" A 0 A_JumpIf(user_weapon == 8, "WanderFrame4_RL")
			"----" A 0 A_JumpIf(user_weapon == 9, "WanderFrame4_Plasma")
			"----" A 0 A_JumpIf(user_weapon == 10, "WanderFrame4_Railgun")
			"----" A 0 A_JumpIf(user_weapon == 11, "WanderFrame4_BFG") 
			"----" A 0 A_JumpIf(user_weapon == 12, "WanderFrame4_10K") 
			"----" A 0 A_JumpIf(user_weapon == 13, "WanderFrame4_Unmaker") 
			"----" A 0 A_JumpIf(user_weapon == 16, "WanderFrame4_MG42") 
		WanderFrame4_Fists:
			"----" A 0 A_JumpIf(!user_head_type, 2) // npc, no headbox
			"----" A 0 ACS_NamedExecuteWithResult("AdjustHeadboxMkII", 5, 0, 42)
			"----" A 0 A_JumpIf(user_weapon != 2, 2)
			"----" A 0 A_Wander //200% speed with berserk
			PLA1 C 1 A_Wander
			"----" A 0 A_Wander //150% speed with fists			
			PLA1 C 1 A_Wander
			Goto ChaseLoopContinue
		WanderFrame4_Chainsaw:
			"----" A 0 A_JumpIf(!user_head_type, 2) // npc, no headbox
			"----" A 0 ACS_NamedExecuteWithResult("AdjustHeadboxMkII", 0, -1, 43)
			"----" A 0 A_Wander //150% speed with chainsaw
			MAR1 RR 1 A_Wander
			Goto ChaseLoopContinue
		WanderFrame4_Rifle:
			"----" A 0 A_JumpIf(!user_head_type, 2) // npc, no headbox
			"----" A 0 ACS_NamedExecuteWithResult("AdjustHeadboxMkII", 4, 1, 43)
			PLAY CC 1 A_Wander
			Goto ChaseLoopContinue
		WanderFrame4_Shotgun:
			PLA3 CC 1 A_Wander
			Goto ChaseLoopContinue
		WanderFrame4_SSG:
			PLA9 CC 1 A_Wander
			Goto ChaseLoopContinue
		WanderFrame4_Minugun:
			PL42 CC 1 A_Wander
			Goto ChaseLoopContinue
		WanderFrame4_RL:
			PL5S CC 1 A_Wander
			Goto ChaseLoopContinue
		WanderFrame4_Plasma:
			"----" A 0 A_JumpIf(!user_head_type, 2) // npc, no headbox
			"----" A 0 ACS_NamedExecuteWithResult("AdjustHeadboxMkII", 2, 1, 43)
			PLA6 CC 1 A_Wander
			Goto ChaseLoopContinue
		WanderFrame4_Railgun:
			MRRG CC 1 A_Wander
			Goto ChaseLoopContinue
		WanderFrame4_BFG:
			PLA7 CC 1 A_Wander
			Goto ChaseLoopContinue
		WanderFrame4_10K:
			M10K CC 1 A_Wander
			Goto ChaseLoopContinue
		WanderFrame4_Unmaker:
			P7UM CC 1 A_Wander
			Goto ChaseLoopContinue
		WanderFrame4_MG42:
			P842 CC 1 A_Wander
			Goto ChaseLoopContinue			


		WeaponChargingSFX:
			"----" A 0 A_JumpIf(user_weapon == 7, "WpnChrgSFX_Minugun")
			"----" A 0 A_JumpIf(user_weapon == 11, "WpnChrgSFX_BFG")
			"----" A 0 A_JumpIf(user_weapon == 12, "WpnChrgSFX_10K")
			"----" A 0 A_JumpIf(user_weapon == 13, "WpnChrgSFX_Unmaker")
			Goto WeaponFinish
		WpnChrgSFX_Minugun:
			"----" A 0 A_JumpIf(user_charge != 2, "WeaponFinish")
			"----" A 0 A_PlaySound("CHAINSTA", CHAN_WEAPON)
			
			// not just a sfx, alert cacoes they need to dodge:
			"----" A 0 A_CustomMissile("Alerter", user_muzzle_z, 0, angle, CMF_ABSOLUTEANGLE | CMF_OFFSETPITCH | CMF_SAVEPITCH, 0) 
			Goto WeaponFinish
		WpnChrgSFX_BFG:
			"----" A 0 A_JumpIf(user_charge != 2, 2)
			"----" A 0 A_PlaySound("misc/supermaster_bfg_cha", CHAN_WEAPON) // much larger roloff dist
			"----" A 0 A_SetUserVar("user_sfx_tic", user_sfx_tic + 1)
			"----" A 0 A_JumpIf( user_sfx_tic >= 4, "BfgMuzzle")
			Goto WeaponFinish
		BfgMuzzle:
			"----" A 0 A_SetUserVar("user_sfx_tic", 0)
			"----" A 0 A_JumpIf(user_charge > 18, "BfgMuzzle3")
			"----" A 0 A_JumpIf(user_charge > 9, "BfgMuzzle2")
			"----" A 0 A_SpawnItemEx("BFGMuzzle",30,7,30, momx,momy,momz, 0,SXF_NOCHECKPOSITION | SXF_ABSOLUTEVELOCITY)
			Goto WeaponFinish
		BfgMuzzle2:
			"----" A 0 A_SpawnItemEx("BFGMuzzle2",30,7,30, momx,momy,momz, 0,SXF_NOCHECKPOSITION | SXF_ABSOLUTEVELOCITY)
			Goto WeaponFinish
		BfgMuzzle3:
			"----" A 0 A_SpawnItemEx("BFGMuzzle3",30,7,30, momx,momy,momz, 0,SXF_NOCHECKPOSITION | SXF_ABSOLUTEVELOCITY)
			Goto WeaponFinish
		WpnChrgSFX_10K:
			"----" A 0 A_JumpIf(user_charge != 2, "WeaponFinish")
			"----" A 0 A_PlaySound("maradeur/10k_cha", CHAN_WEAPON) // much larger roloff dist
			Goto WeaponFinish
		WpnChrgSFX_Unmaker:
			"----" A 0 A_JumpIf(user_charge != 2, "WeaponFinish")
			"----" A 0 A_PlaySound("misc/supermaster_laz_sta", CHAN_WEAPON) // much larger roloff dist
			Goto WeaponFinish			
			
		Nag:
			"----" A 0 A_JumpIf(!user_head_type, "NagNPC")
			"----" A 0 A_JumpIfInTargetLOS("NagDone", 160, 0)
			"----" A 0 ACS_NamedExecuteWithResult("FBD_SynthMarineVoice", CHE_NAG)
/*			
			"----" A 0 A_JumpIf(user_maradeur == 1, "NagMaradeur1")
			"----" A 0 A_JumpIf(user_maradeur == 2, "NagMaradeur2")
			"----" A 0 A_JumpIf(user_maradeur == 3, "NagMaradeur3")
		
		NagChhaosMarine:
			//***Che: need new keyboard soon, this one begins doubling "H"s.
			//  Who am I kidding. I'd just flood it with WD-40.
			// Always had great success using WD-40 to clean RAM and PCI-E slots on mobos,
			//   my old laptop's hard drive connector and contacts in general.
			// That 35-year old fridge has its light running again, 
			//   all thanks to flooding the button's innards with the stuff.
			"----" A 0 A_PlaySound("zombiemarine/active", CHAN_VOICE)
			Goto NagDone
*/			
		NagNPC: // dublicated with "NagNPCStanding" in MARINES_npcs.txt
			//"----" A 0 A_PlaySound("MRNWC", CHAN_VOICE)
			"----" A 0 ACS_NamedExecuteWithResult("FBD_SynthMarineVoice", CHE_NAG)
			Goto NagDone
/*			
		NagMaradeur1:
			"----" A 0 A_PlaySound("maradeur/1/act", CHAN_VOICE)
			Goto NagDone
		NagMaradeur2:
			"----" A 0 A_PlaySound("maradeur/2/act", CHAN_VOICE)
			Goto NagDone
		NagMaradeur3:
			"----" A 0 A_PlaySound("maradeur/3/act", CHAN_VOICE)
			Goto NagDone
*/			
		NagPostpone:
			"----" A 0 A_SetUserVar("user_nag_cooldown", Random(15,45))
			Goto ChasePlayer
		NagDone:
			"----" A 0 A_SetUserVar("user_nag_cooldown", Random(user_nag_period / 2, user_nag_period))
			Goto ChasePlayer
			
		SeeGuarding: // evil marines were locking up because they did not have this state -- caused the check to misfire.	
			"----" A 1
			Goto See
			
		StandLoop: // a necessary stub
			"----" A 1
			Goto See
	}		
}



ACTOR EvilMarineDebugTrail: CheDebugMarkerQuestion
{
	Radius 4
	Height 2
	XScale 0.2
	YScale 0.3

}

ACTOR DebugTrail: EvilMarineDebugTrail
{
	-CLIENTSIDEONLY
}



ACTOR EvilMarineCheckFront: FastProjectile
{
	DamageType None
	Damage (random (0, 0))
	//+THRUACTORS
	+THRUSPECIES
	Radius 2
	Height 2
	Speed 60
	
	//***Che: debug
	Missileheight 12 // zero Y offset
	//Missiletype "EvilMarineDebugTrail"	
	
	//***Che: the problem with this, when they use it up close! 
	// (when facing a player with a, say, crate behind that player
	// -- this probe goes through the player and hits the crate 
	// and the chaos marine here keeps jumping like a rabbit on crack!
	// I add distance check: do not jump if in target's LOS and closer than 100 map units.
	
	//TNT1 A 0 A_JumpIfInTargetLOS(3, 180, 0, 100) // a certain fix for close distances
	
	States
	{
		Spawn:
			TNT1 A 2 
			TNT1 A 0 A_TakeInventory("evmarinenoway", 1, 0, AAPTR_TARGET)
			//TNT1 A 0 A_SpawnItemEx("CheDebugMarkerPass",0,0,0, 0,0,0, 0,SXF_NOCHECKPOSITION,0)
			Stop
		Death:
		   // TNT1 A 0 A_SpawnItemEx("CheDebugMarkerFail",0,0,0, 0,0,0, 0,SXF_NOCHECKPOSITION,0)
			TNT1 A 1 A_Stop
			TNT1 A 0 A_GiveToTarget("evmarinenoway", 1)
			TNT1 A 1
			Stop
		Xdeath:
			TNT1 A 0 A_Stop
			TNT1 A 0 A_TakeInventory("evmarinenoway", 1, 0, AAPTR_TARGET)
			//TNT1 A 0 A_SpawnItemEx("CheDebugMarkerPass",0,0,0, 0,0,0, 0,SXF_NOCHECKPOSITION,0)
			TNT1 A 1
			Stop
	}
}



ACTOR EvilMarineCheckJump: EvilMarineCheckFront
{
	Speed 80
	States
	{
		Spawn:
			TNT1 A 2
			TNT1 A 0 A_GiveToTarget("evmarinecanjump", 1)
			//TNT1 A 0 A_SpawnItemEx("CheDebugMarkerPass",0,0,0, 0,0,0, 0,SXF_NOCHECKPOSITION,0)
			TNT1 A 0 A_Stop
			Stop
		Death:
		    TNT1 A 0
			//***Che: it is important to *remove* the result of the previous check
			// In this bug, they were jumping a lot like bunnies, while facing a solid wall,
			// even as this check failed!
			// Because previously, they cast it while walking *along* the wall and it succeeded.
			TNT1 A 0 A_TakeInventory("evmarinecanjump", 1, 0, AAPTR_TARGET)
			//TNT1 A 0 A_SpawnItemEx("CheDebugMarkerFail",0,0,0, 0,0,0, 0,SXF_NOCHECKPOSITION,0)
			TNT1 A 1
			Stop
	}
}

