//PLAYER LIVES 1 == NO RESPAWN 
//														DEFAULT:1
const int D_LIVES 								= 1;

//DAMAGE MULTIPLIER
//														DEFAULT:1
const int D_MULTIPLIER 						= 1;

//TIME BEFORE RESPAWN
//														DEFAULT:300
const int D_RESPAWN_FRAMES 					= 300;

//TIME BEFORE PLAYERS CAN BE DAMAGED
//														DEFAULT:60
const int D_INVINCIBLE_FRAMES 				= 60;


static float Top = 0;
static Random rnd = new Random();
IList<Fighter> Fighters = new List<Fighter>();

public class Fighter{
	IPlayer Player;
	IUser User;	
	double Damage = 0;
	IObjectText Hud;
	bool IsHit = false;
	bool WasRocketRiding = false;
	int ResFrames = D_RESPAWN_FRAMES;
	int InvFrames = D_INVINCIBLE_FRAMES;
	int Lives = D_LIVES;
	
	public Fighter(IPlayer input_player){
		Player = input_player;	
		User = input_player.GetUser();	

		Player.SetStatusBarsVisible(false);

		PlayerModifiers stats = Player.GetModifiers();
		stats.MaxHealth = 9999;
		stats.CurrentHealth = stats.MaxHealth;
		Player.SetModifiers(stats);

		Hud = (IObjectText)Game.CreateObject("Text");
		Hud.SetTextAlignment(TextAlignment.Middle);
		Hud.SetTextScale(0.5f);
	}
	public void Step(){
		if(User != null){
			chkNULL();
		}
		if(Player != null && !Player.IsDead && !Player.IsRemoved){
			PlayerModifiers stats = Player.GetModifiers();
			if(stats.CurrentHealth != stats.MaxHealth && InvFrames <= 0){
				Damage += (stats.MaxHealth - stats.CurrentHealth) * D_MULTIPLIER;
			}else{
				InvFrames --;
			}
			stats.CurrentHealth = stats.MaxHealth;
			Player.SetModifiers(stats);

			if(Player.IsDisabled && Player.IsFalling && !IsHit){
				IsHit = true;
				Vector2 v = Player.GetLinearVelocity();
				v *= 1 + (float)(Damage/100);
				Player.SetLinearVelocity(v);
			}else if(!Player.IsDisabled && !Player.IsFalling && Player.IsOnGround && IsHit){
				IsHit = false;
			}

			int alt_col = (int)Math.Round(Damage);
			if(Damage > 255){
				alt_col = 255;
			}
			Hud.SetTextColor(new Color(255,(byte)(255 - alt_col),(byte)(255 - alt_col)));
			Hud.SetText(Math.Round(Damage) + "%");
			Hud.SetWorldPosition(Player.GetWorldPosition() + new Vector2(0,24));
	
			if(Player.GetWorldPosition().Y > Top + 48){
				Player.Remove();
			}
			if(Player.IsRocketRiding){
				WasRocketRiding = true;
			}else if(WasRocketRiding){
				ResetPlayer();
			}
		}else{
			Hud.SetText("");
		}
		if(Player != null && User != null && !Player.IsRemoved && Player.IsDead){
			ResetPlayer();
		}
		if(User != null && Player.IsRemoved && Lives > 0){
			if(Lives > 1){
				if(ResFrames <= 0){
					SpawnPlayer();
				}else{
					ResFrames --;
				}
			}else{
				Lives = 0;
			}	
		}
		if(User == null){
			Lives = 0;	
			Player.Remove();
		}
	}
	public void chkNULL(){
		bool success = false;
		foreach(IUser usr in Game.GetActiveUsers()){
			if(User == usr){
				success = true;
			}
		}
		if(!success){
			User = null;
		}
	}
	public void ResetPlayer(){
		Game.WriteToConsole("Reset " + User.Name);
		IPlayer temp = Game.CreatePlayer(Player.GetWorldPosition());
		temp.SetAngularVelocity(Player.GetAngularVelocity());
		temp.SetLinearVelocity(Player.GetLinearVelocity());
		temp.SetProfile(Player.GetProfile());
		temp.SetModifiers(Player.GetModifiers());
		temp.SetTeam(Player.GetTeam());
		Player.Remove();
		User.SetPlayer(temp);
		Player = temp;
		WasRocketRiding = false;
	}
	public void SpawnPlayer(){
		Game.WriteToConsole("Respawned " + User.Name);
		IObject[] Spawns = Game.GetObjectsByName("SpawnPlayer");
		int index = rnd.Next(0,Spawns.Length);
		IPlayer temp = Game.CreatePlayer(Spawns[index].GetWorldPosition());
		temp.SetFaceDirection(Spawns[index].GetFaceDirection());
		temp.SetProfile(User.GetProfile());
		temp.SetTeam(User.GetTeam());
		User.SetPlayer(temp);
		Player = temp;
		Damage = 0;
		IsHit = false;
		Lives --;
		ResFrames = D_RESPAWN_FRAMES;
		InvFrames = D_INVINCIBLE_FRAMES;
	}
	public int GetLives(){
		return Lives;
	}
	public IPlayer GetPlayer(){
		return Player;
	}
	public IUser GetUser(){
		return User;
	}
}

public void OnStartup(){
	Game.RunCommand("/msg Super Fighter Bros.");
	Game.RunCommand("/msg Game Options:");
	Game.RunCommand("/msg Lives:" + D_LIVES);
	if (D_MULTIPLIER != 1){ Game.RunCommand("/msg Multiplier: " + D_MULTIPLIER); }
	if (D_RESPAWN_FRAMES != 300){ Game.RunCommand("/msg Respawn Time: " + D_RESPAWN_FRAMES); }
	if (D_INVINCIBLE_FRAMES != 60){ Game.RunCommand("/msg Invincible Time: " + D_INVINCIBLE_FRAMES); }

	Top = Game.GetCameraArea().Top;
	if(Game.GetObjectsByName("CameraAreaTrigger").Length > 0){
		Top = Game.GetObjectsByName("CameraAreaTrigger")[0].GetAABB().Top;
	}
	
	Game.SetAllowedCameraModes(CameraMode.Static);
	Game.AutoVictoryConditionEnabled = false;
	foreach(IPlayer ply in Game.GetPlayers()){
		Fighters.Add(new Fighter(ply));
	}

	Game.RunCommand("/msg " + Top);
	//IDLE Blocks
	Game.CreateObject("Concrete00A",new Vector2(0,2000));
	IObject block = Game.CreateObject("Concrete00A",new Vector2(-8,Top + 64));
	block.SetSizeFactor(new Point(3,0));
	IObject block2 = Game.CreateObject("Concrete00A",new Vector2(-8,Top + 96));
	block2.SetSizeFactor(new Point(3,0));
	Game.CreateObject("Concrete00A",new Vector2(0,2000));
	IObject block3 = Game.CreateObject("Concrete00A",new Vector2(-16,Top + 96));
	block3.SetSizeFactor(new Point(1,5));
	IObject block4 = Game.CreateObject("Concrete00A",new Vector2(16,Top + 96));
	block4.SetSizeFactor(new Point(1,5));
	IPlayer temp = Game.CreatePlayer(new Vector2(0,Top + 80));
	temp.SetStatusBarsVisible(false);
	temp.SetNametagVisible(false);

	IObjectTimerTrigger stepper = (IObjectTimerTrigger)Game.CreateObject("TimerTrigger");
	stepper.SetScriptMethod("GameStep");
	stepper.SetIntervalTime(0);
	stepper.SetRepeatCount(0);
	stepper.Trigger();
}

public void GameStep(TriggerArgs args){
	int[] teams = new int[5];

	foreach(Fighter o in Fighters){
		o.Step();
		if(o.GetLives() > 0){
			teams[(int)o.GetUser().GetTeam()] ++;
		}	
	}
	if(teams[0] == 1 && teams[1] + teams[2] + teams[3] + teams[4] == 0){
		foreach(Fighter o in Fighters){
			if(o.GetLives() > 0 && !o.GetPlayer().IsDead){
				Game.SetGameOver(o.GetUser().Name + "\nWins!");
			}
		}
	}
	if(teams[1] >= 1 && teams[0] + teams[2] + teams[3] + teams[4] == 0){
		string Names = "";
		foreach(Fighter o in Fighters){
			if((int)o.GetUser().GetTeam() == 1){
				Names += o.GetUser().Name + "\n";
			}
		}
		Game.SetGameOver(Names + "Wins!");
	}
	if(teams[2] >= 1 && teams[0] + teams[1] + teams[3] + teams[4] == 0){
		string Names = "";
		foreach(Fighter o in Fighters){
			if((int)o.GetUser().GetTeam() == 2){
				Names += o.GetUser().Name + "\n";
			}
		}
		Game.SetGameOver(Names + "Wins!");
	}
	if(teams[3] >= 1 && teams[0] + teams[2] + teams[1] + teams[4] == 0){
		string Names = "";
		foreach(Fighter o in Fighters){
			if((int)o.GetUser().GetTeam() == 3){
				Names += o.GetUser().Name + "\n";
			}
		}
		Game.SetGameOver(Names + "Wins!");
	}
	if(teams[4] >= 1 && teams[0] + teams[2] + teams[3] + teams[1] == 0){
		string Names = "";
		foreach(Fighter o in Fighters){
			if((int)o.GetUser().GetTeam() == 4){
				Names += o.GetUser().Name + "\n";
			}
		}
		Game.SetGameOver(Names + "Wins!");
	}
}