#include "zcommon.acs"
#library "bugfix"

#define TEAM_NONE -1

script 187 (void)
{
}

script 137 (void)
{
}

script 139 (void)
{
}

script 144 (void)
{
}

script 188 ENTER
{
	/*
	while (PlayerIsBot(PlayerNumber())) {
		PrintBold(i:distance(ActivatorTID(),1000));
		delay(1);
	}
	*/
	/*
	if (PlayerIsBot(PlayerNumber())) {
		GiveInventory("CloneSpawning",1);
	}
	*/
}

script 140 (void)
{/*
if (CheckActorClass (0,"megaman")){terminate;}
else{
if(CheckInventory("PowerUpgrade")>0){
	TakeInventory("PowerUpgrade",1);
}
if(CheckInventory("JetUpgrade")>0){
	TakeInventory("JetUpgrade",1);
}

if(CheckInventory("PowerFist")>0){
	TakeInventory("PowerFist",1);
}
if(CheckInventory("JetBuster")>0){
	TakeInventory("JetBuster",1);
}
if(CheckInventory("SuperAdaptorWep")>0){
	TakeInventory("SuperAdaptorWep",1);
}
if(CheckInventory("AdaptorUpgrade2")>0){
	TakeInventory("AdaptorUpgrade2",255);
}

}*/}

script 141 ENTER
{
  if ( GetCVar("teamlms")==1||GetCVar("ctf")==1||GetCVar("teamplay")==1||GetCVar("oneflagctf")==1||GetCVar("teampossession")==1 ) {

     int colorfix = GetPlayerInfo (PlayerNumber(), PLAYERINFO_TEAM);
     
     switch (colorfix){
     
     case 0:  // dr. light/ blue team
      Thing_SetTranslation(PlayerNumber(), 0);
      break;
     
     case 1:  // dr. wily/ red team
      Thing_SetTranslation(PlayerNumber(), 36);
      break;
/*      
     case 6:  // dr. cossack/ orange team ?
       Thing_SetTranslation(PlayerNumber(), 43);
      break;

     case 7:  // mr. x/ purple team ?
       Thing_SetTranslation(PlayerNumber(), 53);
      break;
*/      
     }
  }
}

script 142 RESPAWN
{
  ACS_ExecuteAlways(141, 0);
}

script 655 DEATH
{
/*
SpawnProjectile(0, "JunkBits9", random(0,360), random(1,102), random(10,120), 800, 0);
SpawnProjectile(0, "JunkBits4", random(0,360), random(1,102), random(10,120), 800, 0);
SpawnProjectile(0, "JunkBits6", random(0,360), random(1,102), random(10,120), 800, 0);
*/
//TakeInventory("EnergyBalancerActive", 1);
}

script 143 (void)
{
if(!(ClassifyActor(ActivatorTID()) & ACTOR_PLAYER)) {
SetActivatorToTarget(0);
}
if(GetCVar("teamlms")==1||GetCVar("ctf")==1||GetCVar("teamplay")==1||GetCVar("oneflagctf")==1||GetCVar("teampossession")==1 ){SetResultValue(PlayerTeam());terminate;}
SetResultValue(TEAM_NONE);
}

script 210 (void)
{

}

/*
script 145 (void)
{
	
 If(CheckActorProperty(0,APROP_Gravity,0.25) || GetCvar("sv_gravity") <= 300)
	{
	SetResultValue(1);
	//printbold(s:"true");
	}
	else
		{
		SetResultValue(0);
		} 
}
*/

script 147 (void)
{
SetActivatorToTarget(0);
/*int Result = ActivatorTID();
print(i:Result);*/
SetResultValue(ActivatorTID());
}

function void startMorph (void)
{
ClearInventory();
SetActorProperty(0, APROP_Invulnerable , 0);
MorphActor(ActivatorTID(), "BearerClass", "", 999999999999, MRF_NEWTIDBEHAVIOUR, "", "HumanMorphFlash");
}

function void completeMorph(int i)
{
GiveInventory("BearerFlag",1);
GiveInventory("CanCopyWeapons",1);
GiveInventory("CanUseItems",1);
ACS_ExecuteAlways(423,0,1);
//GiveInventory("ArchiveBusterC",1);
GiveInventory("ArchiveItem",1);
//GiveInventory("UnGlitcher",1);
SetPlayerProperty(0,0,3);
SetActorProperty(0, APROP_Speed, 1.0);
SetActorProperty(0, APROP_JumpZ, 10.0);
SetActorProperty(0, APROP_Gravity, 0.8);
SetActorProperty(0,APROP_HEALTH,i);
SetPlayerProperty(0,0,0);
SetPlayerProperty(0,0,4);
if(GetActorProperty(0,APROP_HEALTH)>100){
SetActorProperty(0,APROP_HEALTH,100);
}
}

Script 500 ENTER
{
int i = GetActorProperty(0, APROP_HEALTH);

if (!(i>0)) { terminate;}

//print(s:"500 executed");

if(CheckInventory("BearerFlag")==1){
if(CheckInventory("RedFlag")==0&&CheckInventory("BlueFlag")==0&&CheckInventory("WhiteFlag")==0
&&CheckInventory("PowerPossessionArtifact")==0&&CheckInventory("PowerTerminatorArtifact")==0
&&CheckInventory("OrangeFlag")==0&&CheckInventory("PurpleFlag")==0)
{
Thing_Damage2(ActivatorTID(), 256, "Suicide"); 
}
Delay(1);
restart;
}

if(CheckInventory("BlueFlag")==1){
startMorph();
Delay(1);
GiveInventory("BlueFlag",1);
completeMorph(i);
}
if(CheckInventory("RedFlag")==1){
startMorph();
Delay(1);
GiveInventory("RedFlag",1);
completeMorph(i);
}
if(CheckInventory("WhiteFlag")==1){
startMorph();
Delay(1);
GiveInventory("WhiteFlag",1);
completeMorph(i);
}
if(CheckInventory("PowerPossessionArtifact")==1){
startMorph();
Delay(1);
GiveInventory("PossessionStone",1);
completeMorph(i);
}
if(CheckInventory("PowerTerminatorArtifact")==1){
startMorph();
Delay(1);
//GiveInventory("PowerTerminatorArtifact",1);
completeMorph(i);
GiveInventory("Terminator",1);
}
if(CheckInventory("OrangeFlag")==1){
startMorph();
Delay(1);
GiveInventory("OrangeFlag",1);
completeMorph(i);
}
if(CheckInventory("PurpleFlag")==1){
startMorph();
Delay(1);
GiveInventory("PurpleFlag",1);
completeMorph(i);
}

Delay(1);
restart;
}

Script 501 RESPAWN
{
ACS_ExecuteAlways(500,0);
}


//Some Chill Penguin used for junk man
#define temporary_acs_tid 2000
int GuyAng;

script 159 (void)
{
	Thing_ChangeTID(0, temporary_acs_tid); // set the activator's tid to the temporary value
    SetActivatorToTarget(0); // set the player as the activator
	GuyAng = GetActorAngle(0);
	SetActorAngle (temporary_acs_tid, GuyAng);
    Thing_ChangeTID(temporary_acs_tid, 0); // change any temporary_acs_tid to 0 so that the tid is no longer in use
}

//Wall jump angling
int JumpAngByte;
int TotalAngles;

script 160 (void)
{
	SetActivatorToTarget(0);
	JumpAngByte = 0;
	TotalAngles = 0;
    if (CheckInventory("WallN") && !CheckInventory("WallS")) {
		JumpAngByte += 128;
		TotalAngles++;
	}
    if (/*CheckInventory("WallS") &&*/ !CheckInventory("WallN")) {
		JumpAngByte += 256;
		TotalAngles++;
	}
	if (CheckInventory("WallE") && !CheckInventory("WallW")) {
	    JumpAngByte += 64;
		TotalAngles++;
	}
	if (CheckInventory("WallW") && !CheckInventory("WallE")) {
	    JumpAngByte += 192;
		TotalAngles++;
	}
	if (/*CheckInventory("WallS") && */ !CheckInventory("WallN") && CheckInventory("WallE") && !CheckInventory("WallW")) { //Somewhere, a mathematician is crying.
	    JumpAngByte = 32;
		TotalAngles = 1;
	}
	if (TotalAngles>0) {
		JumpAngByte /= TotalAngles;
		if (CheckInventory("QuickBoomerangBoss")) {
			ThrustThing(((GetActorAngle(0) >> 8) + JumpAngByte),12,1);
		} else {
			ThrustThing(((GetActorAngle(0) >> 8) + JumpAngByte),10,1);
		}
	}
}

script 647 (int p) DISCONNECT
{
	GiveInventory("StopTrollingNoobDC",1);
/*	GiveInventory("StopTrollingNoob",1);
	GiveInventory("StopTrollingNoob2",1);*/
	GiveInventory("ClashFlagDC",1);
/*	GiveInventory("ClashFlag1",1);
	GiveInventory("ClashFlag2",1);
	GiveInventory("ClashFlag3",1);
	GiveInventory("ClashFlag4",1);*/
	//SetActorState(p+1200, "Death");
	Thing_Remove(p+1200);
	//thing_destroy(p+1200,0);
	//thing_damage(p+1200,100);
}

function int min (int a, int b)
{
	if (a < b)
		return a;

	return b;
}

// Player Modifier
//
script 648 (int jump)
{
	switch (jump) {
	//Enker absorb
	    case 12:
		  if (CheckInventory("EnkerAbsorbCount")) {
		  int armor = PlayerArmorPoints();
		  GiveInventory("MirrorCharge",max(CheckInventory("LastArmorCount")-Armor-3, 0));
		  TakeInventory("LastArmorCount",999);
		  GiveInventory("LastArmorCount",armor);
		  }
		  break;
	//Star gravity
	    case 11:
		  SetActorProperty(0, APROP_Gravity, min(GetActorProperty(0, APROP_Gravity),0.7));
		  break;
	//Cloud gravity
		case 10:
		  SetActorProperty(0, APROP_Gravity, min(GetActorProperty(0, APROP_Gravity),0.4));
		  break;
	//Doc Default
		case 9:
		  SetActorProperty(0,APROP_JumpZ,11.0);
		  SetActorProperty(0,APROP_SPEED,1.05);
		  //SetActorProperty(0,APROP_DamageFactor,1.0);
		  //TakeInventory("BasicArmor",999);
		  GiveInventory("NormalDocArmor",1);
		  TakeInventory("LightHealthBar",999);
		  TakeInventory("SturdyHealthBar",999);
		  TakeInventory("ToadHealthBar",999);
		  break;
	//Doc Copy
		case 8:
		  //ACS_ExecuteAlways(648,0,9);
		  //Jump Mode
		  if (CheckWeapon("MetalBladeWepC")||CheckWeapon("ShadowBladeWepC")||
		  CheckWeapon("RainFlushWepC")|| CheckWeapon("GyroAttackWepC")||
		  CheckWeapon("GravityHoldWepC")||CheckWeapon("ThunderBoltWepC")||
		  CheckWeapon("GravitySphereWepC")||CheckWeapon("StarCrashWepC")||
		  CheckWeapon("WildCoilWepC")||CheckWeapon("WindStormWepC")||
		  CheckWeapon("NoiseCrushWepC")) {
			SetActorProperty(0,APROP_JumpZ,13.0);
			SetActorProperty(0,APROP_SPEED,1.0);
			GiveInventory("NormalDocArmor",1);
			TakeInventory("LightHealthBar",999);
			TakeInventory("SturdyHealthBar",999);
			TakeInventory("ToadHealthBar",999);
		  //Speed Mode
		  } else if (CheckWeapon("AirShooterWepC")||CheckWeapon("NapalmBombWepC")||
		  CheckWeapon("ChargeKickWepC")||CheckWeapon("BlizzardAttackWepC")||
		  CheckWeapon("SilverTomahawkWepC")) {
			SetActorProperty(0,APROP_JumpZ,10.0);
			SetActorProperty(0,APROP_SPEED,1.1);
			GiveInventory("NormalDocArmor",1);
			TakeInventory("LightHealthBar",999);
			TakeInventory("SturdyHealthBar",999);
			TakeInventory("ToadHealthBar",999);
		  //Armor Mode
		  } else if (CheckWeapon("PowerStoneWepC")||CheckWeapon("LeafShieldWepC")||
		  CheckWeapon("HyperBombWepC")||CheckWeapon("YamatoSpearWepC")||
		  CheckWeapon("KnightCrushWepC")){
			//SetActorProperty(0,APROP_DamageFactor,0.8);
			GiveInventory("SturdyDocArmor",1);
			GiveInventory("SturdyHealthBar",1);
			TakeInventory("LightHealthBar",999);
			TakeInventory("ToadHealthBar",999);
			SetActorProperty(0,APROP_JumpZ,10.0);
			SetActorProperty(0,APROP_SPEED,1.0);
		  //Frail Mode
		  } else if (CheckWeapon("RollingCutterWepC")||CheckWeapon("SlashClawWepC")){
			//SetActorProperty(0,APROP_DamageFactor,1.2);
			//GiveInventory("LightDocArmor",1);
			TakeInventory("BasicArmor",999);
			GiveInventory("LightHealthBar",1);
			TakeInventory("SturdyHealthBar",999);
			TakeInventory("ToadHealthBar",999);
			SetActorProperty(0,APROP_JumpZ,12.0);
			SetActorProperty(0,APROP_SPEED,1.15);
		  //Frail Speed Mode
		  } else if (CheckWeapon("ThunderBeamWepC")||CheckWeapon("QuickBoomerangWepC")||
		  CheckWeapon("TopSpinWepC")||CheckWeapon("CentaurFlashWepC")||
		  CheckWeapon("SearchSnakeWepC")||CheckWeapon("CentaurArrowWepC")){
			//SetActorProperty(0,APROP_DamageFactor,1.2);
			//GiveInventory("LightDocArmor",1);
			TakeInventory("BasicArmor",999);
			GiveInventory("LightHealthBar",1);
			TakeInventory("SturdyHealthBar",999);
			TakeInventory("ToadHealthBar",999);
			SetActorProperty(0,APROP_JumpZ,10.0);
			SetActorProperty(0,APROP_SPEED,1.20);
		  //Slow Armor Mode
		  } else if (CheckWeapon("HardKnuckleWepC")||CheckWeapon("SuperArmWepC")||
		  CheckWeapon("JunkShieldWepC")){
			//SetActorProperty(0,APROP_DamageFactor,0.65);
			GiveInventory("ToadDocArmor",1);
			GiveInventory("ToadHealthBar",1);
			TakeInventory("LightHealthBar",999);
			TakeInventory("SturdyHealthBar",999);
			SetActorProperty(0,APROP_JumpZ,10.0);
			SetActorProperty(0,APROP_SPEED,0.9);
		  } else {
			if (!CheckActorProperty(0,APROP_SPEED,1.45)) {
				SetActorProperty(0,APROP_SPEED,1.05);
			}
		  	SetActorProperty(0,APROP_JumpZ,11.0);
			//SetActorProperty(0,APROP_DamageFactor,1.0);
			//TakeInventory("BasicArmor",999);
			GiveInventory("NormalDocArmor",1);
			TakeInventory("LightHealthBar",999);
			TakeInventory("SturdyHealthBar",999);
			TakeInventory("ToadHealthBar",999);
		  }
		  break;
	//Bomb priming
		case 7:
		  SetActorProperty(0,APROP_SPEED,0.5);
		  SetActorProperty(0,APROP_JumpZ,0.0);
		  break;
	//Bomb Normal
		case 6:
		  SetActorProperty(0,APROP_SPEED,1.0);
		  SetActorProperty(0,APROP_JumpZ,13.0);
		  break;
	//Disable jump and reduce speed for proto dash
		case 5:
		  SetActorProperty(0,APROP_SPEED,0.2);
		  SetActorProperty(0,APROP_JumpZ,0.0);
		  break;
	//Disable jump and reduce speed for dash
		case 4:
		  //SetActorProperty(0,APROP_SPEED,0.85);
		  SetActorProperty(0,APROP_JumpZ,0.0);
		  break;
	//Reenable jump and speed
	    case 3:
		  SetActorProperty(0,APROP_SPEED,1.0);
		  SetActorProperty(0,APROP_JumpZ,10.0);
		  break;
	//Restore Toad Jump
		case 2:
		  SetActorProperty(0,APROP_JumpZ,15.0);
		  break;
	//Disable Jump
		case 1:
		  SetActorProperty(0,APROP_JumpZ,0.0);
		  break;
	//Restore Normal jump
		case 0:
		  SetActorProperty(0,APROP_JumpZ,10.0);
		  break;
		default:
		  SetActorProperty(0,APROP_JumpZ,10.0);
		  break;
	}
}

//sqrt and distance functions from ZDoom wiki
function int sqrt(int number)
{
	if(number <= 3)
	{
		if(number > 0)
		{
			return 1;
		}
		return 0;
	}

	int oldAns = number >> 1,                     // initial guess
	    newAns = (oldAns + number / oldAns) >> 1; // first iteration

	// main iterative method
	while(newAns < oldAns)
	{
		oldAns = newAns;
		newAns = (oldAns + number / oldAns) >> 1;
	}

	return oldAns;
}

function int distance (int tid1, int tid2)
{
	int x, y, z, d;
	x = GetActorX(tid1) - GetActorX(tid2) >> 16; // Convert fixed point to integer
	y = GetActorY(tid1) - GetActorY(tid2) >> 16;
	z = GetActorZ(tid1) - GetActorZ(tid2) >> 16;
	d = sqrt( x*x + y*y + z*z );
	return d;
}

function int distanceVal (int tid1x, int tid1y, int tid1z, int tid2)
{
	int x, y, z, d;
	x = tid1x - GetActorX(tid2) >> 16; // Convert fixed point to integer
	y = tid1y - GetActorY(tid2) >> 16;
	z = tid1z - GetActorZ(tid2) >> 16;
	d = sqrt( x*x + y*y + z*z );
	return d;
}

function int distanceVal2 (int tid1x, int tid1y, int tid1z, int tid2x, int tid2y, int tid2z)
{
	int x, y, z, d;
	x = tid1x - tid2x >> 16; // Convert fixed point to integer
	y = tid1y - tid2y >> 16;
	z = tid1z - tid2z >> 16;
	d = sqrt( x*x + y*y + z*z );
	return d;
}


#DEFINE MAX_PLAYERS 31 //0-31

function bool differentTeams (int pusherTeam, int pushee)
{
	return (pusherTeam != GetPlayerInfo(pushee-1000, PLAYERINFO_TEAM));
}

// General push script
//
function bool push (int pusher, int pushee, int force, int range)
{
	bool pushvalid;
	
	int x = GetActorX(pusher);
	int y = GetActorY(pusher);
	int z = GetActorZ(pusher);
	int x2 = GetActorX(pushee);
	int y2 = GetActorY(pushee);
	int z2 = GetActorZ(pushee);
	
	pushvalid = (range == 0 || distanceVal2(x, y, z, x2, y2, z2) < range);
	if (pushvalid) {
		if (force!=0) {
			ThrustThing(VectorAngle(x2 - x, y2 - y) >> 8, force, 1, pushee);
		}
	}
	return pushvalid;
}

/*
function bool push2 (int pusher, int pushee, int force, int range)
{
	bool pushvalid;

	pushvalid = (distance(pusher, pushee) < range);
	if (pushvalid) {
		if (force!=0) {
				int angleMod = 0;
				if (force<0) {
					force *= -1;
					angleMod = 128;
				}
			ThrustThing(((GetActorAngle(pusher) >> 8) + angleMod), force, 1, pushee);
		}
	}
	return pushvalid;
}
*/

function bool push2Val (int x, int y, int z, int angle, int pushee, int force, int range)
{
	bool pushvalid;

	pushvalid = (range == 0 || distanceVal(x, y, z, pushee) < range);
	if (pushvalid) {
		if (force!=0) {
				int angleMod = 0;
				if (force<0) {
					force *= -1;
					angleMod = 128;
				}
			ThrustThing(((angle >> 8) + angleMod), force, 1, pushee);
		}
	}
	return pushvalid;
}


// Push Scripts
//
script 207 (int type, int pushee)
{
	//int pushee = ActivatorTID();
	//if(ClassifyActor(pushee) & ACTOR_PLAYER) {
	//int pushee = 999 + CheckInventory("PusheeID");
	pushee += 999;
	//print(i:pushee);
	switch (type) {
		case 1: //Knight Push
		  if (push(ActivatorTID(), pushee, 8, 0)) {
			if(!PlayerIsBot(pushee-1000)){
			GiveActorInventory(pushee,"TempPitProtect",1);
			}
		  }
		  break;
		case 0: //Magnet Push
		  int force = 30;
		  force += 2*CheckInventory("PullCharge");
		  if (push(ActivatorTID(), pushee, force, 0)) {
			if(!PlayerIsBot(pushee-1000)){
			GiveActorInventory(pushee,"TempPitProtect",1);
			}
		  }
		  break;
		default:
		  break;
	}
	//}
}

// Plant party healer
//
script 208 (void)
{
	int team = ACS_ExecuteWithResult(143, 0);
	if (team != TEAM_NONE) {
		int owner = ActivatorTID();
		int x = GetActorX(0);
		int y = GetActorY(0);
		int z = GetActorZ(0);
		for(int i=0; i<MAX_PLAYERS; i++) {
			if (owner != 1000 + i) {
				if (!differentTeams(team,1000+i)) {
					if(distanceVal(x,y,z, 1000+i) < 160) {
						GiveActorInventory(1000 + i, "TeamRegen", 1);
					}
				}
			}
		}
	}
}

// Dust puller
//
script 209 (void)
{
	int owner = ACS_ExecuteWithResult(147, 0);
	int team = ACS_ExecuteWithResult(143, 0);
	int x = GetActorX(0);
	int y = GetActorY(0);
	int z = GetActorZ(0);
	int angle = GetActorAngle(0);
	if (team == TEAM_NONE) {
		for(int i=0; i<MAX_PLAYERS; i++) {
			if (owner != 1000 + i) {
				if(push2Val(x,y,z,angle, 1000 +i, -4, 50)) {
//				GiveActorInventory(1000 + i, "PitProtection", 1);
				}
			}
		}	
	} else {
		for(int j=0; j<MAX_PLAYERS; j++) {
			if (owner != 1000 + j) {
				if (differentTeams(team,1000+i)) {
					if(push2Val(x,y,z,angle, 1000 +j, -4, 50)) {
//					GiveActorInventory(1000 + i, "PitProtection", 1);
					}
				}
			}
		}	
	}
}

script 148 (void)
{
//	for(int j=0; j<499; j++) {
		while(CheckInventory("Clip")>0) {
			for(int i=0; i<MAX_PLAYERS; i++) {
				if (distance(ActivatorTID(), 1100 + i) < 50) {
					GiveActorInventory(1000+i,"DustBits",1);
					SetActorState(0, "Vacuumed");
					terminate;
				}
			}
//			SetActorProperty(0, APROP_RenderStyle, STYLE_Translucent);
//			SetActorProperty(0, APROP_Alpha, 0.5);
			Delay(1);
		}
//	}
}

function void clearCloneSpawn (void)
{
	for(int i=0; i<MAX_PLAYERS; i++) {
		takeActorInventory(1000 + i, "CloneSpawning", 999);
	}
}

// Gemini Clones
//
// Spawner
script 149 (int j)
{
	if (j==2) {
		bool oneFound = false;
		bool twoMany = false;
		int cloner;
		for(int i=0; i<MAX_PLAYERS; i++) {
			if (CheckActorInventory(1000 + i, "CloneSpawning")>0) {
				if (!oneFound) {
					cloner = 1000 + i;
					oneFound = true;
				} else {
					twoMany = true;
					takeActorInventory(1000 + i, "CloneSpawning", 999);
					giveActorInventory(1000 + i, "CloneRareBug", 1);
				}
			}
		}
		if (twoMany) {
			takeActorInventory(cloner, "CloneSpawning", 999);
			giveActorInventory(cloner, "CloneRareBug", 1);
			//SetActorState(0, "Death");
			//thing_destroy(ActivatorTID(),0);
			//DamageThing(0);
			Thing_Remove(0);
			terminate;
		}
		if (oneFound) {
			Thing_ChangeTID(0, cloner + 200);
			//SpawnProjectile(activatorTID(), "GemCloneVisual", GetActorAngle(0), 0, 0, 0, cloner+300);
			giveActorInventory(cloner, "CloneSpawned", 1);
			takeActorInventory(cloner, "CloneSpawning", 999);
			terminate;
		}
		//SetActorState(0, "Death");
		//thing_destroy(ActivatorTID(),0);
		//DamageThing(0);
		Thing_Remove(0);
		terminate;
	}
	if (j==1) { //This doesn't make a loyal clone
//		SpawnProjectile(activatorTID(), "GemClone", GetActorAngle(0), 0, 0, 0, activatorTID()+200);
		Spawn("GemClone", GetActorX(activatorTID()), GetActorY(activatorTID()), GetActorZ(activatorTID()), activatorTID()+200, GetActorAngle(activatorTID()));
	}
	TakeInventory("cloneAngle",999);
	GiveInventory("cloneAngle",GetActorAngle(0) >> 8);
}

// Reposition sync
script 150 (void)
{
	if (checkInventory("CloneID")==0) {
		giveInventory("CloneID", (ACS_ExecuteWithResult(147, 0)-999));
	}
	int owner = (checkInventory("CloneID") + 999);
	int cloneHealth = GetActorProperty(0, APROP_HEALTH);
	takeActorInventory(owner, "CloneAmmo", 999);
	giveActorInventory(owner, "CloneAmmo", cloneHealth);
	takeActorInventory(owner, "CloneFiring", 999);
	giveActorInventory(owner, "CloneFiring", checkActorInventory(owner+200, "CloneFiring"));
	if (cloneHealth>0 && GetActorProperty(owner, APROP_HEALTH)>0 && checkActorInventory(owner, "cloneSpawned")>0) {
		if (checkActorInventory(owner, "cloneStationary")==0) {
			int cloneAngle = checkActorInventory(owner, "cloneAngle") << 8;
			//print(i:cloneAngle);
			int cloneDistanceInv = checkActorInventory(owner, "cloneDistance");
			int cloneDistanceX = 15.0;
			cloneDistanceX *= cloneDistanceInv;
			int cloneDistanceY = FixedMul(cloneDistanceX,sin(cloneAngle));
			cloneDistanceX = FixedMul(cloneDistanceX,cos(cloneAngle));
			if(!SetActorPosition(owner+200, GetActorX(owner)+cloneDistanceX, GetActorY(owner)+cloneDistanceY, GetActorZ(owner+200), 0)) {
				SetActorPosition(owner+200, GetActorX(owner)+cloneDistanceX, GetActorY(owner)+cloneDistanceY, GetActorZ(owner), 0);
			}
			if (cloneDistanceInv<=1) {
				SetActorState(owner+200, "SummonCooldown");
			}
		}
		SetActorAngle(0, GetActorAngle(owner+200));
		SetActorPosition(0, GetActorX(owner+200), GetActorY(owner+200), GetActorZ(owner+200), 0);
	} else {
		if (checkActorInventory(owner, "cloneBug")==0) {
			takeActorInventory(owner, "CloneAmmo", cloneHealth/2);
			takeActorInventory(owner, "cloneSpawned", 999);			
		}
		takeActorInventory(owner, "cloneBug", 999);
		SetActorState(0, "Death2");
		//thing_destroy(owner+200,0);
		Thing_Remove(owner+200);
		//SetActorState(owner+200, "Death");
	}
}

script 151 (void)
{
/*
int result = ACS_ExecuteWithResult(147, 0);
print(i:Result);

rint(s:"ACS activated");
int owner = ActivatorTID()-300;
if (cloneHealth>0 && GetActorProperty(owner, APROP_HEALTH)>0 && checkActorInventory(owner, "cloneSpawned")>0) {
} else {
SetActorState(0, "Death");
}
*/
}

function int max (int a, int b)
{
	if (a > b)
		return a;

	return b;
}

function int round(int fixedNumber)
{
	return (fixedNumber + 0.5) >> 16;
}

//Gravity Hold

#DEFINE GRAVITY_FACTOR 20
//#DEFINE FORCE_DIVIDER 1
#DEFINE FORCE_MULTIPLIER 6
#DEFINE SPRING_CUSHION 4 //+1
#DEFINE FALLING_TIME_START 0

script 206 (int gravitated)
{
gravitated += 999;
int gravity = GetActorProperty(gravitated,APROP_Gravity);
int downZ = GetActorVelZ(gravitated);
int gZ = GetActorZ(gravitated);
int gZ1 = gZ;
int fallingTime = FALLING_TIME_START;
int lastDownZ = downZ;

/*
if (gZ < 0) {
	ThrustThingZ(gravitated,0,1,0);
}
*/

while (gZ - GetActorFloorZ (gravitated) != 0.0 &&
!(lastdownZ <= 0.0 && downZ >= 0.0 && fallingTime>FALLING_TIME_START)) {
	
	giveActorInventory(gravitated,"LadderDisable",1);
	giveActorInventory(gravitated,"TeleDisable",1);
	giveActorInventory(gravitated,"FlightDisable",1);
	
	if (gravity == 0.25*GRAVITY_FACTOR || gravity == 0.25) {
		SetActorProperty(gravitated,APROP_Gravity,0.25*GRAVITY_FACTOR);
	} else {
		SetActorProperty(gravitated,APROP_Gravity,0.8*GRAVITY_FACTOR);
	}
	
	fallingTime++;
	
	Delay(1);
	
	gravity = GetActorProperty(gravitated,APROP_Gravity);
	lastDownZ = downZ;
	downZ = GetActorVelZ(gravitated);
	gZ = GetActorZ(gravitated);
	gZ1 = max(gZ, gZ1);
}

if (gravity == 0.25*GRAVITY_FACTOR || gravity == 0.25) {
	SetActorProperty(gravitated,APROP_Gravity,0.25);
} else {
	SetActorProperty(gravitated,APROP_Gravity,0.8);
}

giveActorInventory(gravitated,"LadderEnable",1);
giveActorInventory(gravitated,"TeleEnable",1);
giveActorInventory(gravitated,"FlightEnable",1);

Thing_Move(0,gravitated,1);
//SetActorPosition(0,GetActorX(gravitated),GetActorY(gravitated),gZ,0);

int springCheck = 1;
springCheck += SPRING_CUSHION*(downZ >= lastDownZ*-1 && fallingTime>FALLING_TIME_START);

/*
if (springCheck > 1) {
	printBold(s:"Spring detected");
}
*/

GiveInventory("CutterFlag",max(0,round((gZ1 - gZ)*FORCE_MULTIPLIER/max(1,fallingTime)))/springCheck);

//PrintBold(i:round((gZ1 - gZ)*FORCE_MULTIPLIER));
//PrintBold(i:fallingTime);
//PrintBold(i:CheckInventory("CutterFlag"));
//PrintBold(i:(CheckInventory("CutterFlag")/10)*3);

GiveInventory("CollideFlag",1);
}

script 211 (int burninated)
{
burninated += 999;

while (CheckActorInventory(burninated, "WilyBurnTimer")>0) {
	Thing_Move(0,burninated,1);
	TakeActorInventory(burninated, "WilyBurnTimer", 1);
	Delay(1);
}
	
GiveInventory("CollideFlag",1);
}

script 146 (void)
{
SetResultValue(round(fixedmul(GetActorProperty(0,APROP_JUMPZ),4.2)));
}

script 649 (int type)
{
SetActivatorToTarget(0);
switch (type) {
	//Ring Man
		case 1:
		  SetResultValue(CheckInventory("RingBoomerangBoss"));
		  break;
	//Crash Man
		case 0:
		  SetResultValue(CheckInventory("CrashBombBoss"));
		  break;
		default:
		  SetResultValue(CheckInventory("CrashBombBoss"));
		  break;
}
//SetResultValue(PlayerInGame(ACS_ExecuteWithResult(146,0)-1000));
}