Page 1 of 1

Multiple errors attempting to make a ZScript status bar

Posted: Sun Jun 12, 2022 6:21 pm
by Chaosvolt
I'd ask this in the pinned thread but it's locked. In a nutshell, I'm trying to make a status bar in ZScript but I'm running into issues. The wiki's utter lack of functional documentation for this didn't help, and couldn't find any examples in the locked thread that would illuminate the cause of the errors I'm running into. Can anyone tell me what I'm doing wrong here?

Here is the current status bar class I'm trying to use, currently in my main zscipt file:
[spoiler]

Code: Select all

class CVShotguneryStatusBar : BaseStatusBar
{
   HUDFont mHUDFont;
   HUDFont mIndexFont;
   HUDFont mAmountFont;
   InventoryBarState diparms;
   

   override void Init()
   {
      Super.Init();
      SetSize(32, 320, 200);

      // Create the font used for the fullscreen HUD
      Font fnt = "HUDFONT_DOOM";
      mHUDFont = HUDFont.Create(fnt, fnt.GetCharWidth("0"), Mono_CellLeft, 1, 1);
      fnt = "INDEXFONT_DOOM";
      mIndexFont = HUDFont.Create(fnt, fnt.GetCharWidth("0"), Mono_CellLeft);
      mAmountFont = HUDFont.Create("INDEXFONT");
      diparms = InventoryBarState.Create();
   }

   override void Draw (int state, double TicFrac)
   {
      Super.Draw (state, TicFrac);

      if (state == HUD_StatusBar)
      {
         BeginStatusBar();
         CVDrawMainBar (TicFrac);
      }
      else if (state == HUD_Fullscreen)
      {
         BeginHUD();
         DrawFullScreenStuff ();
      }
   }

   protected virtual void CVDrawMainBar (double TicFrac)
   {
      DrawImage("CVBAR", (0, 168), DI_ITEM_OFFSETS);
      DrawImage("STTPRCNT", (90, 171), DI_ITEM_OFFSETS);
      DrawImage("STTPRCNT", (215, 171), DI_ITEM_OFFSETS);
      
      Inventory a1 = GetCurrentAmmo();
      if (a1 != null) DrawString(mHUDFont, FormatNumber(a1.Amount, 3), (44, 171), DI_TEXT_ALIGN_RIGHT|DI_NOSHADOW);
      DrawString(mHUDFont, FormatNumber(CPlayer.health, 3), (90, 171), DI_TEXT_ALIGN_RIGHT|DI_NOSHADOW);
      DrawString(mHUDFont, FormatNumber(GetArmorAmount(), 3), (215, 171), DI_TEXT_ALIGN_RIGHT|DI_NOSHADOW);

      CVDrawBarKeys();
      CVDrawBarAmmo();
       DrawString(mHUDFont, FormatNumber(CPlayer.FragCount, 3), (138, 171), DI_TEXT_ALIGN_RIGHT);
      
      if (multiplayer)
      {
         DrawImage("STFBANY", (137, 168), DI_ITEM_OFFSETS|DI_TRANSLATABLE);
      }
      
      if (CPlayer.mo.InvSel != null && !Level.NoInventoryBar)
      {
         DrawInventoryIcon(CPlayer.mo.InvSel, (154, 198));
         if (CPlayer.mo.InvSel.Amount > 1)
         {
            DrawString(mAmountFont, FormatNumber(CPlayer.mo.InvSel.Amount), (169, 198-mIndexFont.mFont.GetHeight()), DI_TEXT_ALIGN_RIGHT, Font.CR_GOLD);
         }
      }
      else
      {
         DrawTexture(GetMugShot(5), (137, 168), DI_ITEM_OFFSETS);
      }
      if (isInventoryBarVisible())
      {
         DrawInventoryBar(diparms, (48, 169), 7, DI_ITEM_LEFT_TOP);
      }
      
   }
   
   protected virtual void CVDrawBarKeys()
   {
      bool locks[6];
      String image;
      for(int i = 0; i < 6; i++) locks[i] = CPlayer.mo.CheckKeys(i + 1, false, true);
      // key 1
      if (locks[1] && locks[4]) image = "STKEYS6";
      else if (locks[1]) image = "STKEYS0";
      else if (locks[4]) image = "STKEYS3";
      DrawImage(image, (233, 171), DI_ITEM_OFFSETS);
      // key 2
      if (locks[2] && locks[5]) image = "STKEYS7";
      else if (locks[2]) image = "STKEYS1";
      else if (locks[5]) image = "STKEYS4";
      else image = "";
      DrawImage(image, (233, 181), DI_ITEM_OFFSETS);
      // key 3
      if (locks[0] && locks[3]) image = "STKEYS8";
      else if (locks[0]) image = "STKEYS2";
      else if (locks[3]) image = "STKEYS5";
      else image = "";
      DrawImage(image, (233, 191), DI_ITEM_OFFSETS);
   }
   
   protected virtual void CVDrawBarAmmo()
   {
      int amt1;
      [amt1] = GetAmount("CVBuckshot");
      DrawString(mIndexFont, FormatNumber(amt1, 3), (282, 173), DI_TEXT_ALIGN_RIGHT);

      [amt1] = GetAmount("CVSlug");
      DrawString(mIndexFont, FormatNumber(amt1, 3), (308, 173), DI_TEXT_ALIGN_RIGHT);
      
      [amt1] = GetAmount("CVFlechette");
      DrawString(mIndexFont, FormatNumber(amt1, 3), (282, 182), DI_TEXT_ALIGN_RIGHT);

      [amt1] = GetAmount("CVExplosive");
      DrawString(mIndexFont, FormatNumber(amt1, 3), (308, 182), DI_TEXT_ALIGN_RIGHT);
      
      [amt1] = GetAmount("CVIncendiary");
      DrawString(mIndexFont, FormatNumber(amt1, 3), (282, 191), DI_TEXT_ALIGN_RIGHT);

      [amt1] = GetAmount("CVPlasma");
      DrawString(mIndexFont, FormatNumber(amt1, 3), (308, 191), DI_TEXT_ALIGN_RIGHT);
   }

   protected void DrawFullScreenStuff ()
   {
      Vector2 iconbox = (40, 20);
      // Draw health
      let berserk = CPlayer.mo.FindInventory("PowerStrength");
      DrawImage(berserk? "PSTRA0" : "MEDIA0", (20, -2));
      DrawString(mHUDFont, FormatNumber(CPlayer.health, 3), (44, -20));
      
      let armor = CPlayer.mo.FindInventory("BasicArmor");
      if (armor != null && armor.Amount > 0)
      {
         DrawInventoryIcon(armor, (20, -22));
         DrawString(mHUDFont, FormatNumber(armor.Amount, 3), (44, -40));
      }
      Inventory ammotype1, ammotype2;
      [ammotype1, ammotype2] = GetCurrentAmmo();
      int invY = -20;
      if (ammotype1 != null)
      {
         DrawInventoryIcon(ammotype1, (-14, -4));
         DrawString(mHUDFont, FormatNumber(ammotype1.Amount, 3), (-30, -20), DI_TEXT_ALIGN_RIGHT);
         invY -= 20;
      }
      if (ammotype2 != null && ammotype2 != ammotype1)
      {
         DrawInventoryIcon(ammotype2, (-14, invY + 17));
         DrawString(mHUDFont, FormatNumber(ammotype2.Amount, 3), (-30, invY), DI_TEXT_ALIGN_RIGHT);
         invY -= 20;
      }
      if (!isInventoryBarVisible() && !Level.NoInventoryBar && CPlayer.mo.InvSel != null)
      {
         DrawInventoryIcon(CPlayer.mo.InvSel, (-14, invY + 17));
         DrawString(mHUDFont, FormatNumber(CPlayer.mo.InvSel.Amount, 3), (-30, invY), DI_TEXT_ALIGN_RIGHT);
      }
      if (deathmatch)
      {
         DrawString(mHUDFont, FormatNumber(CPlayer.FragCount, 3), (-3, 1), DI_TEXT_ALIGN_RIGHT, Font.CR_GOLD);
      }
      else
      {
         DrawFullscreenKeys();
      }
      
      if (isInventoryBarVisible())
      {
         DrawInventoryBar(diparms, (0, 0), 7, DI_SCREEN_CENTER_BOTTOM, HX_SHADOW);
      }
   }
   
   protected virtual void DrawFullscreenKeys()
   {
      // Draw the keys. This does not use a special draw function like SBARINFO because the specifics will be different for each mod
      // so it's easier to copy or reimplement the following piece of code instead of trying to write a complicated all-encompassing solution.
      Vector2 keypos = (-10, 2);
      int rowc = 0;
      double roww = 0;
      for(let i = CPlayer.mo.Inv; i != null; i = i.Inv)
      {
         if (i is "Key" && i.Icon.IsValid())
         {
            DrawTexture(i.Icon, keypos, DI_SCREEN_RIGHT_TOP|DI_ITEM_LEFT_TOP);
            Vector2 size = TexMan.GetScaledSize(i.Icon);
            keypos.Y += size.Y + 2;
            roww = max(roww, size.X);
            if (++rowc == 3)
            {
               keypos.Y = 2;
               keypos.X -= roww + 2;
               roww = 0;
               rowc = 0;
            }
         }
      }
   }
}
[/spoiler]

And here are the errors I'm getting:
Spoiler:


From the looks of it, my guess is it is COMPLETELY failing to grab any of the essential properties you'd expect it to grab by inheriting from BaseStatusBar? GZDoom version is 4.6.0, status bar is largely copied from Doom version.

Re: Multiple errors attempting to make a ZScript status bar

Posted: Sun Jun 12, 2022 8:13 pm
by phantombeta
Based on the errors (e.g., the class being seemingly "play" scope despite BaseStatusBar itself being "ui"), that seems like you have no ZScript version specified. You have to specify a version in your ZScript file to get these errors to go away. Generally, you'll want to use at least 4.0.0, minimum, as some very annoying ZScript bugs were fixed before that. Preferably, though, you should use the latest version possible to avoid getting affected by already-fixed ZScript bugs.

Re: Multiple errors attempting to make a ZScript status bar

Posted: Sun Jun 12, 2022 9:28 pm
by Chaosvolt
Ah, weird. So since I'm testing in 4.6.0 then specifying that version may be the most idiotproof. I'll test it in a bit, thanks.

Re: Multiple errors attempting to make a ZScript status bar

Posted: Sun Jun 12, 2022 9:43 pm
by Chaosvolt
This upgrades the fatal error to a Very Fatal Error:

Code: Select all

Code: C0000005 (Access Violation - tried to read address 0000000000000000)
Address: 00007FF6A0365B17
Flags: 00000000


Tested both 4.0.0 and 4.6.0 for versions.

Re: Multiple errors attempting to make a ZScript status bar

Posted: Mon Jun 13, 2022 4:53 pm
by Blue Shadow
Remove the square brackets around the amt1 variable in CVDrawBarAmmo. You only need them if you're trying to get more than one return value.

Re: Multiple errors attempting to make a ZScript status bar

Posted: Mon Jun 13, 2022 4:58 pm
by Chaosvolt
Ah, that might well be it. I'm actually just about to release the mod I was testing this for, after I finish that post up I'll test that.

Re: Multiple errors attempting to make a ZScript status bar

Posted: Mon Jun 13, 2022 5:13 pm
by Chaosvolt
And yep, that seems to fix it, thanks. I'll have to tinker with offsets to get it line up with how I have it set up in SBARINFO, then I'd be able to switch to a ZScript status bar for the mod in question.

Re: Multiple errors attempting to make a ZScript status bar

Posted: Wed Jun 15, 2022 1:18 pm
by Player701
Chaosvolt wrote:This upgrades the fatal error to a Very Fatal Error:

Code: Select all

Code: C0000005 (Access Violation - tried to read address 0000000000000000)
Address: 00007FF6A0365B17
Flags: 00000000


Tested both 4.0.0 and 4.6.0 for versions.

I've reported the fatal error here, since it still occurs in GZDoom 4.8.0. Please note that even if your code is not correct, very fatal errors are (generally) still engine bugs that should be reported.

Re: Multiple errors attempting to make a ZScript status bar

Posted: Wed Jun 15, 2022 11:31 pm
by Chaosvolt
Ah, thanks. Definitely weird to see that happen, but glad that it was easy to sort out what triggered it.