//=============================================================================
// sgHUD.
// Revised by nOs*Badger
//=============================================================================
class sgHUD extends ChallengeTeamHUD config;

var Pawn            IdentifyPawn;
var() color         GreyColor;
var int Glowing;
var int RedColour;
var color GlowColour;
var color GotoColour;
var() color TheWhiteStuff;
var int nHUDDecPlaces;
var float sCore;
var() config int NumBuildings;
var() string sgBuildings[41];
var() string sgCategory[7];
var() string sgRanks[8];
var() string sgRankDesc[8];
var() int sgOldBuilt[41];
var() texture TeamIcons[4];
var bool UseSpecialColor;

// HUD Item Postions
var float HudItemSpeedX;
var float HudItemSpeedY;
var float HudItemJetX;
var float HudItemJetY;
var float HudItemDashX;
var float HudItemDashY;
var float HudItemSlotX;

var float HudItemSlotOriginX;
var float HudItemSlotOriginY;
var float HudItemSlotSpace;

// Custom stuff by WILDCARD
var DashPlayer DashPlayerInstance;

// The message color variable
var color SpecialMessageColor;

//Thermal Visor Variables
var() bool bSeeAllHeat, bSeeBehindWalls;
var() class<Actor> AffectedActorsClass;
var() name ExcludedClass;
var() class<Actor> HeatClass, HeatInventoryClass;
var() float HeatSensingRange;
var PlayerPawn localPlayer;
struct HeatObj
{
	var Actor SavedHeat;
	var Actor HeatOwner;
};

var HeatObj HeatObjs[32];
var int globalint;
var bool bVisorDeActivated;

simulated function DrawTeam(Canvas Canvas, TeamInfo TI)
{
	local float XL, YL;

	if ( (TI != None) && (TI.Size > 0) )
	{
		Canvas.Font = MyFonts.GetHugeFont( Canvas.ClipX );
		Canvas.DrawColor = TeamColor[TI.TeamIndex];
		Canvas.SetPos(Canvas.ClipX - 72, Canvas.ClipY - (384 + 72 * TI.TeamIndex));

		//Canvas.DrawIcon(TeamIcon[TI.TeamIndex], 1.0);

		Canvas.DrawIcon(TeamIcons[TI.TeamIndex],1.0);

		Canvas.StrLen(int(TI.Score), XL, YL);
		Canvas.SetPos(Canvas.ClipX - 136, Canvas.ClipY - (368 + 72 * TI.TeamIndex));
		Canvas.DrawText(int(TI.Score), false);
	}
}

simulated function string GetPlural(int i, string sObject)
{
	if (i==1) return i@sObject;
	return i@sObject$"s";
}

simulated function TeamRU(canvas C)
{
	local int i,y;
        local string sInfo[32];
	local sgPRI PRI;
	local float widthtotal;
	local float width, height;
	local string s;

	C.Font = Font'SmallFont';
	C.Style = ERenderStyle.STY_Normal;
	for (i=0;i<32;i++)
	{
		PRI = sgPRI(PlayerPawn(Owner).GameReplicationInfo.PRIArray[i]);
		if (PRI != None)
		{
			if (PlayerPawn(Owner).PlayerReplicationInfo.Team == PRI.Team)
			{
				s = PRI.PlayerName @ int(PRI.RU) @ "RU";
				C.TextSize(s, width, height);
				if (width > widthtotal) widthtotal=width;
				y = y + 1;
			}
		}
	}


	C.DrawColor = TeamColor[Pawn(Owner).PlayerReplicationInfo.Team];
	y = C.ClipY/3 - ((y * height)/2);
	for (i=0;i<16;i++)
	{
		PRI = sgPRI(PlayerPawn(Owner).GameReplicationInfo.PRIArray[i]);
		if (PRI != None)
		{
			if (PlayerPawn(Owner).PlayerReplicationInfo.Team == PRI.Team)
			{
				C.SetPos(C.ClipX - widthtotal,y);
				C.DrawText(PRI.PlayerName, true);
				s = int(PRI.RU) @ "RU";
				C.TextSize(s, width, height);
				C.SetPos(C.ClipX - width,y);
				C.DrawText(s, True);
				y += height;
			}
		}
	}

}

simulated function SiegeStats(canvas C)
{

	local float XL, YL, X1, Y1, Height, Width;
	local float TinyFontHeight, SmallFontHeight, BigFontHeight, HugeFontHeight;
	local int X, OldX ,Y,i, nBuildings,Rows, Col, R, nPlayers;
	local string s1, s2;
	local int MaxPerColumn;
	local int Columns;
	local pawn p;

	local color 	cCol;
	
	local sgPRI pInfo[8];
	local string sInfo[8];

	local sgGameReplicationInfo sgGRI;

	local sgPRI PRI;

	sgGRI = sgGameReplicationInfo(PlayerOwner.GameReplicationInfo);
	PRI = sgPRI(PawnOwner.PlayerReplicationInfo);

	C.Style = ERenderStyle.STY_Normal;

	C.Font = MyFonts.GetHugeFont( C.ClipX );
	C.DrawColor = TeamColor[Pawn(Owner).PlayerReplicationInfo.Team];

	C.Font = Font'SmallFont';
	C.TextSize("A", Width, TinyFontHeight);
	C.Font = MyFonts.GetSmallFont( C.ClipX );
	C.TextSize("A", Width, SmallFontHeight);
	C.Font = MyFonts.GetBigFont( C.ClipX );
	C.TextSize("A", Width, BigFontHeight);
	C.Font = MyFonts.GetHugeFont( C.ClipX );
	C.TextSize("A", Width, HugeFontHeight);
	BigFontHeight+=1;

	C.bCenter = true;
	C.SetPos(0, HugeFontHeight );
	C.DrawText("-= Siege Ultimate Game Stats =-", True );
	C.Font = MyFonts.GetBigFont( C.ClipX );
	C.SetPos(0, YL + HugeFontHeight*2);
	
	C.DrawText("Top Player Rankings", True );
	YL+=HugeFontHeight*6;
	C.bCenter = false;
	
	YL = C.ClipY/2 - (5 * (BigFontHeight+TinyFontHeight)) - BigFontHeight;

	for (i=0;i<32;i++)
	{
		PRI = sgPRI(PlayerPawn(Owner).GameReplicationInfo.PRIArray[i]);
		if (PRI != None)
		{
			nPlayers++;
			if ( pInfo[0] == None && PRI.sgInfoCoreKiller > 0 ||
			     pInfo[0] != None && PRI.sgInfoCoreKiller > pInfo[0].sgInfoCoreKiller )
			{
			 pInfo[0]=PRI;
			}
			if ( pInfo[1] == None && PRI.sgInfoCoreRepair > 0 ||
			     pInfo[1] != None && PRI.sgInfoCoreRepair > pInfo[1].sgInfoCoreRepair)
			{
			 pInfo[1]=PRI;
			}
			if ( pInfo[2] == None && PRI.sgInfoBuildingHurt > 0 ||
			     pInfo[2] != None && PRI.sgInfoBuildingHurt > pInfo[2].sgInfoBuildingHurt)
			{
			 pInfo[2]=PRI;
			}
			if ( pInfo[3] == None && PRI.sgInfoKiller > 0 ||
			     pInfo[3] != None && PRI.sgInfoKiller > pInfo[3].sgInfoKiller)
			{
			 pInfo[3]=PRI; sInfo[3] = GetPlural(PRI.sgInfoKiller,"player")@"killed";
			}
			if ( pInfo[4] == None && PRI.sgInfoBuildingMaker > 0 ||
			     pInfo[4] != None && PRI.sgInfoBuildingMaker > pInfo[4].sgInfoBuildingMaker)
			{
			 pInfo[4]=PRI; sInfo[4] = GetPlural(PRI.sgInfoBuildingMaker,"building")@"created";
			}
			if ( pInfo[5] == None && PRI.sgInfoWarheadMaker > 0 ||
			     pInfo[5] != None && PRI.sgInfoWarheadMaker > pInfo[5].sgInfoWarheadMaker)
			{
			 pInfo[5]=PRI; sInfo[5] = GetPlural(PRI.sgInfoWarheadMaker,"Warhead")@"created";
			}
			if ( pInfo[6] == None && PRI.sgInfoWarheadKiller > 0 ||
			     pInfo[6] != None && PRI.sgInfoWarheadKiller > pInfo[6].sgInfoWarheadKiller)
			{
			 pInfo[6]=PRI; sInfo[6] = GetPlural(PRI.sgInfoWarheadKiller,"Warhead")@"destroyed";
			}
			if ( pInfo[7] == None && PRI.sgInfoUpgradeRepair > 0 ||
			     pInfo[7] != None && PRI.sgInfoUpgradeRepair > pInfo[7].sgInfoUpgradeRepair)
			{
			 pInfo[7]=PRI;
			}
		}
	}

	for (i=0;i<8;i++)
	{
		X=C.ClipX/4;
		Y1 = YL + ((BigFontHeight+TinyFontHeight+2)*i);
		C.Font = MyFonts.GetBigFont( C.ClipX );
		C.DrawColor = WhiteColor;
		C.SetPos(X, Y1);
		C.DrawText(sgRanks[i]);

		if (pInfo[i] != None) 
		{
			
			s1 = pInfo[i].PlayerName;
			if (s1 == PlayerPawn(Owner).PlayerReplicationInfo.PlayerName)
        			C.DrawColor = GoldColor;
			else
				C.DrawColor = TeamColor[pInfo[i].Team];
		}
		else
		{
			s1 = "None";
			C.DrawColor = GreyColor;
		}
		C.TextSize(s1, Width, Height);
		C.SetPos(((C.ClipX/4)*3)-Width, Y1);
		C.DrawText(s1);	
		C.Font = Font'SmallFont';
		C.DrawColor = GreyColor;
		if (sInfo[i] != "")
		{
			C.TextSize(sInfo[i], Width, Height);
			C.SetPos(((C.ClipX/4)*3)-Width, Y1 + BigFontHeight-2);
			C.DrawText(sInfo[i]);
		}
		C.SetPos(X, Y1 + BigFontHeight-3);
		C.DrawText(sgRankDesc[i]);
	}
	C.Font = MyFonts.GetBigFont( C.ClipX );
	C.DrawColor = TeamColor[Pawn(Owner).PlayerReplicationInfo.Team];
	Y1 = YL + ((BigFontHeight+TinyFontHeight+2)*9);
	C.bCenter = true;
	C.SetPos(0, Y1 + BigFontHeight-3);
	C.DrawText(GetPlural(nPlayers,"Player")@"Playing");
	C.bCenter = false;
}

//========================================
// Master HUD render function.

simulated function PostRender( canvas Canvas )
{
	local float XL, YL, XPos, YPos, FadeValue;
	local string Message;
	local int M, i, j, k, XOverflow;
	local float OldOriginX, l;

	local bool bWatchingTV;
	local bool bSiegeStats, bTeamRU;
	local int count;
	
	local PlayerPawn PP;
	local Actor A;

	///////////////////////	
	//Thermal Visor Stuff//
	///////////////////////
	
		if (localPlayer == None)
			{
				foreach AllActors(class'PlayerPawn', PP)
				{
					if (Viewport(PP.Player) != None)
					{
						localPlayer = PP;
						break;
					}
				}
				
				if (localPlayer == None)
					return;
			}
	
	if (localPlayer.FindInventoryType(HeatInventoryClass) != None && !bVisorDeActivated)
		{
			globalint=0;
			
			Canvas.SetPos(0, 0);
			Canvas.Style = ERenderStyle.STY_Modulated;
			Canvas.DrawRect(Texture'BlueSquare', Canvas.ClipX, Canvas.ClipY);
			
			if (bSeeBehindWalls)
				{
					foreach RadiusActors(AffectedActorsClass, A, HeatSensingRange, localPlayer.Location)
						{
							if (A != localPlayer && !A.IsA(ExcludedClass) && !A.bHidden && FMax(A.CollisionRadius, A.CollisionHeight) > 0 
							&& A.DrawType == DT_Mesh && (A.bCollideActors || A.bProjTarget))
							HeatUp(A, globalint, Canvas);
						}
				}
			else
				{
					foreach VisibleCollidingActors(AffectedActorsClass, A, HeatSensingRange, localPlayer.Location)
						{
							if (A != localPlayer && !A.IsA(ExcludedClass) && A.DrawType == DT_Mesh)
							HeatUp(A, globalint, Canvas);
						}
				}				
		}

	HUDSetup(canvas);

	if ( (PawnOwner == None) || (PlayerOwner.PlayerReplicationInfo == None) )
		return;

	if (Owner.IsA('PlayerPawn') && sgPRI(PlayerPawn(Owner).PlayerReplicationInfo) != None )
	{
		l = sgPRI(PlayerPawn(Owner).PlayerReplicationInfo).iStatus;
		if (int(l/2)*2 != l) bSiegeStats = true;
		if (int(l/4)*4 != l) bTeamRU = true;
	}
	
	if ( bShowInfo )
	{
		ServerInfo.RenderInfo( Canvas );
		return;
	}


	Canvas.Font = MyFonts.GetSmallFont( Canvas.ClipX );
	OldOriginX = Canvas.OrgX;
	// Master message short queue control loop.
	Canvas.Font = MyFonts.GetSmallFont( Canvas.ClipX );
	Canvas.StrLen("TEST", XL, YL);
	Canvas.SetClip(768*Scale - 10, Canvas.ClipY);
	bDrawFaceArea = false;
	if ( !bHideFaces && !PlayerOwner.bShowScores && !bForceScores && !bHideHUD
			&& !PawnOwner.PlayerReplicationInfo.bIsSpectator && (Scale >= 0.4) )
	{
		DrawSpeechArea(Canvas, XL, YL);
		bDrawFaceArea = (FaceTexture != None) && (FaceTime > Level.TimeSeconds);
		if ( bDrawFaceArea )
		{
			if ( !bHideHUD && ((PawnOwner.PlayerReplicationInfo == None) || !PawnOwner.PlayerReplicationInfo.bIsSpectator) )
				Canvas.SetOrigin( FMax(YL*4 + 8, 70*Scale) + 7*Scale + 6 + FaceAreaOffset, Canvas.OrgY );
		}
	}

	for (i=0; i<4; i++)
	{
		if ( ShortMessageQueue[i].Message != None )
		{
			j++;

			if ( bResChanged || (ShortMessageQueue[i].XL == 0) )
			{
				if ( ShortMessageQueue[i].Message.Default.bComplexString )
					Canvas.StrLen(ShortMessageQueue[i].Message.Static.AssembleString(
											self,
											ShortMessageQueue[i].Switch,
											ShortMessageQueue[i].RelatedPRI,
											ShortMessageQueue[i].StringMessage),
								   ShortMessageQueue[i].XL, ShortMessageQueue[i].YL);
				else
					Canvas.StrLen(ShortMessageQueue[i].StringMessage, ShortMessageQueue[i].XL, ShortMessageQueue[i].YL);
				Canvas.StrLen("TEST", XL, YL);
				ShortMessageQueue[i].numLines = 1;
				if ( ShortMessageQueue[i].YL > YL )
				{
					ShortMessageQueue[i].numLines++;
					for (k=2; k<4-i; k++)
					{
						if (ShortMessageQueue[i].YL > YL*k)
							ShortMessageQueue[i].numLines++;
					}
				}
			}

			// Keep track of the amount of lines a message overflows, to offset the next message with.
			Canvas.SetPos(6, 2 + YL * YPos);
			YPos += ShortMessageQueue[i].numLines;
			if ( YPos > 4 )
				break;

			if ( ShortMessageQueue[i].Message.Default.bComplexString )
			{
				// Use this for string messages with multiple colors.
				ShortMessageQueue[i].Message.Static.RenderComplexMessage(
					Canvas,
					ShortMessageQueue[i].XL,  YL,
					ShortMessageQueue[i].StringMessage,
					ShortMessageQueue[i].Switch,
					ShortMessageQueue[i].RelatedPRI,
					None,
					ShortMessageQueue[i].OptionalObject
					);
			}
			else
			{
				Canvas.DrawColor = ShortMessageQueue[i].Message.Default.DrawColor;
				Canvas.DrawText(ShortMessageQueue[i].StringMessage, False);
			}
		}
	}

	Canvas.DrawColor = WhiteColor;
	Canvas.SetClip(OldClipX, Canvas.ClipY);
	Canvas.SetOrigin(OldOriginX, Canvas.OrgY);

	if ( PlayerOwner.bShowScores || bForceScores )
	{
		if ( (PlayerOwner.Scoring == None) && (PlayerOwner.ScoringType != None) )
			PlayerOwner.Scoring = Spawn(PlayerOwner.ScoringType, PlayerOwner);
		if ( PlayerOwner.Scoring != None )
		{
			PlayerOwner.Scoring.OwnerHUD = self;
			PlayerOwner.Scoring.ShowScores(Canvas);
			if ( PlayerOwner.Player.Console.bTyping )
				DrawTypingPrompt(Canvas, PlayerOwner.Player.Console);
			return;
		}
	}

	YPos = FMax(YL*4 + 8, 70*Scale);
	if ( bDrawFaceArea )
		DrawTalkFace( Canvas,0, YPos );
	if (j > 0)
	{
		bDrawMessageArea = True;
		MessageFadeCount = 2;
	}
	else
		bDrawMessageArea = False;

	if ( !bHideCenterMessages )
	{
		// Master localized message control loop.
		for (i=0; i<10; i++)
		{
			if (LocalMessages[i].Message != None)
			{
				if (LocalMessages[i].Message.Default.bFadeMessage && Level.bHighDetailMode)
				{
					Canvas.Style = ERenderStyle.STY_Translucent;
					FadeValue = (LocalMessages[i].EndOfLife - Level.TimeSeconds);
					if (FadeValue > 0.0)
					{
						if ( bResChanged || (LocalMessages[i].XL == 0) )
						{
							if ( LocalMessages[i].Message.Static.GetFontSize(LocalMessages[i].Switch) == 1 )
								LocalMessages[i].StringFont = MyFonts.GetBigFont( Canvas.ClipX );
							else // ==2
								LocalMessages[i].StringFont = MyFonts.GetHugeFont( Canvas.ClipX );
							Canvas.Font = LocalMessages[i].StringFont;
							Canvas.StrLen(LocalMessages[i].StringMessage, LocalMessages[i].XL, LocalMessages[i].YL);
							LocalMessages[i].YPos = LocalMessages[i].Message.Static.GetOffset(LocalMessages[i].Switch, LocalMessages[i].YL, Canvas.ClipY);
						}
						Canvas.Font = LocalMessages[i].StringFont;
						Canvas.DrawColor = LocalMessages[i].DrawColor * (FadeValue/LocalMessages[i].LifeTime);
						Canvas.SetPos( 0.5 * (Canvas.ClipX - LocalMessages[i].XL), LocalMessages[i].YPos );
						Canvas.DrawText( LocalMessages[i].StringMessage, False );
					}
				}
				else
				{
					if ( bResChanged || (LocalMessages[i].XL == 0) )
					{
						if ( LocalMessages[i].Message.Static.GetFontSize(LocalMessages[i].Switch) == 1 )
							LocalMessages[i].StringFont = MyFonts.GetBigFont( Canvas.ClipX );
						else // == 2
							LocalMessages[i].StringFont = MyFonts.GetHugeFont( Canvas.ClipX );
						Canvas.Font = LocalMessages[i].StringFont;
						Canvas.StrLen(LocalMessages[i].StringMessage, LocalMessages[i].XL, LocalMessages[i].YL);
						LocalMessages[i].YPos = LocalMessages[i].Message.Static.GetOffset(LocalMessages[i].Switch, LocalMessages[i].YL, Canvas.ClipY);
					}
					Canvas.Font = LocalMessages[i].StringFont;
					Canvas.Style = ERenderStyle.STY_Normal;
					Canvas.DrawColor = LocalMessages[i].DrawColor;
					Canvas.SetPos( 0.5 * (Canvas.ClipX - LocalMessages[i].XL), LocalMessages[i].YPos );
					Canvas.DrawText( LocalMessages[i].StringMessage, False );
				}
			}
		}
	}
	Canvas.Style = ERenderStyle.STY_Normal;

    if ( !bWatchingTV && !bSiegeStats) //OVERRIDE
	if ( !PlayerOwner.bBehindView && (PawnOwner.Weapon != None) && (Level.LevelAction == LEVACT_None) )
	{
		Canvas.DrawColor = WhiteColor;
		PawnOwner.Weapon.PostRender(Canvas);
		if ( !PawnOwner.Weapon.bOwnsCrossHair )
			DrawCrossHair(Canvas, 0,0 );
	}

    if ( !bWatchingTV && !bSiegeStats) //OVERRIDE
	if ( (PawnOwner != Owner) && PawnOwner.bIsPlayer )
	{
		Canvas.Font = MyFonts.GetSmallFont( Canvas.ClipX );
		Canvas.bCenter = true;
		Canvas.Style = ERenderStyle.STY_Normal;
		Canvas.DrawColor = CyanColor * TutIconBlink;
		Canvas.SetPos(4, Canvas.ClipY - 96 * Scale);
		Canvas.DrawText( LiveFeed$PawnOwner.PlayerReplicationInfo.PlayerName, true );
		Canvas.bCenter = false;
		Canvas.DrawColor = WhiteColor;
		Canvas.Style = Style;
	}

	if ( bStartUpMessage && (Level.TimeSeconds < 5) )
	{
		bStartUpMessage = false;
		PlayerOwner.SetProgressTime(7);
	}
	if ( (PlayerOwner.ProgressTimeOut > Level.TimeSeconds) && !bHideCenterMessages )
		DisplayProgressMessage(Canvas);

	// Display MOTD
	if ( MOTDFadeOutTime > 0.0 )
		DrawMOTD(Canvas);

	if( !bHideHUD )
	{
		if ( !PawnOwner.PlayerReplicationInfo.bIsSpectator )
		{
			Canvas.Style = Style;

			// Draw Ammo
			if ( !bWatchingTV && !bSiegeStats) //OVERRIDE
			if ( !bHideAmmo )
				DrawAmmo(Canvas);

			// Draw Health/Armor status
			if ( !bWatchingTV  && !bSiegeStats) //OVERRIDE
			DrawStatus(Canvas);

			// Display Weapons
			if ( !bWatchingTV  && !bSiegeStats) //OVERRIDE
			if ( !bHideAllWeapons )
				DrawWeapons(Canvas);
			else if ( Level.bHighDetailMode
					&& (PawnOwner == PlayerOwner) && (PlayerOwner.Handedness == 2) )
			{
				// if weapon bar hidden and weapon hidden, draw weapon name when it changes
				if ( PawnOwner.PendingWeapon != None )
				{
					WeaponNameFade = 1.0;
					Canvas.Font = MyFonts.GetBigFont( Canvas.ClipX );
					Canvas.DrawColor = PawnOwner.PendingWeapon.NameColor;
					Canvas.SetPos(Canvas.ClipX - 360 * Scale, Canvas.ClipY - 64 * Scale);
					Canvas.DrawText(PawnOwner.PendingWeapon.ItemName, False);
				}
				else if ( (Level.NetMode == NM_Client)
						&& PawnOwner.IsA('TournamentPlayer') && (TournamentPlayer(PawnOwner).ClientPending != None) )
				{
					WeaponNameFade = 1.0;
					Canvas.Font = MyFonts.GetBigFont( Canvas.ClipX );
					Canvas.DrawColor = TournamentPlayer(PawnOwner).ClientPending.NameColor;
					Canvas.SetPos(Canvas.ClipX - 360 * Scale, Canvas.ClipY - 64 * Scale);
					Canvas.DrawText(TournamentPlayer(PawnOwner).ClientPending.ItemName, False);
				}
				else if ( (WeaponNameFade > 0) && (PawnOwner.Weapon != None) )
				{
					Canvas.Font = MyFonts.GetBigFont( Canvas.ClipX );
					Canvas.DrawColor = PawnOwner.Weapon.NameColor;
					if ( WeaponNameFade < 1 )
						Canvas.DrawColor = Canvas.DrawColor * WeaponNameFade;
					Canvas.SetPos(Canvas.ClipX - 360 * Scale, Canvas.ClipY - 64 * Scale);
					Canvas.DrawText(PawnOwner.Weapon.ItemName, False);
				}
			}

			// Display Frag count
			if ( !bWatchingTV  && !bSiegeStats) //OVERRIDE
			if ( !bAlwaysHideFrags && !bHideFrags )
				DrawFragCount(Canvas);
		}
		// Team Game Synopsis
		if ( !bWatchingTV  && !bSiegeStats) //OVERRIDE
		if ( !bHideTeamInfo )
			DrawGameSynopsis(Canvas);

		// Display Identification Info
		//if ( !bWatchingTV  && !bSiegeStats) //OVERRIDE
		if ( PawnOwner == PlayerOwner )
			DrawIdentifyInfo(Canvas);

		if ( HUDMutator != None )
			HUDMutator.PostRender(Canvas);

		if ( (PlayerOwner.GameReplicationInfo != None) && (PlayerPawn(Owner).GameReplicationInfo.RemainingTime > 0) )
		{
			if ( TimeMessageClass == None )
				TimeMessageClass = class<CriticalEventPlus>(DynamicLoadObject("Botpack.TimeMessage", class'Class'));

			if ( (PlayerOwner.GameReplicationInfo.RemainingTime <= 300)
			  && (PlayerOwner.GameReplicationInfo.RemainingTime != LastReportedTime) )
			{
				LastReportedTime = PlayerOwner.GameReplicationInfo.RemainingTime;
				if ( PlayerOwner.GameReplicationInfo.RemainingTime <= 30 )
				{
					bTimeValid = ( bTimeValid || (PlayerOwner.GameReplicationInfo.RemainingTime > 0) );
					if ( PlayerOwner.GameReplicationInfo.RemainingTime == 30 )
						TellTime(5);
					else if ( bTimeValid && PlayerOwner.GameReplicationInfo.RemainingTime <= 10 )
						TellTime(16 - PlayerOwner.GameReplicationInfo.RemainingTime);
				}
				else if ( PlayerOwner.GameReplicationInfo.RemainingTime % 60 == 0 )
				{
					M = PlayerOwner.GameReplicationInfo.RemainingTime/60;
					TellTime(5 - M);
				}
			}
		}
	}
	if ( PlayerOwner.Player.Console.bTyping )
		DrawTypingPrompt(Canvas, PlayerOwner.Player.Console);

	if ( PlayerOwner.bBadConnectionAlert && (PlayerOwner.Level.TimeSeconds > 5) )
	{
		Canvas.Style = ERenderStyle.STY_Normal;
		Canvas.DrawColor = WhiteColor;
		Canvas.SetPos(Canvas.ClipX - (64*Scale), Canvas.ClipY / 2);
		Canvas.DrawIcon(texture'DisconnectWarn', Scale);
	}

	if (bSiegeStats)
		SiegeStats(Canvas);
	else if (bTeamRU)
		TeamRU(Canvas);
}

///////////////////////////////////////////
/////////MORE THERMAL VISOR STUFF//////////
///////////////////////////////////////////

simulated function HeatUp(Actor A, int i, canvas Canvas)
{

	if (HeatObjs[i].SavedHeat == None)
	{
		HeatObjs[i].HeatOwner = A;
		
		if (A.IsA('Bot'))
		{
		
			if (Bot(A).playerreplicationinfo.Team == 0)
			{
			Canvas.DrawColor.R=255;
			Canvas.DrawColor.G=0;
			Canvas.DrawColor.B=0;
			HeatObjs[i].SavedHeat = Spawn(Class'sgHeatRed', A,, A.Location, A.Rotation);
			}
			else if (Bot(A).playerreplicationinfo.Team == 1)
			{
			Canvas.DrawColor.R=0;
			Canvas.DrawColor.G=0;
			Canvas.DrawColor.B=255;
			HeatObjs[i].SavedHeat = Spawn(Class'sgHeatBlue', A,, A.Location, A.Rotation);
			}
			else
			{
			}
			
		}
		
		if (A.IsA('PlayerPawn'))
		{
		
			if (PlayerPawn(A).playerreplicationinfo.Team == 0)
			{
			Canvas.DrawColor.R=255;
			Canvas.DrawColor.G=0;
			Canvas.DrawColor.B=0;
			HeatObjs[i].SavedHeat = Spawn(Class'sgHeatRed', A,, A.Location, A.Rotation);
			}
			else if (PlayerPawn(A).playerreplicationinfo.Team == 1)
			{
			Canvas.DrawColor.R=0;
			Canvas.DrawColor.G=0;
			Canvas.DrawColor.B=255;
			HeatObjs[i].SavedHeat = Spawn(Class'sgHeatBlue', A,, A.Location, A.Rotation);
			}
			else
			{
			}
			
		}
	}
	
	if (A.DrawScale == A.default.DrawScale)
	{
	HeatObjs[i].SavedHeat.Mesh = HeatObjs[i].HeatOwner.Mesh;
	HeatObjs[i].SavedHeat.AnimFrame = HeatObjs[i].HeatOwner.AnimFrame;
	HeatObjs[i].SavedHeat.AnimSequence = HeatObjs[i].HeatOwner.AnimSequence;
	HeatObjs[i].SavedHeat.PrePivot = HeatObjs[i].HeatOwner.PrePivot;
	HeatObjs[i].SavedHeat.SetLocation(HeatObjs[i].HeatOwner.Location);
	HeatObjs[i].SavedHeat.SetRotation(HeatObjs[i].HeatOwner.Rotation);
	}
	else
	{
	HeatObjs[i].SavedHeat.Mesh = LodMesh'UnrealShare.Candl2';
	HeatObjs[i].SavedHeat.SetLocation(HeatObjs[i].HeatOwner.Location);
	HeatObjs[i].SavedHeat.SetRotation(HeatObjs[i].HeatOwner.Rotation);
	}
	
	Canvas.DrawActor(HeatObjs[i].SavedHeat, false, bSeeAllHeat);
	globalint++;
}

exec function ToggleVisor()
{
local int i;

if (localPlayer.FindInventoryType(HeatInventoryClass) != None)
	{
	if (!bVisorDeActivated)
		{
			bVisorDeActivated=True;
			Owner.PlaySound(Sound'UnrealShare.Menu.side1b', SLOT_Misc, Pawn(Owner).SoundDampening*2.5);
			Pawn(Owner).ClientMessage("Thermal Visor Deactivated");
			
			for (i=0; i<32; i++)
			HeatObjs[i].SavedHeat.Destroy();
		}
	else
		{
			bVisorDeActivated=False;
			Owner.PlaySound(Sound'UnrealShare.Menu.side1b', SLOT_Misc, Pawn(Owner).SoundDampening*2.5);
			Pawn(Owner).ClientMessage("Thermal Visor Activated");
		}
	}
}


//========================================
//Siege stuff.

simulated function bool TraceIdentify(canvas Canvas)
{
	local Actor         other;
	local vector        hitLocation,
                        hitNormal,
                        startTrace,
                        endTrace;

	startTrace = Owner.Location;
	startTrace.Z += PawnOwner.BaseEyeHeight;
	endTrace = startTrace + vector(PawnOwner.ViewRotation) * 10000.0;
	other = Trace(hitLocation, hitNormal, endTrace, startTrace, true);

	if ( Pawn(other) != None && !other.bHidden )
	{
		IdentifyTarget = Pawn(other).PlayerReplicationInfo;
		IdentifyPawn = Pawn(other);
		IdentifyFadeTime = 3.0;
	}

	if ( IdentifyFadeTime == 0 || IdentifyPawn == None ||
      (IdentifyTarget != None && IdentifyTarget.bFeigningDeath) )
		return false;

	return true;
}

simulated function SetIDColor(canvas Canvas, int type)
{
    local int team;

    if ( sgBuilding(IdentifyPawn) != None )
        team = sgBuilding(IdentifyPawn).Team;
    else if ( IdentifyTarget != None )
        team = IdentifyTarget.Team;

    if ( type == 0 )
		Canvas.DrawColor = AltTeamColor[team] * 0.333 *
          IdentifyFadeTime;
	else
    	Canvas.DrawColor = TeamColor[team] * 0.333 *
          IdentifyFadeTime;
}

simulated function DrawTwoColorID(canvas Canvas, string TitleString,
  string ValueString, int YStart)
{
	local float XL, YL, XOffset, X1;

	Canvas.Style = ERenderStyle.STY_Masked;
	Canvas.StrLen(TitleString$": ", XL, YL);
	X1 = XL;
	Canvas.StrLen(ValueString, XL, YL);
	XOffset = Canvas.ClipX/2 - (X1+XL)/2;
	Canvas.SetPos(XOffset, YStart);
	SetIDColor(Canvas, 0);
	XOffset += X1;
	Canvas.DrawText(TitleString);
	Canvas.SetPos(XOffset, YStart);
	SetIDColor(Canvas, 1);
	Canvas.DrawText(ValueString);
	Canvas.DrawColor = WhiteColor;
	Canvas.Font = MyFonts.GetSmallFont(Canvas.ClipX);
}

//====================================================================================================
// HISTORY: The DrawIdentifyInfo() function use to SPAM the log file on clients with Acessed None
// Errors. Badger made some bad refrences to the building owner's PlayerReplicationInfo when the owner
// did not exist. Example: The core does not have an owner so when the player looks at the core the 
// acessed none errors come cranking same could happen if a player left and all the ownership of the 
// buildings they created were lost so those building have no owner so they behave like the core would
//====================================================================================================

simulated function bool DrawIdentifyInfo(canvas Canvas)
{
	local sgTeleporter tel;
	local string s;
	local float l;

	local bool bSiegeStats;

	local PlayerReplicationInfo BuilderPRI;
	local sgBuilding Building;
	local Pawn ViewedBuilder;
	
	local float NextLVCost;
	local int BasicUpgradeCost;
	

	// Here were making sure that the object HAS AN OWNER before we ask the owner what it's PlayerReplicationInfo is.
	// Thus getting rid of all the accesed none spam in the error log
	if ( IdentifyPawn != None && IdentifyPawn.IsA('sgBuilding') && IdentifyPawn.Owner != None )
		BuilderPRI = Pawn(sgBuilding(IdentifyPawn).Owner).PlayerReplicationInfo;
	else
		BuilderPRI = None;

	if (Owner.IsA('PlayerPawn'))
		{
			if ( PlayerPawn(Owner) != None && sgPRI(PlayerPawn(Owner).PlayerReplicationInfo) != None )
				l = sgPRI(PlayerPawn(Owner).PlayerReplicationInfo).iStatus;
			if (int(l/2)*2 != l)
				bSiegeStats = true;
		}
	else
		bSiegeStats = False;

	if (bSiegeStats)
		return false;

	if ( !TraceIdentify(Canvas) )
		return false;

if( sgBuilding(IdentifyPawn) != None )
	{
		// We Are Looking at a building

		if ( IdentifyPawn.bDeleteMe )
			return false;

		s = string(sgBuilding(IdentifyPawn).Energy / sgBuilding(IdentifyPawn).MaxEnergy * 100);

		s = left(s, InStr(s, ".")+nHUDDecPlaces+1);
		if (right(s,1)==".")
			s = left(s,len(s)-1);

		Canvas.Font = MyFonts.GetBigFont(Canvas.ClipX);
		DrawTwoColorID(Canvas,sgBuilding(IdentifyPawn).BuildingName, s,Canvas.ClipY - 216 * Scale);

		Canvas.Font = MyFonts.GetBigFont(Canvas.ClipX);

		if( sgBuilding(IdentifyPawn).bNoUpgrade == True )
		{
		 s = "N/A";
		}
		else
		{
		 s = string(sgBuilding(IdentifyPawn).Grade);
		 s = left(s, InStr(s, ".")+nHUDDecPlaces+1);
                 if (right(s,1)==".")
                 {
                         s = left(s,len(s)-1);
                 }
                 
                 if( sgBuilding(IdentifyPawn).Grade != 5 &&
                     ( sgBuilding(IdentifyPawn).Team == PlayerPawn(Owner).PlayerReplicationInfo.Team || Spectator(Owner) != None ))
                 {
                  NextLVCost = sgBuilding(IdentifyPawn).Grade - int(sgBuilding(IdentifyPawn).Grade);
                  NextLVCost = 1 - NextLVCost;
                  if( NextLVCost == 0 )
                  {
                   NextLVCost=1;
                  }
                  
                  if( WildcardsForceField(IdentifyPawn) != None )
                  {
                   BasicUpgradeCost=class'WildcardsForceField'.default.UpgradeCost;
                  }
                  else
                  {
                   BasicUpgradeCost=sgBuilding(IdentifyPawn).UpgradeCost;
                  }
                  log(NextLVCost);
                  
                  NextLVCost *= ( BasicUpgradeCost * (int(sgBuilding(IdentifyPawn).Grade)+1));
                  s = s$"  [NextLV :"@Left( string(NextLVCost) ,InStr( string(NextLVCost), "."))$"]";
                 }
		}
		

		DrawTwoColorID(Canvas,"Level",s,Canvas.ClipY - 176 * Scale);
	}
else 
	{
		// We are looking at a Player
		if ( IdentifyTarget != None )
			if ( IdentifyTarget.PlayerName != "" )
				{
					Canvas.Font = MyFonts.GetBigFont(Canvas.ClipX);
					DrawTwoColorID(Canvas,IdentifyTarget.PlayerName,string(IdentifyPawn.Health)
					,Canvas.ClipY - 256 * Scale);
				}
	}

if ( BuilderPRI != None )
	{
		Canvas.Font = MyFonts.GetBigFont(Canvas.ClipX);
		DrawTwoColorID(Canvas,"Built by",
		BuilderPRI.PlayerName,
		Canvas.ClipY - 136 * Scale);
	}

}

simulated function DrawTextCentered(Canvas canvas, coerce string text)
{
    local float width, height;
    canvas.TextSize(text, width, height);
    canvas.SetPos(Canvas.CurX - width/2, Canvas.CurY);
    canvas.DrawText(text, false);
}

simulated function DrawGameSynopsis(canvas Canvas)
{
    local TournamentGameReplicationInfo
                        GRI;
    local float         XL,XL2,
                        YL,YL2,
                        XOffset,l,
                        YOffset;
    local int           i,
                        X;
    local string        text;
    local sgConstructor gun;
    local class<sgBuilding>
                        buildType;
    local Inventory     inv;
	
	// Percents
    local float fuelPercent, DashPercent;
	
    local sgPRI		PRI;
    local Jetpack       pack;
    local string 	s;
    local color 	cCol;
    local bool		bSiegeStats;

    local sgBaseCore sgB;
	local WildcardsOrbs Orb, OrbLocked;
	local int OrbX;
	local int OrbSpace;
	local WildcardsOrbs WOR;
	
	// HUD Item Slot Vars
	local float HudItemSlotY;

	if (Owner.IsA('PlayerPawn') && sgPRI(PlayerPawn(Owner).PlayerReplicationInfo) != None )
	{
		l = sgPRI(PlayerPawn(Owner).PlayerReplicationInfo).iStatus;
		if (int(l/2)*2 != l) bSiegeStats = true;
	}
	else
		bSiegeStats=false;
	if (bSiegeStats) return;

	PRI = sgPRI(PawnOwner.PlayerReplicationInfo);
	
	if( PRI != None )
	{
	 sgB = PRI.Cores[PRI.Team];
	}
	GRI = TournamentGameReplicationInfo(PlayerOwner.GameReplicationInfo);
	if ( GRI != None )
		for ( i = 0; i < 4; i++ )
			DrawTeam(Canvas, GRI.Teams[i]);

	if ( PawnOwner.PlayerReplicationInfo == None ||
      PawnOwner.PlayerReplicationInfo.bIsSpectator )
		return;

	Canvas.Font = MyFonts.GetBigFont(Canvas.ClipX);
	Canvas.DrawColor = WhiteColor;

    Canvas.TextSize("RU:", XL, YL);
    Canvas.TextSize("BaseCore:", XL2, YL2);

    if ( bHideAllWeapons )
	    YOffset = Canvas.ClipY - YL*3;
	else if ( HudScale * WeaponScale * Canvas.ClipX <= Canvas.ClipX - 256 * Scale )
		YOffset = Canvas.ClipY - 64*Scale - YL*3;
	else
		YOffset = Canvas.ClipY - 128*Scale - YL*3;

    Canvas.SetPos(0, YOffset);
    Canvas.Style = ERenderStyle.STY_Masked;
    Canvas.DrawText("RU:", false);

     if (sgB != None)
     {
     	Canvas.SetPos(0, YOffset+YL);
     	Canvas.DrawText("BaseCore:", false);

		Orb = sgPRI(Pawn(Owner).PlayerReplicationInfo).Orb;

		if ( Orb != None )
			{		
				Orb = sgPRI(Pawn(Owner).PlayerReplicationInfo).Orb;
			}

		foreach AllActors( class'WildcardsOrbs',WOR)
			{
				Orb = WOR;
			}

		// The log is an EPIC fail so I want some facts NOW!!
		OrbX = 384;
		OrbSpace = 24;
		Canvas.SetPos(0,YOffset-OrbX);

		if ( Orb != None )
			{
     			Canvas.DrawText("Orb Debug Information", false);
				OrbX -= OrbSpace; Canvas.SetPos(0,YOffset-OrbX);
     			Canvas.DrawText("Type:"@Orb.OrbName, false);
				OrbX -= OrbSpace; Canvas.SetPos(0,YOffset-OrbX);
     			Canvas.DrawText("Owner:"@Orb.Owner, false);
				OrbX -= OrbSpace; Canvas.SetPos(0,YOffset-OrbX);
     			Canvas.DrawText("Location (server):"@Orb.ServerLocation, false);
				OrbX -= OrbSpace; Canvas.SetPos(0,YOffset-OrbX);
     			Canvas.DrawText("Location (client):"@Orb.ClientLocation, false);
				OrbX -= OrbSpace; Canvas.SetPos(0,YOffset-OrbX);
     			Canvas.DrawText("OrbHolder (server):"@Orb.ServerOrbHolder, false);
				OrbX -= OrbSpace; Canvas.SetPos(0,YOffset-OrbX);
     			Canvas.DrawText("OrbHolder (client):"@Orb.ClientOrbHolder, false);
				OrbX -= OrbSpace; Canvas.SetPos(0,YOffset-OrbX);
     			Canvas.DrawText("Physics (server):"@Orb.ServerPhysics, false);
				OrbX -= OrbSpace; Canvas.SetPos(0,YOffset-OrbX);
     			Canvas.DrawText("Physics (client):"@Orb.ClientPhysics, false);
			}

     }

	 
	 
    if ( sgPRI(PawnOwner.PlayerReplicationInfo) != None )
    {

        Canvas.DrawColor = GreyColor;
        Canvas.SetPos(XL, YOffset);
        Canvas.DrawText(""@int(PRI.RU)@"/"@
          int(sgPRI(PawnOwner.PlayerReplicationInfo).MaxRU), false);

	 if (sgB != none)
	 {
        	Canvas.SetPos(XL2, YOffset+YL);

		s = string(sgB.Energy / sgB.MaxEnergy * 100);
		s = left(s, InStr(s, ".")+nHUDDecPlaces+1);
		if (right(s,1)==".")
			s = left(s,len(s)-1);

		fuelPercent = float(s);
		if (fuelPercent > sCore)
			RedColour=256;
		else if (fuelPercent < sCore)
			RedColour = 0;

		if (RedColour<128)
		{
			RedColour+=4;
			cCol.R=128+(128-RedColour);
			cCol.G=RedColour;
			cCol.B=RedColour;
		}
		else if (RedColour>128)
		{
			RedColour-=4;
			cCol.R=RedColour;
			cCol.G=RedColour;
			cCol.B=RedColour;

		}
		else
			cCol=GreyColor;
		
        	Canvas.DrawColor = cCol;
		sCore = fuelPercent;
                Canvas.DrawText(""@s, false);
	 }


        Canvas.SetPos(XL, YOffset+20);
    }



    gun = sgConstructor(PawnOwner.Weapon);
    if ( gun != None )
    {
        text = gun.GetOptionName();

	if ( gun.IsFunction() )
        {
	    Canvas.DrawColor = WhiteColor;
            X = Canvas.ClipX - 384 * Scale;
            Canvas.TextSize(text, XL, YL);
            Canvas.SetPos(X + XL/4, YOffset);
            Canvas.DrawText(text, false);
        }
        else if ( gun.IsCategory() )
        {           
            X = Canvas.ClipX - 384 * Scale;
			
            Canvas.DrawColor = WhiteColor;
            Canvas.TextSize("Select", XL, YL);
            Canvas.SetPos(X, YOffset);
            Canvas.DrawText(""@text, false);

            Canvas.DrawColor = GreyColor;
            Canvas.TextSize("Category", XL, YL);
            Canvas.SetPos(X + XL/4, YOffset + YL);
            Canvas.DrawText("Category", false);
        }
        else if ( gun.IsBuilding() )
        {
            Canvas.DrawColor = WhiteColor;
            X = Canvas.ClipX - 384 * Scale;
            Canvas.TextSize(text, XL, YL);
            Canvas.SetPos(X - XL/4, YOffset);
            Canvas.DrawText(text, false);

            buildType = gun.GetBuildType();
            if ( buildType != None )
                text = "Cost:"@buildType.default.BuildCost;
            else
                text = "Cost:";
            Canvas.DrawColor = GreyColor;
            Canvas.TextSize(text, XL, YL);
            Canvas.SetPos(X, YOffset + YL);
            Canvas.DrawText(text, false);
        }

    }
	
	///////////////////////////////////////////////////////////////	
	// HUD ITEM SLOTS /////////////////////////////////////////////
	///////////////////////////////////////////////////////////////
	
	HudItemSlotY = HudItemSlotOriginY;
	
	//////////////////////// HUD ITEM /////////////////////////////
	//////////////////////// JETPACK / Super JETPACK //////////////

    for ( inv = PlayerOwner.Inventory; inv != None; inv = inv.Inventory )
		{
			if ( JetPack(inv) != None )
				{
					pack = Jetpack(inv);
					Canvas.DrawColor = GreyColor;
					fuelPercent = FClamp(Jetpack(inv).Fuel / Jetpack(inv).MaxFuel,0, 1);
					
					if ( pack.MaxFuel == 999999999 )
						{
							Canvas.SetPos(HudItemSlotOriginX,YOffset - HudItemSlotY);	
							Canvas.DrawTile(texture'IconSuperJetpackFuelBar', 128 * fuelPercent, 32, 0, 0, 128 * fuelPercent, 32);
							Canvas.SetPos(HudItemSlotOriginX,YOffset - HudItemSlotY);	
							Canvas.DrawTile(texture'IconSuperJetpackFrame', 128, 32, 0, 0, 128, 32);
						}
					else
						{
							Canvas.SetPos(HudItemSlotOriginX,YOffset - HudItemSlotY);	
							Canvas.DrawTile(texture'IconJetpackFuelBar', 128 * fuelPercent, 32, 0, 0, 128 * fuelPercent, 32);
							Canvas.SetPos(HudItemSlotOriginX,YOffset - HudItemSlotY);	
							Canvas.DrawTile(texture'IconJetpackFrame', 128, 32, 0, 0, 128, 32);
						}
					HudItemSlotY += HudItemSlotSpace;
				}

	//////////////////////// HUD ITEM /////////////////////////////
	//////////////////////// SPEED ////////////////////////////////

			if ( sgSpeed(inv) != None && sgSpeed(inv).bActivated )
				{
					Canvas.DrawColor = GreyColor;
					Canvas.SetPos(HudItemSlotOriginX,YOffset - HudItemSlotY);	
					//Canvas.SetPos(4, YOffset - YL*2 + 26);
					Canvas.DrawTile(texture'IconSpeed', 128, 32, 0, 0, 128, 32);
					HudItemSlotY += HudItemSlotSpace;
				}
		}
		
	//////////////////////// HUD ITEM //////////////////////////////////////
	//////////////////////// DASH PAD METER ////////////////////////////////
	if ( DashPlayerInstance != None )
		{
			OrbX = 384;
			OrbSpace = 24;
			Canvas.SetPos(HudItemSlotOriginX,YOffset - HudItemSlotY);			
			Canvas.DrawColor = NewColor(128,128,128);
			DashPercent = FClamp(DashPlayerInstance.ClientLifeSpan / DashPlayerInstance.MaxCharge,0, 1);
			Canvas.DrawTile(texture'IconDashPadChargeBar', 128 * DashPercent, 32, 0, 0, 128 * DashPercent, 32);	
			Canvas.SetPos(HudItemSlotOriginX,YOffset - HudItemSlotY);			
			Canvas.DrawTile(texture'IconDashPadFrame', 128, 32, 0, 0, 128, 32);
			HudItemSlotY += HudItemSlotSpace;
		}
		
		/*
		log("SiegeGI(Level.Game).MonsterMadness"@SiegeGI(Level.Game).MonsterMadness);
		log("SiegeGI(Level.Game).MonsterMadness"@SiegeGI(Level.Game).MonstersLeft);
		if ( SiegeGI(Level.Game).MonsterMadness == true )
			{
				XL = 20;
				YL = 384;
				Canvas.SetPos(XL,YL);
				Canvas.DrawColor = NewColor(128,128,128);
				
				Canvas.DrawText("Monster Left:"@SiegeGI(Level.Game).MonstersLeft, false);
			}
	*/
}


		

//=====================================================================
// Deal with a localized message.
// Modified By WILDCARD
// Contains a hack to FORCE it to allow non-hardcodded messages!

simulated function LocalizedMessage( class<LocalMessage> Message, optional int Switch, optional PlayerReplicationInfo RelatedPRI_1, optional PlayerReplicationInfo RelatedPRI_2, optional Object OptionalObject, optional String CriticalString )
{
	local int i;

	if ( ClassIsChildOf( Message, class'PickupMessagePlus' ) )
		PickupTime = Level.TimeSeconds;

	if ( !Message.Default.bIsSpecial )
	{
		if ( ClassIsChildOf(Message, class'SayMessagePlus') || 
						 ClassIsChildOf(Message, class'TeamSayMessagePlus') )
		{
			FaceTexture = RelatedPRI_1.TalkTexture;
			if ( FaceTexture != None )
				FaceTime = Level.TimeSeconds + 3;
		} 
		// Find an empty slot.
		for (i=0; i<4; i++)
		{
			if ( ShortMessageQueue[i].Message == None )
			{
				ShortMessageQueue[i].Message = Message;
				ShortMessageQueue[i].Switch = Switch;
				ShortMessageQueue[i].RelatedPRI = RelatedPRI_1;
				ShortMessageQueue[i].OptionalObject = OptionalObject;
				ShortMessageQueue[i].EndOfLife = Message.Default.Lifetime + Level.TimeSeconds;
				if ( Message.Default.bComplexString )
					ShortMessageQueue[i].StringMessage = CriticalString;
				else
					ShortMessageQueue[i].StringMessage = Message.Static.
					GetString(Switch,RelatedPRI_1, RelatedPRI_2, OptionalObject);
				return;
			}

		}
		// No empty slots.  Force a message out.
		for (i=0; i<3; i++)
			CopyMessage(ShortMessageQueue[i], ShortMessageQueue[i+1]);

		ShortMessageQueue[3].Message = Message;
		ShortMessageQueue[3].Switch = Switch;
		ShortMessageQueue[3].RelatedPRI = RelatedPRI_1;
		ShortMessageQueue[3].OptionalObject = OptionalObject;
		ShortMessageQueue[3].EndOfLife = Message.Default.Lifetime + Level.TimeSeconds;
		if ( Message.Default.bComplexString )
			ShortMessageQueue[3].StringMessage = CriticalString;
		else
			ShortMessageQueue[3].StringMessage = Message.Static.GetString(Switch, RelatedPRI_1, RelatedPRI_2, OptionalObject);
		return;
	} 
	else 
	{
		if ( CriticalString == "" )
			CriticalString = Message.Static.GetString(Switch, RelatedPRI_1, RelatedPRI_2, OptionalObject);
		if ( Message.Default.bIsUnique )
		{
			for (i=0; i<10; i++)
			{
				if (LocalMessages[i].Message != None)
				{
					if ((LocalMessages[i].Message == Message) 
						|| (LocalMessages[i].Message.Static.GetOffset(LocalMessages[i].Switch, 24, 640) 
								== Message.Static.GetOffset(Switch, 24, 640)) ) 
					{
						LocalMessages[i].Message = Message;
						LocalMessages[i].Switch = Switch;
						LocalMessages[i].RelatedPRI = RelatedPRI_1;
						LocalMessages[i].OptionalObject = OptionalObject;
						LocalMessages[i].LifeTime = Message.Default.Lifetime;
						LocalMessages[i].EndOfLife = Message.Default.Lifetime + Level.TimeSeconds;
						LocalMessages[i].StringMessage = CriticalString;
						
						// The Color Hack! :)
						if ( UseSpecialColor == true )
							{
								LocalMessages[i].DrawColor = SpecialMessageColor;
								//LocalMessages[i].DrawColor.R = 255;
								log("SGX: This is a Siege Message Class");
							}
						else
							{
								LocalMessages[i].DrawColor = Message.Static.GetColor(Switch, RelatedPRI_1, RelatedPRI_2);
								log("SGX: This NOT Siege Message Class");
							}

						LocalMessages[i].XL = 0;
						return;
					}
				}
			}
		}
		for (i=0; i<10; i++)
		{
			if (LocalMessages[i].Message == None)
			{
				LocalMessages[i].Message = Message;
				LocalMessages[i].Switch = Switch;
				LocalMessages[i].RelatedPRI = RelatedPRI_1;
				LocalMessages[i].OptionalObject = OptionalObject;
				LocalMessages[i].EndOfLife = Message.Default.Lifetime + Level.TimeSeconds;
				LocalMessages[i].StringMessage = CriticalString;
				LocalMessages[i].DrawColor = Message.Static.GetColor(Switch, RelatedPRI_1, RelatedPRI_2);				
				LocalMessages[i].LifeTime = Message.Default.Lifetime;
				LocalMessages[i].XL = 0;
				return;
			}
		}

		// No empty slots.  Force a message out.
		for (i=0; i<9; i++)
			CopyMessage(LocalMessages[i],LocalMessages[i+1]);

		LocalMessages[9].Message = Message;
		LocalMessages[9].Switch = Switch;
		LocalMessages[9].RelatedPRI = RelatedPRI_1;
		LocalMessages[9].OptionalObject = OptionalObject;
		LocalMessages[9].EndOfLife = Message.Default.Lifetime + Level.TimeSeconds;
		LocalMessages[9].StringMessage = CriticalString;
		LocalMessages[9].DrawColor = Message.Static.GetColor(Switch, RelatedPRI_1, RelatedPRI_2);				
		LocalMessages[9].LifeTime = Message.Default.Lifetime;
		LocalMessages[9].XL = 0;
		return;
	}
}

// ANOTHER Entry point for string messages.
simulated function SpecialMessage( PlayerReplicationInfo PRI, coerce string Msg, color SMC )
{
	local int i;
	local Class<LocalMessage> MessageClass;

	SpecialMessageColor = SMC;
	MessageClass = class'CriticalEventPlus';
	LocalizedMessage(MessageClass, 0, None, None, None, Msg );
	return;
/*
	for (i=0; i<4; i++)
	{
		if ( ShortMessageQueue[i].Message == None )
		{
			// Add the message here.
			ShortMessageQueue[i].Message = MessageClass;
			ShortMessageQueue[i].Switch = 0;
			ShortMessageQueue[i].RelatedPRI = PRI;
			ShortMessageQueue[i].OptionalObject = None;
			ShortMessageQueue[i].EndOfLife = MessageClass.Default.Lifetime + Level.TimeSeconds;
			if ( MessageClass.Default.bComplexString )
				ShortMessageQueue[i].StringMessage = Msg;
			else
				ShortMessageQueue[i].StringMessage = MessageClass.Static.AssembleString(self,0,PRI,Msg);
			return;
		}
	}

	// No empty slots.  Force a message out.
	for (i=0; i<3; i++)
		CopyMessage(ShortMessageQueue[i], ShortMessageQueue[i+1]);

	ShortMessageQueue[3].Message = MessageClass;
	ShortMessageQueue[3].Switch = 0;
	ShortMessageQueue[3].RelatedPRI = PRI;
	ShortMessageQueue[3].OptionalObject = None;
	ShortMessageQueue[3].EndOfLife = MessageClass.Default.Lifetime + Level.TimeSeconds;
	if ( MessageClass.Default.bComplexString )
		ShortMessageQueue[3].StringMessage = Msg;
	else
		ShortMessageQueue[3].StringMessage = MessageClass.Static.AssembleString(self,0,PRI,Msg);
*/
}

// Entry point for string messages.
simulated function Message( PlayerReplicationInfo PRI, coerce string Msg, name MsgType )
{
	local int i;
	local Class<LocalMessage> MessageClass;

	switch (MsgType)
	{
		case 'Say':
			MessageClass = class'SayMessagePlus';
			break;
		case 'TeamSay':
			MessageClass = class'TeamSayMessagePlus';
			break;

		// Another step to defeat hardcoding
		case 'Custom':
			MessageClass = class'CriticalStringPlus';
			UseSpecialColor = true;
			LocalizedMessage( MessageClass, 0, None, None, None, Msg );
			return;

		case 'CriticalEvent':
			MessageClass = class'CriticalStringPlus';
			LocalizedMessage( MessageClass, 0, None, None, None, Msg );
			return;

		case 'DeathMessage':
			//MessageClass = class'RedSayMessagePlus';
			MessageClass = class'StringMessagePlus';
			break;
		case 'Pickup':
			PickupTime = Level.TimeSeconds;
		default:
			MessageClass = class'StringMessagePlus';
			break;
	}

	if ( ClassIsChildOf(MessageClass, class'SayMessagePlus') || 
				     ClassIsChildOf(MessageClass, class'TeamSayMessagePlus') )
	{
		FaceTexture = PRI.TalkTexture;
		if ( FaceTexture != None )
			FaceTime = Level.TimeSeconds + 3;
		if ( Msg == "" )
			return;
	} 
	for (i=0; i<4; i++)
	{
		if ( ShortMessageQueue[i].Message == None )
		{
			// Add the message here.
			ShortMessageQueue[i].Message = MessageClass;
			ShortMessageQueue[i].Switch = 0;
			ShortMessageQueue[i].RelatedPRI = PRI;
			ShortMessageQueue[i].OptionalObject = None;
			ShortMessageQueue[i].EndOfLife = MessageClass.Default.Lifetime + Level.TimeSeconds;
			if ( MessageClass.Default.bComplexString )
				ShortMessageQueue[i].StringMessage = Msg;
			else
				ShortMessageQueue[i].StringMessage = MessageClass.Static.AssembleString(self,0,PRI,Msg);
			return;
		}
	}

	// No empty slots.  Force a message out.
	for (i=0; i<3; i++)
		CopyMessage(ShortMessageQueue[i], ShortMessageQueue[i+1]);

	ShortMessageQueue[3].Message = MessageClass;
	ShortMessageQueue[3].Switch = 0;
	ShortMessageQueue[3].RelatedPRI = PRI;
	ShortMessageQueue[3].OptionalObject = None;
	ShortMessageQueue[3].EndOfLife = MessageClass.Default.Lifetime + Level.TimeSeconds;
	if ( MessageClass.Default.bComplexString )
		ShortMessageQueue[3].StringMessage = Msg;
	else
		ShortMessageQueue[3].StringMessage = MessageClass.Static.AssembleString(self,0,PRI,Msg);
}

simulated function Color NewColor( byte r, byte g, byte b )
{
	local Color CreatedColor;
	CreatedColor.r = r;
	CreatedColor.g = g;
	CreatedColor.b = b;
	return CreatedColor;
}

defaultproperties
{
    GreyColor=(R=128,G=128,B=128,A=0),
    RedColour=128
    TheWhiteStuff=(R=255,G=255,B=255,A=0),
    nHUDDecPlaces=1
    NumBuildings=41
    sgBuildings(0)="0Container"
    sgBuildings(1)="0Super Container"
    sgBuildings(2)="0Booster"
    sgBuildings(3)="0Super Booster"
    sgBuildings(4)="0Super Protector"
    sgBuildings(5)="0Poison Guardian"
    sgBuildings(6)="0Platform"
    sgBuildings(7)="0Motion Alarm"
    sgBuildings(8)="0Nuke Siren"
    sgBuildings(9)="0Mini Shield"
    sgBuildings(10)="0Forcefield"
    sgBuildings(11)="1Supplier"
    sgBuildings(12)="1Super Supplier"
    sgBuildings(13)="1Super Health Pod"
    sgBuildings(14)="1Shrinker"
    sgBuildings(15)="2Shieldbelt"
    sgBuildings(16)="2Jump Boots"
    sgBuildings(17)="2Super Jump Boots"
    sgBuildings(18)="2Speed"
    sgBuildings(19)="2Invisibility"
    sgBuildings(20)="2Damage Amplifier"
    sgBuildings(21)="3Hyper Leecher"
    sgBuildings(22)="3ASMD Pulse Rifle"
    sgBuildings(23)="3Flame Thrower"
    sgBuildings(24)="3Warhead"
    sgBuildings(25)="3Invincible Warhead"
    sgBuildings(26)="4Teleporter"
    sgBuildings(27)="4Tele Network"
    sgBuildings(28)="4Translocator"
    sgBuildings(29)="5Mine"
    sgBuildings(30)="5Super Mine"
    sgBuildings(31)="5Rocket Cannon"
    sgBuildings(32)="5Bio Bomb"
    sgBuildings(33)="5Mortor Bomb"
    sgBuildings(34)="5EMP Bomb"
    sgBuildings(35)="5Neutron Bomb"
    sgBuildings(36)="6Jetpack"
    sgBuildings(37)="6Super Jetpack"
    sgBuildings(38)="6Toxin Suit"
    sgBuildings(39)="6Asbestos Suit"
    sgBuildings(40)="6Scuba Gear"
    sgCategory(0)="Fortification"
    sgCategory(1)="Supply"
    sgCategory(2)="Special Items"
    sgCategory(3)="Weapons"
    sgCategory(4)="Teleportation"
    sgCategory(5)="Explosives"
    sgCategory(6)="Suits"
    sgRanks(0)="Top BaseCore attacker"
    sgRanks(1)="Top BaseCore defender"
    sgRanks(2)="Top attacker"
    sgRanks(3)="Top player killer"
    sgRanks(4)="Top builder"
    sgRanks(5)="Top Warhead maker"
    sgRanks(6)="Top Warhead defender"
    sgRanks(7)="Top team player"
    sgRankDesc(0)="The player who caused most BaseCore damage"
    sgRankDesc(1)="The player who repaired the BaseCore the most"
    sgRankDesc(2)="The player who caused the most building damage"
    sgRankDesc(3)="The player who killed more than any other"
    sgRankDesc(4)="The player who built the greatest number of buildings"
    sgRankDesc(5)="The player who built the greatest number of warheads"
    sgRankDesc(6)="The player who killed the greatest number of warheads"
    sgRankDesc(7)="The player who repaired and upgraded the most"
    TeamIcons(0)=Texture'SiegeUltimateRC7UB01Media.U.Icons.IconCoreRed'
    TeamIcons(1)=Texture'SiegeUltimateRC7UB01Media.U.Icons.IconCoreBlue'
    TeamIcons(2)=Texture'SiegeUltimateRC7UB01Media.U.Icons.IconCoreGreen'
    TeamIcons(3)=Texture'SiegeUltimateRC7UB01Media.U.Icons.IconCoreYellow'
    HudItemSlotOriginX=4.00
    HudItemSlotOriginY=36.00
    HudItemSlotSpace=36.00
    bSeeAllHeat=True
    bSeeBehindWalls=True
    AffectedActorsClass=Class'Engine.Pawn'
    ExcludedClass=StationaryPawn
    HeatClass=Class'sgHeatBlue'
    HeatInventoryClass=Class'sgVisor'
    HeatSensingRange=16384.00
}
