// An almost 1:1 recreation of the UT HUD // Because this requires some flexibility, it barely makes use of the Statusbar // functions and instead uses the raw Screen API. Class ViewTracer : LineTracer { Actor ignore; override ETraceStatus TraceCallback() { if ( Results.HitType == TRACE_HitActor ) { if ( (Results.HitActor == ignore) || !Results.HitActor.player || !Results.HitActor.bSHOOTABLE || Results.HitActor.bINVISIBLE ) return TRACE_Skip; return TRACE_Stop; } else if ( (Results.HitType == TRACE_HitWall) && (Results.Tier == TIER_Middle) ) { if ( !Results.HitLine.sidedef[1] ) return TRACE_Stop; return TRACE_Skip; } return TRACE_Stop; } } Class UTHud : BaseStatusBar { TextureID AmmoBar, Boxes[4], Keys[5], BigNum[12], Flash, Slots[10], Icons[14], Uses[14], Man[5], Woman[5], Boss[5], WeaponBox, IconTloc2, UseTloc2, IconSaw2, UseSaw2, IconAuto2, UseAuto2, ItemBox, ItemSel, ItemFlash, ItemArrow[2], LastItem, FacePanel[3]; Class IconClasses[14]; double HScale; Color tintcolor, bgcolor; int opacity; int lastfrag, lastfragcnt, lastpickup, lastslot, lastamount; ViewTracer vtracer; Actor lastseen; int lastseentic; bool showweapons, showfrags, showammo, showstatus, showinfo; double hudsize, weaponsize, statussize; bool justselected; HUDFont mUTFont12, mUTFont40; String PickupMsg; int PickupMsgTic; String ShortMsg[4]; int ShortMsgTic[4]; int ShortMsgCol[4]; int LastMsgTic; TextureID LastTalkFace; // guessed from voice type int LastTalkTic, faceout; String MidPrintStr; int MidPrintTic; double MidPrintScale; // For easier UT Canvas drawing Color DrawColor, WhiteColor, GoldColor; double CurX, CurY; double FracTic; Weapon lastwep; String ntagstr; int ntagtic; Color ntagcol; override void Init() { Super.Init(); SetSize(0,640,480); // this exists here merely to scale the automap text lastfrag = int.min; lastfragcnt = 0; vtracer = new("ViewTracer"); mUTFont12 = HUDFont.Create("UTFONT12"); mUTFont40 = HUDFont.Create("UTFONT40"); // Set defaults DrawColor = WhiteColor = "White"; GoldColor = "Gold"; // Load textures AmmoBar = TexMan.CheckForTexture("AmoBar",TexMan.Type_Any); Boxes[0] = TexMan.CheckForTexture("AmoBox",TexMan.Type_Any); Boxes[1] = TexMan.CheckForTexture("ArmoBox",TexMan.Type_Any); Boxes[2] = TexMan.CheckForTexture("HPBox",TexMan.Type_Any); Boxes[3] = TexMan.CheckForTexture("FragBox",TexMan.Type_Any); Keys[0] = TexMan.CheckForTexture("RKey",TexMan.Type_Any); Keys[1] = TexMan.CheckForTexture("BKey",TexMan.Type_Any); Keys[2] = TexMan.CheckForTexture("YKey",TexMan.Type_Any); Keys[3] = TexMan.CheckForTexture("Skul",TexMan.Type_Any); Keys[4] = TexMan.CheckForTexture("GKey",TexMan.Type_Any); // Heretic compat BigNum[0] = TexMan.CheckForTexture("Big0",TexMan.Type_Any); BigNum[1] = TexMan.CheckForTexture("Big1",TexMan.Type_Any); BigNum[2] = TexMan.CheckForTexture("Big2",TexMan.Type_Any); BigNum[3] = TexMan.CheckForTexture("Big3",TexMan.Type_Any); BigNum[4] = TexMan.CheckForTexture("Big4",TexMan.Type_Any); BigNum[5] = TexMan.CheckForTexture("Big5",TexMan.Type_Any); BigNum[6] = TexMan.CheckForTexture("Big6",TexMan.Type_Any); BigNum[7] = TexMan.CheckForTexture("Big7",TexMan.Type_Any); BigNum[8] = TexMan.CheckForTexture("Big8",TexMan.Type_Any); BigNum[9] = TexMan.CheckForTexture("Big9",TexMan.Type_Any); BigNum[10] = TexMan.CheckForTexture("BigColon",TexMan.Type_Any); BigNum[11] = TexMan.CheckForTexture("BigMinus",TexMan.Type_Any); Flash = TexMan.CheckForTexture("HFlash",TexMan.Type_Any); Slots[0] = TexMan.CheckForTexture("SlotImp",TexMan.Type_Any); Slots[1] = TexMan.CheckForTexture("SlotAuto",TexMan.Type_Any); Slots[2] = TexMan.CheckForTexture("SlotBio",TexMan.Type_Any); Slots[3] = TexMan.CheckForTexture("SlotASMD",TexMan.Type_Any); Slots[4] = TexMan.CheckForTexture("SlotPuls",TexMan.Type_Any); Slots[5] = TexMan.CheckForTexture("SlotRip",TexMan.Type_Any); Slots[6] = TexMan.CheckForTexture("SlotMini",TexMan.Type_Any); Slots[7] = TexMan.CheckForTexture("SlotFlak",TexMan.Type_Any); Slots[8] = TexMan.CheckForTexture("Slot8bal",TexMan.Type_Any); Slots[9] = TexMan.CheckForTexture("SlotRifl",TexMan.Type_Any); Icons[0] = TexMan.CheckForTexture("IconImpH",TexMan.Type_Any); Icons[1] = TexMan.CheckForTexture("IconAuto",TexMan.Type_Any); Icons[2] = TexMan.CheckForTexture("IconBio",TexMan.Type_Any); Icons[3] = TexMan.CheckForTexture("IconASMD",TexMan.Type_Any); Icons[4] = TexMan.CheckForTexture("IconPuls",TexMan.Type_Any); Icons[5] = TexMan.CheckForTexture("IconRip",TexMan.Type_Any); Icons[6] = TexMan.CheckForTexture("IconMini",TexMan.Type_Any); Icons[7] = TexMan.CheckForTexture("IconFlak",TexMan.Type_Any); Icons[8] = TexMan.CheckForTexture("Icon8bal",TexMan.Type_Any); Icons[9] = TexMan.CheckForTexture("IconRifl",TexMan.Type_Any); Icons[10] = TexMan.CheckForTexture("IconSaw",TexMan.Type_Any); Icons[11] = TexMan.CheckForTexture("IconTrns",TexMan.Type_Any); Icons[12] = TexMan.CheckForTexture("IconWarH",TexMan.Type_Any); Icons[13] = TexMan.CheckForTexture("IconASMD",TexMan.Type_Any); Uses[0] = TexMan.CheckForTexture("UseImpH",TexMan.Type_Any); Uses[1] = TexMan.CheckForTexture("UseAuto",TexMan.Type_Any); Uses[2] = TexMan.CheckForTexture("UseBio",TexMan.Type_Any); Uses[3] = TexMan.CheckForTexture("UseASMD",TexMan.Type_Any); Uses[4] = TexMan.CheckForTexture("UsePuls",TexMan.Type_Any); Uses[5] = TexMan.CheckForTexture("UseRip",TexMan.Type_Any); Uses[6] = TexMan.CheckForTexture("UseMini",TexMan.Type_Any); Uses[7] = TexMan.CheckForTexture("UseFlak",TexMan.Type_Any); Uses[8] = TexMan.CheckForTexture("Use8bal",TexMan.Type_Any); Uses[9] = TexMan.CheckForTexture("UseRifl",TexMan.Type_Any); Uses[10] = TexMan.CheckForTexture("UseSaw",TexMan.Type_Any); Uses[11] = TexMan.CheckForTexture("UseTrns",TexMan.Type_Any); Uses[12] = TexMan.CheckForTexture("UseWarH",TexMan.Type_Any); Uses[13] = TexMan.CheckForTexture("UseASMD",TexMan.Type_Any); IconClasses[0] = "ImpactHammer"; IconClasses[1] = "Enforcer"; IconClasses[2] = "BioRifle"; IconClasses[3] = "ShockRifle"; IconClasses[4] = "PulseGun"; IconClasses[5] = "Ripper2"; IconClasses[6] = "Minigun"; IconClasses[7] = "FlakCannon"; IconClasses[8] = "UTRocketLauncher"; IconClasses[9] = "SniperRifle"; IconClasses[10] = "UTChainsaw"; IconClasses[11] = "Translocator"; IconClasses[12] = "WarheadLauncher"; IconClasses[13] = "EnhancedShockRifle"; Man[0] = TexMan.CheckForTexture("Man",TexMan.Type_Any); Man[1] = TexMan.CheckForTexture("ManArmo",TexMan.Type_Any); Man[2] = TexMan.CheckForTexture("ManPad",TexMan.Type_Any); Man[3] = TexMan.CheckForTexture("ManBoot",TexMan.Type_Any); Man[4] = TexMan.CheckForTexture("ManBelt",TexMan.Type_Any); Woman[0] = TexMan.CheckForTexture("Woman",TexMan.Type_Any); Woman[1] = TexMan.CheckForTexture("WomanArm",TexMan.Type_Any); Woman[2] = TexMan.CheckForTexture("WomanPad",TexMan.Type_Any); Woman[3] = TexMan.CheckForTexture("WomanBot",TexMan.Type_Any); Woman[4] = TexMan.CheckForTexture("WomanBlt",TexMan.Type_Any); Boss[0] = TexMan.CheckForTexture("Boss",TexMan.Type_Any); Boss[1] = TexMan.CheckForTexture("BossArm",TexMan.Type_Any); Boss[2] = TexMan.CheckForTexture("BossPad",TexMan.Type_Any); Boss[3] = TexMan.CheckForTexture("BossBot",TexMan.Type_Any); Boss[4] = TexMan.CheckForTexture("BossBlt",TexMan.Type_Any); WeaponBox = TexMan.CheckForTexture("WpSel",TexMan.Type_Any); ItemBox = TexMan.CheckForTexture("ItemBox",TexMan.Type_Any); ItemSel = TexMan.CheckForTexture("ItmSel",TexMan.Type_Any); ItemFlash = TexMan.CheckForTexture("IFlash",TexMan.Type_Any); ItemArrow[0] = TexMan.CheckForTexture("ItmArrw1",TexMan.Type_Any); ItemArrow[1] = TexMan.CheckForTexture("ItmArrw2",TexMan.Type_Any); IconTloc2 = TexMan.CheckForTexture("IconTrn2",TexMan.Type_Any); UseTloc2 = TexMan.CheckForTexture("UseTrn2",TexMan.Type_Any); IconSaw2 = TexMan.CheckForTexture("IconSaw2",TexMan.Type_Any); UseSaw2 = TexMan.CheckForTexture("UseSaw2",TexMan.Type_Any); IconAuto2 = TexMan.CheckForTexture("IconAut2",TexMan.Type_Any); UseAuto2 = TexMan.CheckForTexture("UseAut2",TexMan.Type_Any); FacePanel[0] = TexMan.CheckForTexture("FacePnl",TexMan.Type_Any); FacePanel[1] = TexMan.CheckForTexture("FacePnlA",TexMan.Type_Any); FacePanel[2] = TexMan.CheckForTexture("Static1",TexMan.Type_Any); } 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); HScale = Screen.GetWidth()/1280.; switch ( flak_colorprefs ) { case 0: if ( CPlayer.GetTeam() >= Teams.Size() ) tintcolor = Color("White"); else tintcolor = Color(Teams[CPlayer.GetTeam()].mName); break; case 1: tintcolor = CPlayer.GetColor(); break; case 2: tintcolor = flak_colorcustom; break; } opacity = flak_opacity; bgcolor = Color("Black"); showweapons = flak_showweapons; showstatus = flak_showstatus; showfrags = flak_showfrags; showammo = flak_showammo; showinfo = flak_showinfo; hudsize = flak_hudsize; weaponsize = flak_weaponsize; statussize = flak_statussize; double lbottom = Screen.GetHeight(); if ( showweapons ) { if ( weaponsize*hudsize>=1.0 ) lbottom -= 64*hudsize*HScale; if ( showfrags ) lbottom -= 64*hudsize*HScale; } if ( CPlayer.ReadyWeapon is 'UTWeapon' ) UTWeapon(CPlayer.ReadyWeapon).PreRender(lbottom); if ( (state == HUD_StatusBar) || (state == HUD_Fullscreen) ) { BeginHUD(); FracTic = TicFrac; DrawUTHUD(lbottom); } if ( (CPlayer.ReadyWeapon is 'UTWeapon') ) UTWeapon(CPlayer.ReadyWeapon).PostRender(lbottom); } private Color LerpColor( Color a, Color b, double x ) { return Color(a.a,int(a.r*(1.-x)+b.r*x),int(a.g*(1.-x)+b.g*x),int(a.b*(1.-x)+b.b*x)); } private void UTDrawTintedTex( TextureID tx, double sx = 1.0, int opacity = -1, Color tint = Color("Black"), bool flip = false, bool animated = false ) { double ss = (HScale*sx); double dw = (Screen.GetWidth()/ss), dh = (Screen.GetHeight()/ss); double dx = CurX/ss, dy = CurY/ss; if ( opacity == -1 ) opacity = self.opacity; if ( opacity >= 16 ) Screen.DrawTexture(tx,animated,dx,dy,DTA_VirtualWidthF,dw,DTA_VirtualHeightF,dh,DTA_KeepRatio,true,DTA_FillColor,bgcolor,DTA_TopOffset,0,DTA_LeftOffset,0); double alpha = clamp(opacity/15.,0.0,1.0); Screen.DrawTexture(tx,animated,dx,dy,DTA_VirtualWidthF,dw,DTA_VirtualHeightF,dh,DTA_KeepRatio,true,DTA_Alpha,alpha,DTA_LegacyRenderStyle,STYLE_AddShaded,DTA_FillColor,(tint!="Black")?tint:tintcolor,DTA_TopOffset,0,DTA_LeftOffset,0,DTA_FlipX,flip); } private void UTDrawPlainTex( TextureID tx, double sx = 1.0, int opacity = -1, bool flip = false, bool animated = false ) { double ss = (HScale*sx); double dw = (Screen.GetWidth()/ss), dh = (Screen.GetHeight()/ss); double dx = CurX/ss, dy = CurY/ss; if ( opacity == -1 ) opacity = self.opacity; if ( opacity >= 16 ) Screen.DrawTexture(tx,animated,dx,dy,DTA_VirtualWidthF,dw,DTA_VirtualHeightF,dh,DTA_KeepRatio,true,DTA_FillColor,bgcolor,DTA_TopOffset,0,DTA_LeftOffset,0,DTA_FlipX,flip); double alpha = clamp(opacity/15.,0.0,1.0); Screen.DrawTexture(tx,animated,dx,dy,DTA_VirtualWidthF,dw,DTA_VirtualHeightF,dh,DTA_KeepRatio,true,DTA_Alpha,alpha,DTA_TopOffset,0,DTA_LeftOffset,0,DTA_FlipX,flip); } private bool UTDrawWeaponIcon( Weapon w, bool use, double sx = 1.0 ) { for ( int i=0; i<14; i++ ) { Color halftint = Color(tintcolor.a,tintcolor.r/2,tintcolor.g/2,tintcolor.b/2); if ( !(w is IconClasses[i]) ) continue; if ( use ) { if ( (i == 1) && (w.Amount > 1) ) UTDrawTintedTex(UseAuto2,sx,opacity+7); else if ( (i == 10) && flak_sawammo ) UTDrawTintedTex(UseSaw2,sx,opacity+7); else if ( (i == 11) && flak_transloc2k4 ) UTDrawTintedTex(UseTloc2,sx,opacity+7); else UTDrawTintedTex(Uses[i],sx,opacity+7); } else { if ( (i == 1) && (w.Amount > 1) ) UTDrawTintedTex(IconAuto2,sx,opacity,halftint); else if ( (i == 10) && flak_sawammo ) UTDrawTintedTex(IconSaw2,sx,opacity,halftint); else if ( (i == 11) && flak_transloc2k4 ) UTDrawTintedTex(IconTloc2,sx,opacity,halftint); else UTDrawTintedTex(Icons[i],sx,opacity,halftint); } return true; } return false; } // UT's implementation doesn't seem to translate well to this, so I improvised a bit and made something not so ugly // This whole function might need to be rewritten in a prettier way someday private void UTDrawBigNum( int value, double sx = 1.0 ) { double step = 25*HScale*sx; double ss = (HScale*sx); double dw = (Screen.GetWidth()/ss), dh = (Screen.GetHeight()/ss); String digits = String.Format("%d",min(abs(value),9999)); double flen = 3*step; double len = digits.length()*step; double alpha = clamp((opacity+7)/15.,0.0,1.0); for ( uint i=0; i 15 ) Screen.DrawTexture(BigNum[11],false,CurX/ss,CurY/ss,DTA_VirtualWidthF,dw,DTA_VirtualHeightF,dh,DTA_KeepRatio,true,DTA_FillColor,bgcolor); Screen.DrawTexture(BigNum[11],false,CurX/ss,CurY/ss,DTA_VirtualWidthF,dw,DTA_VirtualHeightF,dh,DTA_KeepRatio,true,DTA_Alpha,alpha,DTA_LegacyRenderStyle,STYLE_AddShaded,DTA_FillColor,DrawColor); CurX += step; } for ( uint i=0; i 15 ) Screen.DrawTexture(BigNum[digits.ByteAt(i)-0x30],false,CurX/ss,CurY/ss,DTA_VirtualWidthF,dw,DTA_VirtualHeightF,dh,DTA_KeepRatio,true,DTA_FillColor,bgcolor); Screen.DrawTexture(BigNum[digits.ByteAt(i)-0x30],false,CurX/ss,CurY/ss,DTA_VirtualWidthF,dw,DTA_VirtualHeightF,dh,DTA_KeepRatio,true,DTA_Alpha,alpha,DTA_LegacyRenderStyle,STYLE_AddShaded,DTA_FillColor,DrawColor); CurX += ((i=1.0) ) CurY -= 64*hudsize*HScale; double BaseX = CurX; double BaseY = CurY; UTDrawTintedTex(Boxes[0],hudsize); CurX += 8*hudsize*HScale; CurY += 14*hudsize*HScale; DrawColor = WhiteColor; let cw = CPlayer.ReadyWeapon; if ( ammotype1 ) UTDrawBigNum(ammotype1.Amount,hudsize); if ( ammotype2 && (ammotype2 != ammotype1) ) { CurX = showweapons?(Screen.GetWidth()-128*hudsize*HScale):((Screen.GetWidth()+256*hudsize*HScale)*0.5); CurY = showweapons?(Screen.GetHeight()-128*hudsize*HScale):(Screen.GetHeight()-64*hudsize*HScale); if ( showweapons && ((weaponsize*hudsize)>=1.0) ) CurY -= 64*hudsize*HScale; UTDrawTintedTex(Boxes[0]); CurX += 8*hudsize*HScale; CurY += 14*hudsize**HScale; UTDrawBigNum(ammotype2.Amount,hudsize); } // extra bars if ( flak_transloc2k4 && (cw is 'Translocator') ) { // draw ammo charge bar double ch = Translocator(cw).ammocharge; CurX = BaseX+6*hudsize*HScale; CurY = BaseY+54*hudsize*HScale; Vector2 ss = (0.54,0.25)*hudsize*HScale; double dw = (Screen.GetWidth()/ss.x), dh = (Screen.GetHeight()/ss.y); double dx = CurX/ss.x, dy = CurY/ss.y; Vector2 bs = TexMan.GetScaledSize(AmmoBar); double ddw = bs.x*ch; double alpha = clamp((opacity+7)/15.,0.0,1.0); Screen.DrawTexture(AmmoBar,false,dx,dy,DTA_VirtualWidthF,dw,DTA_VirtualHeightF,dh,DTA_KeepRatio,true,DTA_WindowRightF,ddw,DTA_Alpha,alpha); } else if ( flak_enforcerreload && (cw is 'Enforcer') ) { // draw clip(s) double ch = Enforcer(cw).ClipCount/double(Enforcer(cw).default.ClipCount); CurX = BaseX+6*hudsize*HScale; CurY = BaseY+53*hudsize*HScale; Vector2 ss; ss = (0.54,(cw.Amount>1)?0.125:0.3)*hudsize*HScale; double dw = (Screen.GetWidth()/ss.x), dh = (Screen.GetHeight()/ss.y); double dx = CurX/ss.x, dy = CurY/ss.y; Vector2 bs = TexMan.GetScaledSize(AmmoBar); double ddw = bs.x*ch; double alpha = clamp((opacity+7)/15.,0.0,1.0); Screen.DrawTexture(AmmoBar,false,dx,dy,DTA_VirtualWidthF,dw,DTA_VirtualHeightF,dh,DTA_KeepRatio,true,DTA_WindowRightF,ddw,DTA_Alpha,alpha); if ( cw.Amount > 1 ) { ch = Enforcer(cw).SlaveClipCount/double(Enforcer(cw).default.SlaveClipCount); CurY += 3*hudsize*HScale; ss = (0.54,0.125)*hudsize*HScale; dw = (Screen.GetWidth()/ss.x); dh = (Screen.GetHeight()/ss.y); dx = CurX/ss.x; dy = CurY/ss.y; ddw = bs.x*ch; Screen.DrawTexture(AmmoBar,false,dx,dy,DTA_VirtualWidthF,dw,DTA_VirtualHeightF,dh,DTA_KeepRatio,true,DTA_WindowRightF,ddw,DTA_Alpha,alpha); } } else if ( flak_pulsereload && (cw is 'Pulsegun') ) { // draw clip double ch = Pulsegun(cw).ClipCount/double(Pulsegun(cw).default.ClipCount); CurX = BaseX+6*hudsize*HScale; CurY = BaseY+53*hudsize*HScale; Vector2 ss = (0.54,0.3)*hudsize*HScale; double dw = (Screen.GetWidth()/ss.x), dh = (Screen.GetHeight()/ss.y); double dx = CurX/ss.x, dy = CurY/ss.y; Vector2 bs = TexMan.GetScaledSize(AmmoBar); double ddw = bs.x*ch; double alpha = clamp((opacity+7)/15.,0.0,1.0); Screen.DrawTexture(AmmoBar,false,dx,dy,DTA_VirtualWidthF,dw,DTA_VirtualHeightF,dh,DTA_KeepRatio,true,DTA_WindowRightF,ddw,DTA_Alpha,alpha); } else if ( cw is 'ImpactHammer' ) { double ch = min(ImpactHammer(cw).chargesize,1.5)/1.5; CurX = BaseX+6*hudsize*HScale; CurY = BaseY+53*hudsize*HScale; Vector2 ss = (0.54,0.3)*hudsize*HScale; double dw = (Screen.GetWidth()/ss.x), dh = (Screen.GetHeight()/ss.y); double dx = CurX/ss.x, dy = CurY/ss.y; Vector2 bs = TexMan.GetScaledSize(AmmoBar); double ddw = bs.x*ch; double alpha = clamp((opacity+7)/15.,0.0,1.0); Screen.DrawTexture(AmmoBar,false,dx,dy,DTA_VirtualWidthF,dw,DTA_VirtualHeightF,dh,DTA_KeepRatio,true,DTA_WindowRightF,ddw,DTA_Alpha,alpha); } else if ( cw is 'BioRifle' ) { double ch = min(BioRifle(cw).charge,5.1)/5.1; CurX = BaseX+6*hudsize*HScale; CurY = BaseY+53*hudsize*HScale; Vector2 ss = (0.54,0.3)*hudsize*HScale; double dw = (Screen.GetWidth()/ss.x), dh = (Screen.GetHeight()/ss.y); double dx = CurX/ss.x, dy = CurY/ss.y; Vector2 bs = TexMan.GetScaledSize(AmmoBar); double ddw = bs.x*ch; double alpha = clamp((opacity+7)/15.,0.0,1.0); Screen.DrawTexture(AmmoBar,false,dx,dy,DTA_VirtualWidthF,dw,DTA_VirtualHeightF,dh,DTA_KeepRatio,true,DTA_WindowRightF,ddw,DTA_Alpha,alpha); } else if ( cw is 'UTRocketLauncher' ) { double ch = cw.special1/6.; CurX = BaseX+6*hudsize*HScale; CurY = BaseY+53*hudsize*HScale; Vector2 ss = (0.54,0.3)*hudsize*HScale; double dw = (Screen.GetWidth()/ss.x), dh = (Screen.GetHeight()/ss.y); double dx = CurX/ss.x, dy = CurY/ss.y; Vector2 bs = TexMan.GetScaledSize(AmmoBar); double ddw = bs.x*ch; double alpha = clamp((opacity+7)/15.,0.0,1.0); Screen.DrawTexture(AmmoBar,false,dx,dy,DTA_VirtualWidthF,dw,DTA_VirtualHeightF,dh,DTA_KeepRatio,true,DTA_WindowRightF,ddw,DTA_Alpha,alpha); } } private void DrawStatus() { UTArmor b, a, t, s; b = UTArmor(CPlayer.mo.FindInventory("UTArmorBonus")); a = UTArmor(CPlayer.mo.FindInventory("UTBodyArmor")); t = UTArmor(CPlayer.mo.FindInventory("UTThighPads")); s = UTArmor(CPlayer.mo.FindInventory("UTShieldBelt")); if ( showstatus ) { CurX = Screen.GetWidth()-128*HScale*hudsize*statussize; CurY = 0; Color dollcolor = tintcolor; DamageAmplifier d; UTInvulPower p; UTJumpBoots j; d = DamageAmplifier(CPlayer.mo.FindInventory("DamageAmplifier")); p = UTInvulPower(CPlayer.mo.FindInventory("UTInvulPower")); j = UTJumpBoots(CPlayer.mo.FindInventory("UTJumpBoots")); if ( d && !d.isBlinking() ) dollcolor = d.BlendColor; int dolltype = 0; if ( p && !p.isBlinking() ) dollcolor = LerpColor(GoldColor,dollcolor,((gametic+fractic)/15)%1.); if ( CPlayer.mo is 'UTPlayer' ) dolltype = UTPlayer(CPlayer.mo).DollType; else { // female doll for female, male doll for male/neutral, boss doll for object dolltype = (CPlayer.GetGender()==3)?UTPlayer.DOLL_Boss:(CPlayer.GetGender()==1)?UTPlayer.DOLL_Female:UTPlayer.DOLL_Male; } if ( dolltype == UTPlayer.DOLL_Boss ) { UTDrawTintedTex(Boss[0],hudsize*statussize,min(opacity,15),dollcolor); if ( a ) UTDrawTintedTex(Boss[1],hudsize*statussize,int(min(opacity,15)*(a.Amount/double(a.MaxAmount))),dollcolor); if ( t ) UTDrawTintedTex(Boss[2],hudsize*statussize,int(min(opacity,15)*(t.Amount/double(t.MaxAmount))),dollcolor); if ( j ) UTDrawTintedTex(Boss[3],hudsize*statussize,int(min(opacity,15)*(j.Amount/double(j.MaxAmount))),dollcolor); if ( s ) UTDrawTintedTex(Boss[4],hudsize*statussize,int(min(opacity,15)*(s.Amount/double(s.MaxAmount))),GoldColor); } else if ( dolltype == UTPlayer.DOLL_Female ) { UTDrawTintedTex(Woman[0],hudsize*statussize,min(opacity,15),dollcolor); if ( a ) UTDrawTintedTex(Woman[1],hudsize*statussize,int(min(opacity,15)*(a.Amount/double(a.MaxAmount))),dollcolor); if ( t ) UTDrawTintedTex(Woman[2],hudsize*statussize,int(min(opacity,15)*(t.Amount/double(t.MaxAmount))),dollcolor); if ( j ) UTDrawTintedTex(Woman[3],hudsize*statussize,int(min(opacity,15)*(j.Amount/double(j.MaxAmount))),dollcolor); if ( s ) UTDrawTintedTex(Woman[4],hudsize*statussize,int(min(opacity,15)*(s.Amount/double(s.MaxAmount))),GoldColor); } else { UTDrawTintedTex(Man[0],hudsize*statussize,min(opacity,15),dollcolor); if ( a ) UTDrawTintedTex(Man[1],hudsize*statussize,int(min(opacity,15)*(a.Amount/double(a.MaxAmount))),dollcolor); if ( t ) UTDrawTintedTex(Man[2],hudsize*statussize,int(min(opacity,15)*(t.Amount/double(t.MaxAmount))),dollcolor); if ( j ) UTDrawTintedTex(Man[3],hudsize*statussize,int(min(opacity,15)*(j.Amount/double(j.MaxAmount))),dollcolor); if ( s ) UTDrawTintedTex(Man[4],hudsize*statussize,int(min(opacity,15)*(s.Amount/double(s.MaxAmount))),GoldColor); } } DrawColor = WhiteColor; if ( !showstatus && !showweapons ) { CurX = Screen.GetWidth()*0.5-128*hudsize*HScale; CurY = Screen.GetHeight()-64*hudsize*HScale; } else { CurX = Screen.GetWidth()-140*hudsize*HScale; if ( showstatus ) CurX -= 128*statussize*hudsize*HScale; CurY = 0; } UTDrawTintedTex(Boxes[1],hudsize); int allarmor = 0; if ( b ) allarmor += b.amount; if ( a ) allarmor += a.amount; if ( t ) allarmor += t.amount; if ( s ) allarmor += s.amount; let ba = CPlayer.mo.FindInventory("BasicArmor"); if ( ba ) allarmor += ba.amount; CurX += 8*hudsize*HScale; CurY += 14*hudsize*HScale; if ( !showstatus && b ) DrawColor = GoldColor; UTDrawBigNum(allarmor,hudsize); DrawColor = WhiteColor; if ( !showstatus && !showweapons ) { CurX = Screen.GetWidth()*0.5; CurY = Screen.GetHeight()-64*hudsize*HScale; } else { CurX = Screen.GetWidth()-140*hudsize*HScale; if ( showstatus ) CurX -= 128*statussize*hudsize*HScale; CurY = 64*hudsize*HScale; } if ( CPlayer.mo.Health < CPlayer.mo.SpawnHealth()/2 ) { Color blinkcolor; double blinky = ((level.time+fractic)/Thinker.TICRATE)*1.5; blinky = blinky-floor(blinky); blinkcolor = LerpColor(tintcolor,WhiteColor,blinky); UTDrawTintedTex(Boxes[2],hudsize,-1,blinkcolor); DrawColor = LerpColor(WhiteColor,blinkcolor,blinky); CurX += 8*hudsize*HScale; CurY += 14*hudsize*HScale; UTDrawBigNum(Max(0,CPlayer.mo.Health),hudsize); } else { UTDrawTintedTex(Boxes[2],hudsize); CurX += 8*hudsize*HScale; CurY += 14*hudsize*HScale; UTDrawBigNum(Max(0,CPlayer.mo.Health),hudsize); } } private void DrawWeapons() { Color halftint = Color(tintcolor.a,tintcolor.r/2,tintcolor.g/2,tintcolor.b/2); double WeapScale = hudsize*weaponsize*HScale; double BaseX = (Screen.GetWidth()-(1280*WeapScale))*0.5; double BaseY = Screen.GetHeight()-64*WeapScale; double WeaponOffset = 128*WeapScale; let cw = CPlayer.ReadyWeapon; int cwslot = -1; if ( cw && (cw.SlotNumber != -1) ) { cwslot = cw.SlotNumber?(cw.SlotNumber-1):9; CurX = BaseX+cwslot*WeaponOffset; CurY = BaseY; UTDrawWeaponIcon(cw,true,hudsize*weaponsize); CurX = BaseX+cwslot*WeaponOffset; CurY = BaseY; } let pw = CPlayer.PendingWeapon; int pwslot = -1; if ( pw && (pw != WP_NOCHANGE) && (pw.SlotNumber != -1) ) { pwslot = pw.SlotNumber?(pw.SlotNumber-1):9; CurX = BaseX+pwslot*WeaponOffset-64*WeapScale; CurY = BaseY-32*WeapScale; UTDrawTintedTex(Flash,hudsize*weaponsize,min(opacity,15),GoldColor); CurX = BaseX+pwslot*WeaponOffset; CurY = BaseY; UTDrawWeaponIcon(pw,true,hudsize*weaponsize); } if ( cwslot != -1 ) { CurX = BaseX+cwslot*WeaponOffset; UTDrawPlainTex(WeaponBox,hudsize*weaponsize,opacity+7); } Weapon wslots[10]; // zero-initialize, fixes asmjit crash for ( int i=0; i<10; i++ ) wslots[i] = null; // first run, populate the full array of weapons for ( int i=0; i<10; i++ ) { int sslot = (i<9)?(i+1):0; for ( Inventory i = CPlayer.mo.Inv; i; i=i.Inv ) { if ( !(i is 'Weapon') ) continue; let w = Weapon(i); if ( w.SlotNumber != sslot ) continue; int slot = w.SlotNumber?(w.SlotNumber-1):9; if ( !wslots[slot] ) { wslots[slot] = w; continue; } if ( (wslots[slot] == pw) || (wslots[slot] == cw) ) continue; if ( (w == pw) || (w == cw) ) { wslots[slot] = w; continue; } if ( (w.SelectionOrder < wslots[slot].SelectionOrder) && (!w.Ammo1 || (w.Ammo1.Amount > 0)) ) wslots[slot] = w; else if ( (w.SelectionOrder >= wslots[slot].SelectionOrder) && wslots[slot].Ammo1 && (wslots[slot].Ammo1.Amount <= 0) ) wslots[slot] = w; } } for ( int i=0; i<10; i++ ) { CurX = BaseX+i*WeaponOffset; CurY = BaseY; if ( !wslots[i] ) UTDrawTintedTex(Slots[i],2*hudsize*weaponsize,-1,halftint); else if ( (i != cwslot) && (i != pwslot) ) if ( !UTDrawWeaponIcon(wslots[i],false,hudsize*weaponsize) ) UTDrawTintedTex(Slots[i],2*hudsize*weaponsize,-1,halftint); } for ( int i=0; i<10; i++ ) { if ( !wslots[i] ) continue; CurX = BaseX+i*WeaponOffset+4*WeapScale; CurY = BaseY+4*WeapScale; UTDrawTintedTex(BigNum[(i==9)?0:(i+1)],0.75*hudsize*weaponsize,opacity+7,GoldColor); if ( !wslots[i].Ammo1 ) continue; CurY = BaseY+52*WeapScale; Vector2 ss = (0.6875,0.5)*WeapScale; double dw = (Screen.GetWidth()/ss.x), dh = (Screen.GetHeight()/ss.y); double dx = CurX/ss.x, dy = CurY/ss.y; Vector2 bs = TexMan.GetScaledSize(AmmoBar); double ddw = bs.x*(wslots[i].Ammo1.Amount/double(wslots[i].Ammo1.MaxAmount)); double alpha = clamp((opacity+7)/15.,0.0,1.0); Screen.DrawTexture(AmmoBar,false,dx,dy,DTA_VirtualWidthF,dw,DTA_VirtualHeightF,dh,DTA_KeepRatio,true,DTA_WindowRightF,ddw,DTA_Alpha,alpha); } } private void DrawFragCount() { CurX = showweapons?0:(Screen.GetWidth()*0.5-256*hudsize*HScale); CurY = Screen.GetHeight()-64*hudsize*HScale; if ( showweapons && ((weaponsize*hudsize)>=1.0) ) CurY -= 64*hudsize*HScale; DrawColor = tintcolor; double whiten = ((level.time+fractic)-lastfrag)/Thinker.TICRATE; if ( whiten < 3.0 ) { if ( tintcolor == GoldColor ) DrawColor = WhiteColor; else DrawColor = GoldColor; CurX -= 64*hudsize*HScale; CurY -= 32*hudsize*HScale; UTDrawTintedTex(Flash,hudsize,min(opacity,15),DrawColor); CurX += 64*hudsize*HScale; CurY += 32*hudsize*HScale; whiten = 4*whiten-int(4*whiten); DrawColor = lerpcolor(tintcolor,DrawColor,whiten); } UTDrawTintedTex(Boxes[3],hudsize,-1,DrawColor); CurX += 44*hudsize*HScale; CurY += 14*hudsize*HScale; DrawColor = WhiteColor; UTDrawBigNum((deathmatch||teamplay)?CPlayer.fragcount:CPlayer.killcount,hudsize); } private void DrawIdentifyInfo() { double lalpha = 2.0-((level.time+fractic)-lastseentic)/Thinker.TICRATE; if ( !lastseen || (lalpha <= 0) ) return; String cl1 = "UTHUDTextLight", cl2 = "UTHUDText"; 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()); double scl = HScale/5.; CurX = (640-mUTFont40.mFont.StringWidth(tname)*scl)*0.5; CurY = 480*0.75; Screen.DrawText(mUTFont40.mFont,Font.CR_UNTRANSLATED,CurX/scl,CurY/scl,tname,DTA_VirtualWidthF,640/scl,DTA_VirtualHeightF,480/scl,DTA_Alpha,lalpha/2.,DTA_LegacyRenderStyle,STYLE_Add); if ( !deathmatch || (lastseen.IsTeammate(CPlayer.mo)) ) { tname = String.Format("\c[%s]%s:\c[%s] %d",cl1,StringTable.Localize("$M_HEALTH"),cl2,lastseen.Health); CurY += mUTFont40.mFont.GetHeight()*scl; CurX = (640-mUTFont40.mFont.StringWidth(tname)*scl)*0.5; Screen.DrawText(mUTFont40.mFont,Font.CR_UNTRANSLATED,CurX/scl,CurY/scl,tname,DTA_VirtualWidthF,640/scl,DTA_VirtualHeightF,480/scl,DTA_Alpha,lalpha/2.,DTA_LegacyRenderStyle,STYLE_Add); } } private void DrawKeys() { 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; double ks = (gameinfo.gametype&GAME_Strife)?2.:1.5; int nkeys = 0; Array rows; Array 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 = (Screen.GetWidth()-kw*hudsize*HScale*ks); for ( int i=0; i1 if ( itm.Amount > 1 ) { CurX = BaseX+32*hudsize*HScale; CurY = BaseY+40*hudsize*HScale; DrawColor = WhiteColor; UTDrawBigNum(itm.Amount,hudsize*0.5); } // selection box if current item if ( itm == CPlayer.mo.InvSel ) { CurX = BaseX; CurY = BaseY; UTDrawPlainTex(ItemSel,hudsize,opacity+7); } BaseX += 64*hudsize*HScale; i++; } // draw arrows CurY = Screen.GetHeight()-204*hudsize*HScale; CurX = (Screen.GetWidth()-(64*5+40)*hudsize*HScale)/2.; UTDrawTintedTex(ItemArrow[CPlayer.mo.InvFirst!=CPlayer.mo.FirstInv()],hudsize,flip:true); CurX = (Screen.GetWidth()+(64*5+8)*hudsize*HScale)/2.; UTDrawTintedTex(ItemArrow[!!itm],hudsize); } else if ( CPlayer.mo.InvSel || artiflashtick ) { // flashie if ( artiflashtick ) { DrawColor = GoldColor; CurX = -32*hudsize*HScale; CurY = lbottom-96*hudsize*HScale; UTDrawTintedTex(ItemFlash,hudsize,min(opacity,15),DrawColor); } // position 64x64 box CurX = 0; CurY = lbottom-64*hudsize*HScale; UTDrawTintedTex(ItemBox,hudsize); if ( artiflashtick ) { // scale to fit Vector2 scl = TexMan.GetScaledSize(LastItem); double mscl = 56./max(scl.x,scl.y); CurX += (4+(56.-scl.x*mscl)/2.)*hudsize*HScale; CurY += (4+(56.-scl.y*mscl)/2.)*hudsize*HScale; UTDrawTintedTex(LastItem,hudsize*mscl); if ( LastAmount <= 1 ) return; CurX = 32*hudsize*HScale; CurY = lbottom-24*hudsize*HScale; DrawColor = WhiteColor; UTDrawBigNum(LastAmount,hudsize*0.5); return; } if ( !CPlayer.mo.InvSel ) return; // scale to fit Vector2 scl = TexMan.GetScaledSize(CPlayer.mo.InvSel.Icon); double mscl = 56./max(scl.x,scl.y); CurX += (4+(56.-scl.x*mscl)/2.)*hudsize*HScale; CurY += (4+(56.-scl.y*mscl)/2.)*hudsize*HScale; UTDrawTintedTex(CPlayer.mo.InvSel.Icon,hudsize*mscl); // amount if >1 if ( CPlayer.mo.InvSel.Amount <= 1 ) return; CurX = 32*hudsize*HScale; CurY = lbottom-24*hudsize*HScale; DrawColor = WhiteColor; UTDrawBigNum(CPlayer.mo.InvSel.Amount,hudsize*0.5); } } private void SetChatFace( String str ) { Array splitme; str.Split(splitme,":"); if ( splitme.Size() < 2 ) return; String pname = splitme[0]; // guess the player int p = -1; for ( int i=0; i PRINT_TEAMCHAT) ) rprintlevel = PRINT_HIGH; outline.DeleteLastCharacter(); if ( rprintlevel == PRINT_LOW ) // pickups { PickupMsg = outline; PickupMsgTic = gametic+50; return true; } else if ( rprintlevel == PRINT_MEDIUM ) // obituaries { AppendMessage(outline,Font.CR_RED); return true; } else if ( (rprintlevel == PRINT_CHAT) || (rprintlevel == PRINT_TEAMCHAT) ) // chat { AppendMessage(outline,Font.CR_GREEN); SetChatFace(outline); return true; } else // other messages { AppendMessage(outline,Font.CR_WHITE); return true; } return false; } override bool ProcessMidPrint( Font fnt, String msg, bool bold ) { if ( !fnt || (fnt == SmallFont) || (fnt == OriginalSmallFont) || (fnt == NewSmallFont) ) { MidPrintStr = msg; MidPrintScale = 2.5; MidPrintTic = gametic+70; return true; } else if ( fnt == BigFont ) { MidPrintStr = msg; MidPrintScale = 1.2; MidPrintTic = gametic+70; return true; } return false; } private void AppendMessage( String msg, int col ) { BrokenLines lines = mUTFont40.mFont.BreakLines(msg,2450); for ( int i=0; i0; j-- ) { ShortMsg[j] = ShortMsg[j-1]; ShortMsgTic[j] = ShortMsgTic[j-1]; ShortMsgCol[j] = ShortMsgCol[j-1]; } // jam it in ShortMsg[0] = lines.StringAt(i); LastMsgTic = ShortMsgTic[0] = gametic+170; ShortMsgCol[0] = col; } } override void FlushNotify() { for ( int i=0; i<4; i++ ) { ShortMsg[i] = ""; ShortMsgTic[i] = int.min; ShortMsgCol[i] = Font.CR_UNTRANSLATED; } LastTalkTic = LastMsgTic = PickupMsgTic = int.min; LastTalkFace.SetNull(); PickupMsg = ""; PickupMsgTic = int.min; MidPrintStr = ""; MidPrintTic = int.min; } override bool DrawChat( String txt ) { if ( gamestate != GS_LEVEL ) return false; // not during intermissions CurX = 0; CurY = 68*HScale; if ( LastTalkTic > gametic ) CurX += (68+faceout)*HScale; int areatime = max(LastTalkTic,LastMsgTic)+30; if ( areatime > gametic ) UTDrawTintedTex(FacePanel[1],opacity:clamp(int((areatime-gametic+fractic)*0.75),0,15)); CurX += 6*HScale; CurY += HScale; double scl = HScale/3.; String fullstr = String.Format("(> Say %s%s",txt,mUTFont40.mFont.GetCursor()); // cut out until it fits while ( (mUTFont40.mFont.StringWidth(fullstr) > 2450) && (fullstr.Length() > 7) ) fullstr.Remove(7,1); Screen.DrawText(mUTFont40.mFont,Font.CR_GREEN,CurX/scl,CurY/scl,fullstr,DTA_VirtualWidthF,Screen.GetWidth()/scl,DTA_VirtualHeightF,Screen.GetHeight()/scl,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()-mUTFont40.mFont.StringWidth(str))/2; double yy = (Screen.GetHeight()-mUTFont40.mFont.GetHeight())/2; Screen.DrawText(mUTFont40.mFont,Font.CR_BLUE,xx,yy,str); if ( multiplayer && (player != -1) ) { str = "by "..players[player].GetUserName(); xx = (Screen.GetWidth()-mUTFont12.mFont.StringWidth(str))/2; yy += mUTFont40.mFont.GetHeight(); Screen.DrawText(mUTFont12.mFont,Font.CR_WHITE,xx,yy,str); } return true; } private void DrawTalkFace() { // this doesn't even get close to how it's supposed to look but whatever double ss = (HScale*0.265625); double dw = (Screen.GetWidth()/ss), dh = (Screen.GetHeight()/ss); double dx = CurX/ss, dy = CurY/ss; Screen.DrawTexture(FacePanel[2],false,dx,dy,DTA_VirtualWidthF,dw,DTA_VirtualHeightF,dh,DTA_KeepRatio,true,DTA_FillColor,Color("Black")); Screen.DrawTexture(FacePanel[2],true,dx,dy,DTA_VirtualWidthF,dw,DTA_VirtualHeightF,dh,DTA_KeepRatio,true,DTA_LegacyRenderStyle,STYLE_AddShaded,DTA_FillColor,tintcolor); ss = HScale; dw = (Screen.GetWidth()/ss); dh = (Screen.GetHeight()/ss); dx = (CurX+2*HScale)/ss; dy = (CurY+2*HScale)/ss; Screen.DrawTexture(LastTalkFace,false,dx,dy,DTA_VirtualWidthF,dw,DTA_VirtualHeightF,dh,DTA_KeepRatio,true,DTA_Alpha,0.8); Screen.DrawTexture(LastTalkFace,false,dx,dy,DTA_VirtualWidthF,dw,DTA_VirtualHeightF,dh,DTA_KeepRatio,true,DTA_LegacyRenderStyle,STYLE_Add); } private void DrawMessages() { // midprint if ( (MidPrintStr.Length() > 0) && (MidPrintTic > gametic) ) { double scl = HScale/MidPrintScale; CurX = (Screen.GetWidth()-mUTFont40.mFont.StringWidth(MidPrintStr)*scl)/2; CurY = 256*HScale; Screen.DrawText(mUTFont40.mFont,Font.FindFontColor('UTHudText'),CurX/scl,CurY/scl,MidPrintStr,DTA_VirtualWidthF,Screen.GetWidth()/scl,DTA_VirtualHeightF,Screen.GetHeight()/scl,DTA_KeepRatio,true,DTA_Alpha,clamp((MidPrintTic-gametic+fractic)*0.1,0,1),DTA_LegacyRenderStyle,STYLE_Add); } // pickup message if ( PickupMsgTic > gametic ) { double scl = HScale/2.2; CurX = (Screen.GetWidth()-mUTFont40.mFont.StringWidth(PickupMsg)*scl)/2; CurY = Screen.GetHeight()-112*HScale; Screen.DrawText(mUTFont40.mFont,Font.CR_WHITE,CurX/scl,CurY/scl,PickupMsg,DTA_VirtualWidthF,Screen.GetWidth()/scl,DTA_VirtualHeightF,Screen.GetHeight()/scl,DTA_KeepRatio,true,DTA_Alpha,clamp((PickupMsgTic-gametic+fractic)*0.1,0,1),DTA_LegacyRenderStyle,STYLE_Add); } // name tags if ( ntagtic > gametic ) { double scl = HScale/2.5; CurX = (Screen.GetWidth()-mUTFont40.mFont.StringWidth(ntagstr)*scl)/2; CurY = Screen.GetHeight()-88*HScale; Screen.DrawText(mUTFont40.mFont,Font.CR_UNTRANSLATED,CurX/scl,CurY/scl,ntagstr,DTA_VirtualWidthF,Screen.GetWidth()/scl,DTA_VirtualHeightF,Screen.GetHeight()/scl,DTA_KeepRatio,true,DTA_Alpha,clamp((ntagtic-gametic+fractic)*0.1,0,1),DTA_LegacyRenderStyle,STYLE_AddShaded,DTA_FillColor,Color(255,ntagcol.r,ntagcol.g,ntagcol.b)); } // talk face CurX = 0; CurY = 0; if ( LastTalkTic > gametic ) { if ( (LastTalkTic-gametic) < 30 ) faceout = max(-68,faceout-8); else faceout = 0; CurX = faceout*HScale; DrawTalkFace(); CurX += 68*HScale; } // message frame int areatime = max(LastTalkTic,LastMsgTic)+30; if ( areatime > gametic ) UTDrawTintedTex(FacePanel[0],opacity:clamp(int((areatime-gametic+fractic)*0.75),0,15)); // messages themselves if ( LastMsgTic < gametic ) return; CurX = 8*HScale; if ( LastTalkTic > gametic ) CurX += (68+faceout)*HScale; CurY = HScale; double scl = HScale/3.; for ( int i=3; i>=0; i-- ) { if ( ShortMsgTic[i] < gametic ) continue; Screen.DrawText(mUTFont40.mFont,ShortMsgCol[i],CurX/scl,CurY/scl,ShortMsg[i],DTA_VirtualWidthF,Screen.GetWidth()/scl,DTA_VirtualHeightF,Screen.GetHeight()/scl,DTA_KeepRatio,true); CurY += 16*HScale; } } override void Tick() { Super.Tick(); if ( CPlayer.mo.InvSel && !artiflashtick ) { LastItem = CPlayer.mo.InvSel.Icon; LastAmount = CPlayer.mo.InvSel.Amount-1; } if ( CPlayer.inventorytics >= (5*Thinker.TICRATE)-1 ) { if ( CPlayer.mo.InvSel ) { ntagstr = CPlayer.mo.InvSel.GetTag(); ntagtic = gametic+70; ntagcol = Color(255,255,255); S_StartSound("misc/hud_sel",CHAN_BODY,CHANF_UI|CHANF_MAYBE_LOCAL); } } if ( CPlayer.inventorytics > 0 ) justselected = false; else { if ( !justselected && CPlayer.mo.InvSel ) { Console.Printf(StringTable.Localize("$M_ISELECT"),CPlayer.mo.InvSel.GetTag()); S_StartSound("misc/hud_sel",CHAN_BODY,CHANF_UI|CHANF_MAYBE_LOCAL); } justselected = true; } // part of gross hackery to override nametag display if ( CPlayer.PendingWeapon && (CPlayer.PendingWeapon != WP_NOCHANGE) && (CPlayer.PendingWeapon != lastwep) ) { if ( (displaynametags&2) && (CPlayer == players[consoleplayer]) ) { ntagstr = CPlayer.PendingWeapon.GetTag(); ntagtic = gametic+70; ntagcol = (CPlayer.PendingWeapon is 'UTWeapon')?UTWeapon(CPlayer.PendingWeapon).NameColor:Color(255,255,255); } } lastwep = CPlayer.PendingWeapon; if ( deathmatch||teamplay ) { if ( CPlayer.fragcount != lastfragcnt ) lastfrag = level.time; lastfragcnt = CPlayer.fragcount; } else { if ( CPlayer.killcount != lastfragcnt ) lastfrag = level.time; lastfragcnt = CPlayer.killcount; } 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 = level.time; } private void DrawUTHUD( double lbottom ) { // Display Weapons if ( showweapons ) DrawWeapons(); // Display Frag count if ( showfrags ) DrawFragCount(); // Draw Ammo if ( showammo ) DrawAmmo(); // Draw Health/Armor status DrawStatus(); // Display Keys DrawKeys(); // Inventory Bar DrawInventory(lbottom); // Display Identification Info if ( CPlayer == players[consoleplayer] && showinfo ) DrawIdentifyInfo(); // Display messages DrawMessages(); } override void DrawAutomapHUD( double ticFrac ) { int crdefault = Font.FindFontColor('UTHUDTextLight'); int highlight = Font.FindFontColor('UTHUDText'); HScale = Screen.GetWidth()/1280.; showweapons = flak_showweapons; showstatus = flak_showstatus; weaponsize = flak_weaponsize; statussize = flak_statussize; double cbottom = Screen.GetHeight()*0.99; let scale = GetHUDScale(); double textdist = 8./scale.Y; int height = mUTFont12.mFont.GetHeight(); String printtext; int SCREENWIDTH = screen.GetWidth(); BeginHUD(); let y = textdist; let width = mUTFont12.mFont.StringWidth("00:00:00"); double tmp, hres; [tmp,tmp,hres] = StatusbarToRealCoords(0,0,HorizontalResolution); double swidth = 0; if ( !(players[consoleplayer].camera is 'GuidedWarShell') ) { if ( showweapons ) cbottom -= 64*hudsize*weaponsize*HScale; else if ( showfrags || showammo || !showstatus ) cbottom -= 64*hudsize*HScale; if ( showstatus ) swidth += 128*hudsize*statussize*HScale; if ( showweapons ) swidth += 140*hudsize*HScale+Screen.GetWidth()*0.01; } 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(mUTFont12,level.TimeFormatted(),(-textdist-width,y),0,crdefault); y += height; } if ( am_showtotaltime ) DrawString(mUTFont12,level.TimeFormatted(true),(-textdist-width,y),0,crdefault); if ( !deathmatch ) { y = textdist; if ( am_showmonsters ) { DrawString(mUTFont12,String.Format("%s\34%c %d/%d",Stringtable.Localize("$AM_MONSTERS"),crdefault+65,level.killed_monsters,level.total_monsters),(textdist,y),0,highlight); y += height; } if ( am_showsecrets ) { DrawString(mUTFont12,String.Format("%s\34%c %d/%d",Stringtable.Localize("$AM_SECRETS"),crdefault+65,level.found_secrets,level.total_secrets),(textdist,y),0,highlight); y += height; } if ( am_showitems ) DrawString(mUTFont12,String.Format("%s\34%c %d/%d",Stringtable.Localize("$AM_ITEMS"),crdefault+65,level.found_items,level.total_items),(textdist,y),0,highlight); } String mapname = level.FormatMapName(crdefault); BrokenLines lines = mUTFont12.mFont.BreakLines(mapname,int(SCREENWIDTH/scale.X)); int numlines = lines.Count(); int finalwidth = int(mUTFont12.mFont.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(mUTFont12,lines.StringAt(i),(0,y),DI_TEXT_ALIGN_CENTER|DI_SCREEN_HCENTER|DI_SCREEN_TOP,highlight); y += height; } } }