Botpack
Class ChallengeHUD

source: e:\games\UnrealTournament\Botpack\Classes\ChallengeHUD.uc
Core.Object
   |
   +--Engine.Actor
      |
      +--Engine.HUD
         |
         +--Botpack.ChallengeHUD
Direct Known Subclasses:ChallengeTeamHUD, CHEOLHud, CHNullHud, CHSpectatorHud

class ChallengeHUD
extends Engine.HUD

//============================================================================= // ChallengeHUD // Heads up display //=============================================================================
Variables
 MapTitleString, AuthorString
           pawn currently managing this HUD (may be the viewtarget of the owner rather than the owner)
 MapTitleString2, AuthorString2
           pawn currently managing this HUD (may be the viewtarget of the owner rather than the owner)
 UnitColor, BlueColor,
           should be between 1 and 16
 Texture CrossHairTextures[20]
           pawn currently managing this HUD (may be the viewtarget of the owner rather than the owner)
 string CrossHairs[20]
           pawn currently managing this HUD (may be the viewtarget of the owner rather than the owner)
 FavoriteHUDColor, CrosshairColor
           should be between 1 and 16
 int CrosshairCount
           pawn currently managing this HUD (may be the viewtarget of the owner rather than the owner)
 string CurrentMessage
 FP2[3], FP3[3]
           pawn currently managing this HUD (may be the viewtarget of the owner rather than the owner)
 color FaceTeam
           pawn currently managing this HUD (may be the viewtarget of the owner rather than the owner)
 Texture FaceTexture
           pawn currently managing this HUD (may be the viewtarget of the owner rather than the owner)
 float FaceTime
           pawn currently managing this HUD (may be the viewtarget of the owner rather than the owner)
 string FontInfoClass
           should be between 1 and 16
 Texture GrayWeapons[11]
           pawn currently managing this HUD (may be the viewtarget of the owner rather than the owner)
 float HitDamage[4]
           should be between 1 and 16
 vector HitPos[4]
           should be between 1 and 16
 float HitTime[4]
           should be between 1 and 16
 IdentifyHealth, IdentifyCallsign
           should be between 1 and 16
 float IdentifyFadeTime
 PlayerReplicationInfo IdentifyTarget
 int LastReportedTime
           pawn currently managing this HUD (may be the viewtarget of the owner rather than the owner)
 string LiveFeed
           should be between 1 and 16
 HUDLocalizedMessage LocalMessages[10]
           pawn currently managing this HUD (may be the viewtarget of the owner rather than the owner)
 float MOTDFadeOutTime
 int MessageFadeCount
           should be between 1 and 16
 float MessageFadeTime
           should be between 1 and 16
 FaceAreaOffset, MinFaceAreaOffset
           should be between 1 and 16
 FontInfo MyFonts
           pawn currently managing this HUD (may be the viewtarget of the owner rather than the owner)
 int OldClipX
           pawn currently managing this HUD (may be the viewtarget of the owner rather than the owner)
 byte Opacity
           should be between 1 and 16
 Pawn PawnOwner
           pawn currently managing this HUD (may be the viewtarget of the owner rather than the owner)
 float PickupTime
           should be between 1 and 16
 int PlayerCount
           pawn currently managing this HUD (may be the viewtarget of the owner rather than the owner)
 VersionMessage, PlayerCountString
           pawn currently managing this HUD (may be the viewtarget of the owner rather than the owner)
 string RankString
           pawn currently managing this HUD (may be the viewtarget of the owner rather than the owner)
 string ReceivedMessage
           pawn currently managing this HUD (may be the viewtarget of the owner rather than the owner)
 string ReceivedName
           pawn currently managing this HUD (may be the viewtarget of the owner rather than the owner)
 float ReceivedTime
           pawn currently managing this HUD (may be the viewtarget of the owner rather than the owner)
 ZoneInfo ReceivedZone
           pawn currently managing this HUD (may be the viewtarget of the owner rather than the owner)
 float Scale
           should be between 1 and 16
 float ScoreTime
           should be between 1 and 16
 ServerInfo ServerInfo
           should be between 1 and 16
 class ServerInfoClass
           should be between 1 and 16
 HUDLocalizedMessage ShortMessageQueue[4]
           pawn currently managing this HUD (may be the viewtarget of the owner rather than the owner)
 int SizeY,Count
 string SpreadString
           pawn currently managing this HUD (may be the viewtarget of the owner rather than the owner)
 byte Style
           should be between 1 and 16
 class TimeMessageClass
           should be between 1 and 16
 float TutIconBlink
           pawn currently managing this HUD (may be the viewtarget of the owner rather than the owner)
 Texture TutIconTex
           pawn currently managing this HUD (may be the viewtarget of the owner rather than the owner)
 TutIconX, TutIconY
           pawn currently managing this HUD (may be the viewtarget of the owner rather than the owner)
 float WeaponNameFade
           should be between 1 and 16
 StatusScale, WeaponScale
           should be between 1 and 16
 bool bDrawFaceArea
           should be between 1 and 16
 bool bDrawMessageArea
           should be between 1 and 16
 bStartUpMessage, bForceScores
           pawn currently managing this HUD (may be the viewtarget of the owner rather than the owner)
 bAlwaysHideFrags, bHideCenterMessages
           pawn currently managing this HUD (may be the viewtarget of the owner rather than the owner)
 bHideNoviceMessages, bHideFaces
           pawn currently managing this HUD (may be the viewtarget of the owner rather than the owner)
 bool bLowRes
           pawn currently managing this HUD (may be the viewtarget of the owner rather than the owner)
 bool bResChanged
           pawn currently managing this HUD (may be the viewtarget of the owner rather than the owner)
 bool bShowInfo
           should be between 1 and 16
 bool bTiedScore
           pawn currently managing this HUD (may be the viewtarget of the owner rather than the owner)
 bool bTimeValid
           pawn currently managing this HUD (may be the viewtarget of the owner rather than the owner)
 bool bUseTeamColor
           pawn currently managing this HUD (may be the viewtarget of the owner rather than the owner)
 rank, lead
           should be between 1 and 16


Function Summary
 
simulated
ChangeCrosshair(int d)
 void Destroyed()
 bool DisplayMessages(Canvas Canvas)
 
simulated
DisplayProgressMessage(Canvas Canvas)
 
simulated
DrawAmmo(Canvas Canvas)
 
simulated
DrawBigNum(Canvas Canvas, int Value, int X, int Y, optional float)
     
// DrawBigNum should already have Canvas set up
// X and Y should be the left most allowed position of the number (will be adjusted right if possible)
 
simulated
DrawCrossHair(Canvas Canvas, int X, int Y)
 
simulated
DrawDigit(Canvas Canvas, int d, int Step, float UpScale, out byte)
 
simulated
DrawFragCount(Canvas Canvas)
 
simulated
DrawGameSynopsis(Canvas Canvas)
 bool DrawIdentifyInfo(Canvas Canvas)
 
simulated
DrawMOTD(Canvas Canvas)
 float DrawNextMessagePart(Canvas Canvas, string MString, float XOffset, int YPos)
 bool DrawSpeechArea(Canvas Canvas, float XL, float YL)
 
simulated
DrawStatus(Canvas Canvas)
 void DrawTalkFace(Canvas Canvas, float YPos)
 
simulated
DrawTwoColorID(Canvas Canvas, string TitleString, string ValueString, int YStart)
 
simulated
DrawTypingPrompt(Canvas Canvas, Console Console)
 
simulated
DrawWeapons(Canvas Canvas)
 void GrowHUD()
 
simulated
HUDSetup(Canvas canvas)
 Texture LoadCrosshair(int c)
 
simulated
Message(PlayerReplicationInfo PRI, string Msg, name MsgType)
     
// Entry point for string messages.
 
simulated
PostBeginPlay()
 
simulated
PostRender(Canvas Canvas)
     
//========================================
// Master HUD render function.
 void SetDamage(vector HitLoc, float damage)
 void SetHUDB(int n)
 void SetHUDG(int n)
 void SetHUDR(int n)
 
simulated
SetIDColor(Canvas Canvas, int type)
 void ShowServerInfo()
 void ShrinkHUD()
 bool SpecialIdentify(Canvas Canvas, Actor Other)
 
simulated
TellTime(int num)
 
simulated
Tick(float DeltaTime)
 void Timer()
 bool TraceIdentify(Canvas Canvas)
     
//================================================================================
// Identify Info
 void UpdateRankAndSpread()



Source Code


00001	//=============================================================================
00002	// ChallengeHUD
00003	// Heads up display
00004	//=============================================================================
00005	class ChallengeHUD extends HUD
00006		config;
00007	
00008	#exec TEXTURE IMPORT NAME=HudLine FILE=..\unrealshare\TEXTURES\HUD\Line.PCX GROUP="Icons" MIPS=OFF
00009	#exec TEXTURE IMPORT NAME=IconSelection FILE=..\unrealshare\TEXTURES\HUD\i_rim.PCX GROUP="Icons" FLAGS=2 MIPS=OFF
00010	
00011	#exec TEXTURE IMPORT NAME=CHair1  FILE=Textures\Hud\cross1.PCX GROUP="Icons" MIPS=OFF
00012	#exec TEXTURE IMPORT NAME=CHair2  FILE=Textures\Hud\cross2.PCX GROUP="Icons" MIPS=OFF
00013	#exec TEXTURE IMPORT NAME=CHair3  FILE=Textures\Hud\cross3.PCX GROUP="Icons" MIPS=OFF
00014	#exec TEXTURE IMPORT NAME=CHair4  FILE=Textures\Hud\cross4.PCX GROUP="Icons" MIPS=OFF
00015	#exec TEXTURE IMPORT NAME=CHair5  FILE=Textures\Hud\cross5.PCX GROUP="Icons" MIPS=OFF
00016	#exec TEXTURE IMPORT NAME=CHair6  FILE=Textures\Hud\cross6.PCX GROUP="Icons" MIPS=OFF
00017	#exec TEXTURE IMPORT NAME=CHair7  FILE=Textures\Hud\cross7.PCX GROUP="Icons" MIPS=OFF
00018	#exec TEXTURE IMPORT NAME=CHair8  FILE=Textures\Hud\cross8.PCX GROUP="Icons" MIPS=OFF
00019	#exec TEXTURE IMPORT NAME=CHair9  FILE=Textures\Hud\cross9.PCX GROUP="Icons" MIPS=OFF
00020	
00021	#exec Font Import File=..\unrealshare\Textures\TinyFont.pcx Name=TinyFont
00022	#exec Font Import File=..\unrealshare\Textures\TinyFon3.pcx Name=TinyWhiteFont
00023	#exec Font Import File=..\unrealshare\Textures\TinyFon2.pcx Name=TinyRedFont
00024	
00025	#exec TEXTURE IMPORT NAME=HudElements1 FILE=TEXTURES\HUD\HudElements1.PCX GROUP="Icons" MIPS=OFF FLAGS=2
00026	#exec TEXTURE IMPORT NAME=HUDWeapons FILE=TEXTURES\HUD\HudElements2.PCX GROUP="Icons" MIPS=OFF FLAGS=2
00027	
00028	#exec TEXTURE IMPORT NAME=FacePanel0 FILE=TEXTURES\HUD\FacePan0.PCX GROUP="FacePanel" MIPS=OFF
00029	#exec TEXTURE IMPORT NAME=FacePanel1 FILE=TEXTURES\HUD\FacePan1.PCX GROUP="FacePanel" MIPS=OFF
00030	#exec TEXTURE IMPORT NAME=FacePanel2 FILE=TEXTURES\HUD\FacePan2.PCX GROUP="FacePanel" MIPS=OFF
00031	#exec TEXTURE IMPORT NAME=FacePanel3 FILE=TEXTURES\HUD\FacePan3.PCX GROUP="FacePanel" MIPS=OFF
00032	#exec TEXTURE IMPORT NAME=FacePanel1a FILE=TEXTURES\HUD\FacePan1a.PCX GROUP="FacePanel" MIPS=OFF
00033	#exec TEXTURE IMPORT NAME=FacePanel2a FILE=TEXTURES\HUD\FacePan2a.PCX GROUP="FacePanel" MIPS=OFF
00034	#exec TEXTURE IMPORT NAME=FacePanel3a FILE=TEXTURES\HUD\FacePan3a.PCX GROUP="FacePanel" MIPS=OFF
00035	#exec TEXTURE IMPORT NAME=FacePanel1b FILE=TEXTURES\HUD\FacePan1b.PCX GROUP="FacePanel" MIPS=OFF
00036	#exec TEXTURE IMPORT NAME=FacePanel2b FILE=TEXTURES\HUD\FacePan2b.PCX GROUP="FacePanel" MIPS=OFF
00037	#exec TEXTURE IMPORT NAME=FacePanel3b FILE=TEXTURES\HUD\FacePan3b.PCX GROUP="FacePanel" MIPS=OFF
00038	
00039	#exec TEXTURE IMPORT NAME=DisconnectWarn FILE=TEXTURES\HUD\Disconnect.PCX GROUP="Icons" MIPS=OFF FLAGS=2
00040	
00041	#exec OBJ LOAD FILE=..\Textures\LadrStatic.utx PACKAGE=Botpack.LadrStatic
00042	
00043	var() int SizeY,Count;
00044	var string CurrentMessage;
00045	var float MOTDFadeOutTime;
00046	
00047	var float IdentifyFadeTime;
00048	var PlayerReplicationInfo IdentifyTarget;
00049	var Pawn PawnOwner;	// pawn currently managing this HUD (may be the viewtarget of the owner rather than the owner)
00050	var FontInfo MyFonts;
00051	
00052	// Localized Messages
00053	var HUDLocalizedMessage ShortMessageQueue[4];
00054	var HUDLocalizedMessage LocalMessages[10];
00055	
00056	var texture FaceTexture;
00057	var float FaceTime;
00058	var color FaceTeam;
00059	 
00060	var() localized string VersionMessage, PlayerCountString;
00061	var localized string MapTitleString, AuthorString;
00062	var localized string MapTitleString2, AuthorString2;
00063	
00064	var localized string RankString;
00065	var localized string SpreadString;
00066	
00067	var int PlayerCount;
00068	var bool bTiedScore;
00069	
00070	var string ReceivedMessage;
00071	var string ReceivedName;
00072	var ZoneInfo ReceivedZone;
00073	var float ReceivedTime;
00074	var texture TutIconTex;
00075	var int TutIconX, TutIconY;
00076	var float TutIconBlink;
00077	
00078	var globalconfig int CrosshairCount;
00079	var globalconfig string CrossHairs[20];
00080	var texture CrossHairTextures[20];
00081	
00082	var texture GrayWeapons[11];
00083	var texture FP1[3], FP2[3], FP3[3];
00084	var int LastReportedTime;
00085	var bool bStartUpMessage, bForceScores;
00086	var bool bTimeValid;
00087	var bool bLowRes;
00088	var bool bResChanged;
00089	var int OldClipX;
00090	
00091	// configuration options
00092	var bool bAlwaysHideFrags, bHideCenterMessages;
00093	var globalconfig bool bHideAllWeapons, bHideStatus, bHideAmmo, bHideTeamInfo, bHideFrags, bHideHUD, bHideNoviceMessages, bHideFaces;
00094	var globalconfig bool bUseTeamColor;
00095	var globalconfig byte Opacity;	// should be between 1 and 16
00096	var globalconfig float HUDScale, StatusScale, WeaponScale;
00097	var globalconfig color FavoriteHUDColor, CrosshairColor;
00098	var float Scale;
00099	var byte Style;
00100	var color BaseColor, WhiteColor, RedColor, GreenColor, CyanColor, UnitColor, BlueColor,
00101			 GoldColor, HUDColor, SolidHUDColor, PurpleColor, TurqColor, GrayColor, FaceColor;
00102	
00103	// Identify Strings
00104	var localized string IdentifyName, IdentifyHealth, IdentifyCallsign;
00105	var localized string LiveFeed;
00106	
00107	// scoring 
00108	var float ScoreTime;
00109	var int rank, lead;
00110	
00111	// showing damage
00112	var vector HitPos[4];
00113	var float HitTime[4];
00114	var float HitDamage[4];
00115	
00116	var float PickupTime;
00117	
00118	var float WeaponNameFade;
00119	var float MessageFadeTime;
00120	var int MessageFadeCount;
00121	var bool bDrawMessageArea;
00122	var bool bDrawFaceArea;
00123	var float FaceAreaOffset, MinFaceAreaOffset;
00124	var class<CriticalEventPlus> TimeMessageClass;
00125	
00126	// Server info.
00127	var ServerInfo ServerInfo;
00128	var bool bShowInfo;
00129	
00130	var class<ServerInfo> ServerInfoClass;
00131	
00132	var globalconfig string FontInfoClass;
00133	
00134	function Destroyed()
00135	{
00136		Super.Destroyed();
00137		if ( MyFonts != None )
00138			MyFonts.Destroy();
00139	}
00140	
00141	function SetDamage(vector HitLoc, float damage)
00142	{
00143		local int i, best;
00144		local vector X,Y,Z;
00145		local float Max, XOffset, YOffset;
00146	
00147		if ( Level.bDropDetail || !PlayerOwner.IsA('TournamentPlayer') )
00148			return;
00149	
00150		for ( i=0; i<4; i++ )
00151			if ( Level.TimeSeconds - HitTime[i] > Max )
00152			{
00153				best = i;	
00154				Max = Level.TimeSeconds - HitTime[i];
00155			}
00156	
00157		HitTime[best] = Level.TimeSeconds;
00158		HitDamage[best] = FClamp(Damage * 0.06,2,4);
00159		GetAxes(Owner.Rotation,X,Y,Z);
00160		XOffset = - 0.5 * FClamp((Y Dot HitLoc)/CollisionRadius , -1, 1);
00161		YOffset = -0.5 * FClamp((Z Dot HitLoc)/CollisionHeight , -1, 1);
00162	
00163		// hack for positions around head or near legs
00164		if ( YOffset < -0.35 )
00165		{
00166			XOffset *= 0.3;
00167			YOffset = FMax(HitPos[best].Y, -0.45);
00168		}
00169		else if ( YOffset > 0.1 )
00170		{
00171			if ( abs(XOffset) < 0.25 )
00172			{
00173				if ( XOffset > 0 )
00174					XOffset = 0.25;
00175				else
00176					XOffset = -0.25;
00177			}				
00178			YOffset = FMin(YOffset, 0.4);
00179		}
00180	
00181		HitPos[best].X = 128 * (0.5 + XOffset) - 0.5 * 25 * HitDamage[best];
00182		HitPos[best].Y = 256 * (0.5 + YOffset) - 0.5 * HitDamage[Best] * 64;
00183	}
00184	
00185	simulated function PostBeginPlay()
00186	{
00187		local int i;
00188	
00189		if ( Level.NetMode != NM_Standalone )
00190			MOTDFadeOutTime = 350;
00191		FaceAreaOffset = -64;
00192		MyFonts = FontInfo(spawn(Class<Actor>(DynamicLoadObject(FontInfoClass, class'Class'))));
00193		Super.PostBeginPlay();
00194		SetTimer(1.0, True);
00195	
00196		if ( (PlayerPawn(Owner).GameReplicationInfo != None)
00197			&& (PlayerPawn(Owner).GameReplicationInfo.RemainingTime > 0) )
00198			TimeMessageClass = class<CriticalEventPlus>(DynamicLoadObject("Botpack.TimeMessage", class'Class'));
00199	
00200		ServerInfo = Spawn(ServerInfoClass, Owner);
00201	}
00202	
00203	exec function SetHUDR(int n)
00204	{
00205		FavoriteHUDColor.R = Clamp(n,0,16);
00206	}
00207	
00208	exec function SetHUDG(int n)
00209	{
00210		FavoriteHUDColor.G = Clamp(n,0,16);
00211	}
00212	
00213	exec function SetHUDB(int n)
00214	{
00215		FavoriteHUDColor.B = Clamp(n,0,16);
00216	}
00217	
00218	exec function ShowServerInfo()
00219	{
00220		if (bShowInfo)
00221		{
00222			bShowInfo = False;
00223		} else {
00224			bShowInfo = True;
00225			PlayerPawn(Owner).bShowScores = False;
00226		}
00227	}
00228	
00229	exec function GrowHUD()
00230	{
00231		if ( bHideHUD )
00232			bHideHud = false;
00233		else if ( bHideAmmo )
00234			bHideAmmo = false;
00235		else if ( bHideFrags )
00236			bHideFrags = false;
00237		else if ( bHideTeamInfo )
00238			bHideTeamInfo = false;
00239		else if ( bHideAllWeapons )
00240			bHideAllWeapons = false;
00241		else if ( bHideStatus )
00242			bHideStatus = false;
00243		else 
00244			WeaponScale = 1.0;
00245	
00246		SaveConfig();
00247	}
00248	
00249	exec function ShrinkHUD()
00250	{
00251		if ( !bLowRes && (WeaponScale * HUDScale > 0.8) )
00252			WeaponScale = 0.8/HUDScale;
00253		else if ( !bHideStatus )
00254			bHideStatus = true;
00255		else if ( !bHideAllWeapons )
00256			bHideAllWeapons = true;
00257		else if ( !bHideTeamInfo )
00258			bHideTeamInfo = true;
00259		else if ( !bHideFrags )
00260			bHideFrags = true;
00261		else if ( !bHideAmmo )
00262			bHideAmmo = true;
00263		else
00264			bHideHud = true;
00265	
00266		SaveConfig();
00267	}
00268		
00269	simulated function ChangeCrosshair(int d)
00270	{
00271		Crosshair = Crosshair + d;
00272		if ( Crosshair >= CrossHairCount )
00273			Crosshair = 0;
00274		else
00275		if ( Crosshair < 0 )
00276			Crosshair = CrossHairCount-1;
00277	}
00278	
00279	simulated function Texture LoadCrosshair(int c)
00280	{
00281		CrossHairTextures[c] = Texture(DynamicLoadObject(CrossHairs[c], class'Texture'));
00282		return CrossHairTextures[c];
00283	}
00284	
00285	simulated function HUDSetup(canvas canvas)
00286	{
00287		local int FontSize;
00288	
00289		bResChanged = (Canvas.ClipX != OldClipX);
00290		OldClipX = Canvas.ClipX;
00291			
00292		PlayerOwner = PlayerPawn(Owner);
00293		if ( PlayerOwner.ViewTarget == None )
00294			PawnOwner = PlayerOwner;
00295		else if ( PlayerOwner.ViewTarget.bIsPawn )
00296			PawnOwner = Pawn(PlayerOwner.ViewTarget);
00297		else 
00298			PawnOwner = PlayerOwner;
00299	
00300		// Setup the way we want to draw all HUD elements
00301		Canvas.Reset();
00302		Canvas.SpaceX=0;
00303		Canvas.bNoSmooth = True;
00304	
00305		FontSize = Min(3, HUDScale * Canvas.ClipX/500);
00306		Scale = (HUDScale * Canvas.ClipX)/1280.0;
00307	
00308		Canvas.Font = MyFonts.GetSmallFont( Canvas.ClipX );
00309	
00310		SolidHUDColor = FavoriteHUDColor * 15.9;
00311		if ( (Opacity == 16) || !Level.bHighDetailMode )
00312		{
00313			Style = ERenderStyle.STY_Normal;
00314			BaseColor = WhiteColor;
00315			HUDColor = SolidHUDColor;
00316		}
00317		else
00318		{
00319			Style = ERenderStyle.STY_Translucent;
00320			BaseColor = (16 * Opacity + 15) * UnitColor;
00321			HUDColor = FavoriteHUDColor * (Opacity + 0.9);
00322		}
00323		Canvas.DrawColor = BaseColor;
00324		Canvas.Style = Style;
00325		bLowRes = ( Canvas.ClipX < 400 );
00326		if ( bLowRes )
00327			WeaponScale = 1.0;
00328	}
00329	
00330	simulated function DrawDigit(Canvas Canvas, int d, int Step, float UpScale, out byte bMinus )
00331	{
00332		if ( bMinus == 1 )
00333		{
00334			Canvas.CurX -= Step;
00335			Canvas.DrawTile(Texture'BotPack.HudElements1', UpScale*25, 64*UpScale, 0, 64, 25.0, 64.0);
00336			bMinus = 0;
00337		}
00338		if ( d == 1 )
00339			Canvas.CurX -= 0.625 * Step;
00340		else
00341			Canvas.CurX -= 0.25 * Step;		
00342		Canvas.DrawTile(Texture'BotPack.HudElements1', UpScale*25, 64*UpScale, d*25, 0, 25.0, 64.0);
00343		Canvas.CurX += 7*UpScale;
00344	}
00345	
00346	// DrawBigNum should already have Canvas set up
00347	// X and Y should be the left most allowed position of the number (will be adjusted right if possible)
00348	simulated function DrawBigNum(Canvas Canvas, int Value, int X, int Y, optional float ScaleFactor)
00349	{
00350		local int d, Mag, Step;
00351		local float UpScale;
00352		local byte bMinus;
00353	
00354		if ( ScaleFactor != 0 )
00355			UpScale = Scale * ScaleFactor;
00356		else
00357			UpScale = Scale;
00358	
00359		Canvas.CurX = X;	
00360		Canvas.CurY = Y;
00361		Step = 16 * UpScale;
00362		if ( Value < 0 )
00363			bMinus = 1;
00364		Mag = FMin(9999, Abs(Value));
00365	
00366		if ( Mag >= 1000 )
00367		{
00368			Canvas.CurX -= Step;
00369			d = 0.001 * Mag;
00370			DrawDigit(Canvas, d, Step, UpScale, bMinus);
00371			Mag = Mag - 1000 * d;
00372			d = 0.01 * Mag;
00373			DrawDigit(Canvas, d, Step, UpScale, bMinus);
00374			Mag = Mag - 100 * d;
00375		}
00376		else if ( Mag >= 100 )
00377		{
00378			d = 0.01 * Mag;
00379			DrawDigit(Canvas, d, Step, UpScale, bMinus);
00380			Mag = Mag - 100 * d;
00381		}
00382		else
00383			Canvas.CurX += Step;
00384	
00385		if ( Mag >= 10 )
00386		{
00387			d = 0.1 * Mag;
00388			DrawDigit(Canvas, d, Step, UpScale, bMinus);
00389			Mag = Mag - 10 * d;
00390		}
00391		else if ( d > 0 )
00392			DrawDigit(Canvas, 0, Step, UpScale, bMinus);
00393		else
00394			Canvas.CurX += Step;
00395	
00396		DrawDigit(Canvas, Mag, Step, UpScale, bMinus);
00397	}
00398	
00399	simulated function DrawStatus(Canvas Canvas)
00400	{
00401		local float StatScale, ChestAmount, ThighAmount, H1, H2, X, Y, DamageTime;
00402		Local int ArmorAmount,CurAbs,i;
00403		Local inventory Inv,BestArmor;
00404		local bool bChestArmor, bShieldbelt, bThighArmor, bJumpBoots, bHasDoll;
00405		local Bot BotOwner;
00406		local TournamentPlayer TPOwner;
00407		local texture Doll, DollBelt;
00408	
00409		ArmorAmount = 0;
00410		CurAbs = 0;
00411		i = 0;
00412		BestArmor=None;
00413		for( Inv=PawnOwner.Inventory; Inv!=None; Inv=Inv.Inventory )
00414		{ 
00415			if (Inv.bIsAnArmor) 
00416			{
00417				if ( Inv.IsA('UT_Shieldbelt') )
00418					bShieldbelt = true;
00419				else if ( Inv.IsA('Thighpads') )
00420				{
00421					ThighAmount += Inv.Charge;
00422					bThighArmor = true;
00423				}
00424				else
00425				{ 
00426					bChestArmor = true;
00427					ChestAmount += Inv.Charge;
00428				}
00429				ArmorAmount += Inv.Charge;
00430			}
00431			else if ( Inv.IsA('UT_JumpBoots') )
00432				bJumpBoots = true;
00433			else
00434			{
00435				i++;
00436				if ( i > 100 )
00437					break; // can occasionally get temporary loops in netplay
00438			}
00439		}
00440	
00441		if ( !bHideStatus )
00442		{	
00443			TPOwner = TournamentPlayer(PawnOwner);
00444			if ( Canvas.ClipX < 400 )
00445				bHasDoll = false;
00446			else if ( TPOwner != None)
00447			{
00448				Doll = TPOwner.StatusDoll;
00449				DollBelt = TPOwner.StatusBelt;
00450				bHasDoll = true;
00451			}
00452			else
00453			{
00454				BotOwner = Bot(PawnOwner);
00455				if ( BotOwner != None )
00456				{
00457					Doll = BotOwner.StatusDoll;
00458					DollBelt = BotOwner.StatusBelt;
00459					bHasDoll = true;
00460				}
00461			}
00462			if ( bHasDoll )
00463			{ 							
00464				Canvas.Style = ERenderStyle.STY_Translucent;
00465				StatScale = Scale * StatusScale;
00466				X = Canvas.ClipX - 128 * StatScale;
00467				Canvas.SetPos(X, 0);
00468				if (PawnOwner.DamageScaling > 2.0)
00469					Canvas.DrawColor = PurpleColor;
00470				else
00471					Canvas.DrawColor = HUDColor;
00472				Canvas.DrawTile(Doll, 128*StatScale, 256*StatScale, 0, 0, 128.0, 256.0);
00473				Canvas.DrawColor = HUDColor;
00474				if ( bShieldBelt )
00475				{
00476					Canvas.DrawColor = BaseColor;
00477					Canvas.DrawColor.B = 0;
00478					Canvas.SetPos(X, 0);
00479					Canvas.DrawIcon(DollBelt, StatScale);
00480				}
00481				if ( bChestArmor )
00482				{
00483					ChestAmount = FMin(0.01 * ChestAmount,1);
00484					Canvas.DrawColor = HUDColor * ChestAmount;
00485					Canvas.SetPos(X, 0);
00486					Canvas.DrawTile(Doll, 128*StatScale, 64*StatScale, 128, 0, 128, 64);
00487				}
00488				if ( bThighArmor )
00489				{
00490					ThighAmount = FMin(0.02 * ThighAmount,1);
00491					Canvas.DrawColor = HUDColor * ThighAmount;
00492					Canvas.SetPos(X, 64*StatScale);
00493					Canvas.DrawTile(Doll, 128*StatScale, 64*StatScale, 128, 64, 128, 64);
00494				}
00495				if ( bJumpBoots )
00496				{
00497					Canvas.DrawColor = HUDColor;
00498					Canvas.SetPos(X, 128*StatScale);
00499					Canvas.DrawTile(Doll, 128*StatScale, 64*StatScale, 128, 128, 128, 64);
00500				}
00501				Canvas.Style = Style;
00502				if ( (PawnOwner == PlayerOwner) && Level.bHighDetailMode && !Level.bDropDetail )
00503				{
00504					for ( i=0; i<4; i++ )
00505					{
00506						DamageTime = Level.TimeSeconds - HitTime[i];
00507						if ( DamageTime < 1 )
00508						{
00509							Canvas.SetPos(X + HitPos[i].X * StatScale, HitPos[i].Y * StatScale);
00510							if ( (HUDColor.G > 100) || (HUDColor.B > 100) )
00511								Canvas.DrawColor = RedColor;
00512							else
00513								Canvas.DrawColor = (WhiteColor - HudColor) * FMin(1, 2 * DamageTime);
00514							Canvas.DrawColor.R = 255 * FMin(1, 2 * DamageTime);
00515							Canvas.DrawTile(Texture'BotPack.HudElements1', StatScale * HitDamage[i] * 25, StatScale * HitDamage[i] * 64, 0, 64, 25.0, 64.0);
00516						}
00517					}
00518				}
00519			}
00520		}
00521		Canvas.DrawColor = HUDColor;
00522		if ( bHideStatus && bHideAllWeapons )
00523		{
00524			X = 0.5 * Canvas.ClipX;
00525			Y = Canvas.ClipY - 64 * Scale;
00526		}
00527		else
00528		{
00529			X = Canvas.ClipX - 128 * StatScale - 140 * Scale;
00530			Y = 64 * Scale;
00531		}
00532		Canvas.SetPos(X,Y);
00533		if ( PawnOwner.Health < 50 )
00534		{
00535			H1 = 1.5 * TutIconBlink;
00536			H2 = 1 - H1;
00537			Canvas.DrawColor = WhiteColor * H2 + (HUDColor - WhiteColor) * H1;
00538		}
00539		else
00540			Canvas.DrawColor = HUDColor;
00541		Canvas.DrawTile(Texture'BotPack.HudElements1', 128*Scale, 64*Scale, 128, 128, 128.0, 64.0);
00542	
00543		if ( PawnOwner.Health < 50 )
00544		{
00545			H1 = 1.5 * TutIconBlink;
00546			H2 = 1 - H1;
00547			Canvas.DrawColor = Canvas.DrawColor * H2 + (WhiteColor - Canvas.DrawColor) * H1;
00548		}
00549		else
00550			Canvas.DrawColor = WhiteColor;
00551	
00552		DrawBigNum(Canvas, Max(0, PawnOwner.Health), X + 4 * Scale, Y + 16 * Scale, 1);
00553	
00554		Canvas.DrawColor = HUDColor;
00555		if ( bHideStatus && bHideAllWeapons )
00556		{
00557			X = 0.5 * Canvas.ClipX - 128 * Scale;
00558			Y = Canvas.ClipY - 64 * Scale;
00559		}
00560		else
00561		{
00562			X = Canvas.ClipX - 128 * StatScale - 140 * Scale;
00563			Y = 0;
00564		}
00565		Canvas.SetPos(X, Y);
00566		Canvas.DrawTile(Texture'BotPack.HudElements1', 128*Scale, 64*Scale, 0, 192, 128.0, 64.0);
00567		if ( bHideStatus && bShieldBelt )
00568			Canvas.DrawColor = GoldColor;
00569		else
00570			Canvas.DrawColor = WhiteColor;
00571		DrawBigNum(Canvas, Min(150,ArmorAmount), X + 4 * Scale, Y + 16 * Scale, 1);
00572	}
00573	
00574	simulated function DrawAmmo(Canvas Canvas)
00575	{
00576		local int X,Y;
00577	
00578		Canvas.Style = Style;
00579		Canvas.DrawColor = HUDColor;
00580		if ( bHideAllWeapons || (HudScale * WeaponScale * Canvas.ClipX <= Canvas.ClipX - 256 * Scale) )
00581			Y = Canvas.ClipY - 63.5 * Scale;
00582		else
00583			Y = Canvas.ClipY - 127.5 * Scale;
00584		if ( bHideAllWeapons )
00585			X = 0.5 * Canvas.ClipX + 128 * Scale;
00586		else
00587			X = Canvas.ClipX - 128 * Scale;
00588		Canvas.SetPos(X, Y);
00589		Canvas.DrawTile(Texture'BotPack.HudElements1', 128*Scale, 64*Scale, 128, 192, 128.0, 64.0);
00590	
00591		if ( (PawnOwner.Weapon == None) || (PawnOwner.Weapon.AmmoType == None) )
00592			return;
00593	
00594		Canvas.DrawColor = WhiteColor;
00595		DrawBigNum(Canvas, PawnOwner.Weapon.AmmoType.AmmoAmount, X + 4 * Scale, Y + 16 * Scale);
00596	}
00597	
00598	simulated function DrawFragCount(Canvas Canvas)
00599	{
00600		local float Whiten;
00601		local int X,Y;
00602	
00603		if ( PawnOwner.PlayerReplicationInfo == None )
00604			return;
00605	
00606		Canvas.Style = Style;
00607		if ( bHideAllWeapons || (HudScale * WeaponScale * Canvas.ClipX <= Canvas.ClipX - 256 * Scale) )
00608			Y = Canvas.ClipY - 63.5 * Scale;
00609		else
00610			Y = Canvas.ClipY - 127.5 * Scale;
00611		if ( bHideAllWeapons )
00612			X = 0.5 * Canvas.ClipX - 256 * Scale;
00613		Canvas.CurX = X;
00614		Canvas.CurY = Y;
00615		Canvas.DrawColor = HUDColor; 
00616		Whiten = Level.TimeSeconds - ScoreTime;
00617		if ( Whiten < 3.0 )
00618		{
00619			if ( HudColor == GoldColor )
00620				Canvas.DrawColor = WhiteColor;
00621			else
00622				Canvas.DrawColor = GoldColor;
00623			if ( Level.bHighDetailMode )
00624			{
00625				Canvas.CurX = X - 64 * Scale;
00626				Canvas.CurY = Y - 32 * Scale;
00627				Canvas.Style = ERenderStyle.STY_Translucent;
00628				Canvas.DrawTile(Texture'BotPack.HUDWeapons', 256 * Scale, 128 * Scale, 0, 128, 256.0, 128.0);
00629			}
00630			Canvas.CurX = X;
00631			Canvas.CurY = Y;
00632			Whiten = 4 * Whiten - int(4 * Whiten);
00633			Canvas.DrawColor = Canvas.DrawColor + (HUDColor - Canvas.DrawColor) * Whiten;
00634		}
00635	
00636		Canvas.DrawTile(Texture'BotPack.HudElements1', 128*Scale, 64*Scale, 0, 128, 128.0, 64.0);
00637		Canvas.DrawColor = WhiteColor;
00638		DrawBigNum(Canvas, PawnOwner.PlayerReplicationInfo.Score, X + 40 * Scale, Y + 16 * Scale);
00639	}
00640	
00641	
00642	simulated function DrawGameSynopsis(Canvas Canvas)
00643	{
00644		local float XL, YL, XOffset, YOffset;
00645		local int MaxPlayers;
00646		local string Spread;
00647	
00648		if ( (PawnOwner.PlayerReplicationInfo == None) 
00649			|| PawnOwner.PlayerReplicationInfo.bIsSpectator 
00650			|| (PlayerCount == 1) )
00651			return;
00652	
00653		Canvas.Font = MyFonts.GetBigFont( Canvas.ClipX );
00654		Canvas.DrawColor = WhiteColor;
00655	
00656		// Rank String
00657		Canvas.StrLen(RankString, XL, YL);
00658		if ( bHideAllWeapons )
00659			YOffset = Canvas.ClipY - YL*2;
00660		else if ( HudScale * WeaponScale * Canvas.ClipX <= Canvas.ClipX - 256 * Scale )
00661			YOffset = Canvas.ClipY - 64*Scale - YL*2;
00662		else
00663			YOffset = Canvas.ClipY - 128*Scale - YL*2;
00664		Canvas.SetPos(0, YOffset);
00665		Canvas.DrawText(RankString, False);
00666		if (bTiedScore)
00667			Canvas.DrawColor = RedColor;
00668		Canvas.SetPos(XL, YOffset);
00669		Canvas.DrawText(" "$Rank@"/"@PlayerCount, False);
00670		Canvas.DrawColor = WhiteColor;
00671	
00672		// Spread String
00673		Canvas.SetPos(0, YOffset + YL);
00674		if (Lead > 0)
00675			Spread = SpreadString$" +"$Lead;
00676		else
00677			Spread = SpreadString$" "$Lead;
00678	
00679		Canvas.DrawText(Spread, False);
00680	}
00681	
00682	simulated function DrawWeapons(Canvas Canvas)
00683	{
00684		local Weapon W, WeaponSlot[11];
00685		local inventory Inv;
00686		local int i, j, BaseY, BaseX, Pending, WeapX, WeapY;
00687		local float AmmoScale, WeaponOffset, WeapScale, WeaponX, TexX, TexY;
00688	
00689		BaseX = 0.5 * (Canvas.ClipX - HudScale * WeaponScale * Canvas.ClipX);
00690		WeapScale = WeaponScale * Scale;
00691		Canvas.Style = Style;
00692		BaseY = Canvas.ClipY - 63.5 * WeapScale;
00693		WeaponOffset = 0.1 * HUDScale * WeaponScale * Canvas.ClipX;
00694	
00695		if ( PawnOwner.Weapon != None )
00696		{
00697			W = PawnOwner.Weapon;
00698			if ( (Opacity > 8) || !Level.bHighDetailMode )
00699				Canvas.Style = ERenderStyle.STY_Normal;
00700			WeaponX = BaseX + (W.InventoryGroup - 1) * WeaponOffset;
00701			Canvas.CurX = WeaponX;
00702			Canvas.CurY = BaseY;
00703			Canvas.DrawColor = SolidHUDColor;
00704			Canvas.DrawIcon(W.StatusIcon, WeapScale);
00705			Canvas.DrawColor = GoldColor;
00706			Canvas.CurX = WeaponX + 4 * WeapScale;
00707			Canvas.CurY = BaseY + 4 * WeapScale;
00708			Canvas.Style = Style;
00709			if ( W.InventoryGroup == 10 )
00710				Canvas.DrawTile(Texture'BotPack.HudElements1', 0.75 * WeapScale * 25, 0.75 * WeapScale * 64, 0, 0, 25.0, 64.0);
00711			else
00712				Canvas.DrawTile(Texture'BotPack.HudElements1', 0.75 * WeapScale * 25, 0.75 * WeapScale * 64, 25*W.InventoryGroup, 0, 25.0, 64.0);
00713	
00714			WeaponSlot[W.InventoryGroup] = W;  
00715			Canvas.CurX = WeaponX;
00716			Canvas.CurY = BaseY;
00717			Canvas.DrawTile(Texture'BotPack.HUDWeapons', 128 * WeapScale, 64 * WeapScale, 128, 64, 128, 64);
00718		}
00719		if ( Level.bHighDetailMode && (PawnOwner.PendingWeapon != None) )
00720		{
00721			Pending = PawnOwner.PendingWeapon.InventoryGroup;
00722			Canvas.CurX = BaseX + (Pending - 1) * WeaponOffset - 64 * WeapScale;
00723			Canvas.CurY = Canvas.ClipY - 96 * WeapScale; 
00724			Canvas.Style = ERenderStyle.STY_Translucent;
00725			Canvas.DrawColor = GoldColor;
00726			Canvas.DrawTile(Texture'BotPack.HUDWeapons', 256 * WeapScale, 128 * WeapScale, 0, 128, 256.0, 128.0);
00727		}
00728		else
00729			Pending = 100;
00730	
00731		Canvas.Style = Style;
00732		i = 0;
00733		for ( Inv=PawnOwner.Inventory; Inv!=None; Inv=Inv.Inventory )
00734		{
00735			if ( Inv.IsA('Weapon') && (Inv != PawnOwner.Weapon) )
00736			{
00737				W = Weapon(Inv);
00738				if ( WeaponSlot[W.InventoryGroup] == None )
00739					WeaponSlot[W.InventoryGroup] = W;
00740				else if ( (WeaponSlot[W.InventoryGroup] != PawnOwner.Weapon)
00741						&& ((W == PawnOwner.PendingWeapon) || (WeaponSlot[W.InventoryGroup].AutoSwitchPriority < W.AutoSwitchPriority)) )
00742					WeaponSlot[W.InventoryGroup] = W;
00743			}
00744			i++;
00745			if ( i > 100 )
00746				break; // can occasionally get temporary loops in netplay
00747		}
00748		W = PawnOwner.Weapon;
00749	
00750		// draw weapon list
00751		TexX = 128 * WeapScale;
00752		TexY = 64 * WeapScale;
00753		for ( i=1; i<11; i++ )
00754		{
00755			if ( WeaponSlot[i] == None )
00756			{
00757				Canvas.Style = Style;
00758				Canvas.DrawColor =  0.5 * HUDColor;
00759				Canvas.CurX = BaseX + (i - 1) * WeaponOffset;
00760				Canvas.CurY = BaseY;
00761				
00762				WeapX = ((i-1)%4) * 64;
00763				WeapY = ((i-1)/4) * 32;
00764				Canvas.DrawTile(Texture'BotPack.HUDWeapons',TexX,TexY,WeapX,WeapY,64.0,32.0);
00765			}
00766			else if ( WeaponSlot[i] != W )
00767			{
00768				if ( Pending == i )
00769				{
00770					if ( (Opacity > 8) || !Level.bHighDetailMode )
00771						Canvas.Style = ERenderStyle.STY_Normal;
00772					Canvas.DrawColor = SolidHUDColor;
00773				}
00774				else
00775				{
00776					Canvas.Style = Style;
00777					Canvas.DrawColor = 0.5 * HUDColor;
00778				}
00779				Canvas.CurX = BaseX + (i - 1) * WeaponOffset;
00780				Canvas.CurY = BaseY;
00781				
00782				if ( WeaponSlot[i].bSpecialIcon )
00783					Canvas.DrawIcon(WeaponSlot[i].StatusIcon, WeapScale);
00784				else
00785				{
00786					WeapX = ((i-1)%4) * 64;
00787					WeapY = ((i-1)/4) * 32;
00788					Canvas.DrawTile(Texture'BotPack.HUDWeapons',TexX,TexY,WeapX,WeapY,64.0,32.0);
00789				}
00790			}
00791		}
00792	
00793		//draw weapon numbers and ammo
00794		TexX = 0.75 * WeapScale * 25;
00795		TexY = 0.75 * WeapScale * 64;
00796		for ( i=1; i<11; i++ )
00797		{
00798			if ( WeaponSlot[i] != None )
00799			{
00800				WeaponX = BaseX + (i - 1) * WeaponOffset + 4 * WeapScale;
00801				if ( WeaponSlot[i] != W )
00802				{
00803					Canvas.CurX = WeaponX;
00804					Canvas.CurY = BaseY + 4 * WeapScale;
00805					Canvas.DrawColor = GoldColor;
00806					if ( (Opacity > 8) || !Level.bHighDetailMode )
00807						Canvas.Style = ERenderStyle.STY_Normal;
00808					else
00809						Canvas.Style = Style;
00810					if ( i == 10 )
00811						Canvas.DrawTile(Texture'BotPack.HudElements1', TexX, TexY, 0, 0, 25.0, 64.0);
00812					else
00813						Canvas.DrawTile(Texture'BotPack.HudElements1', TexX, TexY, 25*i, 0, 25.0, 64.0);
00814				}
00815				if ( WeaponSlot[i].AmmoType != None )
00816				{
00817					// Draw Ammo bar
00818					Canvas.CurX = WeaponX;
00819					Canvas.CurY = BaseY + 52 * WeapScale;
00820					Canvas.DrawColor = BaseColor;
00821					AmmoScale = FClamp(88.0 * WeapScale * WeaponSlot[i].AmmoType.AmmoAmount/WeaponSlot[i].AmmoType.MaxAmmo, 0, 88);
00822					Canvas.DrawTile(Texture'BotPack.HudElements1', AmmoScale, 8 * WeapScale,64,64,128.0,8.0);
00823				}
00824			}
00825		}
00826	}
00827	
00828	simulated function DisplayProgressMessage( canvas Canvas )
00829	{
00830		local int i;
00831		local float XL, YL, YOffset;
00832		local GameReplicationInfo GRI;
00833	
00834		PlayerOwner.ProgressTimeOut = FMin(PlayerOwner.ProgressTimeOut, Level.TimeSeconds + 8);
00835		Canvas.Style = ERenderStyle.STY_Normal;	
00836	
00837		Canvas.bCenter = True;
00838		Canvas.Font = MyFonts.GetBigFont( Canvas.ClipX );
00839		Canvas.StrLen("TEST", XL, YL);
00840		if ( UTIntro(Level.Game) != None )
00841			YOffset = 64 * scale + 2 * YL;
00842		else if ( (MOTDFadeOutTime <= 0) || (Canvas.ClipY < 300) )
00843			YOffset = 64 * scale + 6 * YL;
00844		else
00845		{
00846			YOffset = 64 * scale + 6 * YL;
00847			GRI = PlayerOwner.GameReplicationInfo;
00848			if ( GRI != None )
00849			{
00850				if ( GRI.MOTDLine1 != "" )
00851					YOffset += YL;
00852				if ( GRI.MOTDLine2 != "" )
00853					YOffset += YL;
00854				if ( GRI.MOTDLine3 != "" )
00855					YOffset += YL;
00856				if ( GRI.MOTDLine4 != "" )
00857					YOffset += YL;
00858			}
00859		}
00860		for (i=0; i<8; i++)
00861		{
00862			Canvas.SetPos(0, YOffset);
00863			Canvas.DrawColor = PlayerPawn(Owner).ProgressColor[i];
00864			Canvas.DrawText(PlayerPawn(Owner).ProgressMessage[i], False);
00865			YOffset += YL + 1;
00866		}
00867		Canvas.DrawColor = WhiteColor;
00868		Canvas.bCenter = False;
00869		HUDSetup(Canvas);	
00870	}
00871	
00872	function DrawTalkFace(Canvas Canvas, float YPos)
00873	{
00874		if ( !bHideHUD && !PawnOwner.PlayerReplicationInfo.bIsSpectator )
00875		{
00876			Canvas.DrawColor = WhiteColor;
00877			Canvas.Style = ERenderStyle.STY_Normal;
00878			Canvas.SetPos(FaceAreaOffset + 4*Scale, 4*Scale);
00879			Canvas.DrawTile(FaceTexture, YPos - 1*Scale, YPos - 1*Scale, 0, 0, FaceTexture.USize, FaceTexture.VSize);
00880			Canvas.Style = ERenderStyle.STY_Translucent;
00881			Canvas.DrawColor = FaceColor;
00882			Canvas.SetPos(FaceAreaOffset, 0);
00883			Canvas.DrawTile(texture'LadrStatic.Static_a00', YPos + 7*Scale, YPos + 7*Scale, 0, 0, texture'LadrStatic.Static_a00'.USize, texture'LadrStatic.Static_a00'.VSize);
00884			Canvas.DrawColor = WhiteColor;
00885		}
00886	}
00887	
00888	function bool DrawSpeechArea( Canvas Canvas, float XL, float YL )
00889	{
00890		local float YPos, Yadj;
00891		local float WackNumber;
00892		local int paneltype;
00893	
00894		YPos = FMax(YL*4 + 8, 70*Scale);
00895		Yadj = YPos + 7*Scale;
00896		YPos *=2;
00897		MinFaceAreaOffset = -1 * Yadj;
00898		Canvas.Style = ERenderStyle.STY_Translucent;
00899		Canvas.DrawColor = HUDColor * MessageFadeTime;
00900	
00901		Canvas.SetPos(FaceAreaOffset, 0);
00902		Canvas.DrawTile(texture'LadrStatic.Static_a00', Yadj, Yadj, 0, 0, texture'LadrStatic.Static_a00'.USize, texture'LadrStatic.Static_a00'.VSize);
00903	
00904		WackNumber = 512*Scale - 64 + FaceAreaOffset; // 256*Scale - (512*Scale - (768*Scale - 64 + FaceAreaOffset));
00905		if ( !PlayerOwner.Player.Console.bTyping )
00906			paneltype = 0;
00907		else 
00908		{
00909			Canvas.StrLen("(>"@PlayerOwner.Player.Console.TypedStr$"_", XL, YL);
00910			if (XL < 768*Scale)
00911				paneltype = 1;
00912			else 
00913				paneltype = 2;
00914		}
00915	
00916		Canvas.SetPos(Yadj + FaceAreaOffset, 0);
00917		Canvas.DrawTile(FP1[paneltype], 256*Scale - FaceAreaOffset, YPos, 0, 0, FP1[paneltype].USize, FP1[paneltype].VSize);
00918	
00919		Yadj += 256 * Scale;
00920		Canvas.SetPos(Yadj, 0);
00921		Canvas.DrawTile(FP2[paneltype], WackNumber, YPos, 0, 0, FP2[paneltype].USize, FP2[paneltype].VSize);
00922	
00923		Canvas.SetPos(Yadj + WackNumber, 0);
00924		Canvas.DrawTile(FP3[paneltype], 64, YPos, 0, 0, FP3[paneltype].USize, FP3[paneltype].VSize);
00925	}
00926	
00927	//========================================
00928	// Master HUD render function.
00929	
00930	simulated function PostRender( canvas Canvas )
00931	{
00932		local float XL, YL, XPos, YPos, FadeValue;
00933		local string Message;
00934		local int M, i, j, k, XOverflow;
00935		local float OldOriginX;
00936	
00937		HUDSetup(canvas);
00938		if ( (PawnOwner == None) || (PlayerOwner.PlayerReplicationInfo == None) )
00939			return;
00940	
00941		if ( bShowInfo )
00942		{
00943			ServerInfo.RenderInfo( Canvas );
00944			return;
00945		}
00946	
00947		Canvas.Font = MyFonts.GetSmallFont( Canvas.ClipX );
00948		OldOriginX = Canvas.OrgX;
00949		// Master message short queue control loop.
00950		Canvas.Font = MyFonts.GetSmallFont( Canvas.ClipX );
00951		Canvas.StrLen("TEST", XL, YL);
00952		Canvas.SetClip(768*Scale - 10, Canvas.ClipY);
00953		bDrawFaceArea = false;
00954		if ( !bHideFaces && !PlayerOwner.bShowScores && !bForceScores && !bHideHUD 
00955				&& !PawnOwner.PlayerReplicationInfo.bIsSpectator && (Scale >= 0.4) )
00956		{
00957			DrawSpeechArea(Canvas, XL, YL);
00958			bDrawFaceArea = (FaceTexture != None) && (FaceTime > Level.TimeSeconds);
00959			if ( bDrawFaceArea )
00960			{
00961				if ( !bHideHUD && ((PawnOwner.PlayerReplicationInfo == None) || !PawnOwner.PlayerReplicationInfo.bIsSpectator) )
00962					Canvas.SetOrigin( FMax(YL*4 + 8, 70*Scale) + 7*Scale + 6 + FaceAreaOffset, Canvas.OrgY );
00963			}
00964		}
00965	
00966		for (i=0; i<4; i++)
00967		{
00968			if ( ShortMessageQueue[i].Message != None )
00969			{
00970				j++;
00971	
00972				if ( bResChanged || (ShortMessageQueue[i].XL == 0) )
00973				{
00974					if ( ShortMessageQueue[i].Message.Default.bComplexString )
00975						Canvas.StrLen(ShortMessageQueue[i].Message.Static.AssembleString( 
00976												self,
00977												ShortMessageQueue[i].Switch,
00978												ShortMessageQueue[i].RelatedPRI,
00979												ShortMessageQueue[i].StringMessage), 
00980									   ShortMessageQueue[i].XL, ShortMessageQueue[i].YL);
00981					else
00982						Canvas.StrLen(ShortMessageQueue[i].StringMessage, ShortMessageQueue[i].XL, ShortMessageQueue[i].YL);
00983					Canvas.StrLen("TEST", XL, YL);
00984					ShortMessageQueue[i].numLines = 1;
00985					if ( ShortMessageQueue[i].YL > YL )
00986					{
00987						ShortMessageQueue[i].numLines++;
00988						for (k=2; k<4-i; k++)
00989						{
00990							if (ShortMessageQueue[i].YL > YL*k)
00991								ShortMessageQueue[i].numLines++;
00992						}
00993					}
00994				}
00995	
00996				// Keep track of the amount of lines a message overflows, to offset the next message with.
00997				Canvas.SetPos(6, 2 + YL * YPos);
00998				YPos += ShortMessageQueue[i].numLines;
00999				if ( YPos > 4 )
01000					break; 
01001	
01002				if ( ShortMessageQueue[i].Message.Default.bComplexString )
01003				{
01004					// Use this for string messages with multiple colors.
01005					ShortMessageQueue[i].Message.Static.RenderComplexMessage( 
01006						Canvas,
01007						ShortMessageQueue[i].XL,  YL,
01008						ShortMessageQueue[i].StringMessage,
01009						ShortMessageQueue[i].Switch,
01010						ShortMessageQueue[i].RelatedPRI,
01011						None,
01012						ShortMessageQueue[i].OptionalObject
01013						);				
01014				} 
01015				else
01016				{
01017					Canvas.DrawColor = ShortMessageQueue[i].Message.Default.DrawColor;
01018					Canvas.DrawText(ShortMessageQueue[i].StringMessage, False);
01019				}
01020			}
01021		}
01022	
01023		Canvas.DrawColor = WhiteColor;
01024		Canvas.SetClip(OldClipX, Canvas.ClipY);
01025		Canvas.SetOrigin(OldOriginX, Canvas.OrgY);
01026	
01027		if ( PlayerOwner.bShowScores || bForceScores )
01028		{
01029			if ( (PlayerOwner.Scoring == None) && (PlayerOwner.ScoringType != None) )
01030				PlayerOwner.Scoring = Spawn(PlayerOwner.ScoringType, PlayerOwner);
01031			if ( PlayerOwner.Scoring != None )
01032			{ 
01033				PlayerOwner.Scoring.OwnerHUD = self;
01034				PlayerOwner.Scoring.ShowScores(Canvas);
01035				if ( PlayerOwner.Player.Console.bTyping )
01036					DrawTypingPrompt(Canvas, PlayerOwner.Player.Console);
01037				return;
01038			}
01039		}
01040	
01041		YPos = FMax(YL*4 + 8, 70*Scale);
01042		if ( bDrawFaceArea )
01043			DrawTalkFace( Canvas, YPos );
01044		if (j > 0) 
01045		{
01046			bDrawMessageArea = True;
01047			MessageFadeCount = 2;
01048		} 
01049		else 
01050			bDrawMessageArea = False;
01051	
01052		if ( !bHideCenterMessages )
01053		{
01054			// Master localized message control loop.
01055			for (i=0; i<10; i++)
01056			{
01057				if (LocalMessages[i].Message != None)
01058				{
01059					if (LocalMessages[i].Message.Default.bFadeMessage && Level.bHighDetailMode)
01060					{
01061						Canvas.Style = ERenderStyle.STY_Translucent;
01062						FadeValue = (LocalMessages[i].EndOfLife - Level.TimeSeconds);
01063						if (FadeValue > 0.0)
01064						{
01065							if ( bResChanged || (LocalMessages[i].XL == 0) )
01066							{
01067								if ( LocalMessages[i].Message.Static.GetFontSize(LocalMessages[i].Switch) == 1 )
01068									LocalMessages[i].StringFont = MyFonts.GetBigFont( Canvas.ClipX );
01069								else // ==2
01070									LocalMessages[i].StringFont = MyFonts.GetHugeFont( Canvas.ClipX );
01071								Canvas.Font = LocalMessages[i].StringFont;
01072								Canvas.StrLen(LocalMessages[i].StringMessage, LocalMessages[i].XL, LocalMessages[i].YL);
01073								LocalMessages[i].YPos = LocalMessages[i].Message.Static.GetOffset(LocalMessages[i].Switch, LocalMessages[i].YL, Canvas.ClipY);
01074							}
01075							Canvas.Font = LocalMessages[i].StringFont;
01076							Canvas.DrawColor = LocalMessages[i].DrawColor * (FadeValue/LocalMessages[i].LifeTime);
01077							Canvas.SetPos( 0.5 * (Canvas.ClipX - LocalMessages[i].XL), LocalMessages[i].YPos );
01078							Canvas.DrawText( LocalMessages[i].StringMessage, False );
01079						}
01080					} 
01081					else 
01082					{
01083						if ( bResChanged || (LocalMessages[i].XL == 0) )
01084						{
01085							if ( LocalMessages[i].Message.Static.GetFontSize(LocalMessages[i].Switch) == 1 )
01086								LocalMessages[i].StringFont = MyFonts.GetBigFont( Canvas.ClipX );
01087							else // == 2
01088								LocalMessages[i].StringFont = MyFonts.GetHugeFont( Canvas.ClipX );
01089							Canvas.Font = LocalMessages[i].StringFont;
01090							Canvas.StrLen(LocalMessages[i].StringMessage, LocalMessages[i].XL, LocalMessages[i].YL);
01091							LocalMessages[i].YPos = LocalMessages[i].Message.Static.GetOffset(LocalMessages[i].Switch, LocalMessages[i].YL, Canvas.ClipY);
01092						}
01093						Canvas.Font = LocalMessages[i].StringFont;
01094						Canvas.Style = ERenderStyle.STY_Normal;
01095						Canvas.DrawColor = LocalMessages[i].DrawColor;
01096						Canvas.SetPos( 0.5 * (Canvas.ClipX - LocalMessages[i].XL), LocalMessages[i].YPos );
01097						Canvas.DrawText( LocalMessages[i].StringMessage, False );
01098					}
01099				}
01100			}
01101		}
01102		Canvas.Style = ERenderStyle.STY_Normal;
01103	
01104		if ( !PlayerOwner.bBehindView && (PawnOwner.Weapon != None) && (Level.LevelAction == LEVACT_None) )
01105		{
01106			Canvas.DrawColor = WhiteColor;
01107			PawnOwner.Weapon.PostRender(Canvas);
01108			if ( !PawnOwner.Weapon.bOwnsCrossHair )
01109				DrawCrossHair(Canvas, 0,0 );
01110		}
01111	
01112		if ( (PawnOwner != Owner) && PawnOwner.bIsPlayer )
01113		{
01114			Canvas.Font = MyFonts.GetSmallFont( Canvas.ClipX );
01115			Canvas.bCenter = true;
01116			Canvas.Style = ERenderStyle.STY_Normal;
01117			Canvas.DrawColor = CyanColor * TutIconBlink;
01118			Canvas.SetPos(4, Canvas.ClipY - 96 * Scale);
01119			Canvas.DrawText( LiveFeed$PawnOwner.PlayerReplicationInfo.PlayerName, true );
01120			Canvas.bCenter = false;
01121			Canvas.DrawColor = WhiteColor;
01122			Canvas.Style = Style;
01123		}
01124	
01125		if ( bStartUpMessage && (Level.TimeSeconds < 5) )
01126		{
01127			bStartUpMessage = false;
01128			PlayerOwner.SetProgressTime(7);
01129		}
01130		if ( (PlayerOwner.ProgressTimeOut > Level.TimeSeconds) && !bHideCenterMessages )
01131			DisplayProgressMessage(Canvas);
01132	
01133		// Display MOTD
01134		if ( MOTDFadeOutTime > 0.0 )
01135			DrawMOTD(Canvas);
01136			 
01137		if( !bHideHUD )
01138		{
01139			if ( !PawnOwner.PlayerReplicationInfo.bIsSpectator )
01140			{
01141				Canvas.Style = Style;
01142	
01143				// Draw Ammo
01144				if ( !bHideAmmo )
01145					DrawAmmo(Canvas);
01146				
01147				// Draw Health/Armor status
01148				DrawStatus(Canvas);
01149	
01150				// Display Weapons
01151				if ( !bHideAllWeapons )
01152					DrawWeapons(Canvas);
01153				else if ( Level.bHighDetailMode
01154						&& (PawnOwner == PlayerOwner) && (PlayerOwner.Handedness == 2) )
01155				{
01156					// if weapon bar hidden and weapon hidden, draw weapon name when it changes
01157					if ( PawnOwner.PendingWeapon != None )
01158					{
01159						WeaponNameFade = 1.0;
01160						Canvas.Font = MyFonts.GetBigFont( Canvas.ClipX );
01161						Canvas.DrawColor = PawnOwner.PendingWeapon.NameColor;
01162						Canvas.SetPos(Canvas.ClipX - 360 * Scale, Canvas.ClipY - 64 * Scale);
01163						Canvas.DrawText(PawnOwner.PendingWeapon.ItemName, False);
01164					}
01165					else if ( (Level.NetMode == NM_Client)  
01166							&& PawnOwner.IsA('TournamentPlayer') && (TournamentPlayer(PawnOwner).ClientPending != None) )
01167					{
01168						WeaponNameFade = 1.0;
01169						Canvas.Font = MyFonts.GetBigFont( Canvas.ClipX );
01170						Canvas.DrawColor = TournamentPlayer(PawnOwner).ClientPending.NameColor;
01171						Canvas.SetPos(Canvas.ClipX - 360 * Scale, Canvas.ClipY - 64 * Scale);
01172						Canvas.DrawText(TournamentPlayer(PawnOwner).ClientPending.ItemName, False);
01173					}
01174					else if ( (WeaponNameFade > 0) && (PawnOwner.Weapon != None) )
01175					{
01176						Canvas.Font = MyFonts.GetBigFont( Canvas.ClipX );
01177						Canvas.DrawColor = PawnOwner.Weapon.NameColor;
01178						if ( WeaponNameFade < 1 )
01179							Canvas.DrawColor = Canvas.DrawColor * WeaponNameFade;
01180						Canvas.SetPos(Canvas.ClipX - 360 * Scale, Canvas.ClipY - 64 * Scale);
01181						Canvas.DrawText(PawnOwner.Weapon.ItemName, False);
01182					}
01183				}
01184				// Display Frag count
01185				if ( !bAlwaysHideFrags && !bHideFrags )
01186					DrawFragCount(Canvas);
01187			}
01188			// Team Game Synopsis
01189			if ( !bHideTeamInfo )
01190				DrawGameSynopsis(Canvas);
01191	
01192			// Display Identification Info
01193			if ( PawnOwner == PlayerOwner )
01194				DrawIdentifyInfo(Canvas);
01195	
01196			if ( HUDMutator != None )
01197				HUDMutator.PostRender(Canvas);
01198	
01199			if ( (PlayerOwner.GameReplicationInfo != None) && (PlayerPawn(Owner).GameReplicationInfo.RemainingTime > 0) ) 
01200			{
01201				if ( TimeMessageClass == None )
01202					TimeMessageClass = class<CriticalEventPlus>(DynamicLoadObject("Botpack.TimeMessage", class'Class'));
01203	
01204				if ( (PlayerOwner.GameReplicationInfo.RemainingTime <= 300)
01205				  && (PlayerOwner.GameReplicationInfo.RemainingTime != LastReportedTime) )
01206				{
01207					LastReportedTime = PlayerOwner.GameReplicationInfo.RemainingTime;
01208					if ( PlayerOwner.GameReplicationInfo.RemainingTime <= 30 )
01209					{
01210						bTimeValid = ( bTimeValid || (PlayerOwner.GameReplicationInfo.RemainingTime > 0) );	
01211						if ( PlayerOwner.GameReplicationInfo.RemainingTime == 30 )
01212							TellTime(5);
01213						else if ( bTimeValid && PlayerOwner.GameReplicationInfo.RemainingTime <= 10 )
01214							TellTime(16 - PlayerOwner.GameReplicationInfo.RemainingTime);
01215					}
01216					else if ( PlayerOwner.GameReplicationInfo.RemainingTime % 60 == 0 )
01217					{
01218						M = PlayerOwner.GameReplicationInfo.RemainingTime/60;
01219						TellTime(5 - M);
01220					}
01221				}
01222			}
01223		}
01224		if ( PlayerOwner.Player.Console.bTyping )
01225			DrawTypingPrompt(Canvas, PlayerOwner.Player.Console);
01226	
01227		if ( PlayerOwner.bBadConnectionAlert && (PlayerOwner.Level.TimeSeconds > 5) )
01228		{
01229			Canvas.Style = ERenderStyle.STY_Normal;
01230			Canvas.DrawColor = WhiteColor;
01231			Canvas.SetPos(Canvas.ClipX - (64*Scale), Canvas.ClipY / 2);
01232			Canvas.DrawIcon(texture'DisconnectWarn', Scale);
01233		}
01234	}
01235	
01236	function Timer()
01237	{
01238		local int i, j;
01239	
01240		if (!bDrawMessageArea)
01241		{
01242			if (MessageFadeCount > 0)
01243				MessageFadeCount--;
01244		}
01245	
01246		// Age the short message queue.
01247		for (i=0; i<4; i++)
01248		{
01249			// Purge expired messages.
01250			if ( (ShortMessageQueue[i].Message != None) && (Level.TimeSeconds >= ShortMessageQueue[i].EndOfLife) )
01251				ClearMessage(ShortMessageQueue[i]);
01252		}
01253	
01254		// Clean empty slots.
01255		for (i=0; i<3; i++)
01256		{
01257			if ( ShortMessageQueue[i].Message == None )
01258			{
01259				for (j=i; j<4; j++)
01260				{
01261					if ( ShortMessageQueue[j].Message != None )
01262					{
01263						CopyMessage(ShortMessageQueue[i],ShortMessageQueue[j]);
01264						ClearMessage(ShortMessageQueue[j]);
01265						break;
01266					}
01267				}
01268			}
01269		}
01270	
01271		// Age all localized messages.
01272		for (i=0; i<10; i++)
01273		{
01274			// Purge expired messages.
01275			if ( (LocalMessages[i].Message != None) && (Level.TimeSeconds >= LocalMessages[i].EndOfLife) )
01276				ClearMessage(LocalMessages[i]);
01277		}
01278	
01279		// Clean empty slots.
01280		for (i=0; i<9; i++)
01281		{
01282			if ( LocalMessages[i].Message == None )
01283			{
01284				CopyMessage(LocalMessages[i],LocalMessages[i+1]);
01285				ClearMessage(LocalMessages[i+1]);
01286			}
01287		}
01288	
01289		if ( (PlayerOwner == None) || (PawnOwner == None) || (PlayerOwner.GameReplicationInfo == None)
01290			|| (PawnOwner.PlayerReplicationInfo == None) )
01291			return;
01292	
01293		// Update the rank and spread.
01294		UpdateRankAndSpread();
01295	}
01296	
01297	function UpdateRankAndSpread()
01298	{
01299		local PlayerReplicationInfo PRI;
01300		local int HighScore;
01301		local int i, j;
01302	
01303		PlayerCount = 0;
01304		HighScore = -100;
01305		bTiedScore = False;
01306		Rank = 1;
01307		for (i=0; i<32; i++)
01308		{
01309			PRI = PlayerOwner.GameReplicationInfo.PRIArray[i];
01310			if ( (PRI != None) && (!PRI.bIsSpectator || PRI.bWaitingPlayer) )
01311			{
01312				PlayerCount++;
01313				if (PRI != PawnOwner.PlayerReplicationInfo)
01314				{
01315					if (PRI.Score > PawnOwner.PlayerReplicationInfo.Score)
01316						Rank += 1;
01317					else if (PRI.Score == PawnOwner.PlayerReplicationInfo.Score)
01318					{
01319						bTiedScore = True;
01320						if (PRI.Deaths < PawnOwner.PlayerReplicationInfo.Deaths)
01321							Rank += 1;
01322						else if (PRI.Deaths == PawnOwner.PlayerReplicationInfo.Deaths)
01323							if (PRI.PlayerID < PawnOwner.PlayerReplicationInfo.PlayerID)
01324								Rank += 1;
01325					}
01326					if (PRI.Score > HighScore)
01327						HighScore = PRI.Score;
01328				}
01329			}
01330		}
01331		Lead = int(PawnOwner.PlayerReplicationInfo.Score) - HighScore;
01332	}
01333	
01334	simulated function TellTime(int num)
01335	{
01336		PlayerOwner.ReceiveLocalizedMessage( TimeMessageClass, Num );
01337	}
01338	
01339	simulated function Tick(float DeltaTime)
01340	{
01341		local int i;
01342	
01343		Super.Tick(DeltaTime);
01344	
01345		IdentifyFadeTime = FMax(0.0, IdentifyFadeTime - DeltaTime);
01346		MOTDFadeOutTime = FMax(0.0, MOTDFadeOutTime - DeltaTime * 55);
01347		
01348		TutIconBlink += DeltaTime;
01349		if (TutIconBlink >= 0.5)
01350			TutIconBlink = 0.0;
01351	
01352		if ( bDrawFaceArea )
01353		{
01354			if ( FaceAreaOffset < 0 )
01355				FaceAreaOffset += DeltaTime * 600;
01356			if ( FaceAreaOffset > 0 )
01357				FaceAreaOffset = 0.0;
01358		} 
01359		else if ( FaceAreaOffset > MinFaceAreaOffset )
01360			FaceAreaOffset = FMax(FaceAreaOffset - DeltaTime * 600, MinFaceAreaOffset );
01361	
01362		if ( bDrawMessageArea )
01363		{
01364			if ( MessageFadeTime < 1.0 )
01365			{
01366				MessageFadeTime += DeltaTime * 8;
01367				if (MessageFadeTime > 1.0)
01368					MessageFadeTime = 1.0;
01369			}
01370		} 
01371		else if ( (MessageFadeTime > 0.0) && (MessageFadeCount == 0) )
01372		{
01373			MessageFadeTime -= DeltaTime * 2;
01374			if (MessageFadeTime < 0.0)
01375				MessageFadeTime = 0.0;
01376		}
01377		WeaponNameFade -= DeltaTime;
01378	}
01379	
01380	simulated function DrawMOTD(Canvas Canvas)
01381	{
01382		local GameReplicationInfo GRI;
01383		local float XL, YL;
01384		local float InitialY;
01385	
01386		GRI = PlayerPawn(Owner).GameReplicationInfo;
01387		if ( (GRI == None) || (GRI.GameName == "Game") || (MOTDFadeOutTime <= 0) ) 
01388			return;
01389	
01390		Canvas.Font = MyFonts.GetSmallFont( Canvas.ClipX );
01391		Canvas.Style = Style;
01392		Canvas.bCenter = true;
01393		Canvas.DrawColor = UnitColor * MOTDFadeOutTime * 0.5;
01394		InitialY = 64*Scale;
01395		Canvas.SetPos(0.0, InitialY);
01396		Canvas.StrLen("TEST", XL, YL);
01397		if ( Level.NetMode != NM_Standalone )
01398		{
01399			Canvas.DrawText(GRI.ServerName);
01400			if ( Canvas.ClipY >= 300 )
01401			{
01402				Canvas.SetPos(0.0, InitialY + 6*YL);
01403				Canvas.DrawText(GRI.MOTDLine1, true);
01404				Canvas.SetPos(0.0, InitialY + 7*YL);
01405				Canvas.DrawText(GRI.MOTDLine2, true);
01406				Canvas.SetPos(0.0, InitialY + 8*YL);
01407				Canvas.DrawText(GRI.MOTDLine3, true);
01408				Canvas.SetPos(0.0, InitialY + 9*YL);
01409				Canvas.DrawText(GRI.MOTDLine4, true);
01410			}
01411		}
01412		Canvas.DrawColor = UnitColor * MOTDFadeOutTime * 0.6;
01413		Canvas.SetPos(0.0, InitialY + YL);
01414		Canvas.DrawText(GRI.GameName, true);
01415		Canvas.SetPos(0.0, InitialY + 2*YL);
01416		Canvas.DrawText(MapTitleString2@Level.Title, true);
01417		if ( Canvas.ClipY >= 300 )
01418		{
01419			Canvas.SetPos(0.0, InitialY + 3*YL);
01420			Canvas.DrawText(AuthorString2@Level.Author, true);
01421			if (Level.IdealPlayerCount != "")
01422			{
01423				Canvas.SetPos(0.0, InitialY + 4*YL);
01424				Canvas.DrawText(PlayerCountString$Level.IdealPlayerCount, true);
01425			}
01426		}
01427		Canvas.bCenter = false;
01428	}
01429	
01430	simulated function DrawCrossHair( canvas Canvas, int X, int Y)
01431	{
01432		local float XScale, PickDiff;
01433		local float XLength;
01434		local texture T;
01435	
01436	 	if (Crosshair>=CrosshairCount) Return;
01437		if ( Canvas.ClipX < 512 )
01438			XScale = 0.5;
01439		else
01440			XScale = FMax(1, int(0.1 + Canvas.ClipX/640.0));
01441		PickDiff = Level.TimeSeconds - PickupTime;
01442		if ( PickDiff < 0.4 )
01443		{
01444			if ( PickDiff < 0.2 )
01445				XScale *= (1 + 5 * PickDiff);
01446			else
01447				XScale *= (3 - 5 * PickDiff);
01448		}
01449		XLength = XScale * 64.0;
01450	
01451		Canvas.bNoSmooth = False;
01452		if ( PlayerOwner.Handedness == -1 )
01453			Canvas.SetPos(0.503 * (Canvas.ClipX - XLength), 0.504 * (Canvas.ClipY - XLength));
01454		else if ( PlayerOwner.Handedness == 1 )
01455			Canvas.SetPos(0.497 * (Canvas.ClipX - XLength), 0.496 * (Canvas.ClipY - XLength));
01456		else
01457			Canvas.SetPos(0.5 * (Canvas.ClipX - XLength), 0.5 * (Canvas.ClipY - XLength));
01458		Canvas.Style = ERenderStyle.STY_Translucent;
01459		Canvas.DrawColor = 15 * CrosshairColor;
01460	
01461		T = CrossHairTextures[Crosshair];
01462		if( T == None )
01463			T = LoadCrosshair(Crosshair);
01464	
01465		Canvas.DrawTile(T, XLength, XLength, 0, 0, 64, 64);
01466		Canvas.bNoSmooth = True;
01467		Canvas.Style = Style;
01468	}
01469	
01470	simulated function DrawTypingPrompt( canvas Canvas, console Console )
01471	{
01472		local string TypingPrompt;
01473		local float XL, YL, YPos, XOffset;
01474		local float MyOldClipX, OldClipY, OldOrgX, OldOrgY;
01475	
01476		MyOldClipX = Canvas.ClipX;
01477		OldClipY = Canvas.ClipY;
01478		OldOrgX = Canvas.OrgX;
01479		OldOrgY = Canvas.OrgY;
01480	
01481		Canvas.DrawColor = GreenColor;
01482		TypingPrompt = "(>"@Console.TypedStr$"_";
01483		Canvas.Font = MyFonts.GetSmallFont( Canvas.ClipX );
01484		Canvas.StrLen( "TEST", XL, YL );
01485		YPos = YL*4 + 8;
01486		if (PawnOwner.PlayerReplicationInfo.bIsSpectator || bHideHUD || bHideFaces)
01487			XOffset = 0;
01488		else
01489			XOffset = FMax(0,FaceAreaOffset + 15*Scale + YPos);
01490		Canvas.SetOrigin(XOffset, FMax(0,YPos + 7*Scale));
01491		Canvas.SetClip( 760*Scale, Canvas.ClipY );
01492		Canvas.SetPos( 0, 0 );
01493		Canvas.DrawText( TypingPrompt, false );
01494		Canvas.SetOrigin( OldOrgX, OldOrgY );
01495		Canvas.SetClip( MyOldClipX, OldClipY );
01496	}
01497	
01498	// Entry point for string messages.
01499	simulated function Message( PlayerReplicationInfo PRI, coerce string Msg, name MsgType )
01500	{
01501		local int i;
01502		local Class<LocalMessage> MessageClass;
01503	
01504		switch (MsgType)
01505		{
01506			case 'Say':
01507			case 'TeamSay':
01508				MessageClass = class'SayMessagePlus';
01509				break;
01510			case 'CriticalEvent':
01511				MessageClass = class'CriticalStringPlus';
01512				LocalizedMessage( MessageClass, 0, None, None, None, Msg );
01513				return;
01514			case 'DeathMessage':
01515				MessageClass = class'RedSayMessagePlus';
01516				break;
01517			case 'Pickup':
01518				PickupTime = Level.TimeSeconds;
01519			default:
01520				MessageClass = class'StringMessagePlus';
01521				break;
01522		}
01523	
01524		if ( ClassIsChildOf(MessageClass, class'SayMessagePlus') || 
01525					     ClassIsChildOf(MessageClass, class'TeamSayMessagePlus') )
01526		{
01527			FaceTexture = PRI.TalkTexture;
01528			if ( FaceTexture != None )
01529				FaceTime = Level.TimeSeconds + 3;
01530			if ( Msg == "" )
01531				return;
01532		} 
01533		for (i=0; i<4; i++)
01534		{
01535			if ( ShortMessageQueue[i].Message == None )
01536			{
01537				// Add the message here.
01538				ShortMessageQueue[i].Message = MessageClass;
01539				ShortMessageQueue[i].Switch = 0;
01540				ShortMessageQueue[i].RelatedPRI = PRI;
01541				ShortMessageQueue[i].OptionalObject = None;
01542				ShortMessageQueue[i].EndOfLife = MessageClass.Default.Lifetime + Level.TimeSeconds;
01543				if ( MessageClass.Default.bComplexString )
01544					ShortMessageQueue[i].StringMessage = Msg;
01545				else
01546					ShortMessageQueue[i].StringMessage = MessageClass.Static.AssembleString(self,0,PRI,Msg);
01547				return;
01548			}
01549		}
01550	
01551		// No empty slots.  Force a message out.
01552		for (i=0; i<3; i++)
01553			CopyMessage(ShortMessageQueue[i], ShortMessageQueue[i+1]);
01554	
01555		ShortMessageQueue[3].Message = MessageClass;
01556		ShortMessageQueue[3].Switch = 0;
01557		ShortMessageQueue[3].RelatedPRI = PRI;
01558		ShortMessageQueue[3].OptionalObject = None;
01559		ShortMessageQueue[3].EndOfLife = MessageClass.Default.Lifetime + Level.TimeSeconds;
01560		if ( MessageClass.Default.bComplexString )
01561			ShortMessageQueue[3].StringMessage = Msg;
01562		else
01563			ShortMessageQueue[3].StringMessage = MessageClass.Static.AssembleString(self,0,PRI,Msg);
01564	}
01565	
01566	simulated function bool DisplayMessages( canvas Canvas )
01567	{
01568		return true;
01569	}
01570	
01571	simulated function float DrawNextMessagePart(Canvas Canvas, string MString, float XOffset, int YPos)
01572	{
01573		local float XL, YL;
01574	
01575		Canvas.SetPos(4 + XOffset, YPos);
01576		Canvas.StrLen( MString, XL, YL );
01577		Canvas.DrawText( MString, false );
01578		return (XOffset + XL);
01579	}
01580	
01581	//================================================================================
01582	// Identify Info
01583	
01584	simulated function bool TraceIdentify(canvas Canvas)
01585	{
01586		local actor Other;
01587		local vector HitLocation, HitNormal, StartTrace, EndTrace;
01588	
01589		StartTrace = PawnOwner.Location;
01590		StartTrace.Z += PawnOwner.BaseEyeHeight;
01591		EndTrace = StartTrace + vector(PawnOwner.ViewRotation) * 1000.0;
01592		Other = Trace(HitLocation, HitNormal, EndTrace, StartTrace, true);
01593	
01594		if ( Pawn(Other) != None )
01595		{
01596			if ( Pawn(Other).bIsPlayer && !Other.bHidden )
01597			{
01598				IdentifyTarget = Pawn(Other).PlayerReplicationInfo;
01599				IdentifyFadeTime = 3.0;
01600			}
01601		}
01602		else if ( (Other != None) && SpecialIdentify(Canvas, Other) )
01603			return false;
01604	
01605		if ( (IdentifyFadeTime == 0.0) || (IdentifyTarget == None) || IdentifyTarget.bFeigningDeath )
01606			return false;
01607	
01608		return true;
01609	}
01610	
01611	simulated function bool SpecialIdentify(Canvas Canvas, Actor Other )
01612	{
01613		return false;
01614	}
01615	
01616	simulated function SetIDColor( Canvas Canvas, int type )
01617	{
01618		Canvas.DrawColor = GreenColor;
01619		if ( type == 0 )
01620			Canvas.DrawColor.G = 160 * (IdentifyFadeTime / 3.0);
01621		else
01622			Canvas.DrawColor.G = 255 * (IdentifyFadeTime / 3.0);
01623	}
01624	
01625	simulated function DrawTwoColorID( canvas Canvas, string TitleString, string ValueString, int YStart )
01626	{
01627		local float XL, YL, XOffset, X1;
01628	
01629		Canvas.Style = Style;
01630		Canvas.StrLen(TitleString$": ", XL, YL);
01631		X1 = XL;
01632		Canvas.StrLen(ValueString, XL, YL);
01633		XOffset = Canvas.ClipX/2 - (X1+XL)/2;
01634		Canvas.SetPos(XOffset, YStart);
01635		SetIDColor(Canvas,0);
01636		XOffset += X1;
01637		Canvas.DrawText(TitleString);
01638		Canvas.SetPos(XOffset, YStart);
01639		SetIDColor(Canvas,1);
01640		Canvas.DrawText(ValueString);
01641		Canvas.DrawColor = WhiteColor;
01642		Canvas.Font = MyFonts.GetSmallFont( Canvas.ClipX );
01643	}
01644		
01645	simulated function bool DrawIdentifyInfo(canvas Canvas)
01646	{
01647		if ( !TraceIdentify(Canvas))
01648			return false;
01649	
01650		if( IdentifyTarget.PlayerName != "" )
01651		{
01652			Canvas.Font = MyFonts.GetBigFont(Canvas.ClipX);
01653			DrawTwoColorID(Canvas,IdentifyName, IdentifyTarget.PlayerName, Canvas.ClipY - 256 * Scale);
01654		}
01655		return true;
01656	}
01657	
01658	//=====================================================================
01659	// Deal with a localized message.
01660	
01661	simulated function LocalizedMessage( class<LocalMessage> Message, optional int Switch, optional PlayerReplicationInfo RelatedPRI_1, optional PlayerReplicationInfo RelatedPRI_2, optional Object OptionalObject, optional String CriticalString )
01662	{
01663		local int i;
01664	
01665		if ( ClassIsChildOf( Message, class'PickupMessagePlus' ) )
01666			PickupTime = Level.TimeSeconds;
01667	
01668		if ( !Message.Default.bIsSpecial )
01669		{
01670			if ( ClassIsChildOf(Message, class'SayMessagePlus') || 
01671							 ClassIsChildOf(Message, class'TeamSayMessagePlus') )
01672			{
01673				FaceTexture = RelatedPRI_1.TalkTexture;
01674				if ( FaceTexture != None )
01675					FaceTime = Level.TimeSeconds + 3;
01676			} 
01677			// Find an empty slot.
01678			for (i=0; i<4; i++)
01679			{
01680				if ( ShortMessageQueue[i].Message == None )
01681				{
01682					ShortMessageQueue[i].Message = Message;
01683					ShortMessageQueue[i].Switch = Switch;
01684					ShortMessageQueue[i].RelatedPRI = RelatedPRI_1;
01685					ShortMessageQueue[i].OptionalObject = OptionalObject;
01686					ShortMessageQueue[i].EndOfLife = Message.Default.Lifetime + Level.TimeSeconds;
01687					if ( Message.Default.bComplexString )
01688						ShortMessageQueue[i].StringMessage = CriticalString;
01689					else
01690						ShortMessageQueue[i].StringMessage = Message.Static.GetString(Switch, RelatedPRI_1, RelatedPRI_2, OptionalObject);
01691					return;
01692				}
01693	
01694			}
01695			// No empty slots.  Force a message out.
01696			for (i=0; i<3; i++)
01697				CopyMessage(ShortMessageQueue[i], ShortMessageQueue[i+1]);
01698	
01699			ShortMessageQueue[3].Message = Message;
01700			ShortMessageQueue[3].Switch = Switch;
01701			ShortMessageQueue[3].RelatedPRI = RelatedPRI_1;
01702			ShortMessageQueue[3].OptionalObject = OptionalObject;
01703			ShortMessageQueue[3].EndOfLife = Message.Default.Lifetime + Level.TimeSeconds;
01704			if ( Message.Default.bComplexString )
01705				ShortMessageQueue[3].StringMessage = CriticalString;
01706			else
01707				ShortMessageQueue[3].StringMessage = Message.Static.GetString(Switch, RelatedPRI_1, RelatedPRI_2, OptionalObject);
01708			return;
01709		} 
01710		else 
01711		{
01712			if ( CriticalString == "" )
01713				CriticalString = Message.Static.GetString(Switch, RelatedPRI_1, RelatedPRI_2, OptionalObject);
01714			if ( Message.Default.bIsUnique )
01715			{
01716				for (i=0; i<10; i++)
01717				{
01718					if (LocalMessages[i].Message != None)
01719					{
01720						if ((LocalMessages[i].Message == Message) 
01721							|| (LocalMessages[i].Message.Static.GetOffset(LocalMessages[i].Switch, 24, 640) 
01722									== Message.Static.GetOffset(Switch, 24, 640)) ) 
01723						{
01724							LocalMessages[i].Message = Message;
01725							LocalMessages[i].Switch = Switch;
01726							LocalMessages[i].RelatedPRI = RelatedPRI_1;
01727							LocalMessages[i].OptionalObject = OptionalObject;
01728							LocalMessages[i].LifeTime = Message.Default.Lifetime;
01729							LocalMessages[i].EndOfLife = Message.Default.Lifetime + Level.TimeSeconds;
01730							LocalMessages[i].StringMessage = CriticalString;
01731							LocalMessages[i].DrawColor = Message.Static.GetColor(Switch, RelatedPRI_1, RelatedPRI_2);				
01732							LocalMessages[i].XL = 0;
01733							return;
01734						}
01735					}
01736				}
01737			}
01738			for (i=0; i<10; i++)
01739			{
01740				if (LocalMessages[i].Message == None)
01741				{
01742					LocalMessages[i].Message = Message;
01743					LocalMessages[i].Switch = Switch;
01744					LocalMessages[i].RelatedPRI = RelatedPRI_1;
01745					LocalMessages[i].OptionalObject = OptionalObject;
01746					LocalMessages[i].EndOfLife = Message.Default.Lifetime + Level.TimeSeconds;
01747					LocalMessages[i].StringMessage = CriticalString;
01748					LocalMessages[i].DrawColor = Message.Static.GetColor(Switch, RelatedPRI_1, RelatedPRI_2);				
01749					LocalMessages[i].LifeTime = Message.Default.Lifetime;
01750					LocalMessages[i].XL = 0;
01751					return;
01752				}
01753			}
01754	
01755			// No empty slots.  Force a message out.
01756			for (i=0; i<9; i++)
01757				CopyMessage(LocalMessages[i],LocalMessages[i+1]);
01758	
01759			LocalMessages[9].Message = Message;
01760			LocalMessages[9].Switch = Switch;
01761			LocalMessages[9].RelatedPRI = RelatedPRI_1;
01762			LocalMessages[9].OptionalObject = OptionalObject;
01763			LocalMessages[9].EndOfLife = Message.Default.Lifetime + Level.TimeSeconds;
01764			LocalMessages[9].StringMessage = CriticalString;
01765			LocalMessages[9].DrawColor = Message.Static.GetColor(Switch, RelatedPRI_1, RelatedPRI_2);				
01766			LocalMessages[9].LifeTime = Message.Default.Lifetime;
01767			LocalMessages[9].XL = 0;
01768			return;
01769		}
01770	}
01771	
01772	defaultproperties
01773	{
01774	     VersionMessage="Version"
01775	     PlayerCountString="Ideal Player Load:"
01776	     MapTitleString="in"
01777	     AuthorString="by"
01778	     MapTitleString2="Map:"
01779	     AuthorString2="Author:"
01780	     RankString="Rank:"
01781	     SpreadString="Spread:"
01782	     CrosshairCount=9
01783	     CrossHairs(0)="Botpack.CHair1"
01784	     CrossHairs(1)="Botpack.CHair2"
01785	     CrossHairs(2)="Botpack.CHair3"
01786	     CrossHairs(3)="Botpack.CHair4"
01787	     CrossHairs(4)="Botpack.CHair5"
01788	     CrossHairs(5)="Botpack.CHair6"
01789	     CrossHairs(6)="Botpack.CHair7"
01790	     CrossHairs(7)="Botpack.CHair8"
01791	     CrossHairs(8)="Botpack.CHair9"
01792	     FP1(0)=Texture'Botpack.FacePanel.FacePanel1'
01793	     FP1(1)=Texture'Botpack.FacePanel.FacePanel1b'
01794	     FP1(2)=Texture'Botpack.FacePanel.FacePanel1a'
01795	     FP2(0)=Texture'Botpack.FacePanel.FacePanel2'
01796	     FP2(1)=Texture'Botpack.FacePanel.FacePanel2b'
01797	     FP2(2)=Texture'Botpack.FacePanel.FacePanel2a'
01798	     FP3(0)=Texture'Botpack.FacePanel.FacePanel3'
01799	     FP3(1)=Texture'Botpack.FacePanel.FacePanel3b'
01800	     FP3(2)=Texture'Botpack.FacePanel.FacePanel3a'
01801	     bStartUpMessage=True
01802	     bUseTeamColor=True
01803	     Opacity=15
01804	     HUDScale=1.000000
01805	     StatusScale=1.000000
01806	     WeaponScale=0.800000
01807	     FavoriteHUDColor=(B=16)
01808	     CrosshairColor=(G=16)
01809	     Style=3
01810	     WhiteColor=(R=255,G=255,B=255)
01811	     RedColor=(R=255)
01812	     GreenColor=(G=255)
01813	     CyanColor=(G=255,B=255)
01814	     UnitColor=(R=1,G=1,B=1)
01815	     BlueColor=(B=255)
01816	     GoldColor=(R=255,G=255)
01817	     PurpleColor=(R=255,B=255)
01818	     TurqColor=(G=128,B=255)
01819	     GrayColor=(R=200,G=200,B=200)
01820	     FaceColor=(R=50,G=50,B=50)
01821	     IdentifyName="Name:"
01822	     IdentifyHealth="Health:"
01823	     IdentifyCallsign="Callsign:"
01824	     LiveFeed="Live Feed from "
01825	     ScoreTime=-10000000.000000
01826	     ServerInfoClass=Class'Botpack.ServerInfo'
01827	     FontInfoClass="Botpack.FontInfo"
01828	     HUDConfigWindowType="UTMenu.UTChallengeHUDConfig"
01829	}

End Source Code