// --------------------------------------------------------------------------------------
// MADHUD v1.0 - By Prodigy  - April 5,1999
// --------------------------------------------------------------------------------------
//	Welcome to the world of MADHUD.
//
//	This script is a great HUD package.  MADHUD is a combination of
//	Dyn_HUD by KillerBunny and Presto's PrestoPak.  We've added a 
//	few tweaks and fixes in as well.
//
//      Check out These Features:
//		
//	Displays Kills and Deaths including Killer, Victim, and Death weapon.
//	Displays all Flag events with Flag Icons
//	Displays Flag Carriers name
//	Functions correctly with 2 name characters. (Dyn-Hud is confused by people with a space in their name
//	Announces Repair Functions
//	Keeps track of inventory Items:
//		Grenades
//		Mines
//		Beacons
//		Repair Kit
//
//	Includes play timer.
//	NEW!!!  Kill per minute ratio!
//	
//	This code is based on the work of many other people including:
//	KillerBunny and his classic Dyn-HUD - It was he who gaves us sight!!!
//
//	Presto for his PrestoPak - AMAZING amount of thought in the prestopak.
//	If you are a programmer, check his pak out.  It is a textbooks worth of
//	scripts for you to play with
//
//	The sweet killtraking is based on the JHUD code by Josh.
//	
//	As I said if it were not for those before me, I would not be before you.
//
//	
//	Anyway to make this work, make sure this file is in your
//	c:\dynamix\tribes\config directory and simply add the line:
//
//	  exec("madhud"); 	
//
//	into your autoexec.cs file.
//
//
//	Updates will be posted regularly and Ideas are appreciated at:
//	
//	MADHUD info  matt1001@earthlink.com
//
//



// --------------------------------------------------------------------------------------
//Toggles the HUD on and off.................
// --------------------------------------------------------------------------------------

editActionMap("playMap.sae");
bindCommand(keyboard0, make, control, "h", TO, "madhud::Toggle();");
bindCommand(keyboard0, break, control, "h", TO, "");
bindCommand(keyboard0, make, control, "r", TO, "madhud::Reset();");
bindCommand(keyboard0, break, control, "r", TO, "");
$madhud::StartConnectTime = timestamp();

// --------------------------------------------------------------------------------------
//MADHUD Load
// --------------------------------------------------------------------------------------

function madhud::Create()
{
	if($madhud::Loaded == 1)
		return;

	$madhud::Loaded = 1;

	$madhud[0] = newObject("madhud_Frame", FearGui::FearGuiMenu, 0, 65, 64, 225);
	$madhud[1] = newObject("madhud_FFlag", FearGui::FearGuiMenu, 2, 67, 60, 50);
	$madhud[2] = newObject("madhud_EFlag", FearGui::FearGuiMenu, 2, 118, 60, 50);
	$madhud[3] = newObject("madhud_StatsFrame", FearGui::FearGuiMenu, 2, 169, 60, 50);
	$madhud[4] = newObject("madhud_InvFrame", FearGui::FearGuiMenu, 2, 220, 60, 68);
	$madhud[5] = newObject("madhud_FFlagText", FearGuiFormattedText, 8, 72, 107, 50);
	$madhud[6] = newObject("madhud_EFlagText", FearGuiFormattedText, 8, 125, 107, 50);
	$madhud[7] = newObject("madhud_Stats", FearGuiFormattedText, 6,174, 10, 20);
	$madhud[8] = newObject("madhud_Inv", FearGuiFormattedText, 6, 229, 10, 182);
	$madhud[9] = newObject("madhud_LblHome", FearGuiFormattedText, 15, 61, 20, 10);
	$madhud[10] = newObject("madhud_LblHScore", FearGuiFormattedText, 23,99, 20, 10);
	$madhud[11] = newObject("madhud_LblAway", FearGuiFormattedText, 15,111, 20, 10);
	$madhud[12] = newObject("madhud_LblAScore", FearGuiFormattedText, 23,152, 20, 4);
	$madhud[13] = newObject("madhud_LblStats", FearGuiFormattedText, 17,162, 20, 10);
	$madhud[14] = newObject("madhud_LblInv", FearGuiFormattedText, 17,214, 20, 10);
	$madhud[15] = newObject("madhud_InfoString", FearGuiFormattedText, 65, 174, 25, 50);
	$madhud[16] = newObject("madhud_FFlagInfoString", FearGuiFormattedText, 65, 68, 25, 50);
	$madhud[17] = newObject("madhud_EFlagInfoString", FearGuiFormattedText, 65, 121, 25, 50);

//	%PlayerID = getclientbyname($pcfg::Name);
//	%PlayerTeamNo =client::getteam(%PlayerID);
//	echo(%playerid,%playerteamno);


	for(%i = 0; $madhud[%i] != ""; %i++)
		addToSet(PlayGui, $madhud[%i]); 

	Control::setValue("madhud_LblHome", "Home");
	Control::setValue("madhud_LblAway", "Away");
	Control::setValue("madhud_LblStats", "Stats");
	Control::setValue("madhud_LblInv", "Equip");

	Control::setVisible("madhud_InfoString",0);
	Control::setVisible("madhud_HFlagInfoString",0);
	Control::setVisible("madhud_EFlagInfoString",0);
	
	madhud::Heartbeat();
}

// --------------------------------------------------------------------------------------
//MADHUD - HUD EVENTS
// --------------------------------------------------------------------------------------
//=======================================================================================
function madhud::Heartbeat()
{
	if($madhud::Loaded == 0)
		return;

	$madhud::MineCount = getItemCount("Mine");
	$madhud::GrenadeCount = getItemCount("Grenade");
	$madhud::BeaconCount = getItemCount("Beacon");	
	$madhud::ConnectTime = String::getSubStr((getsimtime() / 60),0,4);
	$madhud::KPMRatio = $madhud::KillCount / ($madhud::ConnectTime);

	$madhud::KPMDisplay = String::getSubStr($madhud::KPMRatio,0,4); 
	


	schedule("madhud::Heartbeat();", 2);
	madhud::UpdateHUD();
}
//=======================================================================================
function madhud::Remove()
{
	if($madhud::Loaded == 0)
		return;

	$madhud::Loaded = 0;
	for(%i = 0; $madhud[%i] != ""; %i++)
		deleteObject($madhud[%i]);
}
//=======================================================================================
function madhud::Toggle()
{
	if($madhud::Loaded == 1)
		madhud::Remove();
	else
		madhud::Create();
}
//=======================================================================================
function madhud::Reset()
{
	$madhud::KillCount = 0;
	$madhud::DeathCount = 0;
	$madhud::FriendlyCarrier = "";
	$madhud::EnemyCarrier = "";
	$madhud::FlagSafe = 1;
	$madhud::EnemyFlagSafe = 1;
	$madhud::StatusString = "";
	$madhud::FFlagInfoString = "";
	$madhud::EFlagInfoString = "";
	$madhud::GrenadeCount = 0;
	$madhud::MineCount = 0;
	$madhud::PackType = "";
	ResetSimTime();
}
//=======================================================================================
function madhud::PopUp(%objectname, %hold)
{
	$madhud::CurrentObject = %objectname;
	Control::setVisible(%objectname, 1);
	
	if(%hold==0)
		schedule("madhud::PopDown($madhud::CurrentObject);", 4);
	}

//=======================================================================================
function madhud::PopDown(%objectname)
	{
	Control::setVisible(%objectname, 0);
	}


// --------------------------------------------------------------------------------------
//MADHUD - Frag Events
// --------------------------------------------------------------------------------------
//=======================================================================================
function madhud::FragEvents(%client, %msg)
{	
//echo("FRAG START");
	if (Match::String(%msg,"*" @ $PCFG::Name @ "*"))
	{
		KillTrak::OnClientMessage(%client, %msg);
		%v = $killtrak::killer;
		%x = $killtrak::victim;
		%w = $killtrak::weapon;
		
		if(client::getname(%v) == $PCFG::Name)
		{	
			if (client::getname(%x) != $PCFG::Name)
			{	$madhud::Fragstring = "<f0>Kill Added: <f2>" @ client::getname(%X) @"\n<f0>Weapon: <f2>" @ %w; 
	
				echo($PCFG::Name @ " KILL ADDED");
				$madhud::KillCount++;
		
				Control::setValue("madhud_InfoString", $madhud::Fragstring);
				madhud::PopUp(madhud_InfoString, 0);
			}
		}

		if(client::getname(%x) == $PCFG::Name)
		{
			$madhud::Fragstring = "<f0>Death Added: <f2>" @ client::getname(%v) @ "\n<f0>Weapon: <f2>" @ %w; 
//		    	schedule("Client::centerPrint(\"\", 1);", 4);

			echo($PCFG::Name @ " DEATH ADDED");
			$madhud::DeathCount++;

			Control::setValue("madhud_InfoString", $madhud::Fragstring);
			madhud::PopUp(madhud_InfoString, 0);
			
			
		}

	}
}
// --------------------------------------------------------------------------------------
//MADHUD - MAIN LINE 
// --------------------------------------------------------------------------------------
function madhud::UpdateHUD()
{
	if($madhud::Loaded != 1)
		return;
 
	if($madhud::EnemyCarrier != "")
		$madhud::EnemyCarrierStatus = "\n<f2>" @ $madhud::EnemyCarrier;

	if($madhud::FriendlyCarrier != "")
		$madhud::FriendlyCarrierStatus = "\n<f2>" @ $madhud::FriendlyCarrier;

	if($madhud::FlagSafe == 1)
		{
		$madhud::FlagStatus = "<Bflag_atbase.bmp>";
		}
	else
		{
		$madhud::FlagStatus = "";
		$madhud::FFlagInfoString = "<f1>Kill:<f2>" @ $madhud::EnemyCarrierStatus;
		}
        
	if($madhud::EnemyFlagSafe == 1)
		{
		$madhud::EnemyFlagStatus = "<Bflag_enemycaptured.bmp>";
		}
	else
		{
		$madhud::EnemyFlagStatus = "";
		$madhud::EFlagInfoString = "<f1>Help:<f2>" @ $madhud::FriendlyCarrierStatus;
		}
		
	if($madhud::KillCount == "")
		$madhud::KillCount = 0;

	if($madhud::DeathCount == "")
		$madhud::DeathCount = 0;

	$madhud::KillStatus =  "<f1>k/d: <f2>" @ $madhud::KillCount @ "<f1>/<f2>" @ $madhud::DeathCount;

	if($madhud::MineCount == "")
		$madhud::MineCount = 0;

	if($madhud::GrenadeCount == "")
		$madhud::GrenadeCount = 0;

	if($madhud::BeaconCount == "")
		$madhud::BeaconCount = 0;

	if (getItemCount("Repair Kit") > 0)
		$madhud::RepairKitStatus = "Y";
	else $madhud::RepairKitStatus = "N";

	$madhud::StatsString = $madhud::KillStatus @ "\n<f1>Ti:<f2> " @ $madhud::ConnectTime @ "\n<f1>kpm:<f2>" @ $madhud::KPMDisplay;


	$madhud::InvString = "<f1>M:<f2> " @ $madhud::MineCount @ "\n<f1>G: <f2>" @ $madhud::GrenadeCount @ "\n<f1>B: <f2>" @ $madhud::BeaconCount @ "\n<f1>Kit: <f2>" @ $madhud::RepairKitStatus;

	$madhud::FFlagStatusString = $madhud::FlagStatus;
	$madhud::EFlagStatusString = $madhud::EnemyFlagStatus;
	$madhud::FTeamScore = "<f2>";
	$madhud::ETeamScore = "<f2>";


	Control::setValue("madhud_FFlagText", $madhud::FFLagStatusString);
	Control::setValue("madhud_LblHScore", $madhud::FTeamScore);
	Control::setValue("madhud_EFlagText", $madhud::EFlagStatusString);
	Control::setValue("madhud_LblAScore", $madhud::ETeamScore);
	Control::setValue("madhud_Stats", $madhud::StatsString);
	Control::setValue("madhud_Inv", $madhud::InvString);
	Control::setValue("madhud_FFlagInfoString", $madhud::FFlagInfoString);
	Control::setValue("madhud_EFlagInfoString", $madhud::EFlagInfoString);
}


// --------------------------------------------------------------------------------------
//MADHUD - FLAGEVENTS 
// --------------------------------------------------------------------------------------

function madhud::flagEvents(%client, %msg)
{
//echo("FLAG START");

//TAKEN
	%posit = String::findSubStr(%msg, "took the") - 1;

	if(%posit > 0)
		$taker = String::getSubStr(%msg, 0, %posit);


	if(String::findSubStr(%msg, "Your team has the") != -1)
	{
		$madhud::FriendlyCarrier = $taker;
		$madhud::EnemyFlagSafe = 0;
		madhud::PopUp(madhud_EFlagInfoString, 1);
					
	}
	else if(String::findSubStr(%msg, "Your team's flag has been taken.") != -1)	
	{

		$madhud::FlagSafe = 0;
		$madhud::EnemyCarrier = $taker;
		madhud::PopUp(madhud_FFlagInfoString, 1);
	
	}

//CAPTURED

	else if(string::findsubstr(%msg, "Your team captured the") != -1)
	{
		$madhud::EnemyFlagSafe = 1;
		$madhud::EnemyCarrier = "";
		madhud::PopDown(madhud_EFlagInfoString);
	
	}

	else if(string::findsubstr(%msg, "Your team's flag was captured.") != -1)
	{
		$madhud::FlagSafe = 1;
		$madhud::FriendlyCarrier = "";
		madhud::PopDown(madhud_FFlagInfoString);
	
	}
	else if(string::findsubstr(%msg, "captured the") != -1)
	{
		$madhud::FlagSafe = 1;
		$madhud::FriendlyCarrier = "";
		madhud::PopDown(madhud_FFlagInfoString);
	
	}


//RETURNED

	else if(String::findSubStr(%msg, "Your flag was returned to base.") != -1)	
	{
		$madhud::FlagSafe = 1;
		$madhud::EnemyCarrier = "";
		madhud::PopDown(madhud_FFlagInfoString);
	
	}
	else if(String::findSubStr(%msg, "flag was returned to base.") != -1)
	{
		// They returned thier flag
		$madhud::FriendlyCarrier = "";
		$madhud::EnemyFlagSafe = 1;
		madhud::PopDown(madhud_EFlagInfoString);
	
	}

//DROPPED	

	else if(String::findSubStr(%msg, "was dropped") != -1)
	{
		if(String::findSubStr(%msg, "your flag was dropped") != -1)
			{
			$madhud::EnemyCarrier = "--DROPPED--";
			}
		else
			{
			$madhud::FriendlyCarrier = "--DROPPED--";
			}
	}

	
madhud::UpdateHUD();
}

// --------------------------------------------------------------------------------------
//MADHUD - ADMINISTRATIVE FUNCTIONS BASED ON: DYNHUD BY KILLER BUNNY
// --------------------------------------------------------------------------------------

function onExit()
{
	// Added by KB
	madhud::Remove();

   if(isObject(playGui))
      storeObject(playGui, "config\\play.gui");

   saveActionMap("config\\config.cs", "actionMap.sae", "playMap.sae", "pdaMap.sae");

	//update the video mode - since it can be changed with alt-enter
	$pref::VideoFullScreen = isFullScreenMode(MainWindow);

   checkMasterTranslation();
	echo("exporting pref::* to prefs.cs");
   export("pref::*", "config\\ClientPrefs.cs", False);
   export("Server::*", "config\\ServerPrefs.cs", False);
   export("pref::lastMission", "config\\ServerPrefs.cs", True);
   BanList::export("config\\banlist.cs");
}
//=======================================================================================
function onConnection(%message)
{
	Flood::Reset();
   echo("Connection ", %message);
   $dataFinished = false;
   if(%message == "Accepted")
   {
      resetSimTime();
		//execute the custom script
		if ($PCFG::Script != "")
		{
			exec($PCFG::Script);
		}

      resetPlayDelegate();
      remoteEval(2048, "SetCLInfo", $PCFG::SkinBase, $PCFG::RealName, $PCFG::EMail, $PCFG::Tribe, $PCFG::URL, $PCFG::Info, $pref::autoWaypoint, $pref::noEnterInvStation, $pref::messageMask);

		if ($Pref::PlayGameMode == "JOIN")
		{
			cursorOn(MainWindow);
	      GuiLoadContentCtrl(MainWindow, "gui\\Loading.gui");
			renderCanvas(MainWindow);
		}
		// Added by KB
		madhud::Reset();

   }
   else if(%message == "Rejected")
   {
		Quickstart();
      $errorString = "Connection to server rejected:\n" @ $errorString;
      GuiPushDialog(MainWindow, "gui\\MessageDialog.gui");
		schedule("Control::setValue(MessageDialogTextFormat, $errorString);", 0);
   }
   else
   {
      //startMainMenuScreen();
		Quickstart();

      if(%message == "Dropped")
      {
         if($errorString == "")
            $errorString = "Connection to server lost:\nServer went down.";
         else
            $errorString = "Connection to server lost:\n" @ $errorString;

         GuiPushDialog(MainWindow, "gui\\MessageDialog.gui");
		   schedule("Control::setValue(MessageDialogTextFormat, $errorString);", 0);
      }
      else if(%message == "TimedOut")
      {
         $errorString = "Connection to server timed out.";
         GuiPushDialog(MainWindow, "gui\\MessageDialog.gui");
		   schedule("Control::setValue(MessageDialogTextFormat, $errorString);", 0);
      }
   }
}
//=======================================================================================
function remoteMissionChangeNotify(%serverManagerId, %nextMission)
{
   if(%serverManagerId == 2048)
   {
		// Added by KB
		madhud::Reset();
		madhud::Remove();
		Flood::Reset();
		
      echo("Server mission complete - changing to mission: ", %nextMission);
      echo("Flushing Texture Cache");
      flushTextureCache();
      schedule("purgeResources(true);", 3);
	
   }
}
//=======================================================================================
function onClientMessage(%client, %msg)
{
   if(%client)
      $lastClientMessage = %client;

   // filter messages here
	// Added by KB
	//madhud::Parse(%client, %msg);
	
		if (Match::String(%msg,"*" @ "flag" @ "*"))
			madhud::flagEvents(%client, %msg);
		
		if (Match::String(%msg,"*" @ $PCFG::Name @ "*"))
			madhud::fragEvents(%client, %msg);
		
		if (Match::String(%msg,("*" @ "friendly fire" @ "*"||"*" @ "teammate" @ "*")))
			TeamDamageOnClientMessage(%client, %msg);
			
		if (Match::String(%msg,"*" @ "repair" @ "*"))
			{
			Repairs::OnClientMessage(%client, %msg);
			ThanksOnClientMessage(%client, %msg);
			}
   return true;
}

// --------------------------------------------------------------------------------------
//MADHUD -STRING MATCHING    BASED ON: MATCH.CS FROM Presto, March '99 
// --------------------------------------------------------------------------------------
//=======================================================================================
function Match::strLen(%str){
	for (%i = 0; String::GetSubStr(%str, %i, 1) != ""; %i++)
		{}
	return %i;
	}

//=======================================================================================
// Internal function, don't call this directly!
function Match::AddResult() {
	%num = $Match::params[$Match::results];
	$Match::params[$Match::results + 1] = %num;
	for (%i = 0; %i < %num; %i++) {
		$Match::param[$Match::results + 1, %i] = $Match::param[$Match::results, %i];
		}
	$Match::results++;
	}

//=======================================================================================
function Match::Clear() {
	// Clear old results.
	%params = $Match::params[$Match::results];

	%i = 0;
	%param = String::GetSubStr(%params, %i,1);
	%first = %param;
	while (%param != "") {
		$Match::param[$Match::results, %param] = "";

		%i++;
		%param = String::GetSubStr(%params, %i,1);
		if (%param == %first)
			%param = %i;
		}

	$Match::params[$Match::results] = "";
	}
//=======================================================================================
function Match::Success(%params) {
	// Set up for cleanup
	$Match::params[$Match::results] = %params;
	$Match::results++;
	Match::Clear($Match::results);

	%i = 0;
	%param = String::GetSubStr(%params, %i,1);
	%first = %param;
	while (%param != "") {
		$Match::param[$Match::results, %param] = $Match::param[$Match::results - 1, %param];

		%i++;
		%param = String::GetSubStr(%params, %i,1);
		if (%param == %first)
			%param = %i;
		}
	}
//=======================================================================================
function Match::Add(%param, %str, %exists) {
	if (%exists) {
		if ($Match::param[$Match::results, %param] != %str)
			return false;
		}
	else	$Match::param[$Match::results, %param] = %str;
	return true;
	}
//=======================================================================================
function Match::Remove(%param) {
	$Match::param[$Match::results, %param] = "";
	}

//=======================================================================================
// Internal function, don't call this directly!
function Match::_ParamString(%str, %pat, %wc,%lenWc, %params, %numeric) {
	// Look for a wildcard in the pattern
	%lenText = String::FindSubStr(%pat, %wc);
	if (%lenText == -1) {
		// Match entire string
		if (%str == %pat)
			Match::Success(%params);
		return;
		}

	if (%lenText != 0) {
		// Match pattern text up to %lenText
		if (String::GetSubStr(%pat, 0, %lenText) != String::GetSubStr(%str, 0, %lenText))
			return; // no match.

		%str = String::GetSubStr(%str, %lenText, 10000);
		}

	if (%numeric != "") {
		%param = %numeric;
		%exists = false;
		%numeric++;
		%params = %params @ "0";	// trick ... 0000 = 4 numeric params.
		}
	else	{
		%param = String::GetSubStr(%pat, %lenText+%lenWC - 1, 1);
		if (%param == "")	// just in case they forgot.
			%param = 0;
		%exists = String::FindSubStr(%params, %param) != -1;
		if (!%exists)
			%params = %params @ %param;
		}

	// Chop off the wildcard
	%pat = String::GetSubStr(%pat, %lenText+%lenWc, 10000);
	if (%pat == "") {
		// No more pattern left after the wildcard, wildcard matches to end
		if (Match::Add(%param, %str, %exists)) {
			Match::Success(%params);
			Match::Remove(%param);
			}
		return;
		}

	// Look for the next wildcard in the pattern
	%lenText = String::FindSubStr(%pat, %wc);
	if (%lenText == 0)
		return;	// It's illegal to have two wildcards in a row.
	if (%lenText == -1) {
		// Special case:  match "*string".
		%idx = String::FindSubStr(%str@%wc, %pat@%wc);	// @%wc guarantees last match.
		if (%idx != -1 && String::GetSubStr(%str, %idx, 10000)==%pat) {
			if (Match::Add(%param, String::GetSubStr(%str, 0, %idx), %exists)) {
				Match::Success(%params);
				Match::Remove(%param);
				}
			return;
			}
		return;
		}

	// Chop off the text from the pattern
	%textPat = String::GetSubStr(%pat, 0, %lenText);
	%pat = String::GetSubStr(%pat, %lenText, 10000);

	%idx = String::FindSubStr(%str, %textPat);
	while (%idx != -1) {
		// Got one wildcard match

		// Make sure this is a valid match
		if (Match::Add(%param, String::GetSubStr(%str, 0, %idx), %exists)) {
			// Try a match given this wildcard match
			Match::_ParamString(String::GetSubStr(%str, %idx + %lenText, 10000),
						  %pat, %wc,%lenWc, %params, %numeric);
			Match::Remove(%param);
			}

		%newIdx = String::FindSubStr(String::GetSubStr(%str, %idx+1, 10000), %textPat);
		if (%newIdx == -1)
			%idx = -1;
		else	%idx = %newIdx + %idx + 1;
		}
	return;
	}

//=======================================================================================
function Match::ParamString(%string, %pattern, %wildcard) {
	while ($Match::Results >= 0) {
		Match::Clear();
		$Match::Results--;
		}
	$Match::results = 0;

	if (%wildcard == "") {
		%wildcard = "%";
		%lenWC = 2;	// includes the next letter
		}
	else	%lenWC = Match::strLen(%wildcard) + 1;	// includes the next letter
	Match::_ParamString(%string, %pattern, %wildcard,%lenWC, "");
	return $Match::results;
	}
//=======================================================================================
function Match::String(%string, %pattern, %wildcard) {
	while ($Match::Results >= 0) {
		Match::Clear();
		$Match::Results--;
		}
	$Match::results = 0;

	if (%wildcard == "") {
		%wildcard = "*";
		%lenWC = 1;
		}
	else	%lenWC = Match::strLen(%wildcard);
	Match::_ParamString(%string, %pattern, %wildcard,%lenWC,"",0);
	return $Match::results;
	}

//=======================================================================================
function Match::Count(%num) {
	return $Match::results;
	}
//=======================================================================================
function Match::Result(%num, %numWild) {
	if (%numWild == "") {
		%numWild = %num;
		%num = 0;
		}
	return $Match::param[%num, %numwild];
	}

// --------------------------------------------------------------------------------------
//MADHUD - KILLTRAK BASED ON: JHUD SCRIPT BY JOSH  
// --------------------------------------------------------------------------------------
//=======================================================================================
// KillTrak.CS								Presto, March '99 
//
//	This code is based on (and supercedes) the JHUD code by Josh.  I want
//	to thank him for his cool kill-tracking HUD (the JHUD) which he 
//	released soon after the first PrestoPack.  He's stopped coding scripts
//	but gave me permission to take over the kill tracking code he'd
//	written.
//
// A) The Code
// --------------------------------------------------------------------------

//=======================================================================================
function KillTrak::Reset() {
	for (%i = 0; %i < $KillTrak::numDeaths; %i++)
		$KillTrak::message[$KillTrak::death[%num]] = "";
	$KillTrak::numDeaths = 0;
	}

//=======================================================================================
function KillTrak::DeathMessage(%msg, %weapon, %mod) {
	%num = $KillTrak::message[%msg];
	if (%num == "") {
		%num = $KillTrak::numDeaths;
		if (%num == "")
			%num = 0;
		$KillTrak::numDeaths = %num + 1;
		}

	$KillTrak::message[%msg] = %num;
	$KillTrak::death[%num] = %msg;
	$KillTrak::death[%num, mod] = %mod;
	$KillTrak::death[%num, weapon] = %weapon;
	$KillTrak::death[%num, suicide] = (String::FindSubStr(%msg, "%1") == -1);
	}

//=======================================================================================
function KillTrak::GetKiller() {
	return $KillTrak::killer;
	}
//=======================================================================================
function KillTrak::GetVictim() {
	return $KillTrak::victim;
	}
//=======================================================================================
function KillTrak::GetWeapon() {
	return $KillTrak::weapon;
	}

//=======================================================================================
function KillTrak::OnClientMessage(%client, %msg) 
{
//echo("KILLTRAK START");
	if (%client != 0)
		return;
	for (%i = 0; %i < $KillTrak::numDeaths; %i++) {
		%mod = $KillTrak::death[%i, mod];
		if (%mod != "" && %mod != $Mod::current)
			continue;
		if (Match::ParamString(%msg, $KillTrak::death[%i])) {
			$KillTrak::victim = getClientByName(Match::Result(2));
			if ($KillTrak::death[%i, suicide])
				$KillTrak::killer = $KillTrak::victim;
			else	$KillTrak::killer = getClientByName(Match::Result(1));
			$KillTrak::weapon = $KillTrak::death[%i, weapon];
			//Event::Trigger(eventKillTrak, $KillTrak::killer, $KillTrak::victim, $KillTrak::weapon);
			return;
			}
		}
	}

// B) The Death Messages
//	The format of this section is:
//		KillTrak::DeathMessage(message, weapon);
//	The "message" is the text of the
//		Use %1 to match the killer's name
//		Use %2 to match the victim's name
//		Use %3 to match the killer's possessive pronoun (?)
//			For instance "his" or "her"
//		And %4 to match the victim's.
//
//	Yes, you can add new death messages!  Don't put them in this
//	file.  Just add them to your own script somewhere, for instance
//	in your autoexec.cs --
//	People who make server-side mods could also release this list
//	so that kill-tracking works for their clients.
// --------------------------------------------------------------------------
KillTrak::DeathMessage("%2 falls to %3 death.", "Falling");
KillTrak::DeathMessage("%2 forgot to tie %3 bungie cord.", "Falling");
KillTrak::DeathMessage("%2 bites the dust in a forceful manner.", "Falling");
KillTrak::DeathMessage("%2 fall down go boom.", "Falling");

KillTrak::DeathMessage("%1 makes quite an impact on %2.", "Vehicle");
KillTrak::DeathMessage("%2 becomes the victim of a fly-by from %1.", "Vehicle");
KillTrak::DeathMessage("%2 leaves a nasty dent in %1's fender.", "Vehicle");
KillTrak::DeathMessage("%1 says, 'Hey %2, you scratched my paint job!'", "Vehicle");

KillTrak::DeathMessage("%1 ventilates %2 with %3 chaingun.", "Chaingun");
KillTrak::DeathMessage("%1 gives %2 an overdose of lead.", "Chaingun");
KillTrak::DeathMessage("%1 fills %2 full of holes.", "Chaingun");
KillTrak::DeathMessage("%1 guns down %2.", "Chaingun");

KillTrak::DeathMessage("%2 dies of turret trauma.", "Turret");
KillTrak::DeathMessage("%2 is chewed to pieces by a turret.", "Turret");
KillTrak::DeathMessage("%2 walks into a stream of turret fire.", "Turret");
KillTrak::DeathMessage("%2 ends up on the wrong side of a turret.", "Turret");

KillTrak::DeathMessage("%2 feels the warm glow of %1's plasma.", "Plasma");
KillTrak::DeathMessage("%1 gives %2 a white-hot plasma injection.", "Plasma");
KillTrak::DeathMessage("%1 asks %2, 'Got plasma?'", "Plasma");
KillTrak::DeathMessage("%1 gives %2 a plasma transfusion.", "Plasma");
KillTrak::DeathMessage("%1 lights %2 on fire.", "Plasma");
KillTrak::DeathMessage("%1 asks %2, got a light?.", "Plasma");

KillTrak::DeathMessage("%2 catches a Frisbee of Death thrown by %1.", "Disc Launcher");
KillTrak::DeathMessage("%1 blasts %2 with a well-placed disc.", "Disc Launcher");
KillTrak::DeathMessage("%1's spinfusor caught %2 by surprise.", "Disc Launcher");
KillTrak::DeathMessage("%2 falls victim to %1's Stormhammer.", "Disc Launcher");

KillTrak::DeathMessage("%1 blows %2 up real good.", "Mine");
KillTrak::DeathMessage("%2 gets a taste of %1's explosive temper.", "Mine");
KillTrak::DeathMessage("%1 gives %2 a fatal concussion.", "Mine");
KillTrak::DeathMessage("%2 never saw it coming from %1.", "Mine");

KillTrak::DeathMessage("%1 adds %2 to %3 list of sniper victims.", "Laser Rifle");
KillTrak::DeathMessage("%1 fells %2 with a sniper shot.", "Laser Rifle");
KillTrak::DeathMessage("%2 becomes a victim of %1's laser rifle.", "Laser Rifle");
KillTrak::DeathMessage("%2 stayed in %1's crosshairs for too long.", "Laser Rifle");
KillTrak::DeathMessage("%2 was assassinated by %1.", "Sniper Rifle");

KillTrak::DeathMessage("%1 mortars %2 into oblivion.", "Mortar");
KillTrak::DeathMessage("%2 didn't see that last mortar from %1.", "Mortar");
KillTrak::DeathMessage("%1 inflicts a mortal mortar wound on %2.", "Mortar");
KillTrak::DeathMessage("%1's mortar takes out %2.", "Mortar");

KillTrak::DeathMessage("%2 gets a blast out of %1.", "Blaster");
KillTrak::DeathMessage("%2 succumbs to %1's rain of blaster fire.", "Blaster");
KillTrak::DeathMessage("%1's puny blaster shows %2 a new world of pain.", "Blaster");
KillTrak::DeathMessage("%2 meets %1's master blaster.", "Blaster");

KillTrak::DeathMessage("%2 gets zapped with %1's ELF gun.", "ELF Gun");
KillTrak::DeathMessage("%1 gives %2 a nasty jolt.", "ELF Gun");
KillTrak::DeathMessage("%2 gets a real shock out of meeting %1.", "ELF Gun");
KillTrak::DeathMessage("%1 short-circuits %2's systems.", "ELF Gun");

KillTrak::DeathMessage("%2 didn't stay away from the moving parts.", "Crushed");
KillTrak::DeathMessage("%2 is crushed.", "Crushed");
KillTrak::DeathMessage("%2 gets smushed flat.", "Crushed");
KillTrak::DeathMessage("%2 gets caught in the machinery.", "Crushed");

KillTrak::DeathMessage("%2 is a victim among the wreckage.", "Debris");
KillTrak::DeathMessage("%2 is killed by debris.", "Debris");
KillTrak::DeathMessage("%2 becomes a victim of collateral damage.", "Debris");
KillTrak::DeathMessage("%2 got too close to the exploding stuff.", "Debris");

KillTrak::DeathMessage("%2 takes a missile up the keister.", "Missile");
KillTrak::DeathMessage("%2 gets shot down.", "Missile");
KillTrak::DeathMessage("%2 gets real friendly with a rocket.", "Missile");
KillTrak::DeathMessage("%2 feels the burn from a warhead.", "Missile");

KillTrak::DeathMessage("%2 ends it all.", "Suicide");
KillTrak::DeathMessage("%2 takes %3 own life.", "Suicide");
KillTrak::DeathMessage("%2 kills %3 own dumb self.", "Suicide");
KillTrak::DeathMessage("%2 decides to see what the afterlife is like.", "Suicide");
KillTrak::DeathMessage("%2 goes postal.", "Suicide");
KillTrak::DeathMessage("%2 dies.", "Suicide");


// --------------------------------------------------------------------------------------
//MADHUD -AUTO THANKS FOR REPAIRS    BASED ON: THANKS.CS FROM Presto, March '99 
// --------------------------------------------------------------------------------------

$thanksFloodTime = 15;	// For 15 seconds we won't thank him again.

function ThanksOnClientMessage(%client, %msg) 
{
//echo("THANKS START");
	if (%client != 0)
		return;
	if (Match::ParamString(%msg, "Being repaired by %p")) {
		%player = Match::Result(p);
		if (Flood::Protect("thanks"@%player, $thanksFloodTime)) {
			say(1, "Thanks, "@ %player);
			Say::Local(sayThanks); // so everyone doesn't have to hear
			}
		return;
		}
	}

// --------------------------------------------------------------------------------------
//MADHUD -REPAIR ANNOUNCEMENTS     BASED ON: Script by Lord Harlock
// --------------------------------------------------------------------------------------
$repairSameTime = 20; 
	//	For 20 seconds, more repairs on the same item will not message again.

function Repairs::OnClientMessage(%client, %msg) 
{
//echo("REPAIR START");
	if (%client != 0)
		return;
	if (Match::ParamString(%msg, "Repairing %r")) {
		%repair = Match::Result(r);
		if (getClientByName(%repair) != 0)
			return;

		if (Flood::Protect("repair"@%repair, $repairSameTime)) {
			$repairItem = %repair;
			say(1, "I am making repairs to " @ $repairitem);
			}
		return;
		}
	if (%msg == "Repair Done") {
		if ($repairitem != "") {
			say(1, "Repairs completed on " @ $repairitem );
			$repairitem = "";
			}
		return;
		}
	if (%msg == "Repair Stopped") {
		return;
		}
	}
// --------------------------------------------------------------------------------------
//MADHUD -TEAM DAMAGE ANNOUNCEMENTS     BASED ON: script by DS.Poker
// --------------------------------------------------------------------------------------

$teamDamageFloodTime = 10;

function TeamDamageOnClientMessage(%client, %msg) 
{
//echo("DAMAGE START");
	if (%client != 0)
		return;

	if (Match::String(%msg, "You just harmed Teammate *")) {
		if (!Flood::Protect("teamdamageMyFault", $teamDamageFloodTime))
			return;

		%str = Match::Result(0);
		if (Match::String(%str, "* with your mine!"))
			Say::Team(sayHey, "Hey "@Match::Result(0)@", be careful of my mines!");
		else	Say::Team(saySorry, "Sorry, "@%str);
		return;
		}
	if (Match::String(%msg, "You took Friendly Fire from *")) {
		if (Flood::Protect("teamdamage", $teamDamageFloodTime))
			Say::Team(yellWatchShooting, "Watch where you're shooting, "@ Match::Result(0) @"!");
		return;
		}
	}



// --------------------------------------------------------------------------------------
//MADHUD -SAY FUNCTIONS FROM SAY.CS BY PRESTO
// --------------------------------------------------------------------------------------
function Say::SetWav(%name, %wav) {
	$Say::[%name, wav] = %wav;
	}
function Say::SetText(%name, %defaultText) {
	$Say::[%name, text] = %defaultText;
	}
function Say::GetWav(%name) {
	return $Say::[%name, wav];
	}
function Say::GetText(%name) {
	return $Say::[%name, text];
	}

// Say::Public, Say::Team, Say::Local	3 ways of speaking
function Say::Public(%name, %msg) {
	if (%msg == "")
		%msg = Say::GetText(%name);
	remoteEval(2048, say, 0, %msg @ "~w" @ Say::GetWav(%name) );
	}
function Say::Team(%name, %msg) {
	if (%msg == "")
		%msg = Say::GetText(%name);
	remoteEval(2048, say, 1, %msg @ "~w" @ Say::GetWav(%name) );
	}
function Say::Local(%name) {
	remoteEval(2048, lmsg, Say::GetWav(%name) );
	}
function Say::Animation(%name, %anim) {
	remoteEval(2048, playAnimWav, %anim, Say::GetWav(%name) );
	}
function Say::Response(%name, %status, %msg) {
	if (%msg == "")
		%msg = Say::GetText(%name);
	remoteEval(2048, CStatus, %anim, %msg @ "~w" @ Say::GetWav(%name) );
	}

// Say::New		create a new saying.
function Say::New(%name, %sayWavfile, %defaultSayText) {
	Say::SetWav(%name, %sayWavFile);
	Say::SetText(%name, %defaultSayText);
	}

function Flood::Protect(%tag, %protectTime) {
	%lastTime = $Flood::[%tag];
	%time = GetSimTime();
	$Flood::[%tag] = %time;
	return %lastTime == "" || (%time - %lastTime >= %protectTime );
	}
function Flood::Reset() {
	deleteVariables("$Flood::*");
	}

Say::New( sayNone,			"",		"I have nothing to say.");

// Attack sayings
Say::New( attack,			"attack",	"Attack!");
Say::New( attack2,		"attac2",	"Attack!");
Say::New( attackBase,		"attbase",	"Attack the enemy base.");
Say::New( attackEnemy,		"attenem",	"Attack the enemy.");
Say::New( attackGo,		"gooff",	"Go on the offensive.");
Say::New( attackGoing,		"ono",	"Going offense...");

// Base info sayings
Say::New( baseClear,		"isbsclr",	"Is our base clear?");
Say::New( baseSecure,		"bsclr2",	"Our base is secure.");
Say::New( baseTaken,		"basetkn",	"Our base has been taken!");
Say::New( baseUnderAttack,	"basundr",	"The enemy is attacking our base!");

// Chat sayings
Say::New( sayThanks, 		"thanks",	"Thanks.");
Say::New( sayNoProblem,		"noprob",	"No problem.");
Say::New( sayHey,			"wshoot1",	"Hey.");
Say::New( sayBye,			"bye",	"Bye!");
Say::New( sayYes,			"yes",	"Yes.");
Say::New( sayNo,			"no",		"No.");
Say::New( saySorry,		"sorry",	"Sorry.");
Say::New( sayHi,			"hello",	"Hi.");
Say::New( sayIDontKnow,		"dontkno",	"I don't know");
Say::New( sayHmm,			"color3",	"Hmm...");

// Command sayings
Say::New( orderAcknowledged,	"acknow",	"Acknowledged");
Say::New( orderBelay,	 	"belay", 	"Belay Order!");
Say::New( orderBoard, 		"boarda", 	"Board APC.");
Say::New( orderCanceled,	"ordcan",	"Order cancelled.");
Say::New( orderCompleted,	"objcomp",	"Objective completed.");
Say::New( orderDestroyGenerator, "desgen","Destroy the enemy generator.");
Say::New( orderDestroyTurret,	"destur",	"Destroy the enemy turret.");
Say::New( orderNotCompleted, 	"objxcmp", "Unable to complete objective.");

// Coordination
Say::New( orderCeaseFire,	"cease",	"Cease fire!");
Say::New( orderCoverMe,		"coverme",	"Cover me!");
Say::New( orderHitTheDeck,	"hitdeck",	"Hit the deck!");
Say::New( orderMoveAside,	"outway",	"Move out of the way!");
Say::New( orderMoveOut,		"moveout",	"Move out!");
Say::New( orderOverHere,	"ovrhere",	"Over here!");
Say::New( orderProceed,		"proceed",	"Proceed ahead.");
Say::New( orderReady,		"ready",	"Ready.");
Say::New( orderRegroup,		"regroup",	"Regroup!");
Say::New( orderRetreat,		"retreat",	"Retreat!");
Say::New( orderStop,		"stop",	"Stop!");
Say::New( orderTakeCover,	"takcovr",	"Take cover!");
Say::New( orderWait,		"wait1",	"Wait...");
Say::New( orderWaiting,		"wait2",	"Waiting...");
Say::New( orderWaitSignal,	"waitsig",	"Wait for my signal to attack.");

// Defense sayings
Say::New( defendAttacked,	"basatt",	"We're being attacked!");
Say::New( defendBase,		"defbase",	"Defend our base!");
Say::New( defendGo,		"godef",	"Go on the defensive.");
Say::New( defendGoing,		"defend",	"Defending our base.");
Say::New( defendIncoming, 	"incom2",	"Incoming enemies!");
Say::New( defendNeed,		"needdef",	"We need more defense!");

// Deploy sayings
Say::New( deployAmmo,		"depamo",	"Deploy ammo station at waypoint.");
Say::New( deployBeacon,		"depbecn",	"Deploy beacon at waypoint.");
Say::New( deployCamera,		"depcam",	"Deploy camera at waypoint.");
Say::New( deployInventory,	"depinv",	"Deploy inventory station at waypoint.");
Say::New( deployJammer,		"depjamr",	"Deploy sensor jammer at waypoint.");
Say::New( deployMotion,		"depmot",	"Deploy motion sensor at waypoint.");
Say::New( deploySensor,		"deppuls",	"Deploy pulse sensor at waypoint.");
Say::New( deployTurret,		"deptur",	"Deploy turret at waypoint.");

// Flag sayings
Say::New( flagClearMines,	"clrflg",	"Clear the mines from our flag.");
Say::New( flagGet,		"geteflg",	"Get the enemy flag!");
Say::New( flagHave,		"haveflg",	"I have the enemy flag, heading back to our base.");
Say::New( flagMine,		"mineflg",	"Mine the flag.");
Say::New( flagMined,		"flgmine",	"Our flag is mined.");
Say::New( flagNotInBase,	"flgtkn1",	"Our flag is not in the base!");
Say::New( flagReturn,		"retflag",	"Return our flag to our base.");
Say::New( flagSecure,		"flaghm",	"Our flag is secure.");
Say::New( flagTaken,		"flgtkm2",	"The enemy has our flag!");

// Need
Say::New( needAmmo,		"needamo",	"Can anyone bring me some ammo?");
Say::New( needAPC,		"needpku",	"I need an APC pickup");
Say::New( needChaingunAmmo,	"needamo",	"I need Chaingun ammo.");
Say::New( needDiscLauncherAmmo, "needamo","I need Disc Launcher ammo.");
Say::New( needEscort,		"needesc",	"I need an escort back to base.");
Say::New( needGrenadeLauncherAmmo,"needamo","I need Grenade Launcher ammo.");
Say::New( needGrenades,		"needamo",	"I need Grenades.");
Say::New( needMines,		"needamo",	"I need Mines.");
Say::New( needMortarAmmo,	"needamo",	"I need Mortar ammo.");
Say::New( needPlasmaGunAmmo,	"needamo",	"I need Plasma Gun ammo.");
Say::New( needRepairs,		"needrep",	"Need repairs.");
Say::New( needStation,		"hurystn",	"Hurry up with that station!");

// Objective sayings
Say::New( objectiveAttack,	"attobj",	"Attack objective.");
Say::New( objectiveCapture,	"capobj", 	"Capture the objective.");
Say::New( objectiveClearMines,"clrobj",	"Clear the mines from our objective.");
Say::New( objectiveDefend,	"defobj",	"Defend the objective.");
Say::New( objectiveGet,		"getobj", 	"Get the objective.");
Say::New( objectiveMine,	"mineobj",	"Our objective is mined.");
Say::New( objectiveRepair,	"repobj",	"Repair the objective.");

// Status messages
Say::New( statusGeneratorDestroyed,"gendes","Enemy generator destroyed.");
Say::New( statusMinesCleared,	"mineclr",	"Mines have been cleared.");
Say::New( statusTurretDestroyed,"turdes",	"Enemy turret destroyed.");
Say::New( statusAPCReady,	"waitpas",	"APC Ready to go... waiting for passengers.");

// Targeting sayings
Say::New( targetFire,		"firetgt",	"Fire on my target.");
Say::New( targetAcquired,	"tgtacq",	"Target acquired.");
Say::New( targetLocation,	"tgtobj",	"Target location.");
Say::New( targetOutOfRange,	"tgtout",	"Target out of range.");
Say::New( targetNeeded,		"needtgt",	"I need a target.");

// Taunt sayings
Say::New( tauntYoohoo,		"taunt1",	"Yooo hooo!");
Say::New( tauntHowdThatFeel,	"taunt10",	"How'd that feel?");
Say::New( tauntIveHadWorse,	"tautn11",	"I've had worse...");
Say::New( tauntMissedMe,	"taunt2",	"Missed me!");
Say::New( tauntDance,		"taunt3",	"Dance!");
Say::New( tauntComeGetSome,	"taunt4",	"Come get some!");

// Waypoint sayings
Say::New( waypointAttack,	"attway",	"Attack enemy at waypoint.");
Say::New( waypointDefend, 	"defway",	"Defend the waypoint.");
Say::New( waypointEscort,	"escfr",	"Escort friendly at waypoint.");
Say::New( waypointGo,		"goway",	"Proceed to waypoint.");
Say::New( waypointPilot,	"wpilot",	"Pilot APC to waypoint");
Say::New( waypointRepairPlayer,"repplyr",	"Repair friendly at waypoint.");
Say::New( waypointRepairEquipment,"repeqp","Repair equipment at waypoint.");
Say::New( waypointRepairItem,	"repitem",	"Repair item at waypoint.");

// Yellings
Say::New( yellShazbot,		"color2",	"Shazbot!");
Say::New( yellDammit,		"color6",	"Dammit!");
Say::New( yellCrap,		"color7",	"Ahhh crap!");
Say::New( yellDuh,		"dsgst1",	"Duh!");
Say::New( yellYouIdiot,		"dsgst2",	"You idiot!");
Say::New( yellWatchShooting,	"wshoot3",	"Watch where you're shooting!");
Say::New( yellArgh,		"dsgst4",	"Argh!");
Say::New( yellSigh,		"dsgst5",	"(sigh)");
Say::New( yellDoh,		"oops1",	"Doh!");
Say::New( yellOops,		"oops2",	"Oops!");
Say::New( yellYeah,		"cheer1",	"Yeah!");
Say::New( yellWoohoo,		"cheer2",	"Woo hoo!");
Say::New( yellAllRight,		"cheer3",	"All right!");
Say::New( yellHelp, 		"help",	"Help!");
