Level stats "countdown"

Ask about ACS, DECORATE, ZScript, or any other scripting questions here!

Moderator: GZDoom Developers

Forum rules
Before asking on how to use a ZDoom feature, read the ZDoom wiki first. If you still don't understand how to use a feature, then ask here.

Please bear in mind that the people helping you do not automatically know how much you know. You may be asked to upload your project file to look at. Don't be afraid to ask questions about what things mean, but also please be patient with the people trying to help you. (And helpers, please be patient with the person you're trying to help!)
Post Reply
User avatar
NightFright
Spotlight Team
Posts: 1343
Joined: Fri May 02, 2008 12:29 pm
Location: Germany

Level stats "countdown"

Post by NightFright »

I am looking for a solution to implement a short but informative level stats display on-screen that goes with the status bar. It's supposed to show the usual stats (kills, items, secrets), but not in the usual form, i.e. <amount found> / <total amount>.
Instead, it should be showing either
- an (increasing) percentage or
- decreasing amount, like <x> amount of kills left, <y> amount of items left, <z> amount of secrets left.

Since I see no such function available via sbarinfo, I assume it needs to be scripted. If anyone was able and willing to help, I'd be most grateful.
User avatar
NightFright
Spotlight Team
Posts: 1343
Joined: Fri May 02, 2008 12:29 pm
Location: Germany

Re: Level stats "countdown"

Post by NightFright »

OK, I have tried something, but warning: I have NO idea about scripting and therefore it's quite likely that it's absolutely idiotic what I am trying to do:

In folder ACS, I put a compiled script "mapstats.o" with this code:

Code: Select all

#library "mapstats"
#include "zcommon.acs"

global int 1:killprc;
global int 2:itemprc;
global int 3:scrtprc;

script "killcounter" (void)
{
    int mtotal  = GetLevelInfo (LEVELINFO_TOTAL_MONSTERS);
    int mkilled = GetLevelInfo (LEVELINFO_KILLED_MONSTERS);
    if (mtotal > 0) { killprc = (mkilled * 100) / mtotal; }
    else { killprc = 100; }
}

script "itemcounter" (void)
{     
    int itotal  = GetLevelInfo (LEVELINFO_TOTAL_ITEMS);
    int ifound  = GetLevelInfo (LEVELINFO_FOUND_ITEMS);
    if (itotal > 0) { itemprc = (ifound * 100) / itotal; }
    else { itemprc = 100; }
}

script "secretcounter" (void)
{
    int stotal  = GetLevelInfo (LEVELINFO_TOTAL_SECRETS);
    int sfound  = GetLevelInfo (LEVELINFO_FOUND_SECRETS);
    if (stotal > 0) { scrtprc = (sfound * 100) / stotal; }
    else { scrtprc = 100; }
}
LOADACS lump contains:

Code: Select all

mapstats
In SBARINFO, it is referenced like this:

Code: Select all

DrawImage "STATS", -48, 5;
DrawNumber 3, INDEXFONT_DOOM, untranslated, globalvar 1, fillzeros, -12, 5;
DrawNumber 3, INDEXFONT_DOOM, untranslated, globalvar 2, -12, 11;
DrawNumber 3, INDEXFONT_DOOM, untranslated, globalvar 3, -12, 17;
This is what it looks like now:


Needless to say, this doesn't work, the counters stay at 0 ingame. Any ideas what needs to be changed?
User avatar
m8f
 
 
Posts: 1445
Joined: Fri Dec 29, 2017 4:15 am
Preferred Pronouns: He/Him
Operating System Version (Optional): Manjaro Linux
Location: Siberia (UTC+7)
Contact:

Re: Level stats "countdown"

Post by m8f »

The script type probably should be ENTER instead of (void).
User avatar
NightFright
Spotlight Team
Posts: 1343
Joined: Fri May 02, 2008 12:29 pm
Location: Germany

Re: Level stats "countdown"

Post by NightFright »

Hmmm... well, simply replacing "(void)" with "ENTER" everywhere didn't change anything, unfortunately.
User avatar
m8f
 
 
Posts: 1445
Joined: Fri Dec 29, 2017 4:15 am
Preferred Pronouns: He/Him
Operating System Version (Optional): Manjaro Linux
Location: Siberia (UTC+7)
Contact:

Re: Level stats "countdown"

Post by m8f »

You also will need loops to make variable update repeated, like this:

Code: Select all

#library "mapstats"
#include "zcommon.acs"

global int 1:killprc;
global int 2:itemprc;
global int 3:scrtprc;

script "killcounter" ENTER
{
    while (1)
    {
      int mtotal  = GetLevelInfo (LEVELINFO_TOTAL_MONSTERS);
      int mkilled = GetLevelInfo (LEVELINFO_KILLED_MONSTERS);
      if (mtotal > 0) { killprc = (mkilled * 100) / mtotal; }
      else { killprc = 100; }
      
      delay(35);
    }

}

script "itemcounter" ENTER
{
    while (1)
    {
      int itotal  = GetLevelInfo (LEVELINFO_TOTAL_ITEMS);
      int ifound  = GetLevelInfo (LEVELINFO_FOUND_ITEMS);
      if (itotal > 0) { itemprc = (ifound * 100) / itotal; }
      else { itemprc = 100; }
      
      delay(35);
    }
}

script "secretcounter" ENTER
{
    while (1)
    {
      int stotal  = GetLevelInfo (LEVELINFO_TOTAL_SECRETS);
      int sfound  = GetLevelInfo (LEVELINFO_FOUND_SECRETS);
      if (stotal > 0) { scrtprc = (sfound * 100) / stotal; }
      else { scrtprc = 100; }
      
      delay(35);
    }
}
Here, while (1) means to loop forever (until game ends), and delay(35) means to wait 1 second before updating variable values again.
User avatar
NightFright
Spotlight Team
Posts: 1343
Joined: Fri May 02, 2008 12:29 pm
Location: Germany

Re: Level stats "countdown"

Post by NightFright »

Wow, that actually did the trick! It works like a charm now. Thank you so much, pal!
What is also remarkable is that my script actually wasn't that much off after all. The basic idea was correct...!
Blue Shadow
Posts: 4949
Joined: Sun Nov 14, 2010 12:59 am

Re: Level stats "countdown"

Post by Blue Shadow »

Be careful with using global variables. If someone loads the HUD with a map (or a gameplay mod) which happens to use the same global variables as the ones used by the HUD, it'll cause a conflict.
User avatar
NightFright
Spotlight Team
Posts: 1343
Joined: Fri May 02, 2008 12:29 pm
Location: Germany

Re: Level stats "countdown"

Post by NightFright »

If there is a way to use this in sbarinfo other than with global vars, feel free to enlighten me. I think choosing numbers 1, 2, 3 will not exactly help avoiding conflicts with other mods, but well. Other than that, the script seems to be fully functional.

This is how I am using it in my status bar mod (sbarinfo code):

Code: Select all

DrawImage "STATS", -49, 5;
DrawNumber 3, INDEXFONT_DOOM, untranslated, globalvar 1, -12, 5;
DrawNumber 3, INDEXFONT_DOOM, untranslated, globalvar 2, -12, 11;
DrawNumber 3, INDEXFONT_DOOM, untranslated, globalvar 3, -12, 17;
Feel free to use it for your own purposes if needed, even though crediting me would be nice, still.
User avatar
Beed28
Posts: 598
Joined: Sun Feb 24, 2013 4:07 pm
Location: United Kingdom

Re: Level stats "countdown"

Post by Beed28 »

I also did something like this for personal use, though I hadn't released it to the public until this point:


Additionally, each counter turns green when one is depleted, and the percentage counter at the bottom turns gold once it reaches 100%.

This is how I did it, though it could do with some cleaning up a little; along with some slight customisation through CVARINFO and MENUDEF:

Code: Select all

#library "MAPSTAT"
#include "zcommon.acs"

script "map_mapstats" ENTER
{
	if(GameType() == GAME_TITLE_MAP || GameType() == GAME_NET_DEATHMATCH) { Terminate; }
	
	int m_count;
	int i_count;
	int s_count;
	int percentage;
	
	int align = 1.0;
	int ypos = 1.0;
	
	while(true)
	{
		m_count = GetLevelInfo(LEVELINFO_TOTAL_MONSTERS) - GetLevelInfo(LEVELINFO_KILLED_MONSTERS);
		i_count = GetLevelInfo(LEVELINFO_TOTAL_ITEMS) - GetLevelInfo(LEVELINFO_FOUND_ITEMS);
		s_count = GetLevelInfo(LEVELINFO_TOTAL_SECRETS) - GetLevelInfo(LEVELINFO_FOUND_SECRETS);
		
		if(GetLevelInfo(LEVELINFO_TOTAL_MONSTERS) + GetLevelInfo(LEVELINFO_TOTAL_ITEMS) + GetLevelInfo(LEVELINFO_TOTAL_SECRETS) > 0 && GetCVar("MapRemainingStats_Show"))
		{
			percentage = (GetLevelInfo(LEVELINFO_KILLED_MONSTERS) + GetLevelInfo(LEVELINFO_FOUND_ITEMS) + GetLevelInfo(LEVELINFO_FOUND_SECRETS)) * 100 /
			(GetLevelInfo(LEVELINFO_TOTAL_MONSTERS) + GetLevelInfo(LEVELINFO_TOTAL_ITEMS) + GetLevelInfo(LEVELINFO_TOTAL_SECRETS));
			
			if(GetCVar("MapRemainingStats_Alignment"))
				align = 635.2;
			else
				align = 5.1;
			
			ypos = GetCVar("MapRemainingStats_Pos");
			
			SetHudSize(640, 480, true);
			SetFont("SMALLFONT");
			if(m_count <= 0)
				HudMessage(d:m_count, s:" MONSTERS LEFT"; HUDMSG_PLAIN, 0, CR_GREEN, align, ypos, 0.03, 0);
			else
				HudMessage(d:m_count, s:" MONSTERS LEFT"; HUDMSG_PLAIN, 0, CR_WHITE, align, ypos, 0.03, 0);
			if(i_count <= 0)
				HudMessage(d:i_count, s:" ITEMS LEFT"; HUDMSG_PLAIN, 0, CR_GREEN, align, ypos + 10.0, 0.03, 0);
			else
				HudMessage(d:i_count, s:" ITEMS LEFT"; HUDMSG_PLAIN, 0, CR_WHITE, align, ypos + 10.0, 0.03, 0);
			if(s_count <= 0)
				HudMessage(d:s_count, s:" SECRETS LEFT"; HUDMSG_PLAIN, 0, CR_GREEN, align, ypos + 20.0, 0.03, 0);
			else
				HudMessage(d:s_count, s:" SECRETS LEFT"; HUDMSG_PLAIN, 0, CR_WHITE, align, ypos + 20.0, 0.03, 0);
			if(percentage >= 100)
				HudMessage(d:percentage, s:"%"; HUDMSG_PLAIN | HUDMSG_COLORSTRING, 0, "Fire", align, ypos + 30.0, 0.03, 0);
			else
				HudMessage(d:percentage, s:"%"; HUDMSG_PLAIN, 0, CR_WHITE, align, ypos + 30.0, 0.03, 0);
		}
		Delay(1);
	}
}
MENUDEF:

Code: Select all

AddOptionMenu "OptionsMenu"
{
	StaticText ""
	StaticText "Map Remaining Stats", "Yellow"
	Option "Shown", "MapRemainingStats_Show", "OnOff"
	Option "Alignment", "MapRemainingStats_Alignment", "StatsLeftRight"
	Slider "Position", "MapRemainingStats_Pos", 0.1, 440.1, 5.0, 0
}

OptionValue "StatsLeftRight"
{
	0, "Left"
	1, "Right"
}
CVARINFO:

Code: Select all

user bool MapRemainingStats_Show = true;
user bool MapRemainingStats_Alignment = true;
user float MapRemainingStats_Pos = 105.1;
User avatar
NightFright
Spotlight Team
Posts: 1343
Joined: Fri May 02, 2008 12:29 pm
Location: Germany

Re: Level stats "countdown"

Post by NightFright »

I just realized that the level stats are also calculated on the intermission screen. Is there any way to tap into this calculation during the level without having to do it via separate ACS scripts?
Post Reply

Return to “Scripting”