- CORRECTPIXELSTRETCH where needed on models. - Replace CoordUtil.GetAxes with quaternion version.
1047 lines
38 KiB
Text
1047 lines
38 KiB
Text
// An almost 1:1 recreation of the Unreal 1 HUD
|
|
Class UnrealHUD : BaseStatusBar
|
|
{
|
|
double FracTic;
|
|
|
|
// for easy access to ammo slots
|
|
UnrealMainHandler hnd;
|
|
|
|
// Unreal HUD variables
|
|
Color RedColor, GreenColor, BlackColor;
|
|
int HudMode;
|
|
|
|
// Helpers
|
|
Vector2 scalev;
|
|
double CurX, CurY, ClipX, ClipY;
|
|
Color DrawColor;
|
|
ViewTracer vtracer;
|
|
Actor lastseen;
|
|
int lastseentic, Count;
|
|
|
|
// Fonts
|
|
Font LargeFont, LargeRedFont, UBigFont, MedFont, WhiteFont, TinyFont, TinyWhiteFont, TinyRedFont;
|
|
HUDFont mMapFont;
|
|
|
|
// Common Textures
|
|
TextureID HalfHud, HudLine, HudAmmo, IconHeal, IconSkul, IconSel, IconBase, KeyIcons[7];
|
|
|
|
// messaging stuff
|
|
String PickupMsg;
|
|
int PickupMsgTic;
|
|
String ShortMsg[4];
|
|
int ShortMsgTic[4];
|
|
int ShortMsgCol[4];
|
|
String MidPrintStr;
|
|
int MidPrintTic;
|
|
bool MidPrintLarge;
|
|
Weapon lastwep;
|
|
String ntagstr;
|
|
int ntagtic;
|
|
|
|
// 0.83 HUD stuff
|
|
Array<String> OldAmmo;
|
|
Array<Class<Inventory> > OldAmmoType;
|
|
Array<String> OldArmor;
|
|
Array<Class<Inventory> > OldArmorType;
|
|
String OldKeys[7];
|
|
HUDFont mOldDigits, mOldDigitsSmall;
|
|
Font OldLargeFont, OldSmallFont;
|
|
|
|
// Translations
|
|
int RedIcon;
|
|
|
|
// Translator menu interaction
|
|
transient bool bTranslatorActive;
|
|
|
|
override void Init()
|
|
{
|
|
Super.Init();
|
|
SetSize(64,640,400);
|
|
// Initialize
|
|
Count = 0;
|
|
vtracer = new("ViewTracer");
|
|
RedColor = "FF 00 00";
|
|
GreenColor = "00 FF 00";
|
|
BlackColor = "00 00 00";
|
|
DrawColor = "FF FF FF";
|
|
LargeFont = Font.GetFont('ULargeFont');
|
|
LargeRedFont = Font.GetFont('ULargeRedFont');
|
|
UBigFont = Font.GetFont('UBigFont');
|
|
MedFont = Font.GetFont('UMedFont');
|
|
WhiteFont = Font.GetFont('UWhiteFont');
|
|
TinyFont = Font.GetFont('UTinyFont');
|
|
TinyWhiteFont = Font.GetFont('UTinyWhiteFont');
|
|
TinyRedFont = Font.GetFont('UTinyRedFont');
|
|
HalfHud = TexMan.CheckForTexture("HalfHud",TexMan.Type_Any);
|
|
HudLine = TexMan.CheckForTexture("HudLine",TexMan.Type_Any);
|
|
HudAmmo = TexMan.CheckForTexture("HudAmmo",TexMan.Type_Any);
|
|
IconHeal = TexMan.CheckForTexture("IconHeal",TexMan.Type_Any);
|
|
IconSkul = TexMan.CheckForTexture("IconSkul",TexMan.Type_Any);
|
|
IconSel = TexMan.CheckForTexture("IconSel",TexMan.Type_Any);
|
|
IconBase = TexMan.CheckForTexture("IconBase",TexMan.Type_Any);
|
|
RedIcon = Translation.GetID('RedIcon');
|
|
KeyIcons[0] = TexMan.CheckForTexture("I_KeyR",TexMan.Type_Any);
|
|
KeyIcons[1] = TexMan.CheckForTexture("I_KeyB",TexMan.Type_Any);
|
|
KeyIcons[2] = TexMan.CheckForTexture("I_KeyY",TexMan.Type_Any);
|
|
KeyIcons[3] = TexMan.CheckForTexture("I_SkullR",TexMan.Type_Any);
|
|
KeyIcons[4] = TexMan.CheckForTexture("I_SkullB",TexMan.Type_Any);
|
|
KeyIcons[5] = TexMan.CheckForTexture("I_SkullY",TexMan.Type_Any);
|
|
KeyIcons[6] = TexMan.CheckForTexture("I_KeyG",TexMan.Type_Any);
|
|
mOldDigits = HUDFont.Create(Font.GetFont('U083Digits'),26,Mono_CellLeft);
|
|
mOldDigitsSmall = HUDFont.Create(Font.GetFont('U083DigitsSmall'),13,Mono_CellLeft);
|
|
mMapFont = HUDFont.Create(WhiteFont);
|
|
OldLargeFont = Font.GetFont('UOldLargeFont');
|
|
OldSmallFont = Font.GetFont('UOldSmallFont');
|
|
// load icon lists
|
|
Array<String> lst, ent;
|
|
String dat;
|
|
for ( int lmp = Wads.FindLump("oldammoicons.txt"); lmp > 0; lmp = Wads.FindLump("oldammoicons.txt",lmp+1) )
|
|
{
|
|
dat = Wads.ReadLump(lmp);
|
|
lst.Clear();
|
|
dat.Split(lst,"\n",0);
|
|
for ( int i=0; i<lst.Size(); i++ )
|
|
{
|
|
if ( (lst[i].Length() <= 0) || (lst[i].Left(1) ~== "#") ) continue;
|
|
ent.Clear();
|
|
lst[i].Split(ent,",",0);
|
|
if ( ent.Size() != 2 ) continue;
|
|
Class<Inventory> i = ent[1];
|
|
if ( !i ) continue;
|
|
OldAmmo.Push(ent[0]);
|
|
OldAmmoType.Push(i);
|
|
}
|
|
}
|
|
for ( int lmp = Wads.FindLump("oldarmoricons.txt"); lmp > 0; lmp = Wads.FindLump("oldarmoricons.txt",lmp+1) )
|
|
{
|
|
dat = Wads.ReadLump(lmp);
|
|
lst.Clear();
|
|
dat.Split(lst,"\n",0);
|
|
for ( int i=0; i<lst.Size(); i++ )
|
|
{
|
|
if ( (lst[i].Length() <= 0) || (lst[i].Left(1) ~== "#") ) continue;
|
|
ent.Clear();
|
|
lst[i].Split(ent,",",0);
|
|
if ( ent.Size() != 2 ) continue;
|
|
Class<Inventory> i = ent[1];
|
|
if ( !i ) continue;
|
|
OldArmor.Push(ent[0]);
|
|
OldArmorType.Push(i);
|
|
}
|
|
}
|
|
OldKeys[0] = "Redk083";
|
|
OldKeys[1] = "Bluek083";
|
|
OldKeys[2] = "Goldk083";
|
|
OldKeys[3] = "Rskul083";
|
|
OldKeys[4] = "Bskul083";
|
|
OldKeys[5] = "Gskul083";
|
|
OldKeys[6] = "Grenk083";
|
|
}
|
|
|
|
override void Draw( int state, double TicFrac )
|
|
{
|
|
// make sure vanilla nametags don't display
|
|
DetachMessageID(0x5745504e); // WEPN
|
|
DetachMessageID(0x53494e56); // SINV
|
|
// also try with different endianness, just in case
|
|
DetachMessageID(0x4e504557); // WEPN
|
|
DetachMessageID(0x564e4953); // SINV
|
|
Super.Draw(state,TicFrac);
|
|
FracTic = TicFrac;
|
|
HudMode = sting_hudmode;
|
|
scalev.x = scalev.y = hud_scale;
|
|
if ( scalev.x <= 0 )
|
|
{
|
|
scalev.x = CleanXFac_1;
|
|
scalev.y = CleanYFac_1;
|
|
}
|
|
ClipX = Screen.GetWidth()/scalev.x;
|
|
ClipY = Screen.GetHeight()/scalev.y;
|
|
CurX = 0;
|
|
CurY = 0;
|
|
double lbottom = Screen.GetHeight()-32*scalev.y;
|
|
for ( Inventory i=CPlayer.mo.inv; i; i=i.inv )
|
|
if ( i is 'UnrealInventory' )
|
|
UnrealInventory(i).PreRender(lbottom);
|
|
if ( CPlayer.ReadyWeapon is 'UTWeapon' )
|
|
UTWeapon(CPlayer.ReadyWeapon).PreRender(lbottom);
|
|
if ( state == HUD_Fullscreen )
|
|
{
|
|
BeginHUD();
|
|
DrawUnrealHUD();
|
|
}
|
|
else if ( state == HUD_StatusBar )
|
|
{
|
|
BeginStatusBar();
|
|
DrawUnrealBar();
|
|
}
|
|
for ( Inventory i=CPlayer.mo.inv; i; i=i.inv )
|
|
if ( i is 'UnrealInventory' )
|
|
UnrealInventory(i).PostRender(lbottom);
|
|
if ( CPlayer.ReadyWeapon is 'UTWeapon' )
|
|
UTWeapon(CPlayer.ReadyWeapon).PostRender(lbottom);
|
|
DrawIdentifyInfo(state);
|
|
DrawMessages(state);
|
|
}
|
|
|
|
private void DrawNumberOf( Inventory i, double x, double y )
|
|
{
|
|
if ( (i.Amount <= 1) && !((i is 'UnrealInventory') && UnrealInventory(i).bDRAWSPECIAL) ) return;
|
|
double TempX = CurX, TempY = CurY;
|
|
string itxt = String.Format("%d",((i is 'UnrealInventory')&&UnrealInventory(i).bDRAWSPECIAL)?i.special1:min(99999,i.Amount));
|
|
CurX += 30;
|
|
CurY += 23;
|
|
CurX -= TinyRedFont.StringWidth(itxt);
|
|
Screen.DrawText(TinyRedFont,Font.CR_UNTRANSLATED,CurX,CurY,itxt,DTA_VirtualWidthF,ClipX,DTA_VirtualHeightF,ClipY,DTA_KeepRatio,true);
|
|
CurX = TempX;
|
|
CurY = TempY;
|
|
}
|
|
|
|
private void DrawIconValue( int n, bool bIsArmor = false )
|
|
{
|
|
if ( !HudMode || (HudMode == 3) ) return;
|
|
double TempX = CurX, TempY = CurY;
|
|
string itxt = String.Format("%d",n);
|
|
CurX -= 2;
|
|
CurY -= 6;
|
|
CurX -= TinyFont.StringWidth(itxt);
|
|
Screen.DrawText(TinyFont,Font.CR_UNTRANSLATED,CurX,CurY,itxt,DTA_VirtualWidthF,ClipX,DTA_VirtualHeightF,ClipY,DTA_KeepRatio,true);
|
|
CurX = TempX;
|
|
CurY = TempY;
|
|
}
|
|
|
|
private void DrawHudIcon( double x, double y, Inventory i, bool bRed )
|
|
{
|
|
if ( i.Icon.IsNull() ) return;
|
|
double width = CurX;
|
|
CurX = x;
|
|
CurY = y;
|
|
// scale to fit
|
|
Vector2 scl = TexMan.GetScaledSize(i.Icon);
|
|
double mscl = 32./max(scl.x,scl.y);
|
|
double dw = (ClipX/mscl), dh = (ClipY/mscl);
|
|
double dx = (CurX+(32-scl.x*mscl)/2)/mscl, dy = (CurY+(32-scl.y*mscl)/2)/mscl;
|
|
if ( bRed )
|
|
{
|
|
Screen.DrawTexture(IconBase,false,CurX,CurY,DTA_VirtualWidthF,ClipX,DTA_VirtualHeightF,ClipY,DTA_KeepRatio,true,DTA_TranslationIndex,RedIcon);
|
|
Screen.DrawTexture(i.Icon,false,dx,dy,DTA_VirtualWidthF,dw,DTA_VirtualHeightF,dh,DTA_KeepRatio,true,DTA_TranslationIndex,RedIcon,DTA_TopOffset,0,DTA_LeftOffset,0);
|
|
}
|
|
else
|
|
{
|
|
Screen.DrawTexture(IconBase,false,CurX,CurY,DTA_VirtualWidthF,ClipX,DTA_VirtualHeightF,ClipY,DTA_KeepRatio,true);
|
|
Screen.DrawTexture(i.Icon,false,dx,dy,DTA_VirtualWidthF,dw,DTA_VirtualHeightF,dh,DTA_KeepRatio,true,DTA_TopOffset,0,DTA_LeftOffset,0);
|
|
}
|
|
if ( (i is 'UnrealInventory') && (UnrealInventory(i).DefaultCharge > 0) && (UnrealInventory(i).bActive || (UnrealInventory(i).Charge < UnrealInventory(i).DefaultCharge)) )
|
|
Screen.DrawTexture(HudLine,false,CurX+2,CurY+29,DTA_VirtualWidthF,ClipX,DTA_VirtualHeightF,ClipY,DTA_KeepRatio,true,DTA_WindowRightF,Min(28.*(UnrealInventory(i).Charge/double(UnrealInventory(i).DefaultCharge)),28.));
|
|
else if ( (i is 'UTArmor') && ((HudMode == 0) || (HudMode == 3)) )
|
|
Screen.DrawTexture(HudLine,false,CurX+2,CurY+29,DTA_VirtualWidthF,ClipX,DTA_VirtualHeightF,ClipY,DTA_KeepRatio,true,DTA_WindowRightF,Min(28.*(i.Amount/double(i.MaxAmount)),28.));
|
|
}
|
|
|
|
private void DrawFragCount( double x, double y )
|
|
{
|
|
CurX = X;
|
|
CurY = Y;
|
|
Screen.DrawTexture(IconSkul,false,CurX,CurY,DTA_VirtualWidthF,ClipX,DTA_VirtualHeightF,ClipY,DTA_KeepRatio,true);
|
|
CurX += 30;
|
|
CurY += 23;
|
|
string score = String.Format("%d",(deathmatch||teamplay)?CPlayer.fragcount:CPlayer.killcount);
|
|
CurX -= TinyWhiteFont.StringWidth(score);
|
|
Screen.DrawText(TinyWhiteFont,Font.CR_UNTRANSLATED,CurX,CurY,score,DTA_VirtualWidthF,ClipX,DTA_VirtualHeightF,ClipY,DTA_KeepRatio,true);
|
|
}
|
|
|
|
private void DrawInventory( double x, double y, bool bDrawOne = false, bool bNoWeapons = false )
|
|
{
|
|
bool bGotNext, bGotPrev, bGotSelected, bRed, bFlashTranslator;
|
|
Inventory Inv, Prev, Next, SelectedItem;
|
|
UTranslator translator;
|
|
double HalfHUDX, HalfHUDY;
|
|
double AmmoBarSize;
|
|
if ( (HudMode < 4) && !bNoWeapons ) // then draw HalfHUD
|
|
{
|
|
HalfHUDX = ClipX-64;
|
|
HalfHUDY = ClipY-32;
|
|
Screen.DrawTexture(HalfHUD,false,HalfHUDX,HalfHUDY,DTA_VirtualWidthF,ClipX,DTA_VirtualHeightF,ClipY,DTA_KeepRatio,true);
|
|
}
|
|
if ( !CPlayer.mo.Inv ) return; // can this even happen?
|
|
bFlashTranslator = false;
|
|
bGotSelected = false;
|
|
bGotNext = false;
|
|
bGotPrev = false;
|
|
Prev = null;
|
|
Next = null;
|
|
SelectedItem = CPlayer.mo.InvSel;
|
|
for ( Inv=CPlayer.mo.Inv; Inv; Inv=Inv.Inv )
|
|
{
|
|
if ( bDrawOne ) break;
|
|
// if drawing more than one inventory, find next and previous items
|
|
if ( Inv == SelectedItem ) bGotSelected = true;
|
|
else if ( Inv.bINVBAR )
|
|
{
|
|
if ( bGotSelected )
|
|
{
|
|
if ( !bGotNext )
|
|
{
|
|
Next = Inv;
|
|
bGotNext = true;
|
|
}
|
|
else if ( !bGotPrev ) Prev = Inv;
|
|
}
|
|
else
|
|
{
|
|
if ( !Next ) Next = Prev;
|
|
Prev = Inv;
|
|
bGotPrev = true;
|
|
}
|
|
}
|
|
if ( Inv is 'UTranslator' ) translator = UTranslator(Inv);
|
|
}
|
|
// drawing weapon slots differently than Unreal 1 because we have better methods here
|
|
let cw = CPlayer.ReadyWeapon;
|
|
int cwslot = -1;
|
|
if ( cw && (cw.SlotNumber != -1) ) cwslot = cw.SlotNumber;
|
|
let pw = CPlayer.PendingWeapon;
|
|
int pwslot = -1;
|
|
if ( pw && (pw != WP_NOCHANGE) && (pw.SlotNumber != -1) ) pwslot = pw.SlotNumber;
|
|
Array<Ammo> aslots[10];
|
|
// clear the arrays before work
|
|
for ( int i=0; i<10; i++ ) aslots[i].Clear();
|
|
// we need the ammo slots array, if it isn't accessible then we're fucked
|
|
if ( !hnd ) hnd = UnrealMainHandler(EventHandler.Find("UnrealMainHandler"));
|
|
if ( hnd )
|
|
{
|
|
// populate the array
|
|
for ( int i=0; i<hnd.AmmoSlots.Size(); i++ )
|
|
{
|
|
let a = Ammo(CPlayer.mo.FindInventory(hnd.AmmoSlots[i].AmmoType));
|
|
if ( !a ) continue;
|
|
for ( int j=0; j<10; j++ )
|
|
{
|
|
if ( !hnd.AmmoSlots[i].UsedInSlot[j] ) continue;
|
|
aslots[j].Push(a);
|
|
}
|
|
}
|
|
}
|
|
// draw the slots
|
|
if ( (HudMode < 4) && !bNoWeapons )
|
|
{
|
|
for ( int i=0; i<10; i++ )
|
|
{
|
|
Font cfont = TinyFont;
|
|
if ( (pwslot != -1) && (pwslot == i) || (pwslot == -1) && (cwslot == i) )
|
|
cfont = TinyWhiteFont;
|
|
int realslot = i?i:10;
|
|
CurX = HalfHUDX-3+realslot*6;
|
|
CurY = HalfHUDY+4;
|
|
if ( CPlayer.HasWeaponsInSlot(i) )
|
|
Screen.DrawText(cfont,Font.CR_UNTRANSLATED,CurX,CurY,String.Format("%d",i),DTA_VirtualWidthF,ClipX,DTA_VirtualHeightF,ClipY,DTA_KeepRatio,true);
|
|
// Draw ammo bar(s)
|
|
int nammo = 0;
|
|
for ( int j=0; j<aslots[i].Size(); j++ ) if ( aslots[i][j].Amount ) nammo++;
|
|
if ( nammo <= 0 ) continue;
|
|
int cbar = 0;
|
|
for ( int j=0; j<aslots[i].Size(); j++ )
|
|
{
|
|
let amo = aslots[i][j];
|
|
if ( amo.Amount <= 0 ) continue;
|
|
AmmoBarSize = 16*min(1.0,amo.Amount/double(amo.MaxAmount));
|
|
CurX = HalfHUDX-3+realslot*6+(4./nammo)*cbar;
|
|
CurY = HalfHUDY+29-AmmoBarSize;
|
|
if ( (AmmoBarSize < 8) && (amo.Amount < 10) && (amo.Amount > 0) && (nammo == 1) )
|
|
{
|
|
CurY -= 9;
|
|
Screen.DrawText(TinyRedFont,Font.CR_UNTRANSLATED,CurX,CurY,String.Format("%d",amo.Amount),DTA_VirtualWidthF,ClipX,DTA_VirtualHeightF,ClipY,DTA_KeepRatio,true);
|
|
CurY += 9;
|
|
}
|
|
DrawColor = Color(0,255,0);
|
|
if ( AmmoBarSize < 8 ) DrawColor = Color(255-int(AmmoBarSize)*30,int(AmmoBarSize)*30+40,0);
|
|
if ( !cw || (cw.Ammo1 != amo) ) DrawColor = Color(DrawColor.r/2,DrawColor.g/2,DrawColor.b/2);
|
|
if ( amo.Amount > 0 )
|
|
{
|
|
Screen.DrawTexture(HudAmmo,false,CurX,CurY,DTA_VirtualWidthF,ClipX,DTA_VirtualHeightF,ClipY,DTA_KeepRatio,true,DTA_FillColor,BlackColor,DTA_DestWidthF,4./nammo,DTA_DestHeightF,AmmoBarSize);
|
|
Screen.DrawTexture(HudAmmo,false,CurX,CurY,DTA_VirtualWidthF,ClipX,DTA_VirtualHeightF,ClipY,DTA_KeepRatio,true,DTA_AlphaChannel,true,DTA_FillColor,DrawColor,DTA_DestWidthF,4./nammo,DTA_DestHeightF,AmmoBarSize);
|
|
}
|
|
cbar++;
|
|
}
|
|
}
|
|
}
|
|
// flash translator icon
|
|
if ( translator ) bFlashTranslator = (translator.bNewMessage || translator.bNotNewMessage);
|
|
// draw the inventory bar
|
|
if ( (HUDMode == 5) || !SelectedItem ) return;
|
|
Count++;
|
|
if ( Count > 20 ) Count = 0;
|
|
if ( Prev && !Next && !bDrawOne ) x += 32; // this was missing from the original, causing a gap when there's only two items in the inventory
|
|
if ( Prev )
|
|
{
|
|
bRed = ((Prev is 'UnrealInventory') && UnrealInventory(Prev).bActive) || (Prev is 'Powerup') || ((Prev is 'UTranslator') && ((bTranslatorActive) || (bFlashTranslator && ((gametic%8)<4))));
|
|
DrawHudIcon(x,y,Prev,bRed);
|
|
if ( (Prev.MaxAmount > 1) || ((Prev is 'UnrealInventory') && UnrealInventory(Prev).bDRAWSPECIAL) ) DrawNumberOf(Prev,x,y);
|
|
}
|
|
bRed = ((SelectedItem is 'UnrealInventory') && UnrealInventory(SelectedItem).bActive) || (SelectedItem is 'Powerup') || ((SelectedItem is 'UTranslator') && ((bTranslatorActive) || (bFlashTranslator && ((gametic%8)<4))));
|
|
if ( !Next && !Prev && !bDrawOne ) DrawHudIcon(x+64,y,SelectedItem,bRed);
|
|
else DrawHudIcon(x+32,y,SelectedItem,bRed);
|
|
CurX = x+32;
|
|
if ( !Next && !Prev && !bDrawOne ) CurX = x+64;
|
|
CurY = y;
|
|
Screen.DrawTexture(IconSel,false,CurX,CurY,DTA_VirtualWidthF,ClipX,DTA_VirtualHeightF,ClipY,DTA_KeepRatio,true,DTA_Alpha,0.5);
|
|
if ( (SelectedItem.MaxAmount > 1) || ((SelectedItem is 'UnrealInventory') && UnrealInventory(SelectedItem).bDRAWSPECIAL) ) DrawNumberOf(SelectedItem,CurX,y);
|
|
if ( Next )
|
|
{
|
|
bRed = ((Next is 'UnrealInventory') && UnrealInventory(Next).bActive) || (Next is 'Powerup') || ((Next is 'UTranslator') && ((bTranslatorActive) || (bFlashTranslator && ((gametic%8)<4))));
|
|
DrawHudIcon(x+64,y,Next,bRed);
|
|
if ( (Next.MaxAmount > 1) || ((Next is 'UnrealInventory') && UnrealInventory(Next).bDRAWSPECIAL) ) DrawNumberOf(Next,x+64,y);
|
|
}
|
|
}
|
|
|
|
private bool DrawArmor( double x, double y, bool bDrawOne = false, bool bCheckOnly = false )
|
|
{
|
|
bool hasdrawn = false;
|
|
int ArmorAmount = 0, CurAbs = 0;
|
|
Inventory Inv, BestArmor;
|
|
double XL, YL;
|
|
CurX = x;
|
|
CurY = y;
|
|
for ( Inv=CPlayer.mo.Inv; Inv; Inv=Inv.Inv )
|
|
{
|
|
if ( !(Inv is 'UTArmor') ) continue;
|
|
ArmorAmount += Inv.Amount;
|
|
if ( (Inv.Amount <= 0) || Inv.Icon.IsNull() ) continue;
|
|
if ( !bDrawOne )
|
|
{
|
|
hasdrawn = true;
|
|
if ( !bCheckOnly ) DrawHudIcon(CurX,y,Inv,false);
|
|
CurX += 32;
|
|
CurY += HudMode?29:27;
|
|
if ( !bCheckOnly ) DrawIconValue(Inv.Amount);
|
|
CurY -= HudMode?29:27;
|
|
}
|
|
else if ( UTArmor(Inv).absorb > CurAbs )
|
|
{
|
|
CurAbs = UTArmor(Inv).absorb;
|
|
BestArmor = Inv;
|
|
}
|
|
}
|
|
let ba = CPlayer.mo.FindInventory("BasicArmor");
|
|
if ( ba && (ba.Amount > 0) )
|
|
{
|
|
ArmorAmount += ba.Amount;
|
|
if ( !bDrawOne )
|
|
{
|
|
hasdrawn = true;
|
|
if ( !bCheckOnly ) DrawHudIcon(CurX,y,ba,false);
|
|
CurX += 32;
|
|
CurY += HudMode?29:27;
|
|
if ( !bCheckOnly ) DrawIconValue(ba.Amount);
|
|
CurY -= HudMode?29:27;
|
|
}
|
|
}
|
|
if ( bDrawOne )
|
|
{
|
|
if ( BestArmor )
|
|
{
|
|
hasdrawn = true;
|
|
if ( !bCheckOnly ) DrawHudIcon(CurX,Y,BestArmor,false);
|
|
CurX += 32;
|
|
CurY += HudMode?29:27;
|
|
if ( !bCheckOnly ) DrawIconValue(BestArmor.Amount);
|
|
CurY -= HudMode?29:27;
|
|
}
|
|
else if ( ba && (ba.Amount > 0) )
|
|
{
|
|
hasdrawn = true;
|
|
if ( !bCheckOnly ) DrawHudIcon(CurX,Y,ba,false);
|
|
CurX += 32;
|
|
CurY += HudMode?29:27;
|
|
if ( !bCheckOnly ) DrawIconValue(ba.Amount);
|
|
CurY -= HudMode?29:27;
|
|
}
|
|
}
|
|
if ( (ArmorAmount > 0) && !HudMode )
|
|
{
|
|
hasdrawn = true;
|
|
if ( !bCheckOnly ) Screen.DrawText(LargeFont,Font.CR_UNTRANSLATED,CurX+2,Y,String.Format("%d",ArmorAmount),DTA_VirtualWidthF,ClipX,DTA_VirtualHeightF,ClipY,DTA_KeepRatio,true);
|
|
}
|
|
return hasdrawn;
|
|
}
|
|
|
|
private void DrawAmmo( double x, double y )
|
|
{
|
|
CurX = x;
|
|
CurY = y;
|
|
if ( !CPlayer.ReadyWeapon ) return;
|
|
int sec = -1, sec2 = -1;
|
|
bool red = false, red2 = false;
|
|
if ( CPlayer.ReadyWeapon is 'UTWeapon' )
|
|
[sec, sec2, red, red2] = UTWeapon(CPlayer.ReadyWeapon).GetClipAmount();
|
|
Font cfont = LargeFont;
|
|
if ( !CPlayer.ReadyWeapon.Ammo1 )
|
|
{
|
|
if ( CPlayer.ReadyWeapon.Icon.IsNull() ) return;
|
|
if ( !HudMode )
|
|
{
|
|
double bx = CurX;
|
|
CurX = bx-MedFont.StringWidth(String.Format("%d",sec))-2;
|
|
CurY += cfont.GetHeight()-MedFont.GetHeight()-4;
|
|
if ( sec != -1 )
|
|
Screen.DrawText(MedFont,red?Font.CR_RED:Font.CR_UNTRANSLATED,CurX,CurY,String.Format("%d",sec),DTA_VirtualWidthF,ClipX,DTA_VirtualHeightF,ClipY,DTA_KeepRatio,true);
|
|
CurX = bx-MedFont.StringWidth(String.Format("%d",sec2))-2;
|
|
CurY -= MedFont.GetHeight()+2;
|
|
if ( sec2 != -1 )
|
|
Screen.DrawText(MedFont,red2?Font.CR_RED:Font.CR_UNTRANSLATED,CurX,CurY,String.Format("%d",sec2),DTA_VirtualWidthF,ClipX,DTA_VirtualHeightF,ClipY,DTA_KeepRatio,true);
|
|
}
|
|
CurX = x;
|
|
CurY = y;
|
|
Screen.DrawTexture(IconBase,false,CurX,CurY,DTA_VirtualWidthF,ClipX,DTA_VirtualHeightF,ClipY,DTA_KeepRatio,true);
|
|
// scale to fit
|
|
Vector2 scl = TexMan.GetScaledSize(CPlayer.ReadyWeapon.Icon);
|
|
double mscl = 32./max(scl.x,scl.y);
|
|
double dw = (ClipX/mscl), dh = (ClipY/mscl);
|
|
double dx = (CurX+(32-scl.x*mscl)/2)/mscl, dy = (CurY+(32-scl.y*mscl)/2)/mscl;
|
|
Screen.DrawTexture(CPlayer.ReadyWeapon.Icon,false,dx,dy,DTA_VirtualWidthF,dw,DTA_VirtualHeightF,dh,DTA_KeepRatio,true,DTA_TopOffset,0,DTA_LeftOffset,0);
|
|
if ( HudMode )
|
|
{
|
|
CurX = x;
|
|
CurY = y;
|
|
Screen.DrawTexture(IconBase,false,CurX,CurY,DTA_VirtualWidthF,ClipX,DTA_VirtualHeightF,ClipY,DTA_KeepRatio,true);
|
|
CurX = (x+30)-TinyFont.StringWidth(String.Format("%d",sec));
|
|
CurY = y+2;
|
|
if ( sec != -1 )
|
|
Screen.DrawText(red?TinyRedFont:TinyFont,Font.CR_UNTRANSLATED,CurX,CurY,String.Format("%d",sec),DTA_VirtualWidthF,ClipX,DTA_VirtualHeightF,ClipY,DTA_KeepRatio,true);
|
|
CurX = x+3;
|
|
if ( sec2 != -1 )
|
|
Screen.DrawText(red2?TinyRedFont:TinyFont,Font.CR_UNTRANSLATED,CurX,CurY,String.Format("%d",sec2),DTA_VirtualWidthF,ClipX,DTA_VirtualHeightF,ClipY,DTA_KeepRatio,true);
|
|
}
|
|
return;
|
|
}
|
|
if ( CPlayer.ReadyWeapon.Ammo1.Amount <= min(9,CPlayer.ReadyWeapon.Ammo1.MaxAmount/3) ) cfont = LargeRedFont;
|
|
if ( !HudMode )
|
|
{
|
|
CurX -= cfont.StringWidth(String.Format("%d",CPlayer.ReadyWeapon.Ammo1.Amount))+2;
|
|
Screen.DrawText(cfont,Font.CR_UNTRANSLATED,CurX,CurY,String.Format("%d",CPlayer.ReadyWeapon.Ammo1.Amount),DTA_VirtualWidthF,ClipX,DTA_VirtualHeightF,ClipY,DTA_KeepRatio,true);
|
|
double bx = CurX;
|
|
CurX = bx-MedFont.StringWidth(String.Format("%d",sec))-2;
|
|
CurY += cfont.GetHeight()-MedFont.GetHeight()-4;
|
|
if ( sec != -1 )
|
|
Screen.DrawText(MedFont,red?Font.CR_RED:Font.CR_UNTRANSLATED,CurX,CurY,String.Format("%d",sec),DTA_VirtualWidthF,ClipX,DTA_VirtualHeightF,ClipY,DTA_KeepRatio,true);
|
|
CurX = bx-MedFont.StringWidth(String.Format("%d",sec2))-2;
|
|
CurY -= MedFont.GetHeight()+2;
|
|
if ( sec2 != -1 )
|
|
Screen.DrawText(MedFont,red2?Font.CR_RED:Font.CR_UNTRANSLATED,CurX,CurY,String.Format("%d",sec2),DTA_VirtualWidthF,ClipX,DTA_VirtualHeightF,ClipY,DTA_KeepRatio,true);
|
|
}
|
|
CurX = x;
|
|
CurY = y;
|
|
Screen.DrawTexture(IconBase,false,CurX,CurY,DTA_VirtualWidthF,ClipX,DTA_VirtualHeightF,ClipY,DTA_KeepRatio,true);
|
|
TextureID icon = CPlayer.ReadyWeapon.Icon.IsNull()?CPlayer.ReadyWeapon.Ammo1.Icon:CPlayer.ReadyWeapon.Icon;
|
|
// scale to fit
|
|
Vector2 scl = TexMan.GetScaledSize(icon);
|
|
double mscl = 32./max(scl.x,scl.y);
|
|
double dw = (ClipX/mscl), dh = (ClipY/mscl);
|
|
double dx = (CurX+(32-scl.x*mscl)/2)/mscl, dy = (CurY+(32-scl.y*mscl)/2)/mscl;
|
|
Screen.DrawTexture(icon,false,dx,dy,DTA_VirtualWidthF,dw,DTA_VirtualHeightF,dh,DTA_KeepRatio,true,DTA_TopOffset,0,DTA_LeftOffset,0);
|
|
CurX += 32;
|
|
CurY += 29;
|
|
DrawIconValue(CPlayer.ReadyWeapon.Ammo1.Amount);
|
|
CurX = X+2;
|
|
CurY = Y+29;
|
|
if ( (HudMode != 1) && (HudMode != 2) && (HudMode != 4) )
|
|
Screen.DrawTexture(HudLine,false,CurX,CurY,DTA_VirtualWidthF,ClipX,DTA_VirtualHeightF,ClipY,DTA_KeepRatio,true,DTA_WindowRightF,Min(28.*(CPlayer.ReadyWeapon.Ammo1.Amount/double(CPlayer.ReadyWeapon.Ammo1.MaxAmount)),28.));
|
|
if ( HudMode )
|
|
{
|
|
CurX = (x+30)-TinyFont.StringWidth(String.Format("%d",sec));
|
|
CurY = y+2;
|
|
if ( sec != -1 )
|
|
Screen.DrawText(red?TinyRedFont:TinyFont,Font.CR_UNTRANSLATED,CurX,CurY,String.Format("%d",sec),DTA_VirtualWidthF,ClipX,DTA_VirtualHeightF,ClipY,DTA_KeepRatio,true);
|
|
CurX = x+3;
|
|
if ( sec2 != -1 )
|
|
Screen.DrawText(red2?TinyRedFont:TinyFont,Font.CR_UNTRANSLATED,CurX,CurY,String.Format("%d",sec2),DTA_VirtualWidthF,ClipX,DTA_VirtualHeightF,ClipY,DTA_KeepRatio,true);
|
|
}
|
|
}
|
|
|
|
private void DrawHealth( double x, double y )
|
|
{
|
|
CurX = X;
|
|
CurY = Y;
|
|
Font cfont = LargeFont;
|
|
if ( CPlayer.mo.Health < 25 ) cfont = LargeRedFont;
|
|
Screen.DrawTexture(IconHeal,false,CurX,CurY,DTA_VirtualWidthF,ClipX,DTA_VirtualHeightF,ClipY,DTA_KeepRatio,true);
|
|
CurX += 32;
|
|
CurY += 29;
|
|
DrawIconValue(Max(0,CPlayer.mo.Health));
|
|
CurY -= 29;
|
|
if ( !HudMode ) Screen.DrawText(cfont,Font.CR_UNTRANSLATED,CurX+2,CurY,String.Format("%d",Max(0,CPlayer.mo.Health)),DTA_VirtualWidthF,ClipX,DTA_VirtualHeightF,ClipY,DTA_KeepRatio,true);
|
|
CurX = X+2;
|
|
CurY = Y+29;
|
|
if ( (HudMode != 1) && (HudMode != 2) && (HudMode != 4) )
|
|
Screen.DrawTexture(HudLine,false,CurX,CurY,DTA_VirtualWidthF,ClipX,DTA_VirtualHeightF,ClipY,DTA_KeepRatio,true,DTA_WindowRightF,Min(28.*(CPlayer.mo.Health/double(CPlayer.mo.SpawnHealth())),28.));
|
|
}
|
|
|
|
private void DrawIdentifyInfo( int state )
|
|
{
|
|
double lalpha = 2.0-((gametic+fractic)-lastseentic)/Thinker.TICRATE;
|
|
if ( !lastseen || (lalpha <= 0) ) return;
|
|
String cl1 = "DarkGreen", cl2 = "Green";
|
|
if ( deathmatch && (lastseen.player.GetTeam() < teams.size()) )
|
|
{
|
|
cl2 = teams[lastseen.player.GetTeam()].mName;
|
|
cl1 = String.Format("Dark%s",cl2);
|
|
}
|
|
String tname = String.Format("\c[%s]%s:\c[%s] %s",cl1,StringTable.Localize("$M_NAME"),cl2,lastseen.player.GetUserName());
|
|
let fnt = (state==HUD_Fullscreen)?WhiteFont:OldSmallFont;
|
|
CurX = (ClipX-fnt.StringWidth(tname))/2;
|
|
CurY = ClipY-54;
|
|
Screen.DrawText(fnt,Font.CR_UNTRANSLATED,CurX,CurY,tname,DTA_VirtualWidthF,ClipX,DTA_VirtualHeightF,ClipY,DTA_KeepRatio,true,DTA_Alpha,lalpha/2.);
|
|
if ( !deathmatch || (lastseen.IsTeammate(CPlayer.mo)) )
|
|
{
|
|
CurY += 1.2*fnt.GetHeight();
|
|
tname = String.Format("\c[%s]%s:\c[%s] %d",cl1,StringTable.Localize("$M_HEALTH"),cl2,lastseen.Health);
|
|
Screen.DrawText(fnt,Font.CR_UNTRANSLATED,CurX,CurY,tname,DTA_VirtualWidthF,ClipX,DTA_VirtualHeightF,ClipY,DTA_KeepRatio,true,DTA_Alpha,lalpha/2.);
|
|
}
|
|
}
|
|
|
|
private void DrawKeys( double x, double y, bool leftright = false )
|
|
{
|
|
if ( deathmatch ) return; // no need to draw in DM
|
|
if ( gameinfo.gametype&(GAME_Hexen|GAME_Strife) )
|
|
{
|
|
if ( !automapactive ) return;
|
|
int kw = (gameinfo.gametype&GAME_Strife)?20:30,
|
|
kh = (gameinfo.gametype&GAME_Strife)?20:40;
|
|
int nkeys = 0;
|
|
Array<int> rows;
|
|
Array<Inventory> keys;
|
|
keys.Clear();
|
|
rows.Clear();
|
|
rows.Push(0);
|
|
for ( Inventory i=CPlayer.mo.inv; i; i=i.inv )
|
|
{
|
|
if ( !(i is 'Key') ) continue;
|
|
keys.Push(i);
|
|
if ( rows[rows.Size()-1] >= 6 ) rows.Push(1);
|
|
else rows[rows.Size()-1]++;
|
|
}
|
|
int j = 0;
|
|
CurX = (ClipX-kw);
|
|
for ( int i=0; i<rows.Size(); i++ )
|
|
{
|
|
CurY = (ClipY-rows[i]*kh)*0.5;
|
|
for ( int k=0; k<rows[i]; k++ )
|
|
{
|
|
Screen.DrawTexture(keys[j].Icon,false,CurX,CurY,DTA_VirtualWidthF,ClipX,DTA_VirtualHeightF,ClipY,DTA_KeepRatio,true);
|
|
j++;
|
|
CurY += kh;
|
|
}
|
|
CurX -= kw;
|
|
}
|
|
return;
|
|
}
|
|
CurX = x;
|
|
CurY = y;
|
|
int cnt = 0;
|
|
for ( int i=0; i<6; i++ )
|
|
{
|
|
if ( !CPlayer.mo.CheckKeys(i+1,false,true) ) continue;
|
|
Screen.DrawTexture(KeyIcons[((i==0)&&(gameinfo.gametype&GAME_Heretic))?6:i],false,CurX,CurY,DTA_VirtualWidthF,ClipX,DTA_VirtualHeightF,ClipY,DTA_KeepRatio,true);
|
|
cnt++;
|
|
if ( !(cnt%3) )
|
|
{
|
|
CurX = x;
|
|
CurY -= 16;
|
|
}
|
|
else CurX += leftright?16:-16;
|
|
}
|
|
}
|
|
|
|
private void DrawUnrealHUD()
|
|
{
|
|
if ( HudMode >= 5 )
|
|
{
|
|
// minimal hud
|
|
int ArmorAmount = 0;
|
|
for ( Inventory Inv=CPlayer.mo.Inv; Inv; Inv=Inv.Inv )
|
|
{
|
|
if ( !(Inv is 'UTArmor') ) continue;
|
|
ArmorAmount += Inv.Amount;
|
|
}
|
|
int AmmoAmount1 = 0, AmmoAmount2 = 0;
|
|
Ammo amo1, amo2;
|
|
[amo1, amo2] = GetCurrentAmmo();
|
|
if ( amo1 )
|
|
{
|
|
AmmoAmount1 = amo1.Amount;
|
|
if ( amo2 ) AmmoAmount2 = amo2.Amount;
|
|
}
|
|
String str;
|
|
if ( amo1 && amo2 && (amo2 != amo1) ) str = String.Format(StringTable.Localize("$S_MINHUD2"),CPlayer.Health,(deathmatch||teamplay)?CPlayer.fragcount:CPlayer.killcount,AmmoAmount2,AmmoAmount1);
|
|
else str = String.Format(StringTable.Localize("$S_MINHUD"),CPlayer.Health,(deathmatch||teamplay)?CPlayer.fragcount:CPlayer.killcount,AmmoAmount1);
|
|
CurX = (ClipX-OldSmallFont.StringWidth(str))/2;
|
|
CurY = 1;
|
|
Screen.DrawText(OldSmallFont,Font.CR_WHITE,CurX,CurY,str,DTA_VirtualWidthF,ClipX,DTA_VirtualHeightF,ClipY,DTA_KeepRatio,true);
|
|
return;
|
|
}
|
|
if ( ClipX < 320 ) HudMode = 4;
|
|
// Draw Armor
|
|
if ( HudMode < 2 ) DrawArmor(0,0);
|
|
else if ( (HudMode == 3) || (HudMode == 2) ) DrawArmor(0,ClipY-32);
|
|
else if ( HudMode == 4 ) DrawArmor(ClipX-64,ClipY-64,true);
|
|
// Draw Ammo
|
|
if ( HudMode != 4 ) DrawAmmo(ClipX-96,ClipY-32);
|
|
else DrawAmmo(ClipX-32,ClipY-32);
|
|
// Draw Health
|
|
if ( HudMode < 2 ) DrawHealth(0,ClipY-32);
|
|
else if ( (HudMode == 3) || (HudMode == 2) ) DrawHealth(ClipX-128,ClipY-32);
|
|
else if ( HudMode == 4 ) DrawHealth(ClipX-64,ClipY-32);
|
|
// Display Inventory
|
|
if ( HudMode < 2 ) DrawInventory(ClipX-96,0);
|
|
else if ( HudMode == 3 ) DrawInventory(ClipX-96,ClipY-64);
|
|
else if ( HudMode == 4 ) DrawInventory(ClipX-64,ClipY-64,true);
|
|
else if ( HudMode == 2 ) DrawInventory(ClipX/2-64,ClipY-32);
|
|
if ( deathmatch )
|
|
{
|
|
// Display Frag count
|
|
if ( HudMode < 3 ) DrawFragCount(ClipX-32,ClipY-64);
|
|
else if ( HudMode == 3 ) DrawFragCount(0,ClipY-64);
|
|
else if ( HudMode == 4 ) DrawFragCount(ClipX-96,ClipY-32);
|
|
}
|
|
else
|
|
{
|
|
// Display Keys
|
|
if ( HudMode < 3 ) DrawKeys(ClipX-16,ClipY-48);
|
|
else if ( HudMode == 3 ) DrawKeys(0,ClipY-48,true);
|
|
else if ( HudMode == 4 ) DrawKeys(ClipX-80,ClipY-16);
|
|
}
|
|
}
|
|
|
|
override void ReceivedWeapon( Weapon weapn )
|
|
{
|
|
Super.ReceivedWeapon(weapn);
|
|
if ( weapn.SlotNumber == -1 ) return;
|
|
// fuckin' hell
|
|
EventHandler.SendNetworkEvent("Bar083SlotFlash",weapn.SlotNumber);
|
|
}
|
|
|
|
private void DrawUnrealBar()
|
|
{
|
|
// 0.83 status bar, just for funsies
|
|
DrawImage("Bar083",(0,336),DI_ITEM_OFFSETS);
|
|
// extra widescreen filler
|
|
bool first = true;
|
|
double base = -128;
|
|
double rx, dummy;
|
|
do
|
|
{
|
|
[rx, dummy, dummy] = StatusBarToRealCoords(base,0,HorizontalResolution);
|
|
DrawImage(first?"BarL083":"BarM083",(base,336),DI_ITEM_OFFSETS);
|
|
first = false;
|
|
base -= 128;
|
|
} while ( rx >= -128 );
|
|
first = true;
|
|
base = 640;
|
|
do
|
|
{
|
|
[rx, dummy, dummy] = StatusBarToRealCoords(base,0,HorizontalResolution);
|
|
DrawImage(first?"BarR083":"BarM083",(base,336),DI_ITEM_OFFSETS);
|
|
first = false;
|
|
base += 128;
|
|
} while ( rx < Screen.GetWidth() );
|
|
static const float slotofs[] = {525, 84, 128, 173, 216, 259, 349, 392, 436, 481};
|
|
static const float keyofs[] = {187, 211, 235, 379, 403, 427};
|
|
for ( int i=0; i<10; i++ )
|
|
{
|
|
if ( !CPlayer.HasWeaponsInSlot(i) ) continue;
|
|
bool used = (CPlayer.ReadyWeapon&&(CPlayer.ReadyWeapon.SlotNumber==i));
|
|
if ( CPlayer.PendingWeapon && (CPlayer.PendingWeapon != WP_NOCHANGE) )
|
|
used = (CPlayer.PendingWeapon.SlotNumber==i);
|
|
DrawImage(used?"Used083":"Slot083",(slotofs[i],342),DI_ITEM_OFFSETS);
|
|
}
|
|
let hnd = UnrealMainHandler(EventHandler.Find("UnrealMainHandler"));
|
|
if ( hnd )
|
|
{
|
|
for ( int i=0; i<10; i++ )
|
|
if ( hnd.slotflash[i] > gametic )
|
|
DrawImage("Flsh083",(slotofs[i],342),DI_ITEM_OFFSETS,(hnd.slotflash[i]-gametic+FracTic)/20.);
|
|
}
|
|
DrawString(mOldDigits,FormatNumber(CPlayer.health,3),(358,366),DI_TEXT_ALIGN_RIGHT);
|
|
int ArmorAmount = 0, CurAbs = -1;
|
|
Inventory BestArmor = null;
|
|
for ( Inventory Inv=CPlayer.mo.Inv; Inv; Inv=Inv.Inv )
|
|
{
|
|
if ( !(Inv is 'UTArmor') ) continue;
|
|
ArmorAmount += Inv.Amount;
|
|
if ( Inv.Amount <= 0 ) continue;
|
|
if ( UTArmor(Inv).absorb > CurAbs )
|
|
{
|
|
CurAbs = UTArmor(Inv).absorb;
|
|
BestArmor = Inv;
|
|
}
|
|
}
|
|
let ba = CPlayer.mo.FindInventory("BasicArmor");
|
|
if ( ba ) ArmorAmount += ba.amount;
|
|
bool drawnarmor = false;
|
|
for ( int i=0; i<OldArmor.Size(); i++ )
|
|
{
|
|
if ( !(BestArmor is OldArmorType[i]) ) continue;
|
|
DrawImage(OldArmor[i],(4,340),DI_ITEM_OFFSETS);
|
|
drawnarmor = true;
|
|
break;
|
|
}
|
|
if ( !drawnarmor && ba && (ba.Amount > 0) )
|
|
DrawInventoryIcon(ba,(40,366),DI_ITEM_CENTER,1.,(-1,-1),(2.,2.));
|
|
if ( ArmorAmount ) DrawString(mOldDigits,FormatNumber(ArmorAmount,3),(167,366),DI_TEXT_ALIGN_RIGHT);
|
|
Inventory Ammo1, Ammo2;
|
|
[Ammo1, Ammo2] = GetCurrentAmmo();
|
|
if ( Ammo1 && Ammo1.Amount ) DrawString(mOldDigits,FormatNumber(Ammo1.Amount,3),(549,366),DI_TEXT_ALIGN_RIGHT);
|
|
bool drawn = false;
|
|
for ( int i=0; i<OldAmmo.Size(); i++ )
|
|
{
|
|
// match by ammo
|
|
if ( (OldAmmoType[i] is 'Ammo') && (!Ammo1 || !(Ammo1 is OldAmmoType[i])) ) continue;
|
|
// match by weapon
|
|
if ( (OldAmmoType[i] is 'Weapon') && !(CPlayer.ReadyWeapon is OldAmmoType[i]) ) continue;
|
|
DrawImage(OldAmmo[i],(560,336),DI_ITEM_OFFSETS);
|
|
drawn = true;
|
|
break;
|
|
}
|
|
if ( !drawn && Ammo1 )
|
|
DrawInventoryIcon(Ammo1,(600,366),DI_ITEM_CENTER,1.,(-1,-1),(2.,2.));
|
|
int sec = -1, sec2 = -1;
|
|
if ( CPlayer.ReadyWeapon && (CPlayer.ReadyWeapon is 'UTWeapon') )
|
|
[sec, sec2] = UTWeapon(CPlayer.ReadyWeapon).GetClipAmount();
|
|
if ( sec != -1 )
|
|
DrawString(mOldDigitsSmall,FormatNumber(sec,3),(633,378),DI_TEXT_ALIGN_RIGHT);
|
|
if ( sec2 != -1 )
|
|
DrawString(mOldDigitsSmall,FormatNumber(sec2,3),(556,378),DI_TEXT_ALIGN_LEFT);
|
|
if ( gameinfo.gametype&(GAME_Hexen|GAME_Strife) ) DrawKeys(0,0);
|
|
else
|
|
{
|
|
for ( int i=0; i<6; i++ )
|
|
{
|
|
if ( !CPlayer.mo.CheckKeys(i+1,false,true) ) continue;
|
|
DrawImage(OldKeys[((i==0)&&(gameinfo.gametype&GAME_Heretic))?6:i],(keyofs[i],366),DI_ITEM_OFFSETS);
|
|
}
|
|
}
|
|
if ( HudMode > 5 ) return;
|
|
// Draw frags in DM
|
|
if ( deathmatch ) DrawFragCount(ClipX-32,0);
|
|
// Need to draw the inventory bar
|
|
DrawInventory(ClipX-(deathmatch?128:96),0,false,true);
|
|
}
|
|
|
|
override void Tick()
|
|
{
|
|
Super.Tick();
|
|
if ( CPlayer.inventorytics > 0 )
|
|
{
|
|
if ( CPlayer.mo.InvSel )
|
|
Console.Printf(StringTable.Localize("$M_ISELECT"),CPlayer.mo.InvSel.GetTag());
|
|
CPlayer.inventorytics = 0;
|
|
}
|
|
// part of gross hackery to override nametag display
|
|
if ( CPlayer.PendingWeapon && (CPlayer.PendingWeapon != WP_NOCHANGE) && (CPlayer.PendingWeapon != lastwep) )
|
|
{
|
|
// make sure to avoid instantly overriding the current pickup message
|
|
if ( (displaynametags&2) && (CPlayer == players[consoleplayer]) && (PickupMsgTic != gametic+50) )
|
|
{
|
|
ntagstr = CPlayer.PendingWeapon.GetTag();
|
|
ntagtic = gametic+50;
|
|
}
|
|
}
|
|
lastwep = CPlayer.PendingWeapon;
|
|
vtracer.ignore = CPlayer.mo;
|
|
vtracer.trace(CPlayer.mo.Vec2OffsetZ(0,0,CPlayer.viewz),CPlayer.mo.CurSector,dt_Utility.Vec3FromAngle(CPlayer.mo.angle,CPlayer.mo.pitch),1000,0);
|
|
if ( vtracer.Results.HitType != TRACE_HitActor ) return;
|
|
lastseen = vtracer.Results.HitActor;
|
|
lastseentic = gametic;
|
|
}
|
|
|
|
override void FlushNotify()
|
|
{
|
|
for ( int i=0; i<4; i++ )
|
|
{
|
|
ShortMsg[i] = "";
|
|
ShortMsgTic[i] = int.min;
|
|
}
|
|
PickupMsg = "";
|
|
PickupMsgTic = int.min;
|
|
MidPrintStr = "";
|
|
MidPrintTic = int.min;
|
|
}
|
|
|
|
override bool ProcessNotify( EPrintLevel printlevel, String outline )
|
|
{
|
|
if ( gamestate != GS_LEVEL ) return false; // not during intermissions
|
|
int rprintlevel = printlevel&PRINT_TYPES;
|
|
if ( (rprintlevel < PRINT_LOW) || (rprintlevel > PRINT_TEAMCHAT) ) rprintlevel = PRINT_HIGH;
|
|
outline.DeleteLastCharacter();
|
|
if ( rprintlevel == PRINT_LOW )
|
|
{
|
|
// set pickup message
|
|
PickupMsg = outline;
|
|
PickupMsgTic = gametic+50;
|
|
return true;
|
|
}
|
|
else
|
|
{
|
|
// put message into queue
|
|
for ( int i=3; i>0; i-- )
|
|
{
|
|
ShortMsg[i] = ShortMsg[i-1];
|
|
ShortMsgTic[i] = ShortMsgTic[i-1];
|
|
ShortMsgCol[i] = ShortMsgCol[i-1];
|
|
}
|
|
if ( rprintlevel == PRINT_MEDIUM ) ShortMsgCol[0] = Font.CR_RED;
|
|
else if ( (rprintlevel == PRINT_CHAT) || (rprintlevel == PRINT_TEAMCHAT) ) ShortMsgCol[0] = Font.CR_GREEN;
|
|
else ShortMsgCol[0] = Font.CR_WHITE;
|
|
ShortMsg[0] = outline;
|
|
ShortMsgTic[0] = gametic+70;
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
override bool ProcessMidPrint( Font fnt, String msg, bool bold )
|
|
{
|
|
if ( !fnt || (fnt == SmallFont) || (fnt == OriginalSmallFont) || (fnt == NewSmallFont) )
|
|
{
|
|
MidPrintStr = msg;
|
|
MidPrintLarge = false;
|
|
MidPrintTic = gametic+70;
|
|
return true;
|
|
}
|
|
else if ( fnt == BigFont )
|
|
{
|
|
MidPrintStr = msg;
|
|
MidPrintLarge = true;
|
|
MidPrintTic = gametic+70;
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
override bool DrawChat( String txt )
|
|
{
|
|
CurX = 4;
|
|
CurY = ((screenblocks<=10)||automapactive)?(GetTopOfStatusBar()/scalev.y):(ClipY-((screenblocks>11)?0:32));
|
|
CurY -= WhiteFont.GetHeight()+4;
|
|
String fullstr = String.Format("(> Say %s%s",txt,WhiteFont.GetCursor());
|
|
// cut out until it fits
|
|
while ( (WhiteFont.StringWidth(fullstr) > ClipX) && fullstr.Length() > 7 )
|
|
fullstr.Remove(7,1);
|
|
Screen.DrawText(WhiteFont,Font.CR_GREEN,CurX,CurY,fullstr,DTA_VirtualWidthF,ClipX,DTA_VirtualHeightF,ClipY,DTA_KeepRatio,true);
|
|
return true;
|
|
}
|
|
|
|
override bool DrawPaused( int player )
|
|
{
|
|
Screen.Dim(Color(0,24,64),.4,0,0,Screen.GetWidth(),Screen.GetHeight(),STYLE_Add);
|
|
String str = "PAUSED";
|
|
double xx = (Screen.GetWidth()-LargeFont.StringWidth(str))/2;
|
|
double yy = (Screen.GetHeight()-LargeFont.GetHeight())/2;
|
|
Screen.DrawText(LargeFont,Font.CR_UNTRANSLATED,xx,yy,str);
|
|
if ( multiplayer && (player != -1) )
|
|
{
|
|
str = "by "..players[player].GetUserName();
|
|
xx = (Screen.GetWidth()-MedFont.StringWidth(str))/2;
|
|
yy += LargeFont.GetHeight();
|
|
Screen.DrawText(MedFont,Font.CR_UNTRANSLATED,xx,yy,str);
|
|
}
|
|
return true;
|
|
}
|
|
|
|
private void DrawMessages( int state )
|
|
{
|
|
if ( (MidPrintStr.Length() > 0) && (MidPrintTic > gametic) )
|
|
{
|
|
let mfnt = MidPrintLarge?UBigFont:WhiteFont;
|
|
CurX = (ClipX-mfnt.StringWidth(MidPrintStr))/2;
|
|
CurY = 96;
|
|
Screen.DrawText(mfnt,Font.FindFontColor('UTHudText'),CurX,CurY,MidPrintStr,DTA_VirtualWidthF,ClipX,DTA_VirtualHeightF,ClipY,DTA_KeepRatio,true,DTA_Alpha,clamp((MidPrintTic-gametic+fractic)*0.05,0,1),DTA_LegacyRenderStyle,STYLE_Add);
|
|
}
|
|
if ( PickupMsgTic > gametic )
|
|
{
|
|
CurX = (ClipX-WhiteFont.StringWidth(PickupMsg))/2;
|
|
if ( state == HUD_Statusbar ) CurY = GetTopOfStatusBar()/scalev.y-31;
|
|
else CurY = ClipY-41;
|
|
Screen.DrawText(WhiteFont,Font.CR_WHITE,CurX,CurY,PickupMsg,DTA_VirtualWidthF,ClipX,DTA_VirtualHeightF,ClipY,DTA_KeepRatio,true,DTA_Alpha,clamp((PickupMsgTic-gametic+fractic)*0.05,0,1),DTA_LegacyRenderStyle,STYLE_Add);
|
|
}
|
|
if ( ntagtic > gametic )
|
|
{
|
|
CurX = (ClipX-WhiteFont.StringWidth(ntagstr))/2;
|
|
if ( state == HUD_Statusbar ) CurY = GetTopOfStatusBar()/scalev.y-15;
|
|
else CurY = ClipY-25;
|
|
Screen.DrawText(WhiteFont,Font.CR_WHITE,CurX,CurY,ntagstr,DTA_VirtualWidthF,ClipX,DTA_VirtualHeightF,ClipY,DTA_KeepRatio,true,DTA_Alpha,clamp((ntagtic-gametic+fractic)*0.05,0,1),DTA_LegacyRenderStyle,STYLE_Add);
|
|
}
|
|
// draw messages
|
|
if ( (state == HUD_Fullscreen) && (HudMode < 2) && DrawArmor(0,0,false,true) ) CurY = 36;
|
|
else CurY = 4;
|
|
CurX = 4;
|
|
for ( int i=3; i>=0; i-- )
|
|
{
|
|
if ( ShortMsgTic[i] < gametic ) continue;
|
|
let lines = WhiteFont.BreakLines(ShortMsg[i],int(ClipX/2));
|
|
for ( int j=0; j<lines.Count(); j++ )
|
|
{
|
|
Screen.DrawText(WhiteFont,ShortMsgCol[i],CurX,CurY,lines.StringAt(j),DTA_VirtualWidthF,ClipX,DTA_VirtualHeightF,ClipY,DTA_KeepRatio,true);
|
|
CurY += WhiteFont.GetHeight()+2;
|
|
}
|
|
}
|
|
}
|
|
|
|
override void DrawAutomapHUD( double ticFrac )
|
|
{
|
|
int crdefault = Font.CR_GREY;
|
|
int highlight = Font.CR_RED;
|
|
let scale = GetHUDScale();
|
|
double textdist = 8./scale.Y;
|
|
int height = WhiteFont.GetHeight();
|
|
String printtext;
|
|
int SCREENWIDTH = screen.GetWidth();
|
|
BeginHUD();
|
|
let y = textdist;
|
|
let width = WhiteFont.StringWidth("00:00:00");
|
|
double tmp, hres;
|
|
[tmp,tmp,hres] = StatusbarToRealCoords(0,0,HorizontalResolution);
|
|
double swidth = 0;
|
|
double ltop = 0, rtop = 0;
|
|
if ( (HudMode < 5) && CPlayer.mo.InvSel )
|
|
rtop += (32*scalev.y)/scale.Y;
|
|
double cbottom = GetTopOfStatusBar()-textdist;
|
|
int protrusion = GetProtrusion(swidth/hres);
|
|
[tmp,tmp,hres] = StatusbarToRealCoords(0,0,protrusion);
|
|
width += int((swidth-hres)/scale.X);
|
|
if ( am_showtime )
|
|
{
|
|
printtext = level.TimeFormatted();
|
|
DrawString(mMapFont,level.TimeFormatted(),(-textdist-width,y+rtop),0,crdefault);
|
|
y += height;
|
|
}
|
|
if ( am_showtotaltime ) DrawString(mMapFont,level.TimeFormatted(true),(-textdist-width,y+rtop),0,crdefault);
|
|
if ( !deathmatch )
|
|
{
|
|
y = textdist;
|
|
if ( am_showmonsters )
|
|
{
|
|
DrawString(mMapFont,String.Format("%s\34%c %d/%d",Stringtable.Localize("$AM_MONSTERS"),crdefault+65,level.killed_monsters,level.total_monsters),(textdist,y+ltop),0,highlight);
|
|
y += height;
|
|
}
|
|
if ( am_showsecrets )
|
|
{
|
|
DrawString(mMapFont,String.Format("%s\34%c %d/%d",Stringtable.Localize("$AM_SECRETS"),crdefault+65,level.found_secrets,level.total_secrets),(textdist,y+ltop),0,highlight);
|
|
y += height;
|
|
}
|
|
if ( am_showitems ) DrawString(mMapFont,String.Format("%s\34%c %d/%d",Stringtable.Localize("$AM_ITEMS"),crdefault+65,level.found_items,level.total_items),(textdist,y+ltop),0,highlight);
|
|
}
|
|
String mapname = level.FormatMapName(crdefault);
|
|
BrokenLines lines = WhiteFont.BreakLines(mapname,int(SCREENWIDTH/scale.X));
|
|
int numlines = lines.Count();
|
|
int finalwidth = int(WhiteFont.StringWidth(lines.StringAt(numlines-1))*scale.X);
|
|
[tmp,tmp,hres] = StatusbarToRealCoords(0,0,HorizontalResolution);
|
|
protrusion = GetProtrusion(finalwidth/hres);
|
|
[tmp,tmp,tmp,hres] = StatusbarToRealCoords(0,0,0,protrusion);
|
|
y = (cbottom-hres)/scale.Y-height*numlines;
|
|
for ( int i = 0; i < numlines; i++ )
|
|
{
|
|
DrawString(mMapFont,lines.StringAt(i),(0,y+ltop),DI_TEXT_ALIGN_CENTER|DI_SCREEN_HCENTER|DI_SCREEN_TOP,highlight);
|
|
y += height;
|
|
}
|
|
}
|
|
}
|