Page 1 of 1

Scroller HUD

Posted: Sat Dec 04, 2021 1:21 pm
by Hey Doomer
Telnet is still with us as low-level device communication, and perhaps it will be by Doom's time. This is my attempt to simulate a scrolling text overlay similar to a Telnet console interface.

(But I got this idea from looking at the Screen object methods and thinking of Terminator. What would a scrolling HUD message look like?)

Screenshot:
https://i.postimg.cc/mZyJm4pK/Screenshot-Doom-20211204-135403.png

ZScript:

Code: Select all

class scroller_EventHandler : EventHandler
{
   Array<string> scroller;
   int sCounter;
   bool bScroll;
   PlayerInfo player;
   
   void addBlanks(int n)
   {
      for (int i = 0; i < n; i++)
      {
         scroller.Push("");
      }
   }
   void updateStatus()
   {
      scroller.Push(String.Format("Health: %d Armor: %d", player.mo.health, player.mo.CountInv("BasicArmor")));
   }

   override void RenderOverlay(RenderEvent e)
   {
      if (bScroll && scroller.Size() > 0)
      {
         int col = Screen.GetWidth() * 0.5 - 200;
         int row = 100 + sCounter;

         for (int i = 0; i < scroller.Size(); i++)
         {
            row += 15;
            if (row > 300)
            {
               break;
            }
            Screen.DrawText(NewSmallFont, Font.CR_RED, col, row, scroller[i], DTA_ClipTop, 100, DTA_ClipBottom, 300, DTA_Alpha, 0.3 * i);
         }
      }
   }
   override void WorldTick()
   {
      if (scroller.Size() > 0)
      {
         bScroll = true;
         sCounter--;
         if (sCounter <= 0)
         {
            scroller.Delete(0);
            sCounter = 10;
         }
      }
      else
      {
         sCounter = 10;
         bScroll = false;
      }
   }
   override void WorldThingDamaged(WorldEvent e)
   {
      if (e.thing && e.thing is "PlayerPawn")
      {
         scroller.Push(String.Format("You've been hit by %s", e.DamageSource.GetSpecies()));
         scroller.Push(String.Format("Damage is %d of %s", e.Damage, e.DamageType));
         updateStatus();
      }
   }
   override void PlayerSpawned(PlayerEvent e)
   {
      string welcome[6] = {
         "Enjoy your stay :^D",
         "Welcome to the jungle, Marine d:^)",
         "Welcome back :^/",
         "Long time no see :^.",
         "Where the HELL have you been? :^o",
         "It's party time X^D"
      };
      string advice[6] = {
         "Stay in the shadows",
         "Aim for the head",
         "Avoid the barrels",
         "You're on your own, Marine",
         "Now GET THE HELL OUT",
         "Have a nice day"
      };

      sCounter = 10;
      player = players[e.PlayerNumber];
      addBlanks(5);
      scroller.Push("login: _");
      scroller.Push("password: _");
      addBlanks(1);
      scroller.Push("CREDENTIALS VERIFIED");
      scroller.Push("Telnet with UAC suit established");
      addBlanks(1);
      scroller.Push(String.Format("Player has entered %s", level.LevelName));
      addBlanks(1);
      scroller.Push(welcome[Random(0,5)]);
      scroller.Push(advice[Random(0,5)]);
      scroller.Push("Below you will see status messages");
      updateStatus();
      bScroll = true;
      sCounter = 0;
   }
}


How this works is simple: a dynamic string array is displayed with clipping at top and bottom of the display area. As soon as the top can't be displayed index 0 is deleted from the dynamic array. That makes sure it scrolls upward until the last array string is displayed. This works, although there may be a better way to accomplish this. It's hard to find the right mix between smooth scrolling and readability without making it too distracting. So far updateStatus() looks at health and armor as an experiment. I suppose this can be an alternative HUD. Any text can be displayed. I've added damage stats, for example. This may break it at the beginning.

This is another one of those Not sure how I feel about it things, but it works.

Another note:

This crashed when damaged by an environmental hazard e.g. nukage. This may fix it, but still testing:

Code: Select all

         if (e.inflictor)
         {
            scroller.Push(String.Format("You've been hit by %s", e.DamageSource.GetSpecies()));
         }