// The Demolitionist HUD is mostly built on top of what I had already done for // SWWM Z, but with lots of color, gradient text and bars, beveled borders, // drop shadows, and much more to give off this sorta "retro UI" vibe. // (The SWWM Z hud was built entirely on borderless flat graphics and smooth // gradient shadows, not exactly the finest looking aesthetic, to be honest) Class MsgLine { String str; transient BrokenLines l, ls; int tic, type, rep; int lastrep; int lastsz; void UpdateText( int sz = 0 ) { bool mustupdate = (!l||!ls||(lastrep!=rep)||((type==PRINT_LOW)&&(sz!=lastsz))); if ( !mustupdate ) return; if ( l ) l.Destroy(); if ( ls ) ls.Destroy(); lastsz = sz; lastrep = rep; String nstr = str; if ( rep > 1 ) nstr.AppendFormat(" (x%d)",rep); let fnt = Font.GetFont('TewiFont'); l = fnt.BreakLines(nstr,(type==PRINT_LOW)?sz:361); if ( type != PRINT_LOW ) ls = fnt.BreakLines(nstr,211); } } Class KeyGet { Class got; int flashtime; } Enum EMiniHUDFontColor { MCR_DEMOHUD, MCR_IBUKIHUD, MCR_SAYAHUD, MCR_KIRINHUD, MCR_MARISAHUD, MCR_VOIDHUD, MCR_WHITE, MCR_RED, MCR_GREEN, MCR_BLUE, MCR_YELLOW, MCR_CYAN, MCR_PURPLE, MCR_BRASS, MCR_SILVER, MCR_GOLD, MCR_MANA, MCR_CRIMSON, MCR_ELDRITCH, MCR_KINYLUM, MCR_NOKRON, MCR_NOKOROKINYLUM, MCR_DEMOBLUE, MCR_DEMOPINK, MCR_ORANGE, MCR_GRASS, MCR_MINT, MCR_AQUA, MCR_MAGENTA, MCR_PINK, MCR_CRYSTAL, MCR_FIRE, MCR_SULFUR, MCR_WITCH, MCR_CYANBLU, MCR_ICE, MCR_PURPUR, MCR_TOMATO, MCR_BLURP, MCR_PURB, MCR_FLASH, MCR_REDFLASH, MCR_WHITEFLASH, NUM_MINIHUD_COLOR }; Class SWWMStatusBar : BaseStatusBar { TextureID StatusTex, WeaponTex, ScoreTex, InventoryTex, ChatTex[6], HealthTex[9], FuelTex[2], DashTex, EnemyBTex, EnemyHTex[7], GenericAmmoTex[3], AmmoTex[3], MiniBox, bgtex, FaceTex[19]; Font mSmallFont, mSmallFontOutline, mTinyFont, mTinyFontOutline, MiniHUDFont, MiniHUDFontOutline; int mhudfontcol[NUM_MINIHUD_COLOR]; Array MainQueue, PickupQueue; transient ThinkerIterator cti; // the event handler, holding all sorts of stuff SWWMHandler hnd; // shared stuff double hs; double hs1; double hs2; Vector2 ss; Vector2 ss1; Vector2 ss2; int margin; double FracTic; double FrameTime; double PrevFrame; int chatopen; int pausetime; Vector2 pausepos, pausedir; // constants const MAXSHOWN = 4; const MAXSHOWNBIG = 10; const MAXPICKUP = 5; const CHATDURATION = 25; const MSGDURATION = 5; const PICKDURATION = 3; // shared from renderunderlay, needed for proper interpolation of some things Vector3 viewpos, viewrot; // projection data cache SWWMProjectionData projdata; DynamicValueInterpolator ScoreInter; Inventory lastsel; Weapon lastwep; String ntagstr; int ntagtic, ntagcol; String midstr; int midtic, midtype; transient BrokenLines midl; int midsz; int puzzlecnt, realpuzzlecnt; SWWMWeaponTooltip ctip; transient ThinkerIterator mi; // for map markers double minimapzoom, oldminimapzoom; // minimap constants const CLIPDIST = 800; // clip distance for minimap view, with rotation accounted const MAPVIEWDIST = 1132; // maximum distance for something to be considered visible (rounded up CLIPDIST*sqrt(2)) const HALFMAPSIZE = 40; // half the size of the minimap draw region (unscaled) // minimap colors (thats a lot of 'em) Color mm_backcolor, mm_cdwallcolor, mm_efwallcolor, mm_fdwallcolor, mm_interlevelcolor, mm_intralevelcolor, mm_lockedcolor, mm_notseencolor, mm_portalcolor, mm_secretsectorcolor, mm_secretwallcolor, mm_specialwallcolor, mm_thingcolor, mm_thingcolor_citem, mm_thingcolor_friend, mm_thingcolor_item, mm_thingcolor_monster, mm_thingcolor_ncmonster, mm_thingcolor_shootable, mm_thingcolor_vipitem, mm_thingcolor_missile, mm_tswallcolor, mm_unexploredsecretcolor, mm_wallcolor, mm_yourcolor; transient bool mm_cvfirstdraw; transient Canvas mm_canvas; transient TextureID mm_canvastex; // deathmatch stuff int playercount, rank, lead; bool tiedscore; Array sortplayers; Array teamactive; Array teamscore; int PulsePhase; // for health pulsing // for flashing some elements in the hud Array keyflash; int oldkills, olditems, oldsecrets; int oldtkills, oldtitems, oldtsecrets; int oldpkills, oldpitems, oldpsecrets; transient int killflash, itemflash, secretflash; transient int tkillflash, titemflash, tsecretflash; transient int pkillflash, pitemflash, psecretflash; // top stuff colors int tclabel, tcvalue, tcextra, tccompl, tcsucks; String tclabel_s, tcextra_s; transient int AmmoFlash[18]; // flash when new ammo is received int AmmoOldAmounts[18]; // to detect when to flash transient int AmmoMaxFlash[18]; // flash when ammo max amount changes int AmmoOldMaxAmounts[18]; // to detect when to flash Class AmmoSlots[18]; // ammo type on each slot String AmmoNames[18]; // ammo 4-letter names transient int HealthFlash; // flash when healing int LastHealth; // to detect when to flash int LagHealth[10]; // for delayed decay bar SmoothDynamicValueInterpolator HealthInter, FuelInter, DashInter; SmoothLinearValueInterpolator LagHealthInter; transient ui int rss; // called by static handler when loading a game // forcibly flushes our interpolators void Flush() { FlushTopStuff(); FlushStatus(); } // separated so they can be auto-ticked by the demolitionist menu void TickInterpolators() { // ensure money updates when using the store TickTopStuffInterpolators(); // ensure healthbar updates when buying healing items TickStatusInterpolators(); // ensure ammo flashes when buying TickWeaponInterpolators(); } override void Tick() { Super.Tick(); if ( !hnd ) hnd = SWWMHandler(EventHandler.Find("SWWMHandler")); pausetime = gametic; SWWMUtility.PrepareProjData(projdata,ViewPos,ViewRot.x,ViewRot.y,ViewRot.z,players[consoleplayer].fov); // interpolators first TickInterpolators(); // subcategory tickers TickMessages(); TickStatus(); TickTopStuff(); TickWeapons(); // part of gross hackery to override nametag display if ( CPlayer.inventorytics > 0 ) { if ( CPlayer.mo.InvSel && (CPlayer.mo.InvSel != lastsel) && (displaynametags&1) && (CPlayer == players[consoleplayer]) ) { ntagstr = CPlayer.mo.InvSel.GetTag(); ntagtic = level.totaltime; ntagcol = nametagcolor; } lastsel = CPlayer.mo.InvSel; } if ( CPlayer.PendingWeapon && (CPlayer.PendingWeapon != WP_NOCHANGE) && (CPlayer.PendingWeapon != lastwep) ) { if ( (displaynametags&2) && (CPlayer == players[consoleplayer]) && !(CPlayer.PendingWeapon is 'SWWMGesture') && !(CPlayer.PendingWeapon is 'SWWMItemGesture') ) { ntagstr = CPlayer.PendingWeapon.GetTag(); ntagtic = level.totaltime; ntagcol = nametagcolor; } } lastwep = CPlayer.PendingWeapon; } override void Init() { StatusTex = TexMan.CheckForTexture("graphics/HUD/StatusBox.png"); DashTex = TexMan.CheckForTexture("graphics/HUD/DashBar.png"); FuelTex[0] = TexMan.CheckForTexture("graphics/HUD/FuelBar.png"); FuelTex[1] = TexMan.CheckForTexture("graphics/HUD/FuelBarS.png"); HealthTex[0] = TexMan.CheckForTexture("graphics/HUD/HealthBar0.png"); HealthTex[1] = TexMan.CheckForTexture("graphics/HUD/HealthBar1.png"); HealthTex[2] = TexMan.CheckForTexture("graphics/HUD/HealthBar2.png"); HealthTex[3] = TexMan.CheckForTexture("graphics/HUD/HealthBar3.png"); HealthTex[4] = TexMan.CheckForTexture("graphics/HUD/HealthBarS.png"); HealthTex[5] = TexMan.CheckForTexture("graphics/HUD/HealthBarD.png"); HealthTex[6] = TexMan.CheckForTexture("graphics/HUD/HealthBarP.png"); HealthTex[7] = TexMan.CheckForTexture("graphics/HUD/HealthBarF.png"); HealthTex[8] = TexMan.CheckForTexture("graphics/HUD/HealthBarL.png"); ScoreTex = TexMan.CheckForTexture("graphics/HUD/ScoreBox.png"); WeaponTex = TexMan.CheckForTexture("graphics/HUD/WeaponBox.png"); ChatTex[0] = TexMan.CheckForTexture("graphics/HUD/ChatBoxTop.png"); ChatTex[1] = TexMan.CheckForTexture("graphics/HUD/ChatBoxLine.png"); ChatTex[2] = TexMan.CheckForTexture("graphics/HUD/ChatBoxBottom.png"); ChatTex[3] = TexMan.CheckForTexture("graphics/HUD/ChatBoxTop_Smol.png"); ChatTex[4] = TexMan.CheckForTexture("graphics/HUD/ChatBoxLine_Smol.png"); ChatTex[5] = TexMan.CheckForTexture("graphics/HUD/ChatBoxBottom_Smol.png"); InventoryTex = TexMan.CheckForTexture("graphics/HUD/InventoryBox.png"); EnemyBTex = TexMan.CheckForTexture("graphics/HUD/EnemyBox.png"); EnemyHTex[0] = TexMan.CheckForTexture("graphics/HUD/EnemyBar.png"); EnemyHTex[1] = TexMan.CheckForTexture("graphics/HUD/EnemyBarS.png"); EnemyHTex[2] = TexMan.CheckForTexture("graphics/HUD/EnemyBarL.png"); EnemyHTex[3] = TexMan.CheckForTexture("graphics/HUD/EnemyBar1.png"); EnemyHTex[4] = TexMan.CheckForTexture("graphics/HUD/EnemyBar2.png"); EnemyHTex[5] = TexMan.CheckForTexture("graphics/HUD/EnemyBar3.png"); EnemyHTex[6] = TexMan.CheckForTexture("graphics/HUD/EnemyBarD.png"); GenericAmmoTex[0] = TexMan.CheckForTexture("graphics/HUD/GenericAmmoBoxL.png"); GenericAmmoTex[1] = TexMan.CheckForTexture("graphics/HUD/GenericAmmoBoxM.png"); GenericAmmoTex[2] = TexMan.CheckForTexture("graphics/HUD/GenericAmmoBoxR.png"); AmmoTex[0] = TexMan.CheckForTexture("graphics/HUD/AmmoBoxT.png"); AmmoTex[1] = TexMan.CheckForTexture("graphics/HUD/AmmoBoxM.png"); AmmoTex[2] = TexMan.CheckForTexture("graphics/HUD/AmmoBoxB.png"); MiniBox = TexMan.CheckForTexture("graphics/HUD/MinimapBox.png"); bgtex = TexMan.CheckForTexture("graphics/tempbg.png"); FaceTex[0] = TexMan.CheckForTexture("graphics/HUD/DemoFace_Head.png"); FaceTex[1] = TexMan.CheckForTexture("graphics/HUD/DemoFace_Flash.png"); FaceTex[2] = TexMan.CheckForTexture("graphics/HUD/DemoFace_Default.png"); FaceTex[3] = TexMan.CheckForTexture("graphics/HUD/DemoFace_Unamused.png"); FaceTex[4] = TexMan.CheckForTexture("graphics/HUD/DemoFace_Blink.png"); FaceTex[5] = TexMan.CheckForTexture("graphics/HUD/DemoFace_Grin.png"); FaceTex[6] = TexMan.CheckForTexture("graphics/HUD/DemoFace_Evil.png"); FaceTex[7] = TexMan.CheckForTexture("graphics/HUD/DemoFace_Hurt.png"); FaceTex[8] = TexMan.CheckForTexture("graphics/HUD/DemoFace_HurtLeft.png"); FaceTex[9] = TexMan.CheckForTexture("graphics/HUD/DemoFace_HurtRight.png"); FaceTex[10] = TexMan.CheckForTexture("graphics/HUD/DemoFace_Ouch.png"); FaceTex[11] = TexMan.CheckForTexture("graphics/HUD/DemoFace_Dead.png"); FaceTex[12] = TexMan.CheckForTexture("graphics/HUD/DemoFace_Smug.png"); FaceTex[13] = TexMan.CheckForTexture("graphics/HUD/DemoFace_Angery.png"); FaceTex[14] = TexMan.CheckForTexture("graphics/HUD/DemoFace_Barrier.png"); FaceTex[15] = TexMan.CheckForTexture("graphics/HUD/DemoFace_Rage.png"); FaceTex[16] = TexMan.CheckForTexture("graphics/HUD/DemoFace_Angerage.png"); FaceTex[17] = TexMan.CheckForTexture("graphics/HUD/DemoFace_Sad.png"); FaceTex[18] = TexMan.CheckForTexture("graphics/HUD/DemoFace_Wink.png"); // other expressions will be added when needed mSmallFont = Font.GetFont('TewiFont'); mSmallFontOutline = Font.GetFont('TewiFontOutline'); mTinyFont = Font.GetFont('MiniwiFont'); mTinyFontOutline = Font.GetFont('MiniwiFontOutline'); MiniHudFont = Font.GetFont("MiniHUDShadow"); MiniHudFontOutline = Font.GetFont("MiniHUDOutline"); mhudfontcol[MCR_DEMOHUD] = Font.FindFontColor("MiniDemoHUD"); mhudfontcol[MCR_IBUKIHUD] = Font.FindFontColor("MiniIbukiHUD"); mhudfontcol[MCR_SAYAHUD] = Font.FindFontColor("MiniSayaHUD"); mhudfontcol[MCR_KIRINHUD] = Font.FindFontColor("MiniKirinHUD"); mhudfontcol[MCR_MARISAHUD] = Font.FindFontColor("MiniMarisaHUD"); mhudfontcol[MCR_VOIDHUD] = Font.FindFontColor("MiniVoidHUD"); mhudfontcol[MCR_WHITE] = Font.FindFontColor("MiniWhite"); mhudfontcol[MCR_RED] = Font.FindFontColor("MiniRed"); mhudfontcol[MCR_GREEN] = Font.FindFontColor("MiniGreen"); mhudfontcol[MCR_BLUE] = Font.FindFontColor("MiniBlue"); mhudfontcol[MCR_YELLOW] = Font.FindFontColor("MiniYellow"); mhudfontcol[MCR_CYAN] = Font.FindFontColor("MiniCyan"); mhudfontcol[MCR_PURPLE] = Font.FindFontColor("MiniPurple"); mhudfontcol[MCR_BRASS] = Font.FindFontColor("MiniBrass"); mhudfontcol[MCR_SILVER] = Font.FindFontColor("MiniSilver"); mhudfontcol[MCR_GOLD] = Font.FindFontColor("MiniGold"); mhudfontcol[MCR_MANA] = Font.FindFontColor("MiniMana"); mhudfontcol[MCR_CRIMSON] = Font.FindFontColor("MiniCrimson"); mhudfontcol[MCR_ELDRITCH] = Font.FindFontColor("MiniEldritch"); mhudfontcol[MCR_KINYLUM] = Font.FindFontColor("MiniKinylum"); mhudfontcol[MCR_NOKRON] = Font.FindFontColor("MiniNokron"); mhudfontcol[MCR_NOKOROKINYLUM] = Font.FindFontColor("MiniNokorokinylum"); mhudfontcol[MCR_DEMOBLUE] = Font.FindFontColor("MiniDemoBlue"); mhudfontcol[MCR_DEMOPINK] = Font.FindFontColor("MiniDemoPink"); mhudfontcol[MCR_ORANGE] = Font.FindFontColor("MiniOrange"); mhudfontcol[MCR_GRASS] = Font.FindFontColor("MiniGrass"); mhudfontcol[MCR_MINT] = Font.FindFontColor("MiniMint"); mhudfontcol[MCR_AQUA] = Font.FindFontColor("MiniAqua"); mhudfontcol[MCR_MAGENTA] = Font.FindFontColor("MiniMagenta"); mhudfontcol[MCR_PINK] = Font.FindFontColor("MiniPink"); mhudfontcol[MCR_CRYSTAL] = Font.FindFontColor("MiniCrystal"); mhudfontcol[MCR_FIRE] = Font.FindFontColor("MiniFire"); mhudfontcol[MCR_SULFUR] = Font.FindFontColor("MiniSulfur"); mhudfontcol[MCR_WITCH] = Font.FindFontColor("MiniWitch"); mhudfontcol[MCR_CYANBLU] = Font.FindFontColor("MiniCyanblu"); mhudfontcol[MCR_ICE] = Font.FindFontColor("MiniIce"); mhudfontcol[MCR_PURPUR] = Font.FindFontColor("MiniPurpur"); mhudfontcol[MCR_TOMATO] = Font.FindFontColor("MiniTomato"); mhudfontcol[MCR_BLURP] = Font.FindFontColor("MiniBlurp"); mhudfontcol[MCR_PURB] = Font.FindFontColor("MiniPurb"); mhudfontcol[MCR_FLASH] = Font.FindFontColor("MiniFlash"); mhudfontcol[MCR_REDFLASH] = Font.FindFontColor("MiniRedFlash"); mhudfontcol[MCR_WHITEFLASH] = Font.FindFontColor("MiniWhiteFlash"); tclabel = mhudfontcol[MCR_CYANBLU]; tcvalue = mhudfontcol[MCR_WHITE]; tcextra = mhudfontcol[MCR_IBUKIHUD]; tccompl = mhudfontcol[MCR_BRASS]; tcsucks = mhudfontcol[MCR_RED]; tclabel_s = "[MiniCyanblu]"; tcextra_s = "[MiniIbukiHUD]"; minimapzoom = oldminimapzoom = 1.; LastHealth = CPlayer?CPlayer.health:100; let d = Demolitionist(CPlayer?CPlayer.mo:null); HealthInter = SmoothDynamicValueInterpolator.Create(LastHealth,.5); FuelInter = SmoothDynamicValueInterpolator.Create(d?(d.dashfuel/2):120,.5); DashInter = SmoothDynamicValueInterpolator.Create(d?((40-d.dashcooldown)*3):40,.5); LagHealthInter = SmoothLinearValueInterpolator.Create(LastHealth,2); for ( int i=0; i<10; i++ ) LagHealth[i] = LastHealth; AmmoSlots[0] = 'RedShell'; AmmoSlots[1] = 'GoldShell'; AmmoSlots[2] = 'SMW05Ammo'; AmmoSlots[3] = 'EvisceratorShell'; AmmoSlots[4] = 'SheenAmmo'; AmmoSlots[5] = 'HellblazerMissiles'; AmmoSlots[6] = 'QuadravolAmmo'; AmmoSlots[7] = 'SparkUnit'; AmmoSlots[8] = 'SparksterBAmmo'; AmmoSlots[9] = 'SparksterRAmmo'; AmmoSlots[10] = 'SilverBulletAmmo'; AmmoSlots[11] = 'RayAmmo'; AmmoSlots[12] = 'CandyGunAmmo'; AmmoSlots[13] = 'CandyGunSpares'; AmmoSlots[14] = 'MisterAmmo'; AmmoSlots[15] = 'MisterGAmmo'; AmmoSlots[16] = 'YnykronAmmo'; AmmoSlots[17] = 'UltimateAmmo'; AmmoNames[0] = "SHOT"; AmmoNames[1] = "GOLD"; AmmoNames[2] = "SCRW"; AmmoNames[3] = "FLAK"; AmmoNames[4] = "MACH"; AmmoNames[5] = "MISL"; AmmoNames[6] = "QUAD"; AmmoNames[7] = "BSPK"; AmmoNames[8] = "KINY"; AmmoNames[9] = "NOKR"; AmmoNames[10] = "RIFL"; AmmoNames[11] = "BOLT"; AmmoNames[12] = "CAND"; AmmoNames[13] = "CGUN"; AmmoNames[14] = "MSTR"; AmmoNames[15] = "MGRN"; AmmoNames[16] = "CRYS"; AmmoNames[17] = "ULTI"; for ( int i=0; i<18; i++ ) { AmmoFlash[i] = 0; AmmoOldAmounts[i] = int.min; AmmoMaxFlash[i] = 0; AmmoOldMaxAmounts[i] = int.min; } ScoreInter = DynamicValueInterpolator.Create(0,.1,1,999999999); hnd = SWWMHandler(EventHandler.Find("SWWMHandler")); PrevFrame = MSTimeF(); } override void DrawMyPos() { String str = String.Format("(%d,%d,%d)",CPlayer.mo.pos.X,CPlayer.mo.pos.Y,CPlayer.mo.pos.Z); Screen.DrawText(mTinyFontOutline,Font.CR_GREEN,(ss.x-mTinyFontOutline.StringWidth(str))/2,4,str,DTA_VirtualWidthF,ss.x,DTA_VirtualHeightF,ss.y,DTA_KeepRatio,true); } override bool DrawChat( String txt ) { // ignore during intermission if ( gamestate != GS_LEVEL ) return false; chatopen = gametic+1; // have to add 1 because DrawChat is called after everything else double xx = 2; double yy = ss.y-14; Screen.Dim("Black",.8,0,Screen.GetHeight()-int(15*hs),Screen.GetWidth(),int(15*hs)); String pname = players[consoleplayer].GetUserName(); // strip colors SWWMUtility.StripColor(pname); String fullstr = String.Format("\cq%s\cd@\cqdemolitionist%d\cn ~ \cd% \c-wall %s_",pname,consoleplayer+1,txt); // cut out to fit int w = mSmallFont.StringWidth(fullstr); if ( w > ss.x-4 ) { // draw trailing dots Screen.DrawText(mSmallFont,Font.CR_WHITE,xx,yy,"...",DTA_VirtualWidthF,ss.x,DTA_VirtualHeightF,ss.y,DTA_KeepRatio,true); // shift back xx -= w-(ss.x-4); // draw trimmed Screen.DrawText(mSmallFont,Font.CR_WHITE,xx,yy,fullstr,DTA_VirtualWidthF,ss.x,DTA_VirtualHeightF,ss.y,DTA_KeepRatio,true,DTA_ClipLeft,int(26*hs)); } else Screen.DrawText(mSmallFont,Font.CR_WHITE,xx,yy,fullstr,DTA_VirtualWidthF,ss.x,DTA_VirtualHeightF,ss.y,DTA_KeepRatio,true); return true; } override bool DrawPaused( int player ) { let fnt = mSmallFontOutline?mSmallFontOutline:NewSmallFont; let fnt2 = mSmallFont?mSmallFont:NewConsoleFont; if ( swwm_fuzz ) { Vector2 tsize = TexMan.GetScaledSize(bgtex); double zoom = max(ceil(Screen.GetWidth()/tsize.x),ceil(Screen.GetHeight()/tsize.y)); Vector2 vsize = (Screen.GetWidth(),Screen.GetHeight())/zoom; Screen.DrawTexture(bgtex,false,(vsize.x-tsize.x)/2,(vsize.y-tsize.y)/2,DTA_VirtualWidthF,vsize.x,DTA_VirtualHeightF,vsize.y,DTA_KeepRatio,true,DTA_ColorOverlay,Color(192,0,0,0),DTA_Alpha,.5); } else Screen.Dim("Black",.5,0,0,Screen.GetWidth(),Screen.GetHeight()); String str = StringTable.Localize("$SWWM_PAUSE"); if ( gametic < pausetime+1000 ) { pausepos.x = Screen.GetWidth()/2; pausepos.y = Screen.GetHeight()/2; pausedir = (1,1); } else { pausepos.x += pausedir.x*CleanXFac; pausepos.y += pausedir.y*CleanYFac; if ( pausepos.x >= Screen.GetWidth()-((fnt.StringWidth(str)*3+8)*CleanXFac/2) ) pausedir.x = -1; if ( pausepos.x < ((fnt.StringWidth(str)*3+8)*CleanXFac/2) ) pausedir.x = 1; if ( pausepos.y >= Screen.GetHeight()-((fnt.GetHeight()*3+8)*CleanYFac/2) ) pausedir.y = -1; if ( pausepos.y < ((fnt.GetHeight()*3+8)*CleanYFac/2) ) pausedir.y = 1; } double xx = pausepos.x-(fnt.StringWidth(str)*3*CleanXFac)/2; double yy = pausepos.y-(fnt.GetHeight()*3*CleanYFac)/2; int tlen = str.CodePointCount(); for ( int i=0, pos=0; i 0) || (CPlayer != players[consoleplayer]) ) return 1.; String str; double alph; int len; double xx, yy; double deadtimer = (goner?goner.deadtimer:demo.deadtimer)+fractic; if ( goner || (demo.player.viewheight <= 6) ) { double dimalph = goner?1.:min(deadtimer/80.,.8); Screen.Dim("Black",dimalph,0,0,Screen.GetWidth(),Screen.GetHeight()); if ( demo && (demo.revivefail > level.maptime) ) { Screen.Dim("Red",clamp((demo.revivefail-(level.maptime+fractic))/60.,0.,.2),0,0,Screen.GetWidth(),Screen.GetHeight()); str = StringTable.Localize("$SWWM_REFAIL"); len = mSmallFont.StringWidth(str); xx = int((ss.x-len)/2.); yy = ss.y-48; if ( ((demo.revivefail-level.maptime)%16) < 8 ) Screen.DrawText(mSmallFont,Font.CR_RED,xx,yy,str,DTA_VirtualWidthF,ss.x,DTA_VirtualHeightF,ss.y,DTA_KeepRatio,true); } alph = clamp((deadtimer-60)/60.,0.,1.); String nam = CPlayer.GetUserName(); if ( !multiplayer || (nam == "Player") ) str = StringTable.Localize("$SWWM_URDED_GEN"); else str = String.Format(StringTable.Localize("$SWWM_URDED"),nam); len = mSmallFont.StringWidth(str); xx = int((ss.x-len)/2.); yy = (ss.y-mSmallFont.GetHeight()*4)/2.; // shift down if scoreboard is shown if ( (deathmatch && sb_deathmatch_enable && (!teamplay || sb_teamdeathmatch_enable)) || (multiplayer && sb_cooperative_enable) ) yy += ss.y/3.+mSmallFont.GetHeight(); Screen.DrawText(mSmallFont,Font.CR_RED,xx,yy,str,DTA_VirtualWidthF,ss.x,DTA_VirtualHeightF,ss.y,DTA_KeepRatio,true,DTA_Alpha,alph); if ( multiplayer || level.AllowRespawn || sv_singleplayerrespawn || G_SkillPropertyInt(SKILLP_PlayerRespawn) ) { if ( sv_norespawn ) return (1.-dimalph); alph = clamp((deadtimer-90)/60.,0.,1.); str = String.Format(StringTable.Localize("$SWWM_URDEDMP")); len = mSmallFont.StringWidth(str); xx = int((ss.x-len)/2.); yy = ss.y/2.; // shift down if scoreboard is shown if ( (deathmatch && sb_deathmatch_enable && (!teamplay || sb_teamdeathmatch_enable)) || (multiplayer && sb_cooperative_enable) ) yy += ss.y/3.; Screen.DrawText(mSmallFont,Font.CR_WHITE,xx,yy,str,DTA_VirtualWidthF,ss.x,DTA_VirtualHeightF,ss.y,DTA_KeepRatio,true,DTA_Alpha,alph); return (1.-dimalph); } alph = clamp((deadtimer-140)/60.,0.,1.); str = String.Format(StringTable.Localize("$SWWM_URDED2")); len = mSmallFont.StringWidth(str); xx = int((ss.x-len)/2.); yy = ss.y/2.; Screen.DrawText(mSmallFont,Font.CR_WHITE,xx,yy,str,DTA_VirtualWidthF,ss.x,DTA_VirtualHeightF,ss.y,DTA_KeepRatio,true,DTA_Alpha,alph); if ( goner || hnd.gdat.disablerevive || !swwm_revive ) return (1.-dimalph); alph = clamp((deadtimer-160)/60.,0.,1.); str = String.Format(StringTable.Localize("$SWWM_URDED3")); len = mSmallFont.StringWidth(str); xx = int((ss.x-len)/2.); yy = (ss.y+mSmallFont.GetHeight()*2)/2.; Screen.DrawText(mSmallFont,Font.CR_WHITE,xx,yy,str,DTA_VirtualWidthF,ss.x,DTA_VirtualHeightF,ss.y,DTA_KeepRatio,true,DTA_Alpha,alph); return (1.-dimalph); } return 1.; } override void Draw( int state, double TicFrac ) { double CurFrame = MSTimeF(); // 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 if ( deathmatch ) { // forcibly strip these messages // (I decided to drop MP support, so even though there are no // actual spree/multikill announcements in this mod, keeping // the vanilla ones out is important for graphical consistency) DetachMessageID(0x4b535052); // KSPR DetachMessageID(0x5250534b); DetachMessageID(0x4d4b494c); // MKIL DetachMessageID(0x4c494b4d); } Super.Draw(state,TicFrac); FrameTime = (CurFrame-PrevFrame)/1000.; if ( (state != HUD_StatusBar) && (state != HUD_Fullscreen) ) { PrevFrame = CurFrame; return; } if ( !hnd ) hnd = SWWMHandler(EventHandler.Find("SWWMHandler")); hs = max(min(floor(Screen.GetWidth()/640.),floor(Screen.GetHeight()/360.)),1.); ss = (Screen.GetWidth()/hs,Screen.GetHeight()/hs); margin = clamp(swwm_hudmargin,0,20); hs1 = max(hs-1.,1.); hs2 = max(hs-2.,1.); ss1 = (Screen.GetWidth()/hs1,Screen.GetHeight()/hs1); ss2 = (Screen.GetWidth()/hs2,Screen.GetHeight()/hs2); FracTic = TicFrac; if ( (players[consoleplayer].Camera is 'Demolitionist') && (state <= HUD_Fullscreen) ) { if ( hnd ) hnd.DrawBossBar(self); DrawTarget(); DrawTopStuff(); DrawInventory(); DrawStatus(); DrawWeapons(); } DrawPickups(); double malph = DrawDeath(); DrawMessages(malph); if ( state == HUD_AltHud ) { String str = StringTable.Localize("$SWWM_WARNALTHUD"); Screen.DrawText(NewSmallFont,Font.CR_RED,(ss.x-NewSmallFont.StringWidth(str))/2,margin,str,DTA_VirtualWidthF,ss.x,DTA_VirtualHeightF,ss.y,DTA_KeepRatio,true); } PrevFrame = CurFrame; } }