
//***Che these sprites existed in the original BD since forever,
//  folder "Gatekeeper".
// Only four walking frames do exist, no pain, no attack, no death.

/*
	Attacks (not counting him stepping on you):
	1. spamming cubes. A cube each step unless used another attack. These fly to the high ledges surrounding the arena depositing monsters there.
		Eventually, there is a sheet of fireballs coming from slightly above - so it is relatively easy to dodge if you keep moving in a certain direction  without doubling back 
		This is an environmental hazard that grows with time
	
	2. a wall of lightning. Only on flinch, always followed by a power attack. Stretched to the arena's walls, individual bolts wiggling in a certain pattern. Forces you to check your movement and move in a certain way to get between them.
	
	3. Power attack - by cooldown after x steps, or after the lightning attack
		
		3a meteors. Lead you perfectly, *guaranteed* to kill you in a single meteor if you keep moving linearly or standing still. Force you to change your direction and double back and again. Since this stuf fires with a huge delay it has a very high chance of coinciding with another attack that requires a directly opposite dodging pattern.
		
		3b godzilla beam. Traces slowly and easy to outrun *if* you move in a certain direction without doubling back but huge AOE at the point of impact.
		
	All attacks are performed by intangible minion monsters to simplify logic
	
*/

ACTOR IosPerformingPowerAttack: fbd_Token {}
ACTOR IosIsDead: fbd_Token {}

//brain x: 160 * 2.8 = 448
//brain y: -5 x 2.8 = -14
//brain z: 222 x 2.8 = 622

const int IOS2_MUZZLE_X = 450;
const int IOS2_MUZZLE_Y = 0; //-14;
const int IOS2_MUZZLE_Z = 550; //622; // nope, boss too deep, perspective misaligns this with his sprite
const int IOS2_GODZILLA_BEAM_LEAD_ACC = ANGLE_TO_FIXED * 2.5 / 35.0; // fixed, 2.5 degrees per second squared
const int IOS2_GODZILLA_BEAM_LEAD_CAP = ANGLE_TO_FIXED * 10.0 / 35.0; // fixed, 5.0 degrees per second
const int IOS2_LIGHTNING_WALL_STEP = 400; // map units between thunderbolts
	
ACTOR IosStage2_3
{
	damagefactor "Normal", 1.0
	damagefactor "Desintegrate", 1.0	
	damagefactor "Avoid", 0.0
	damagefactor "GibRemoving", 0.0	damagefactor "Trample", 0.0
	damagefactor "TeleportRemover", 0.0
	DamageFactor "CauseSplash", 0.0 DamageFactor "CauseObjectsToSplashSlime", 0.0 DamageFactor "CauseObjectsToSplashNukage", 0.0
	DamageFactor "CauseObjectsToSplashBlood", 0.0 DamageFactor "CauseObjectsToSplashLava", 0.0
	Obituary "%o was destroyed by a Mastermind."
	Painchance "Stomp", 255
	Painchance "Explosive", 255
	
	damagefactor "Burn", 0.0 //immune to imp fireballs - but, more importantly, to blood lake's damage
	

	Tag "$IOSBOSS_T" // The final boss
	Obituary "$IOSBOSS_O" // %o fell in the Final Battle

	Species "FinalBoss"
	
	+BOSS
	+AMBUSH	
	+FLOORCLIP
	+NORADIUSDMG
	+DONTMORPH
	+BOSSDEATH
	+NOBLOOD
	+NOTARGET
	+FORCEXYBILLBOARD
	+NOICEDEATH
	
	+MISSILEMORE
	+MISSILEEVENMORE
	+QUICKTORETALIATE // he instakills any monster that angered him
	+NOPAIN // temporaray, cleared after setup

	DeathSound "cyber/death"
	
	

	Game Doom

	Health 110000

	Radius 320
	Height 640
	
    damagefactor "Crush", 30.0
	
	// immunity to his own AOE devastation
	damagefactor "IOS_Frost", 0.0
	damagefactor "ExplosiveImpact", 0.0
	damagefactor "Stomp", 0.0
	
	Scale 2.8
	
	Mass 996000
	Speed 63 // Similar tests on the cyberlord showed the speed of 70 and above
		// results in the boss outrunning a sprinting player and stepping on him.
		// End of story.
		// ( for 2-tic chase frames)
	
	MaxStepHeight 200
	MaxDropOffHeight 200
	PainChance 15
	Painchance "Fatality", 90
	Painchance "BFG10k", 60
	Painchance "Desintegrate", 60 // 9k & unmaker
	Monster
	//MinMissileChance 200
	DeathHeight 0
	BurnHeight 0
	+BOSS
	+FLOORCLIP
    +DONTRIP
	+DONTMORPH
	+BOSSDEATH
    +NORADIUSDMG
    +NOBLOOD
	+MISSILEMORE
	+SOLID
	+MISSILEEVENMORE
	+SHOOTABLE
	+NOICEDEATH
	DropItem None
	SeeSound "spider/sight"
	AttackSound "spider/attack"
	PainSound "DSBOSPN" //"SPIPAIN1"
	DeathSound "spider/death"
	ActiveSound None //his immensely loud footsteps do the trick

    damagefactor "Blood", 0.0
	
	var int user_cubelevel;
	var int user_pwr_atk_cooldown;
	var int user_pwr_atk_type; // 0 meteor spam, 1 godzilla beam
	
	// these variables are filled by the ACS script that spawns us (see eday32.wad)
	var int user_cubelevel_default;
	var int user_cubelevel_laststand;
	var int user_cooldowns_set;
	var int user_laststand_threshold;
	var int user_death_throes;
	// var int user_repeat;
	
	Species "EvilBosses"
	
	
	States
	{
	
		Spawn:
			KPRM A 0 NODELAY A_JumpIfInventory("HasSpotedThePlayerAlready", 1, "See2")
			TNT1 A 0 A_SetUserVar("user_pwr_atk_cooldown", 999)
			KPRM A 10
			
		Stand:	
			KPRM A 10 A_Look
			Loop

		See:
			TNT1 A 0
			TNT1 A 0 A_JumpIfInventory("HasSpotedThePlayerAlready", 1, "See2")
			TNT1 A 0 A_GiveInventory("HasSpotedThePlayerAlready", 1)		
			TNT1 A 0 ACS_NamedExecuteWithResult("FBD_DisplayBossHealth", 13) // "IOSBOSS2"; // Icon of Sin Unleashed / Лик греха высвобожденный
			
			TNT1 A 0 ACS_NamedExecute("TransformMapForStage2Part2") // map script, switches music among other things
			
			TNT1 A 0 A_ChangeFlag("NOPAIN", 0)
		Idle:
			KPRM A 30 A_Look
			"----" A 0 A_Jump(50, "Wander")
			Loop
		Wander:
			KPRM A 20 A_CustomMissile("IosStage2Stomp")
			KPRM BBBB 2 A_Wander
			KPRM B 2 A_Look
			KPRM C 20 A_CustomMissile("IosStage2Stomp")
			KPRM DDDD 2 A_Wander
			KPRM D 2 A_Look
			"----" A 0 A_Jump(50, "Idle")
			Loop
		See2:
			KPRM A 30
		Chase:
			KPRM A 20 A_CustomMissile("IosStage2Stomp")
			KPRM BBBBB 2 A_Chase("", "")
			KPRM C 20 A_CustomMissile("IosStage2Stomp")
			KPRM DDDDD 2 A_Chase("", "")
			
			"----" A 0 A_ChangeFlag("NOPAIN", 0)
			TNT1 A 0 A_JumpIfTargetInLOS("AttackLogic")
			
			Loop
			
		AttackLogic:
			"----" A 0 A_SetUserVar("user_pwr_atk_cooldown", user_pwr_atk_cooldown - 1)
			"----" A 0 A_JumpIf(CallAcs("GetNoTraget"), "Chase")
			
			// if it is not a player and not a NPC marine, end it instantly
			"----" A 0 A_JumpIfInTargetInventory("TargetIsAMarine", 1, 2)
			"----" A 0 A_JumpIfInTargetInventory("IsPlayer", 1, 1)
			Goto AttackMonster
			
			"----" A 0 A_JumpIfInventory("IosPerformingPowerAttack", 1, 2)
			"----" A 0 A_JumpIf(user_pwr_atk_cooldown <= 0, "PowerAttack")
			
			// the cube then clears its master pointer and acquires the closest visible waypoint as its target
			"----" A 0 A_SpawnItemEx("IosStage2_BossCubeMkIII", 10,IOS2_MUZZLE_Y,IOS2_MUZZLE_Z, 0,0,0, 0, SXF_SETMASTER | SXF_NOCHECKPOSITION) // warps to bosses' head anyway
			Goto Chase
			
/*			
			"----" A 0 A_SetUserVar("user_cubelevel", Random(0, health) < user_laststand_threshold ? user_cubelevel_laststand : user_cubelevel_default)
			
			//"----" A 0 A_JumpIf(user_cubelevel == 1, "Summon1")
			"----" A 0 A_JumpIf(user_cubelevel == 2, "Summon2")
		Summon1:
			//"----" A 0 A_SpawnItemEx("IosStage2_BossCubeFirer", IOS2_MUZZLE_X,IOS2_MUZZLE_Y,IOS2_MUZZLE_Z, 0,0,0, 0, SXF_TRANSFERPOINTERS | SXF_SETMASTER | SXF_NOCHECKPOSITION)
			Goto Chase
		
		Summon2:
			//"----" A 0 A_SpawnItemEx("IosStage2_BossCubeFirer_Bikstronk", IOS2_MUZZLE_X,IOS2_MUZZLE_Y,IOS2_MUZZLE_Z, 0,0,0, 0, SXF_TRANSFERPOINTERS | SXF_SETMASTER | SXF_NOCHECKPOSITION)
			Goto Chase
*/			

		AttackMonster:
			// This missile warps instantly to target and detonates.
			// All monsters are his creations, his tools, his toys.
			// He can end them any moment he wishes.
			// No a_facetarget even, just bam and that stupid bloke is obliterated. 
			// Without even looking.
			"----" A 0 A_Scream
			"----" A 0 A_CustomMissile("IOSAntiMonsterNuke", 650, 0, 0, CMF_AIMDIRECTION | CMF_ABSOLUTEPITCH | CMF_SAVEPITCH, 90)
			"----" A 0 A_ClearTarget
			Goto Chase
		
		Pain:	
			//"----" A 0 A_SetUserVar("user_repeat", 2 + CallAcs("FBD_GetGameSkill")) // from 3 on ITYTD to 6 on Hordes
			
			"----" A 0 A_SpawnItemEx("IosStage2_LightningWallFirer", 10,IOS2_MUZZLE_Y,IOS2_MUZZLE_Z, 0,0,0, 0, SXF_TRANSFERPOINTERS | SXF_SETMASTER | SXF_NOCHECKPOSITION) // warps to bosses' head anyway
/*			
		PainPrainLightning:
			"----" A 0 A_CustomMissile("IOSThunderboltFirer", 700, 0, Random(0, 360), CMF_AIMDIRECTION | CMF_ABSOLUTEPITCH | CMF_SAVEPITCH, 0)
			"----" A 0 A_SetUserVar("user_repeat", user_repeat - 1)
			"----" A 0 A_JumpIf(user_repeat > 0, "PainPrainLightning")
*/			
		PainContinue:
			"----" A 0 A_ChangeFlag("NOPAIN", 1)
			"----" A 10 A_Scream
			KPRM BBBBB 2 A_Wander //A_Chase("", "")
			"----" A 0 A_JumpIfInventory("IosPerformingPowerAttack", 1, "Chase")
			Goto PowerAttack
			
		PowerAttack:	
			"----" A 0 A_SetUserVar("user_pwr_atk_cooldown", 10 + 10 * (2 - user_cooldowns_set))
			"----" A 0 A_GiveInventory("IosPerformingPowerAttack", 1) // removed by minion attack monsters
			"----" A 0 A_SetUserVar("user_pwr_atk_type", user_pwr_atk_type > 1 ? 0 : user_pwr_atk_type + 1)
			"----" A 0 A_JumpIf(user_pwr_atk_type == 1, "MeteorRain")
			Goto GodzillaBeam
			
			
		MeteorRain:
			"----" A 0 A_SpawnItemEx("IosStage2_MeteorsFirer", 10,IOS2_MUZZLE_Y,IOS2_MUZZLE_Z, 0,0,0, 0, SXF_TRANSFERPOINTERS | SXF_SETMASTER | SXF_NOCHECKPOSITION) // warps to bosses' head anyway
			Goto See2	
				
		GodzillaBeam:
			
			"----" A 0 A_Stop
			"----" A 0 A_FaceTarget
			"----" A 0 A_ChangeFlag("NOPAIN", 1)
			"----" A 0 A_SpawnItemEx("IosStage2_GodzillaBeamFirer", 10,IOS2_MUZZLE_Y,IOS2_MUZZLE_Z, 0,0,0, 0, SXF_TRANSFERPOINTERS | SXF_SETMASTER | SXF_NOCHECKPOSITION) // warps to bosses' head anyway
			
		GodzillaBeamFiring:
			KPRM A 0 A_JumpIfInventory("IosPerformingPowerAttack", 1, 2)
			KPRM A 0 A_Jump(256, "GodzillaBeamStop")
			KPRM A 1
			// the jumps do nothing on Zandronum client so this state keeps looping stably until update from the server switches the actor to something else
			Loop
			
		GodzillaBeamStop:	
			
			"----" A 0 A_ChangeFlag("NOPAIN", 0)
			Goto See2
			
		Death:
			KPRM A 1 ACS_NamedExecuteWithResult("BossIsDead") // map script
			TNT1 A 0 A_GiveInventory("IosIsDead", 1)
			TNT1 A 0 ACS_NamedExecute("IOSStage2Death") // colors the map red (sadly, only works in single player)
			TNT1 A 0 A_StopSound(4)
			TNT1 A 0 A_StopSound(3)
			TNT1 A 0 A_StopSound(1)
			TNT1 A 0 A_PLaySoundEx("brain/death", 4, 0, 2)
			TNT1 A 0 Radius_Quake (22, 140, 0, 64, 0)
			KPRM A 25 A_CustomMissile ("HollywoodExplosion2", 300, 0, random (0, 360), 2, random (30, 120))
			TNT1 A 0 Thing_Destroy(660, 1, 0)
			TNT1 A 0 Thing_Destroy(661, 1, 0)
			KPRM A 25 A_CustomMissile ("HollywoodExplosion2", 300, 0, random (0, 360), 2, random (30, 120))
			TNT1 A 0 Thing_Destroy(662, 1, 0)
			KPRM A 25 A_CustomMissile ("HollywoodExplosion2", 300, 0, random (0, 360), 2, random (30, 120))
			TNT1 A 0 Thing_Destroy(663, 1, 0)
			KPRM A 5 A_CustomMissile ("HollywoodExplosion2", 300, 0, random (0, 360), 2, random (30, 120))
			KPRM AAAAAAAAAAAAAAAAAAAA 1 A_CustomMissile ("BloodmistEpic", Random(0,600), Random(-300,300), random (0, 360), CMF_AIMDIRECTION | CMF_ABSOLUTEPITCH, random (40, 90))
			TNT1 A 0 A_NoBlocking
			TNT1 A 0 Thing_Destroy(660, 1, 0)
			TNT1 A 0 Thing_Destroy(661, 1, 0)
			TNT1 A 0 Thing_Destroy(662, 1, 0)
			TNT1 A 0 Thing_Destroy(663, 1, 0)
			TNT1 A 0 A_StopSound(4)
			TNT1 A 0 A_PLaySoundEx("NUKEEXPL", 4, 0, 2)
			//TNT1 A 0 A_SpawnItem("SuperNuclearExplosion", 0, 800)
			TNT1 A 0 A_SpawnItemEx ("HugeNuclearMushroom",0,0,200,0,0,0,0,SXF_NOCHECKPOSITION,0)
			EXPL A 0 Radius_Quake (8, 120, 0, 120, 0)

			TNT1 AAAAAAAAAAA 0 A_CustomMissile ("BloodmistEpic", Random(0,100), Random(-1000,1000), random (0, 360), CMF_AIMDIRECTION | CMF_ABSOLUTEPITCH, random (40, 90))
			
			TNT1 A 0 A_SetUserVar("user_death_throes", 350)
		DeathThroes:
			TNT1 A 1 A_CustomMissile ("BloodmistEpic", Random(0,100), Random(-300,300), random (0, 360), CMF_AIMDIRECTION | CMF_ABSOLUTEPITCH, random (40, 90))
			TNT1 A 0 A_SetUserVar("user_death_throes", user_death_throes - 1)
			TNT1 A 0 A_JumpIf(user_death_throes <= 0, "Finish")
			TNT1 A 0 A_JumpIf(!(user_death_throes % 17), "KillAllDemons")
			Loop
		KillAllDemons:
			TNT1 A 0 Thing_Damage(660, 9999, 0)
			TNT1 A 0 Thing_Destroy(661, 9999, 0)
			TNT1 A 0 Thing_Destroy(662, 9999, 0)
			TNT1 A 0 Thing_Destroy(663, 9999, 0)
			Goto DeathThroes
		Finish:	
			TNT1 A 0 ACS_NamedExecute("TransformMapForStage3", 0, 0, 0, 0)//A_BrainDie // ends the map
			TNT1 A 30	
			Stop
	}
}

ACTOR IosStage2_2 : IosStage2_3
{
	Speed 50
	Health 75600
}

ACTOR IosStage2_1 : IosStage2_3
{
	Speed 40
	Health 66000
}

ACTOR IosStage2_4 : IosStage2_3
{
	Speed 80
	Health 180000
}



ACTOR IosStage2Stomp
{
    Radius 0
    Height 0
	Alpha 1.0
	RenderStyle Add
	Speed 2
	+MISSILE
	PROJECTILE
	Damage 100
	Damagetype "Stomp"
    States
    {
		Spawn:
		Death:
			TNT1 A 1
			TNT1 A 0 A_Explode (6000,600, 0)
			TNT1 A 0 A_PlaySound("eday32/stage3footstep")
			Stop
    }
}

ACTOR HugeNuclearMushroom: NuclearMushroom
{
	Scale 25.0
	-FORCEYBILLBOARD
	+FORCEXYBILLBOARD
	States	{
		Spawn:
			BFEI ABCDEFGHIJKLMNOPQRSTUV 4 BRIGHT
			Stop
	}
}

ACTOR IOS3DeathsplosionPart: CyberLordMissile2
{
	-NOGRAVITY
}

ACTOR FBD_ZillaLightningTrail : FBD_LightningTrail 
{
	States
	{
		Spawn: 
			TNT1 A 0 NODELAY A_SetScale((random(0,1) ? 0.1 : -0.1) * random(25,35), (random(0,1) ? 0.1 : -0.1) * random(25,35))
			ANCB DEFGHI 2 BRIGHT
			Stop
	}
}

Actor GodzillaBeamBoom
{
	+NOCLIP
	+NOGRAVITY
	+MISSILE
	+FORCERADIUSDMG
	+NODAMAGETHRUST
	Speed 2
	Damagetype "SuperPlasma"
	States {
		Spawn:
			TNT1 A 0
			TNT1 A 2 A_PlaySound("FAREXPL")
			TNT1 A 0 A_Explode(900, 100, 0)
			TNT1 A 0 A_SetDamageType("Fire")
			TNT1 A 0 A_Explode(64, 500, 0)
			TNT1 A 32 A_CustomMissile ("NuclearFlames", 0, 0, random (0, 360), 2, random (0, 90))
			TNT1 A 0 A_Explode(32, 600, 0)
			TNT1 A 32 A_CustomMissile ("NuclearFlames", 0, 0, random (0, 360), 2, random (0, 90))
			TNT1 A 0 A_Explode(16, 800, 0)
			TNT1 A 32 A_CustomMissile ("NuclearFlames", 0, 0, random (0, 360), 2, random (0, 90))
			TNT1 A 0 A_SetDamageType("Burn")
			TNT1 A 0 A_Explode(8, 900, 0)
			Stop
	}
}

ACTOR IosStage2_GodzillaBeam: FastProjectile
{
	Speed 5000
	FastSpeed 5000
	Radius 64
	Height 64

	missiletype "none" 
	missileheight 8

	Species "EvilBosses"
	+THRUSPECIES
	+MTHRUSPECIES
	
	SeeSound "IOSBEAM"
	
	Damage 0 //(random(999,999)) // because fuck you, that's why
	DamageType "SuperPlasma"
	
	States {
		Spawn:
			TNT1 AAAAAAAAA 1 // unlimited range, limited by arena width
			Goto Death
			
		Death:
		XDeath:
		Crash:
			TNT1 A 0 A_Stop
			TNT1 A 0 ACS_NamedExecuteWithResult("DrawLazorBeamMk5", 3) // a serverside script that calls a clientside script to actually draw
			
			// re-register the firer's master (the boss) as one who fired this,
			// to make obituary work and avoid damaging the boss
			// cannot do this before calling the lazer beam script: would play havok with its length
			// that's why I replaced direct hit damage with AOE with radius 100
			TNT1 A 0 A_TransferPointer(AAPTR_TARGET, AAPTR_DEFAULT, AAPTR_MASTER, AAPTR_TARGET) 
			
			TNT1 A 0 A_SpawnItemEx("GodzillaBeamBoom",0,0,0, 0,0,0, 0,SXF_NOCHECKPOSITION)
			
			// keep existing in case script starts delayed - it is CLIENTSIDE after all
			TNT1 A 60
			Stop		
	}
}



ACTOR AbstractIosStage2Firer
{
	Monster
	-COUNTKILL
	+NOINTERACTION
	+NOCLIP
	+NOTARGET
	+NEVERTARGET
	+BRIGHT
	RenderStyle Add
	Alpha 0.95
	Scale 3.0
	States {
		Spawn:
			KYDB G 1
			Stop
	}
}

ACTOR IosStage2_Distance_Probe: FastProjectile
{
	+SERVERSIDEONLY
	DamageType None
	Damage (random (0, 0))
	+THRUACTORS
	+THRUSPECIES
	+SKYEXPLODE
	Radius 64
	Height 12
	Speed 5000
	
	Missileheight 12 // zero Y offset
	//Missiletype "CheDebugMarkerQuestion"
	
	States
	{
		Spawn:
			TNT1 A 1
		Death:
		Calculate:
			TNT1 A 0 A_Stop
			TNT1 A 0 ACS_NamedExecuteWithResult("EDAY32_DistanceProbeResult", 0) // a map script, writes the distance into target's user variable
			TNT1 A 1
			Stop
	}
}

ACTOR IosStage2_Distance_Probe_Left: IosStage2_Distance_Probe
{
	States
	{
		Spawn:
			TNT1 A 1
		Death:
		Calculate:
			TNT1 A 0 A_Stop
			TNT1 A 0 ACS_NamedExecuteWithResult("EDAY32_DistanceProbeResult", 1) // a map script, writes the distance into target's user variable
			TNT1 A 1
			Stop
	}
}

/*
script "EDAY32_DistanceProbeResult" (int which) {
	int x = GetActorX(0);
	int y = GetActorY(0);
	if (!SetActivator(0, AAPTR_Target)) Terminate;
	int varname = "user_range";
	switch (which) {
		case 1: varname = "user_range_left"; break;
	}
	SetUserVariable(0, varname, OverflowSafeIntDist(GetActorX(0), GetActorY(0), 0, x, y, 0));
}
*/

ACTOR IosStage2_LightningWallFirer: AbstractIosStage2Firer
{
	+SERVERSIDEONLY
	var int user_angle;
	var int user_range;
	var int user_range_left;
	var int user_d;
	States {
		Spawn:
			// copy master's target
			TNT1 A 0 NODELAY A_TransferPointer(AAPTR_MASTER, AAPTR_DEFAULT, AAPTR_TARGET, AAPTR_TARGET)
			TNT1 A 0 A_FaceTarget
			TNT1 A 0 A_Warp(AAPTR_Master,IOS2_MUZZLE_X,IOS2_MUZZLE_Y,1200,0,WARPF_NOCHECKPOSITION | WARPF_USECALLERANGLE)
			TNT1 A 0 A_CustomMissile("IosStage2_Distance_Probe", 0, 0, -90, CMF_AIMDIRECTION, 0)
			TNT1 A 0 A_CustomMissile("IosStage2_Distance_Probe_Left", 0, 0, 90, CMF_AIMDIRECTION, 0)
			TNT1 A 3 // let the projectiles time to spawn, fly and fill our user variables
			
			TNT1 A 0 A_Jump(192, "Wigglers", "Circlers")
			
		// default wall:	
			TNT1 A 0 A_SetUserVar("user_d", 0)
		FireRight: 
			TNT1 A 0 A_CustomMissile("IosStage2_WallThunderboltSeeker", 0, user_d, 0, CMF_AIMDIRECTION, 0)
			TNT1 A 0 A_SetUserVar("user_d", user_d + IOS2_LIGHTNING_WALL_STEP)
			TNT1 A 0 A_JumpIf (user_d < user_range, "FireRight")
			
			TNT1 A 0 A_SetUserVar("user_d", IOS2_LIGHTNING_WALL_STEP)
		FireLeft:
			TNT1 A 0 A_JumpIf (user_d > user_range_left, "EndSeq")
			TNT1 A 0 A_CustomMissile("IosStage2_WallThunderboltSeeker", 0, 0 - user_d, 0, CMF_AIMDIRECTION, 0)
			TNT1 A 0 A_SetUserVar("user_d", user_d + IOS2_LIGHTNING_WALL_STEP)
			Loop
			
			
		Wigglers:
			TNT1 A 0 A_SetUserVar("user_d", 0)
		FireRightW: 
			TNT1 A 0 A_CustomMissile("IosStage2_WallThunderboltSeekerWiggler", 0, user_d, 0, CMF_AIMDIRECTION, 0)
			TNT1 A 0 A_SetUserVar("user_d", user_d + IOS2_LIGHTNING_WALL_STEP)
			TNT1 A 0 A_JumpIf (user_d < user_range, "FireRightW")
			
			TNT1 A 0 A_SetUserVar("user_d", IOS2_LIGHTNING_WALL_STEP)
		FireLeftW:
			TNT1 A 0 A_JumpIf (user_d > user_range_left, "EndSeq")
			TNT1 A 0 A_CustomMissile("IosStage2_WallThunderboltSeekerWiggler", 0, 0 - user_d, 0, CMF_AIMDIRECTION, 0)
			TNT1 A 0 A_SetUserVar("user_d", user_d + IOS2_LIGHTNING_WALL_STEP)
			Loop

		Circlers:
			TNT1 A 0 A_SetUserVar("user_d", 0)
		FireRightC: 
			TNT1 A 0 A_CustomMissile("IosStage2_WallThunderboltSeekerCircler", 0, user_d, 0, CMF_AIMDIRECTION, 0)
			TNT1 A 0 A_SetUserVar("user_d", user_d + IOS2_LIGHTNING_WALL_STEP)
			TNT1 A 0 A_JumpIf (user_d < user_range, "FireRightC")
			
			TNT1 A 0 A_SetUserVar("user_d", IOS2_LIGHTNING_WALL_STEP)
		FireLeftC:
			TNT1 A 0 A_JumpIf (user_d > user_range_left, "EndSeq")
			TNT1 A 0 A_CustomMissile("IosStage2_WallThunderboltSeekerCircler", 0, 0 - user_d, 0, CMF_AIMDIRECTION, 0)
			TNT1 A 0 A_SetUserVar("user_d", user_d + IOS2_LIGHTNING_WALL_STEP)
			Loop
			
		EndSeq:
			TNT1 A 1
			Stop
	}
}


ACTOR IosStage2_WallThunderboltSeeker: FBD_RevenantBall {
	-SHOOTABLE
	Radius 100 // to avoid hugging walls
	Speed 20
	FastSpeed 20
	Damage (Random(0,0))
	Damagetype Plasma
	SeeSound None
	DeathSound None
	States {
		Spawn: 
			// re-register the firer's master (the boss) as one who fired this,
			// to make obituary work and avoid damaging the boss
			TNT1 A 0 NODELAY A_TransferPointer(AAPTR_TARGET, AAPTR_DEFAULT, AAPTR_MASTER, AAPTR_TARGET) 
			
		FlyForth:
			TNT1 A 0
			TNT1 A 0 A_JumpIfInventory("IosIsDead", 1, "Death", AAPTR_TARGET)
			
			// a pure distance check (to tracer) 
			TNT1 A 0 A_JumpIf(CallAcs("GetXYDistanceToTracer") < 120, "StartHoming")
			TNT1 A 4 //KYDB G 4 BRIGHT // big targetig crosshairs for debugging purposes
			TNT1 A 0 ACS_NamedExecuteWithResult("FixThunderboltSeekerZ") // resets its Z to 700.0 and Zvel to 0.0
			// throw them downward from its position at insane speeds
			TNT1 A 0 A_SpawnItemEx("IOSShortLivedThunderbolt", 0, 0, 0, 0, 0, -1000.0, 0, SXF_TRANSFERPOINTERS) 
			Loop
		
		StartHoming:
			TNT1 A 0 A_GiveInventory("ThunderboltLifetime", 60 + CallAcs("FBD_GetGameSkill") * 10)
			Goto FlyHoming
		
		FlyHoming:
			TNT1 A 0
			TNT1 A 0 A_JumpIfInventory("IosIsDead", 1, "Death", AAPTR_TARGET)
			TNT1 A 0 A_JumpIf(CallAcs("GetXYDistanceToTracer") < 20, "Death")
			TNT1 A 4 //KYDB G 4 BRIGHT // big targetig crosshairs for debugging purposes
			TNT1 A 0 A_TakeInventory("ThunderboltLifetime", 4)
			TNT1 A 0 ACS_NamedExecuteWithResult("FixThunderboltSeekerZ") 
			TNT1 A 0 A_SpawnItemEx("IOSShortLivedThunderbolt", 0, 0, 0, 0, 0, -1000.0, 0, SXF_TRANSFERPOINTERS) 
			TNT1 A 0 A_SeekerMissile (4, 8, SMF_LOOK)
			//SMF_PRECISE)
			TNT1 A 0 A_JumpIfInventory("ThunderboltLifetime", 1, "FlyHoming")
			Goto Death
			
		Death:
			TNT1 A 0 A_Stop
			TNT1 A 0 A_SpawnItemEx("IOSThunderboltFinale", 0, 0, 0, 0, 0, -1000.0, 0, SXF_TRANSFERPOINTERS) 
			TNT1 A 0
			Stop
	}
}


ACTOR IosStage2_WallThunderboltSeekerWiggler: IosStage2_WallThunderboltSeeker
{
	var int user_angle;
	var int user_phase;
	States {
		Spawn: 
			TNT1 A 0 NODELAY A_SetUserVar("user_angle", ANGLE_TO_FIXED * angle)
			TNT1 A 0 A_TransferPointer(AAPTR_TARGET, AAPTR_DEFAULT, AAPTR_MASTER, AAPTR_TARGET)
		FlyForth:
			TNT1 A 0
			TNT1 A 0 A_JumpIfInventory("IosIsDead", 1, "Death", AAPTR_TARGET)
			TNT1 A 0 A_JumpIf(CallAcs("GetXYDistanceToTracer") < 120, "StartHoming")
			TNT1 A 4 
			TNT1 A 0 ACS_NamedExecuteWithResult("ThunderboltSeekerWiggle", 1)
			// throw them downward from its position at insane speeds
			TNT1 A 0 A_SpawnItemEx("IOSShortLivedThunderbolt", 0, 0, 0, 0, 0, -1000.0, 0, SXF_TRANSFERPOINTERS) 
			Loop	
	
	}
}

ACTOR IosStage2_WallThunderboltSeekerCircler: IosStage2_WallThunderboltSeekerWiggler
{
	States {
		Spawn: 
			TNT1 A 0 NODELAY A_SetUserVar("user_angle", ANGLE_TO_FIXED * angle)
			TNT1 A 0 A_TransferPointer(AAPTR_TARGET, AAPTR_DEFAULT, AAPTR_MASTER, AAPTR_TARGET)
		FlyForth:
			TNT1 A 0
			TNT1 A 0 A_JumpIfInventory("IosIsDead", 1, "Death", AAPTR_TARGET)
			TNT1 A 0 A_JumpIf(CallAcs("GetXYDistanceToTracer") < 120, "StartHoming")
			TNT1 A 4 
			TNT1 A 0 ACS_NamedExecuteWithResult("ThunderboltSeekerWiggle", 2)
			// throw them downward from its position at insane speeds
			TNT1 A 0 A_SpawnItemEx("IOSShortLivedThunderbolt", 0, 0, 0, 0, 0, -1000.0, 0, SXF_TRANSFERPOINTERS) 
			Loop	
	
	}
}

/*

script "ThunderboltSeekerWiggle" (int wiggletype) {

	int speed = GetActorProperty(0, APROP_Speed);

	// the frakking seeker LOVES nosediving into the floor!
	SetActorPosition(0, GetActorX(0), GetActorY(0), 700.0, 0);

	int phase = GetUserVariable(0, "user_phase");
	int angle = GetUserVariable(0, "user_angle");
	int velx = GetActorVelX(0);
	int vely = GetActorVelY(0);

	// mind that this gets called every 4 tics (8.75 times per second)
	switch (wiggletype) {
		case 1:
			angle = FixedFrac(angle + FixedMul(0.125, Sin(phase))); // +/- 45 degrees
			velx = FixedMul(speed, Cos(angle));
			vely = FixedMul(speed, Sin(angle));
			phase = FixedFrac(phase + 0.038); // 3 seconds cycle = 1.0 / (3 * 8.75)
			break;
		case 2:
			angle = FixedFrac(angle + FixedMul(0.3, Sin(phase))); // +/- 108 degrees
			velx = FixedMul(speed, Cos(angle));
			vely = FixedMul(speed, Sin(angle));
			phase = FixedFrac(phase + 0.0243); // 4.7 seconds cycle = 1.0 / (3 * 8.75)
			break;
	}
	SetUserVariable(0, "user_phase", phase);
	SetActorAngle(0, angle);
	SetActorVelocity(0, velx, vely, 0.0, FALSE, FALSE);
}

*/

ACTOR IosStage2_GodzillaBeamFirer: AbstractIosStage2Firer
{
	var int user_angle;
	var int user_pitch;
	var int user_life;
	var int user_da;
	var int user_dp;
	States {
		Spawn:
			TNT1 A 0 NODELAY A_Warp(AAPTR_Master,IOS2_MUZZLE_X,IOS2_MUZZLE_Y,IOS2_MUZZLE_Z,0,WARPF_NOCHECKPOSITION)
			TNT1 A 0 A_TransferPointer(AAPTR_MASTER, AAPTR_DEFAULT, AAPTR_TARGET, AAPTR_TARGET)
			TNT1 A 0 A_SetUserVar("user_pitch", CallAcs("GetPitchToTargetFixed", 32, 0, -10.0 * ANGLE_TO_FIXED, 0))
		
			// this small increase is *catastrophical* on Hordes since the beam is inertial (its turning rate increases with time!)
			TNT1 A 0 A_SetUserVar("user_life", 20 + CallAcs("FBD_GetGameSkill") * 5)
			
			TNT1 A 0 A_PlaySound("IOSGBSTA", CHAN_BODY)
			
			LEYS RRRRRRRRRR 1 BRIGHT A_SetScale((random(0,1) ? 0.1 : -0.1) * random(10,15), (random(0,1) ? 0.1 : -0.1) * random(10,15))
			TNT1 A 0 A_JumpIfInventory("IosIsDead", 1, "PutterOut", AAPTR_MASTER)
			TNT1 A 0 A_JumpIf(CallAcs("GetNoTarget"), "PutterOut")
			
			LEYS RRRRRRRRRR 1 BRIGHT A_SetScale((random(0,1) ? 0.1 : -0.1) * random(15,25), (random(0,1) ? 0.1 : -0.1) * random(15,20))
			TNT1 A 0 A_JumpIfInventory("IosIsDead", 1, "PutterOut", AAPTR_MASTER)
			TNT1 A 0 A_JumpIf(CallAcs("GetNoTarget"), "PutterOut")
			
			LEYS RRRRRRRRRR 1 BRIGHT A_SetScale((random(0,1) ? 0.1 : -0.1) * random(15,25), (random(0,1) ? 0.1 : -0.1) * random(20,25))
			TNT1 A 0 A_JumpIfInventory("IosIsDead", 1, "PutterOut", AAPTR_MASTER)
			TNT1 A 0 A_JumpIf(CallAcs("GetNoTarget"), "PutterOut")
			
			TNT1 A 0 A_FaceTarget
			TNT1 A 0 A_SetUserVar("user_angle", ANGLE_TO_FIXED * angle)
			TNT1 A 0 A_SetUserVar("user_angle_to_target", CallAcs("GetAngleToTarget"))
			
			
			TNT1 A 0 A_SetUserVar("user_pitch", CallAcs("GetPitchToTargetFixed", 32, 0, user_pitch, 0))
			
			BLHD ABABABABAB 1 BRIGHT A_SetScale((random(0,1) ? 0.1 : -0.1) * random(25,35), (random(0,1) ? 0.1 : -0.1) * random(25,35))
			TNT1 A 0 A_JumpIfInventory("IosIsDead", 1, "PutterOut", AAPTR_MASTER)
			TNT1 A 0 A_JumpIf(CallAcs("GetNoTarget"), "PutterOut")
			
			BLHD ABABABABAB 1 BRIGHT A_SetScale((random(0,1) ? 0.1 : -0.1) * random(28,38), (random(0,1) ? 0.1 : -0.1) * random(28,38))
			TNT1 A 0 A_JumpIfInventory("IosIsDead", 1, "PutterOut", AAPTR_MASTER)
			TNT1 A 0 A_JumpIf(CallAcs("GetNoTarget"), "PutterOut")
			
			BLHD ABABABABAB 1 BRIGHT A_SetScale((random(0,1) ? 0.1 : -0.1) * random(30,40), (random(0,1) ? 0.1 : -0.1) * random(30,40))
			TNT1 A 0 A_JumpIfInventory("IosIsDead", 1, "PutterOut", AAPTR_MASTER)
			TNT1 A 0 A_JumpIf(CallAcs("GetNoTarget"), "PutterOut")
			
			
			TNT1 A 0 A_PlaySound("IOSGBLOP", CHAN_BODY, 1.0, true)
			
		Firing:	
			
			TNT1 A 0 A_Warp(AAPTR_Master,IOS2_MUZZLE_X,IOS2_MUZZLE_Y,IOS2_MUZZLE_Z,0,WARPF_NOCHECKPOSITION)
			TNT1 A 0 A_CustomMissile("IosStage2_GodzillaBeam", 0, 0, FIXED_TO_ANGLE * user_angle, CMF_AIMDIRECTION | CMF_ABSOLUTEANGLE | CMF_SAVEPITCH, FIXED_TO_ANGLE * user_pitch)
			
			
			BLHD A 1 BRIGHT A_SetScale((random(0,1) ? 0.1 : -0.1) * random(35,50), (random(0,1) ? 0.1 : -0.1) * random(35,50))
			
			TNT1 A 0 A_JumpIfTargetInLOS(3, 0, JLOSF_DEADNOJUMP)
			TNT1 A 0 A_Jump(256, 3)
			TNT1 A 0 A_JumpIf(CallAcs("GetNoTarget"), 2)
			TNT1 A 0 ACS_NamedExecuteWithResult("FBD_LeadTargetInertially", 0, 0, IOS2_GODZILLA_BEAM_LEAD_ACC, IOS2_GODZILLA_BEAM_LEAD_CAP)

			TNT1 A 0 A_Warp(AAPTR_Master,IOS2_MUZZLE_X,IOS2_MUZZLE_Y,IOS2_MUZZLE_Z,0,WARPF_NOCHECKPOSITION)			
			BLHD B 1 BRIGHT A_SetScale((random(0,1) ? 0.1 : -0.1) * random(35,50), (random(0,1) ? 0.1 : -0.1) * random(35,50))
			
			TNT1 A 0 A_JumpIfTargetInLOS(3, 0, JLOSF_DEADNOJUMP)
			TNT1 A 0 A_Jump(256, 3)
			TNT1 A 0 A_JumpIf(CallAcs("GetNoTarget"), 2)
			TNT1 A 0 ACS_NamedExecuteWithResult("FBD_LeadTargetInertially", 0, 0, IOS2_GODZILLA_BEAM_LEAD_ACC, IOS2_GODZILLA_BEAM_LEAD_CAP)
			
			BLHD A 1 BRIGHT A_SetScale((random(0,1) ? 0.1 : -0.1) * random(35,50), (random(0,1) ? 0.1 : -0.1) * random(35,50))
			
			TNT1 A 0 A_JumpIfTargetInLOS(3, 0, JLOSF_DEADNOJUMP)
			TNT1 A 0 A_Jump(256, 3)
			TNT1 A 0 A_JumpIf(CallAcs("GetNoTarget"), 2)
			TNT1 A 0 ACS_NamedExecuteWithResult("FBD_LeadTargetInertially", 0, 0, IOS2_GODZILLA_BEAM_LEAD_ACC, IOS2_GODZILLA_BEAM_LEAD_CAP)
			
			BLHD B 1 BRIGHT A_SetScale((random(0,1) ? 0.1 : -0.1) * random(35,50), (random(0,1) ? 0.1 : -0.1) * random(35,50))
			
			TNT1 A 0 A_JumpIfTargetInLOS(3, 0, JLOSF_DEADNOJUMP)
			TNT1 A 0 A_Jump(256, 3)
			TNT1 A 0 A_JumpIf(CallAcs("GetNoTarget"), 2)
			TNT1 A 0 ACS_NamedExecuteWithResult("FBD_LeadTargetInertially", 0, 0, IOS2_GODZILLA_BEAM_LEAD_ACC, IOS2_GODZILLA_BEAM_LEAD_CAP)
			
			BLHD A 1 BRIGHT A_SetScale((random(0,1) ? 0.1 : -0.1) * random(35,50), (random(0,1) ? 0.1 : -0.1) * random(35,50))
			
			TNT1 A 0 A_JumpIfTargetInLOS(3, 0, JLOSF_DEADNOJUMP)
			TNT1 A 0 A_Jump(256, 3)
			TNT1 A 0 A_JumpIf(CallAcs("GetNoTarget"), 2)
			TNT1 A 0 ACS_NamedExecuteWithResult("FBD_LeadTargetInertially", 0, 0, IOS2_GODZILLA_BEAM_LEAD_ACC, IOS2_GODZILLA_BEAM_LEAD_CAP)
			
			TNT1 A 0 A_JumpIfInventory("IosIsDead", 1, "PutterOut", AAPTR_MASTER)
			TNT1 A 0 A_SetUserVar("user_life", user_life - 1)
			TNT1 A 0 A_JumpIf(user_life <= 0, "PutterOut")
			Loop
			
		PutterOut:
			TNT1 A 0 A_PlaySound("IOSGBSTO", CHAN_BODY)
			TNT1 A 0 A_TakeInventory("IosPerformingPowerAttack", 1, 0, AAPTR_Master)
			TNT1 A 60
			Stop
	}
}

ACTOR IosStage2_MeteorsFirer: AbstractIosStage2Firer
{
	+SERVERSIDEONLY
	var int user_c; // remaining meteor count
	var int user_x; // fixed
	var int user_y; // fixed
	var int user_dx; // fixed
	var int user_dy;
	var int user_range; // int
	var int user_angle;
	var int user_d; // int
	States {
		Spawn:
			TNT1 A 0 NODELAY A_Warp(AAPTR_Master,IOS2_MUZZLE_X,IOS2_MUZZLE_Y,IOS2_MUZZLE_Z,0,WARPF_NOCHECKPOSITION)
			// copy master's target
			TNT1 A 0 A_TransferPointer(AAPTR_MASTER, AAPTR_DEFAULT, AAPTR_TARGET, AAPTR_TARGET)
			TNT1 A 0 A_SetUserVar("user_c", 2 + CallAcs("FBD_GetGameSkill"))
		
		Fire:	
			TNT1 A 0 A_SetUserVar("user_dx", CallAcs("GetTargetX", user_x)) // fixed
			TNT1 A 0 A_SetUserVar("user_dy", CallAcs("GetTargetY", user_y)) // fixed
			TNT1 A 105 // wait three seconds
			TNT1 A 0 A_SetUserVar("user_x", CallAcs("GetTargetX", user_dx))
			TNT1 A 0 A_SetUserVar("user_y", CallAcs("GetTargetY", user_dy))
			
			// nov these variables contain target's velocity in map units per second in fixed point (int)(<value> * 65536.0)
			TNT1 A 0 A_SetUserVar("user_dx", 0.3333333 * (user_x - user_dx))
			TNT1 A 0 A_SetUserVar("user_dy", 0.3333333 * (user_y - user_dy))
			
			TNT1 A 0 A_SetUserVar("user_angle", CallAcs("GetAngleFromdXdY", user_dx, user_dy))
			// meteor speed 25, ceiling height 3000, the player is running across a flat plain at z=-255
			// Thus, meteor's falling distance is 3255 and falling time is 128 tics (3.66 seconds)
			//  while user_dx, user_dy now hold target's velocity averaged in map units per second
			// We add one extra second we spent calculating the averaged velocities
			TNT1 A 0 A_SetUserVar("user_d", 3.66 * CallAcs("GetIntDistFromdXdY", user_dx, user_dy)) // rounds down to integer
			
			// move to above our target's current position:
			TNT1 A 0 A_Warp(AAPTR_Default,(CallAcs("GetTargetX", user_x) * FIXED_TO_FLOAT) - x, (CallAcs("GetTargetY", user_y) * FIXED_TO_FLOAT) - y, 700 - z, 0, WARPF_NOCHECKPOSITION | WARPF_ABSOLUTEOFFSET)
			TNT1 A 0 A_SetAngle(FIXED_TO_ANGLE * user_angle)
			// check distance of a free straight line from this position to target's predicted:
			TNT1 A 0 A_CustomMissile("IosStage2_Distance_Probe", 0, 0, 0, CMF_AIMDIRECTION, 0)
			TNT1 A 3 // give the probe time to work, writes result into user_range
			
			TNT1 A 0 A_SetUserVar("user_dx", user_range < user_d ? user_range * Cos(angle) * FLOAT_TO_FIXED : 3.66 * user_dx)
			TNT1 A 0 A_SetUserVar("user_dy", user_range < user_d ? user_range * Sin(angle) * FLOAT_TO_FIXED : 3.66 * user_dy)
			// now user_x and user_y contain a predicted player position 
			// (clipped to walls in the way)
			
		ActuallyFire:
			TNT1 A 0 A_JumpIfInventory("IosIsDead", 1, "PutterOut", AAPTR_MASTER)
			TNT1 A 0 A_Warp(AAPTR_Default, ((user_x + user_dx) * FIXED_TO_FLOAT) - x, ((user_y + user_dy) * FIXED_TO_FLOAT) - y, 1200 - z, 0, WARPF_NOCHECKPOSITION | WARPF_ABSOLUTEOFFSET)
			
			// is ceiling hugger, ceiling height = 3000
			TNT1 A 0 A_CustomMissile("IosStage2_MeteorDropper", 0, 0, 0, CMF_AIMDIRECTION, 0)
			
			TNT1 A 0 A_SetUserVar("user_c", user_c - 1)
			TNT1 A 0 A_JumpIf(user_c > 0, "Refire")
			Goto PutterOut
			
		Refire:
			TNT1 A 0 A_JumpIF(CallAcs("FBD_GetGameSkill") > 3, "RefireContinue") // hordes, 3s interval
			TNT1 A 0 A_JumpIF(CallAcs("FBD_GetGameSkill") > 2, "Wait35") // ultra violence, 4s interval 
			TNT1 A 58 // all other skills, 4.66 s interval
			Goto RefireContinue
		
		Wait35:	
			TNT1 A 35
			Goto RefireContinue
			
		RefireContinue:	
			TNT1 A 0 A_JumpIfInventory("IosIsDead", 1, "PutterOut", AAPTR_MASTER)
			Goto Fire
		
		PutterOut:
			TNT1 A 0 A_TakeInventory("IosPerformingPowerAttack", 1, 0, AAPTR_Master)
			TNT1 A 60
			Stop	
	}
}

ACTOR IosStage2_MeteorDropper 
{
	Projectile
	Damage (Random(0,0))
	+THRUACTORS
	+THRUGHOST
	FastSpeed 60
	Speed 0
	FastSpeed 0
	Radius 1
	Height 1
	+NOBLOCKMAP
	+CEILINGHUGGER
	+SERVERSIDEONLY
	States
	{
		Spawn:
			// re-register the firer's master (the boss) as one who fired this,
			// to make obituary work and avoid damaging the boss
			TNT1 A 0 NODELAY A_TransferPointer(AAPTR_TARGET, AAPTR_DEFAULT, AAPTR_MASTER, AAPTR_TARGET) 
			TNT1 A 1
			TNT1 A 0 A_CustomMissile("IOSMeteor", -60, 0, 0, CMF_AIMDIRECTION | CMF_ABSOLUTEPITCH | CMF_SAVEPITCH | CMF_TRACKOWNER, -90)
		Death:
			TNT1 A 1
			Stop
	}
}	

ACTOR IosStage2_BossCubeMkIII {

	// gold
	Scale 1.6
	Translation  "61:79=160:167", "48:61=224:227", "144:151=167:167", "101:111=162:167", "13:15=166:166", "0:2=0:0", "5:5=189:189"


	Monster
	-COUNTKILL
	+NOTARGET
	+NEVERTARGET
	+NOTAUTOAIMED
	-SHOOTABLE
	+THRUACTORS
	+THRUGHOST
	+NOBLOCKMAP
	+NOGRAVITY
	-NODROPOFF
	+FLOAT
	+NOTELEPORT
	
	Radius 20
	Height 40
	Speed 48
	
	+BRIGHT
	RenderStyle Add
	Alpha 0.8
	
	var int user_bikstronk;
	
	States 
	{
		Spawn: 
			BOSF B 0 NODELAY A_SetUserVar("user_bikstronk", 0)
			Goto FlashIn
			
		FlashIn:
			BOSF B 1 A_Warp(AAPTR_Master,IOS2_MUZZLE_X,IOS2_MUZZLE_Y,IOS2_MUZZLE_Z,0,WARPF_NOCHECKPOSITION)
			TNT1 A 0 A_PlaySound("brain/spit")
			TNT1 A 0 A_SpawnItemEx("RedFlare3BossCubeSpawn", 0,0,0, 0,0,0, 0,SXF_NOCHECKPOSITION)
			BOSF A 3 BRIGHT A_Warp(AAPTR_Master,IOS2_MUZZLE_X,IOS2_MUZZLE_Y,IOS2_MUZZLE_Z,0,WARPF_NOCHECKPOSITION)
			TNT1 A 0 A_SpawnItemEx("RedFlare3BossCubeSpawn", 0,0,0, 0,0,0, 0,SXF_NOCHECKPOSITION)
			BOSF B 3 BRIGHT A_Warp(AAPTR_Master,IOS2_MUZZLE_X,IOS2_MUZZLE_Y,IOS2_MUZZLE_Z,0,WARPF_NOCHECKPOSITION)
			TNT1 A 0 A_SpawnItemEx("RedFlare3BossCubeSpawn", 0,0,0, 0,0,0, 0,SXF_NOCHECKPOSITION)
			BOSF C 3 BRIGHT A_Warp(AAPTR_Master,IOS2_MUZZLE_X,IOS2_MUZZLE_Y,IOS2_MUZZLE_Z,0,WARPF_NOCHECKPOSITION)
			TNT1 A 0 A_SpawnItemEx("RedFlare3BossCubeSpawn", 0,0,0, 0,0,0, 0,SXF_NOCHECKPOSITION)
			BOSF D 3 BRIGHT A_Warp(AAPTR_Master,IOS2_MUZZLE_X,IOS2_MUZZLE_Y,IOS2_MUZZLE_Z,0,WARPF_NOCHECKPOSITION)
			
			// clear target and minion status:
			TNT1 A 0 A_RearrangePointers(AAPTR_NULL, AAPTR_NULL, AAPTR_Default, 0)
			
		Idle:
		Acquire:	
			TNT1 A 0 ACS_NamedExecuteWithResult("BossCubeAcquirePatrolPoint") // map script
			TNT1 A 0 A_JumpIf(CallAcs("IsBossDead"), "FlashOut") // map script
			BOSF ABCD 3 BRIGHT A_Wander
			Loop // just in case the waypoint acquisition does not work
			
		See:
			TNT1 A 0 ACS_NamedExecuteWithResult("FBD_FaceTargetSlowly", ANGLE_TO_FIXED * 5.0)
			BOSF ABCD 3 BRIGHT A_Wander
			TNT1 A 0 A_JumpIf(CallAcs("IsBossDead"), "FlashOut")
			TNT1 A 0 A_JumpIf(CallAcs("GetNoTarget"), "Acquire")
			
			TNT1 A 0 A_JumpIf(z < 112.0, "BumpUp")
			TNT1 A 0 A_JumpIf(z > 136.0, "BumpDown")
			TNT1 A 0 A_JumpIf(floorz > -8 && floorz < 24, "TrySpawn")
			Loop
			
		BumpUp:
			TNT1 A 0 ThrustThingZ(0, random(1,3), 0, 1)
			Goto See

		BumpDown:
			TNT1 A 0 ThrustThingZ(0, random(1,3), 1, 1)
			Goto See
			
		TrySpawn:
			TNT1 A 0 A_JumpIf(CallAcs("IOS2_BcMkIII_TrySpawn", user_bikstronk), "FlashOut") // map script
			Goto See
			
		FlashOut: 
			TNT1 A 0 A_SpawnItemEx("IosBossCubeExplosion",0,0,0,0,0,0,0,SXF_NOCHECKPOSITION,0)
			TNT1 A 30 A_Stop
			Stop
	}
}


/*

script "BossCubeAcquirePatrolPoint" (void) {
	int found = 0;
	int fdist = 99999;
	int x = GetActorX(0);
	int y = GetActorY(0);
	for (int t = 400; t <= 424; t++) {
		int d = OverflowSafeIntDist(x,y,0, GetActorX(t),GetActorY(t),0);
		if (d > fdist) continue;
		if (!CheckSight(0, t, 0)) continue;
		found = t;
		fdist = d;
	}
	if (found) {
		// alas, this cannot work -- the underlying C++ code ignores monsters without the SHOOTABLE flag
		//Thing_SetGoal(0, t, 0, 0);

		SetPointer(AAPTR_Target, found);
		SetActorState(0, "See");
	}
}

script "IOS2_BcMkIII_TrySpawn" (int bikstronk) {
	int idx = BC2SpawneeIdx(bikstronk);
	int x = GetActorX(0);
	int y = GetActorY(0);
	int z = GetActorFloorZ(0);
	if (FBD_TrySpawn(idx, x >> 16, y >> 16, z, FixedFrac(AngleAtClosestPlayer()), MONTID)) {
		Spawn("TeleportationFog", x,y,z,0);
		Spawn("IosBossCubeBoo", x,y,z,0);
		ACS_NamedExecuteAlways("DrawBossCubeBeamClientside", 0, 0, z - GetActorZ(0), 0);
		SetResultValue(1);
	} else {
		SetResultValue(0);
	}
}
*/

