/*
* author: Ebomb09
* description: Shows a kills feed, damage numbers, stats and achievments
* mapmodes: versus, custom
*/

static bool KILLFEED = true;			//Display Killfeed
static bool STATS = true;				//Save Stats + Achievements
static bool DAMAGE = true;				//Damage Numbers
static bool REMOVEOP = true; 			//Removes OP Weapons M60, Bazooka, Grenade Launcher
static bool SHORTENNAME = true; 		//Shorten Names in Killfeed
static bool KILLFEEDSIDE = true;		//Show Killfeed on side of screen
static bool SHOWWINNER = true;			//Show Winner

static IList<Player> user = new List<Player>();
static IList<string> killswitch = new List<string>();
static IList<int> killswitchtimer = new List<int>();
int GAMEOVER = 0;
string space = "                                                                                                    ";


public void OnStartup(){

for(var x = 0;x < Game.GetPlayers().Length;x ++){
	user.Add(new Player(Game.GetPlayers()[x]));
}

IObjectTimerTrigger timer = (IObjectTimerTrigger)Game.CreateObject("TimerTrigger");
timer.SetIntervalTime(0);
timer.SetRepeatCount(0);
timer.SetScriptMethod("tick");
timer.Trigger();

if (STATS){ Data_Check(); Data_Achieve(); }
}

public void tick(TriggerArgs args){
	foreach(Player player in user){
		player.Step();
	}
	foreach(IObjectText obj in Game.GetObjectsByName("Text")){
		int x;
		if (Int32.TryParse(obj.CustomID, out x)){
			int num = Int32.Parse(obj.CustomID);
			if (num > 0){
				obj.CustomID = (num - 1).ToString();	
				obj.SetWorldPosition(new Vector2(obj.GetWorldPosition().X, obj.GetWorldPosition().Y - 0.1f));
			}else{
				obj.Remove();
			}
		}
	}
	
	if(STATS){
		
		if (Game.IsGameOver){ GAMEOVER ++;}
	
			if (GAMEOVER == 60){
				PlayerTeam winners = new PlayerTeam();		
				int no_winners = 0;
				string id = "";
				
				foreach(Player target in user){
				int check = 0;
				
					if (target.Name != null){
						if (target.IsAlive == 1 && no_winners == 0){
							winners = target.team;
							no_winners = -1;
							check = 1;
							if (target.team == PlayerTeam.Independent){ id = target.ply.Name; }
						}
						if (target.IsAlive == 1 && (target.team != winners || target.team == PlayerTeam.Independent) && check == 0){
							no_winners = 1;
						}
					}
				}
				int check_win = 0;
				foreach(Player target in user){
					if (target.Name != null){
						Data_Add(target.Name_Data,1,target.TotalKills);
						Data_Add(target.Name_Data,4,target.ThrowKills);
						Data_Add(target.Name_Data,7,target.ItemKills);
						Data_Add(target.Name_Data,9,target.MeleeKills);

						if ((target.team == winners && no_winners == -1 && target.team != PlayerTeam.Independent) || (target.team == PlayerTeam.Independent && id == target.ply.Name && no_winners == -1)){
							Data_Add(target.Name_Data,13,1);
							if (check_win == 0 && SHOWWINNER){
							if (winners == PlayerTeam.Independent){ 
								Game.RunCommand("/msg [" + target.Name + " Won]");
								check_win = 1;
							}else if (winners == PlayerTeam.Team1){
								Game.RunCommand("/msg [Blue Team Won]");
								check_win = 1;
							}else if (winners == PlayerTeam.Team2){
								Game.RunCommand("/msg [Red Team Won]");
								check_win = 1;
							}else if (winners == PlayerTeam.Team3){
								Game.RunCommand("/msg [Green Team Won]");
								check_win = 1;
							}else if (winners == PlayerTeam.Team4){
								Game.RunCommand("/msg [Yellow Team Won]");
								check_win = 1;
							}
							}
							if (target.GunPickup == 0){ Data_Add(target.Name,11,target.GunPickup); }
						}else{
							Data_Add(target.Name_Data,13,0);
						}
					}
				}
			}			
	}

	if (REMOVEOP){
		foreach(IObject obj in Game.GetObjectsByName(new string[] {"WpnBazooka", "WpnGrenadeLauncher", "WpnM60"})){
			obj.Remove();
		}
	}

	if (KILLFEEDSIDE){
		string text = "";
		for(var x = 0;x != killswitch.Count;x ++){
			if (killswitch[x] != ""){
			string str = killswitch[x];
			int timer = killswitchtimer[x];

			text += space + str + "\n";

			if (timer > 0){
				timer --;
				killswitchtimer[x] = timer;
			}else{
				killswitch[x] = "";
				killswitchtimer[x] = 0;
			}
			}
		}
		Game.ShowPopupMessage(text);
	}

}

public class Player{
	Random rnd = new Random();
	
	//STORE PLAYER
	public IPlayer ply;
	public PlayerTeam team;
	public string Name;	
	public string Name_Data;	

	//CHECK STATUS OF PLAYER
	public int AirStatus; //0 = Stand //1 == Falling
	public int LastShot;
	public int LastHit;
	public int ShotMemory;
	public int HitMemory;
	public float FireStatus;
	public float ExplodeCheck;
	public int dir;
	public int Throwdir;
	public int LastThrow;
	public int LastThrowHit;
	public WeaponItem LastGun;
	public int IsAlive;
	public string GrabberName;
	public float SinceLastHealth;
	public float LastHealth;
	public int GAMEOVER;
	public int GrabberWait;
	public int DeathMessage;
	
	//STATS
	public int TotalKills;
	public int MeleeKills;
	public int ThrowKills;
	public int ItemKills; 
	public int GunPickup;
	public int Matches;

	int GrabType = -1;	

	public Player(IPlayer test){
		ply = test;
		team = ply.GetTeam();
		Name_Data = (ply.Name);
		if ((ply.Name).Length > 10 && SHORTENNAME){
			Name = (ply.Name).Substring(0,7) + "...";
		}else{
			Name = (ply.Name);
		}
	}

	public void Step(){
		if (KILLFEED){
			string Term = "";
			bool IsBurning = false;
			bool IsExploding = false;	


			if(!ply.IsRemoved){

				//MELEE KILLS
				if (ply.IsMeleeAttacking || ply.IsJumpAttacking || ply.IsJumpKicking || ply.IsKicking){
					if (rnd.Next(0,2) == 0){ Term = "Whacked"; }else{ Term = "Beaten"; }
					if (ply.CurrentMeleeWeapon.WeaponItem == WeaponItem.KATANA || ply.CurrentMeleeWeapon.WeaponItem == WeaponItem.MACHETE || ply.CurrentMeleeWeapon.WeaponItem == WeaponItem.KNIFE || ply.CurrentMeleeWeapon.WeaponItem == WeaponItem.AXE){ if (rnd.Next(0,2) == 0){ Term = "Sliced"; }else{ Term = "Stabbed"; } }
					if (ply.CurrentMeleeWeapon.WeaponItem == WeaponItem.CHAIN){ if (rnd.Next(0,2) == 0){ Term = "Whipped"; }else{ Term = "Lashed"; } }
					if (ply.IsJumpKicking || ply.IsKicking){ Term = "Kicked"; }
					if ((ply.IsMeleeAttacking || ply.IsJumpAttacking) && ply.CurrentMeleeWeapon.WeaponItem == WeaponItem.NONE && ply.CurrentMeleeMakeshiftWeapon.WeaponItem == WeaponItem.NONE ){ Term = "Punched"; }
					
					foreach(Player target in user){
						IPlayer trg = target.ply;
						if (!trg.IsRemoved && trg.IsDead && (trg.GetTeam() != ply.GetTeam() || ply.GetTeam() == PlayerTeam.Independent) && trg.IsInputEnabled && 25 >= Math.Abs(ply.GetWorldPosition().X - trg.GetWorldPosition().X) && 25 >= Math.Abs(ply.GetWorldPosition().Y - trg.GetWorldPosition().Y)){
							TotalKills ++;
							MeleeKills ++;					
							ShowMessage(target.Name + " Was " + Term + " By " + Name);
							target.DeathMessage = 1;
							target.IsAlive = -1;
							trg.SetInputEnabled(false);
						}
					}
				}
				//END OF MELEE

				//GUN KILLS
				if (HitMemory != ply.Statistics.TotalProjectilesHitBy){
					LastHit = 10;
				}
				HitMemory = ply.Statistics.TotalProjectilesHitBy;
				if (LastHit != 0){ LastHit --;}

				if (ShotMemory != ply.Statistics.TotalShotsFired){
					GunPickup = 1;
					LastShot = 30;
					if (ply.CurrentWeaponDrawn == WeaponItemType.Handgun){
						LastGun = ply.CurrentSecondaryWeapon.WeaponItem;
					}
					if (ply.CurrentWeaponDrawn == WeaponItemType.Rifle){
						LastGun = ply.CurrentPrimaryWeapon.WeaponItem;
					}
					dir = ply.FacingDirection;
				}

				ShotMemory = ply.Statistics.TotalShotsFired;
				if (LastShot != 0 && !ply.IsDead){ 
					LastShot --;

					foreach(Player target in user){
						IPlayer trg = target.ply;
						if (!trg.IsRemoved){
							float dist = ply.GetWorldPosition().X - trg.GetWorldPosition().X;
							if(trg.IsDead && (trg.GetTeam() != ply.GetTeam() || ply.GetTeam() == PlayerTeam.Independent) && target.LastHit != 0 && trg.IsInputEnabled && ((dir > 0 && dist < 0) || (dir < 0 && dist > 0))){
								TotalKills ++;
									Term = "Shot";
									if (LastGun == WeaponItem.SNIPER){
										Term = "Sniped";
									}
									if (LastGun == WeaponItem.SAWED_OFF || LastGun == WeaponItem.SHOTGUN){
										Term = "Shelled";
									}
									
								ShowMessage(target.Name + " Was " + Term +  " By " + Name);
								target.DeathMessage = 1;
								target.IsAlive = -1;
								trg.SetInputEnabled(false);	
							}
						}
					}
				}
				//END OF GUN
				
				//EXPLODE DAMAGE
				if (ply.Statistics.TotalExplosionDamageTaken != ExplodeCheck){
					IsExploding = true;
				}
				ExplodeCheck = ply.Statistics.TotalExplosionDamageTaken;
				if (ply.IsDead && IsExploding && ply.IsInputEnabled){			
					int RAND = rnd.Next(0,5);			
						if (RAND == 0){
							Term = " Was Blown Up";
						}
						if (RAND == 1){
							Term = " Was Obliterated";
						}
						if (RAND == 2){
							Term = " Was Annihilated";
						}
						if (RAND == 3){
							Term = " Was Wiped Out";
						}
						if (RAND == 4){
							Term = " Was Gibbed";
						}

					ShowMessage(Name + Term);
					DeathMessage = 1;
					IsAlive = -1;
					ply.SetInputEnabled(false);			
				}
				//END OF EXPLODE

				//FIRE DAMAGE
				if (ply.Statistics.TotalFireDamageTaken != FireStatus){
					IsBurning = true;
				}
				FireStatus = ply.Statistics.TotalFireDamageTaken;
				if (ply.IsDead && IsBurning && ply.IsInputEnabled){
					int RAND = rnd.Next(0,3);			
						if (RAND == 0){
							Term = " Was Burnt To A Crisp";
						}
						if (RAND == 1){
							Term = " Was Charred";
						}
						if (RAND == 2){
							Term = " Was Set Ablaze";
						}

					ShowMessage(Name + Term);
					DeathMessage = 1;
					IsAlive = -1;
					ply.SetInputEnabled(false);			
				}
				//END OF FIRE		
				
				//THROWABLE DAMAGE
				if (ply.IsStunned || ply.IsDeathKneeling || ply.IsStaggering){
					LastThrowHit = 10;
				}

				if (LastThrowHit != 0){ LastThrowHit --; }

				if (ply.IsThrowing){
					LastThrow = 60;
					Throwdir = ply.FacingDirection;
				}

				if (LastThrow != 0 && !ply.IsDead){ 
					LastThrow --;

					foreach(Player target in user){
						IPlayer trg = target.ply;
						
						float dist = ply.GetWorldPosition().X - trg.GetWorldPosition().X;
						if(!trg.IsRemoved && trg.IsDead && (trg.GetTeam() != ply.GetTeam() || ply.GetTeam() == PlayerTeam.Independent) && target.LastThrowHit != 0 && trg.IsInputEnabled && ((Throwdir > 0 && dist < 0) || (Throwdir < 0 && dist > 0))){
							TotalKills ++;
							ItemKills ++;
							ShowMessage(target.Name + " Was Hit By " + Name);
							target.DeathMessage = 1;
							target.IsAlive = -1;
							trg.SetInputEnabled(false);	
						}
					}
				}
				//END OF THROWABLE

				//FALL DAMAGE && ROCKETS && GRABS
				if (ply.IsFalling && AirStatus != 2 && !ply.IsDead){
					AirStatus = 1;	
				}
				if (ply.IsCaughtByPlayerInGrab || ply.IsCaughtByPlayerInDive){
					AirStatus = 2;
					
					foreach(Player target in user){
						IPlayer trg = target.ply;
						if ((trg.IsHoldingPlayerInGrab || trg.IsHoldingPlayerInDive) && (trg.GetTeam() != ply.GetTeam() || ply.GetTeam() == PlayerTeam.Independent) && 25 >= Math.Abs(ply.GetWorldPosition().X - trg.GetWorldPosition().X) && 25 >= Math.Abs(ply.GetWorldPosition().Y - trg.GetWorldPosition().Y)){
							GrabberName = target.Name;
							if(trg.IsHoldingPlayerInGrab){GrabType = 0;}
							if(trg.IsHoldingPlayerInDive){GrabType = 1;}
						}
					}
					
				}
				if (AirStatus != 0){
					IsAlive = -1;
				}
				if (ply.IsDead && (AirStatus == 1 || AirStatus == 0) && ply.IsOnGround && ply.IsInputEnabled && LastHit == 0 && !IsBurning && LastThrowHit == 0 && GrabType == -1){

						int RAND = rnd.Next(0,3);			
						if (RAND == 0){
							Term = " Missed The Landing";
						}
						if (RAND == 1){
							Term = " Broke Their Fall";
						}
						if (RAND == 2){
							Term = " Fell Flat";
						}

					ShowMessage(Name + Term);
					DeathMessage = 1;
					IsAlive = -1;
					ply.SetInputEnabled(false);			
				}
				if (ply.IsDead && (AirStatus == 2 || (GrabType != -1)) && ply.IsOnGround && ply.IsInputEnabled && LastHit == 0 && !IsBurning && LastThrowHit == 0){
					int RAND = rnd.Next(0,2);			
						
						if (GrabType == 0){
							if (RAND == 0){
								Term = " Was Thrown By ";
							}
							if (RAND == 1){
								Term = " Was Flung By ";
							}
						}
						if (GrabType == 1){
							if (RAND == 0){
								Term = " Was Dropped By ";
							}
							if (RAND == 1){
								Term = " Was Nosedived By ";
							}
						}

					foreach(Player target in user){
						if (target.Name == GrabberName){
							target.TotalKills ++;
							target.ThrowKills ++;
						}
					}

					ShowMessage(Name + Term + GrabberName);
					DeathMessage = 1;
					IsAlive = -1;
					ply.SetInputEnabled(false);			
				}
				if (ply.IsOnGround && !ply.IsDead){ AirStatus = 0; }
				if (ply.IsRocketRiding){
					AirStatus = 3;	
				}
				
				if (IsAlive != -1 || !ply.IsDead){ IsAlive = 2; }
			}else if (DeathMessage == 0 && IsAlive == -1){
				ShowMessage(Name + " Was Killed");
				DeathMessage = 1;
			}

				if (IsAlive == 1 && Name != null){
					IsAlive = -1;
					if (AirStatus == 3){
					if (rnd.Next(0,20) == 0){ ShowMessage(Name + " Was Rocket Riding");DeathMessage = 1; }else{ ShowMessage(Name + " Was Bazooka Riding");DeathMessage = 1; }
					}else if (AirStatus == 2 || (GrabType != -1)) {

					int RAND = rnd.Next(0,2);
						if (GrabType == 0){
							if (RAND == 0){
								Term = " Was Thrown By ";
							}
							if (RAND == 1){
								Term = " Was Flung By ";
							}
						}
						if (GrabType == 1){
							if (RAND == 0){
								Term = " Was Dropped By ";
							}
							if (RAND == 1){
								Term = " Was Nosedived By ";
							}
						}

					foreach(Player target in user){
						
						if (target.Name == GrabberName){
							target.TotalKills ++;
							target.ThrowKills ++;
						}
					}

					ShowMessage(Name + Term + GrabberName);
					DeathMessage = 1;
					IsAlive = -1;	
					ply.SetInputEnabled(false);

					}
							
				//END OF FALL

		}
		if (AirStatus == 0 && GrabberWait == 1){ GrabberWait = 0;GrabberName = ""; GrabType = -1;}
		if (AirStatus == 0 && GrabberName != ""){ GrabberWait = 1;}
		
		//CHECK ALIVE
		if(IsAlive == 2){ IsAlive = 1; } 
		}

		if (DAMAGE && !ply.IsRemoved && !ply.IsDead){
			if (SinceLastHealth > 0){
				SinceLastHealth --;
			}
			if (SinceLastHealth == 0 && LastHealth != ply.Statistics.TotalDamageTaken && Math.Round(ply.Statistics.TotalDamageTaken - LastHealth) != 0){
				IObjectText text = (IObjectText)Game.CreateObject("Text",new Vector2(ply.GetWorldPosition().X - 1.5f, ply.GetWorldPosition().Y + 17.5f));
				text.SetTextColor(new Color(81, 18, 13));
				text.SetTextScale(0.75f);
				text.SetText("" + (Math.Round(ply.Statistics.TotalDamageTaken - LastHealth)) );
				text.CustomID = "120";

				IObjectText text2 = (IObjectText)Game.CreateObject("Text",new Vector2(ply.GetWorldPosition().X - 2, ply.GetWorldPosition().Y + 18));
				text2.SetTextColor(new Color(163, 36, 26));
				text2.SetTextScale(0.75f);
				text2.SetText("" + (Math.Round(ply.Statistics.TotalDamageTaken - LastHealth)) );
				text2.CustomID = "120";

				IObjectText text3 = (IObjectText)Game.CreateObject("Text",new Vector2(ply.GetWorldPosition().X - 2.5f, ply.GetWorldPosition().Y + 18.5f));
				text3.SetTextColor(new Color(255, 56, 40));
				text3.SetTextScale(0.75f);
				text3.SetText("" + (Math.Round(ply.Statistics.TotalDamageTaken - LastHealth)) );
				text3.CustomID = "120";

				LastHealth = ply.Statistics.TotalDamageTaken;
			}
			if (LastHealth == ply.Statistics.TotalDamageTaken){
				SinceLastHealth = 60;
			}

		}

	}
	
	public void ShowMessage(string text){
		if (!KILLFEEDSIDE){ 
			Game.RunCommand("/msg " + text);
		}else{
			killswitch.Add(text);
			killswitchtimer.Add(300);
		}
	}
}

static public void Data_Check(){
string[] data;

  data = (Game.Data).Split(',');

	foreach(IPlayer ply in Game.GetPlayers()){
		var check = 0;
		for(var sum = 0;sum != data.Length;sum ++){
			if (data[sum] == ply.Name){
				check = 1;
			}
		}
		if (check == 0){
			Game.Data += ply.Name + ",0,o,o,0,o,o,0,o,0,o,1,o,0,o,o,";
		}
	}

	//Game.RunCommand("/msg " + Game.Data);
}

static public void Data_Add(string NAME,int INDEX,int AMOUNT){
string[] data;

  data = (Game.Data).Split(',');

		for(var sum = 0;sum != data.Length;sum ++){
			if (data[sum] == NAME && INDEX != 11 && !(INDEX == 13 && AMOUNT == 0)){
				int Add = int.Parse(data[sum + INDEX]);
				Add += AMOUNT;
				data[sum + INDEX] = Add.ToString();
			}else if (data[sum] == NAME){
					data[sum + INDEX] = "0";
			}
		}

		Game.Data = string.Join(",",data);
}

static public void Data_Achieve(){
string[] data;
	
  data = (Game.Data).Split(',');

	foreach(IUser usr in Game.GetActiveUsers()){
		int check = 0;
		for(var sum = 0;sum != data.Length;sum ++){
			if (data[sum] == usr.Name){
				check = sum;
			}
		}
		if (int.Parse(data[check + 1]) >= 5 && data[check + 2] == "o"){
			data[check + 2] = "x";
			Game.RunCommand("/msg [" + usr.Name + " Has Achieved 5 Kills]");
		}
		if (int.Parse(data[check + 1]) >= 20 && data[check + 3] == "o"){
			data[check + 3] = "x";
			Game.RunCommand("/msg [" + usr.Name + " Has Achieved 20 Kills]");
		}
		if (int.Parse(data[check + 4]) >= 2 && data[check + 5] == "o"){
			data[check + 5] = "x";
			Game.RunCommand("/msg [" + usr.Name + " Has Achieved Throw 2 Players Off Buildings]");
		}
		if (int.Parse(data[check + 4]) >= 5 && data[check + 6] == "o"){
			data[check + 6] = "x";
			Game.RunCommand("/msg [" + usr.Name + " Has Achieved Throw 5 Players Off Buildings]");
		}
		if (int.Parse(data[check + 7]) >= 5 && data[check + 8] == "o"){
			data[check + 8] = "x";
			Game.RunCommand("/msg [" + usr.Name + " Has Achieved Kill 5 Players By Throwing Items]");
		}
		if (int.Parse(data[check + 9]) >= 10 && data[check + 10] == "o"){
			data[check + 10] = "x";
			Game.RunCommand("/msg [" + usr.Name + " Has Achieved 10 Melee Kills]");
		}
		if (data[check + 11] == "0" && data[check + 12] == "o"){
			data[check + 12] = "x";
			Game.RunCommand("/msg [" + usr.Name + " Has Achieved Win A Game Without Firing A Gun]");
		}
		if (int.Parse(data[check + 13]) >= 2 && data[check + 14] == "o"){
			data[check + 14] = "x";
			Game.RunCommand("/msg [" + usr.Name + " Has Achieved Win 2 Matches In A Row]");
		}
		if (int.Parse(data[check + 13]) >= 5 && data[check + 15] == "o"){
			data[check + 15] = "x";
			Game.RunCommand("/msg [" + usr.Name + " Has Achieved Win 5 Matches In A Row]");
		}
	}
	Game.Data = string.Join(",",data);	
}