Screen Armor [Updated 12/4/21]

Post your example zscripts/ACS scripts/etc here.

Screen Armor [Updated 12/4/21]

Postby Hey Doomer » Thu Dec 02, 2021 5:50 am

While Doom armor provides protection, there's no real indication that anything is happening other than a HUD counter. What if the screen showed some visual indicator of a hit and how much armor was left? Perhaps, this has been addressed by other mods. This is my take.

Code: Select allExpand view
class armor_EventHandler : EventHandler
{
   bool bGrid;
   int tCounter;
   int armor;
   
   override void WorldLoaded(WorldEvent e)
   {
      bGrid = false;
   }
   override void RenderOverlay(RenderEvent e)
   {
      if (bGrid)
      {
         color hexColor = "Green";
         int alpha = 255;
         double thickness = 5;
         int edge = 400;

         if (armor < 100)
         {
            alpha = int(255 * armor / 100);
            thickness = 5 * armor / 100;
         }

         for (int cX = 100; cX < Screen.GetWidth(); cX += 100)
         {
            if (cX < edge || cX > Screen.GetWidth() - edge && cX + 40 < Screen.GetWidth())
            {
               for (int cY = 100; cY < Screen.GetHeight() - 50; cY += 100)
               {
                  if (Random(0, 100) < armor)
                  {
                     // top
                     Screen.DrawThickLine(cX - 40, cY, cX - 20, cY + 33, thickness, hexColor, alpha);
                     Screen.DrawThickLine(cX - 20, cY + 33, cX + 20, cY + 33, thickness, hexColor, alpha);
                     Screen.DrawThickLine(cX + 20, cY + 33, cX + 40, cY, thickness, hexColor, alpha);

                     // bottom
                     Screen.DrawThickLine(cX + 40, cY, cX + 20, cY - 33, thickness, hexColor, alpha);
                     Screen.DrawThickLine(cX + 20, cY - 33, cX - 20, cY - 33, thickness, hexColor, alpha);
                     Screen.DrawThickLine(cX - 20, cY - 33, cX - 40, cY, thickness, hexColor, alpha);
                  }
               }
            }
         }
      }
   }
   override void WorldTick()
   {
      if (tCounter < 14)
      {
         tCounter++;
      }
      else
      {
         bGrid = false;
      }
   }
   override void WorldThingDamaged(WorldEvent e)
   {
      if (e.thing && e.thing is "PlayerPawn")
      {
         armor = e.thing.CountInv("BasicArmor");
         if (armor > 0)
         {
            e.thing.A_StartSound("arhit", CHAN_BODY, CHANF_OVERLAP);
            bGrid = true;
            tCounter = 0;
         }
      }
   }
}


How this works is simple. When a player is damaged if armor is in the inventory a partial screen grid of hexagons flashes on the screen. The number of hexagons drawn varies according to the amount of armor in player inventory. I've added a minimal sound effect, which of course is drowned out in close quarters. I use absolute coordinates for performance reasons, although I suppose drawing these on some kind of curve might be effective.

Can't decide how I feel about this as is - it's a work in progress - but it does the job.
You do not have the required permissions to view the files attached to this post.
Last edited by Hey Doomer on Sat Dec 04, 2021 4:16 am, edited 2 times in total.
User avatar
Hey Doomer
 
Joined: 25 Sep 2021
Operating System: Windows 11
OS Test Version: No (Using Stable Public Version)
Graphics Processor: ATI/AMD with Vulkan Support

Re: Screen Armor

Postby Xim » Thu Dec 02, 2021 9:20 am

This would work great for mods that have energy shields for armor. Very good stuff here, good work!
User avatar
Xim
 
Joined: 20 Feb 2009
Location: Somewhere with trees

Re: Screen Armor

Postby Enjay » Thu Dec 02, 2021 1:21 pm

This is a neat idea.

Personally, I think it would be even better if the hexagons were translucent (at values over 100 they have quite a powerful presence on the screen) and it would be nice if there was some colour support for +100 armour too (blue would be an obvious choice).
User avatar
Enjay
Everyone is a moon, and has a dark side which he never shows to anybody. Twain
 
 
 
Joined: 15 Jul 2003
Location: Scotland

Re: Screen Armor [Updated 12/3/21]

Postby Hey Doomer » Fri Dec 03, 2021 4:54 am

Excellent suggestion, Enjay. I've posted an update after playing around with this adding the following:

    - Lower alpha (you're right about the screen presence, it should be almost subliminal
    - Drawing hexagons on an arc to simulate a curved HUD (this is not yet optimized)
    - Colors for different armor strengths

If the armor is < 50 it starts to flicker on the screen. Not fancy but seems to work. I balked at the notion of trig functions, but even without angle optimization it works.

The curvature draws a circular arc from either edge to the other with a slightly increasing radius and incremented angle to offset the hexagons. Again not fancy but seems to work, and my HS math teacher would be proud.
User avatar
Hey Doomer
 
Joined: 25 Sep 2021
Operating System: Windows 11
OS Test Version: No (Using Stable Public Version)
Graphics Processor: ATI/AMD with Vulkan Support

Re: Screen Armor [Updated 12/3/21]

Postby Enjay » Fri Dec 03, 2021 5:03 am

I think that works really nicely. It definitely makes the mod feel more complete.

I guess the only additional thing I can think of would be some menu options to tailor the effects. Not sure what all the options would be though. An on/off toggle is obvious. Perhaps sound on/off, an alpha scale (so that the alpha of the effect is multiplied by the users preference), colour settings if you feel really ambitious...
User avatar
Enjay
Everyone is a moon, and has a dark side which he never shows to anybody. Twain
 
 
 
Joined: 15 Jul 2003
Location: Scotland

Re: Screen Armor [Updated 12/3/21]

Postby ramon.dexter » Fri Dec 03, 2021 1:10 pm

May I borrow this for my World of Strife? It's like exactly I was thinking about when I wanted to improve new armor type. Great, just great!

Enjay: Also, armor level detection could be easily applied. It's really wonderful what could be done with zscript. I tried to include this eventhandler into my eventhandler with this slight modification:
Code: Select allExpand view
    override void WorldThingDamaged(WorldEvent e) {
        if (e.thing && e.Thing is "binderPlayer") {
            let pawn = binderPlayer(e.Thing);
         If(e.Damage>9/*&&(e.DamageType=="Bullet"||e.DamageType=="Melee")*/) {
            //console.printf(string.format("%i", pawn.bleedlevel));
            pawn.bleedlevel++;            
            If(pawn.bleedlevel>5){pawn.bleedlevel=5;}
         }
            pawn.stamin -= e.Damage*7;
            if (pawn.stamin<0) {
                pawn.stamin = 0;
            }
// modified part //////////////////////////////////////////////////////////////////////////////
         armor = pawn.armoramount; //where pawn.armoramount is integer marking, well, armor amount on player. I'm using jarewill's zscript armor system, so there is no real inventory armor item on player.
         if ( armor > 0 && pawn.currentarmor == 5 ) { //where pawn.currentarmor marks armor level, so this shield effect is displayed only for this one type of armor
            //pawn.A_print("!!!HIT!!!");
            e.thing.A_StartSound("arhit", CHAN_BODY, CHANF_OVERLAP);
            bGrid = true;
            tCounter = 0;
         }
//////////////////////////////////////////////////////////////////////////////////////////////
        }
    }


edit:
Aaand I'm thinking about making several types of differently colored shields for different types/level if armor.
User avatar
ramon.dexter
rudebwoy
 
Joined: 20 Oct 2015
Location: Kozolupy, Bohemia
Operating System: Windows 10/8.1/8/201x 64-bit
OS Test Version: No (Using Stable Public Version)
Graphics Processor: nVidia with Vulkan support

Re: Screen Armor [Updated 12/4/21]

Postby Hey Doomer » Sat Dec 04, 2021 4:33 am

Interesting problem to optimize given ZScript's limitations. My goal was to make "holes" in the armor (missing hexagons) persistent and random. My solution was to define the structures of hexagons and the grid in the WorldLoaded() event. This optimizes use of the trig functions, for one.

Code: Select allExpand view
   struct point
   {
      int x;
      int y;
      int armor;
   }
   point grid[100];
   int gCount;


The point array defines the grid; I chose an arbitrary number of 100 (can't use user defined structures in dynamic arrays), because my display defined 78 points. point.armor is a random threshold where a hexagon is damaged and isn't displayed on the screen e.g. armor holes. The random limits are zero to the blue armor threshold. These seems to be working OK and avoids that seizure-inducing flickering effect.

Drawing the grid has been optimized as well:

Code: Select allExpand view
         color hexColor = armor > ar_blue ? co_blue : armor > ar_green ? co_green : armor > ar_yellow ? co_yellow : co_red;
         int alpha = 80;
         double thickness = armor * .05;

         for (int i = 0; i < gCount; i++)
         {
            // make or repair armor holes
            if (armor > grid[i].armor)
            {
               for (int ii = 0; ii < 6; ii++)
               {
                  Screen.DrawThickLine(grid[i].x + sides[ii].x1, grid[i].y + sides[ii].y1, grid[i].x + sides[ii].x2, grid[i].y + sides[ii].y2,
                     thickness, hexColor, alpha);
               }
            }
         }


If armor is above a threshold for a grid point, a hexagon is drawn at a thickness defined by armor. The weaker the armor, the thinner the line.

Colors are arbitrarily named Blue (strongest armor), Green (still OK but shows some weakness), Yellow (warning levels of weakness), and Red (just plain trouble). These colors can be changed in a MENUDEF color picker to be anything. Since these Cvars are pulled in real time during the game, changes are immediate. The only thing that isn't is the random hexagon armor thresholds, which are defined when the grid is loaded. Thresholds for the armor colors can also be defined in the Options menu, although I'm unsure what happens if these are mutually exclusive. Weird things may happen.

Mind you I still don't really know what armor does in terms of protecting the player from damage. That's another matter.
User avatar
Hey Doomer
 
Joined: 25 Sep 2021
Operating System: Windows 11
OS Test Version: No (Using Stable Public Version)
Graphics Processor: ATI/AMD with Vulkan Support

Re: Screen Armor [Updated 12/3/21]

Postby Hey Doomer » Sat Dec 04, 2021 4:53 am

ramon.dexter wrote:May I borrow this for my World of Strife? It's like exactly I was thinking about when I wanted to improve new armor type. Great, just great!

Enjay: Also, armor level detection could be easily applied. It's really wonderful what could be done with zscript. I tried to include this eventhandler into my eventhandler with this slight modification:
Code: Select allExpand view
    override void WorldThingDamaged(WorldEvent e) {
        if (e.thing && e.Thing is "binderPlayer") {
            let pawn = binderPlayer(e.Thing);
         If(e.Damage>9/*&&(e.DamageType=="Bullet"||e.DamageType=="Melee")*/) {
            //console.printf(string.format("%i", pawn.bleedlevel));
            pawn.bleedlevel++;            
            If(pawn.bleedlevel>5){pawn.bleedlevel=5;}
         }
            pawn.stamin -= e.Damage*7;
            if (pawn.stamin<0) {
                pawn.stamin = 0;
            }
// modified part //////////////////////////////////////////////////////////////////////////////
         armor = pawn.armoramount; //where pawn.armoramount is integer marking, well, armor amount on player. I'm using jarewill's zscript armor system, so there is no real inventory armor item on player.
         if ( armor > 0 && pawn.currentarmor == 5 ) { //where pawn.currentarmor marks armor level, so this shield effect is displayed only for this one type of armor
            //pawn.A_print("!!!HIT!!!");
            e.thing.A_StartSound("arhit", CHAN_BODY, CHANF_OVERLAP);
            bGrid = true;
            tCounter = 0;
         }
//////////////////////////////////////////////////////////////////////////////////////////////
        }
    }


edit:
Aaand I'm thinking about making several types of differently colored shields for different types/level if armor.


Sure. Glad I can help.

I'm not sure if the released and updated version will help or offer other ideas, as I have included options for different color thresholds and persistent holes. The flickering drove me a little crazy. I also have not done this with multiplayer in mind, as I only play singleplayer.

Note that it's easy to define different shapes. I chose a hexagon as reasonably complex, but this can be any shape at all. This sides array defines hexagon offsets but can be any shape at all:

Code: Select allExpand view
   // structures
   struct hex
   {
      int x1;
      int y1;
      int x2;
      int y2;
   }
   hex sides[6];


Since DrawLine draws from x,y to x,y and x,y is a point on the grid, x1 etc are center offsets. It's an easy matter to plot any other shape (a pentagon, or five sided array) on paper and add those offsets to a new array. My definition goes in a clockwise manner, but it doesn't matter so long as offsets define start and end of lines compared to a center.

I suppose different shapes for different point thresholds or armor levels are possible. Also possible to have different sizes of the same shape, although I haven't included a scaling function. (I played around with that and didn't like the way it looked.) The different sizes would have to be defined separately as written.
User avatar
Hey Doomer
 
Joined: 25 Sep 2021
Operating System: Windows 11
OS Test Version: No (Using Stable Public Version)
Graphics Processor: ATI/AMD with Vulkan Support

Re: Screen Armor [Updated 12/4/21]

Postby Enjay » Sat Dec 04, 2021 5:01 am

I like the new improvements. :) An option for toggling sound would still be good (I don't think that was in the menu).

>where a hexagon is damaged and isn't displayed on the screen e.g. armor holes.
Yup, I got that straight away. Very intuitive and just makes sense.

>The weaker the armor, the thinner the line.
Also makes sense but, for me, the holes and colours are enough. I find the very thick lines a bit too thick. However, I guess it does make sense for 100+ armour to look beefier on screen.

Good ideas from ramon.dexter too.
User avatar
Enjay
Everyone is a moon, and has a dark side which he never shows to anybody. Twain
 
 
 
Joined: 15 Jul 2003
Location: Scotland


Return to Script Library

Who is online

Users browsing this forum: No registered users and 1 guest