Jump to content
  • 0

[GZDoom] Changing HUD while playing the same LEVEL?


Dexiaz

Question

Hey there.

 

This might be a strange and tough task, but I'm wondering about making a wad where the level transforms while you're playing through it. I have no problems with implementing this idea in mapping with ACS and other tricks. But I have a "problem" with the HUD image.

 

I'm aware there is a possibility to change HUD images with ZScript, but I'm very bad at this. And I don't have any ideas how to implement it on the playthrough.

 

I've seen HUD change in PSX Doom TC, it was an almost simple idea - there was an actor-token (for PSX Final Doom HUD), which was added in your inventory by the ACS script on the level start. And you can remove this actor-token and the HUD comes back to PSX Ultimate Doom HUD.

 

But I didn't manage to make more BUDs than 2, there were only 2 of them here. I need about 5 or 6, yeah.

 

If you're wondering why I need so much HUD images, I need them to make some kind of "teleport" between classic Doom versions released on consoles. So yes, at first you're seeing PC HUD, after some time 3DO HUD, after some time Sega Saturn HUD, et cetera, et cetera.

 

I would be very grateful for help!

Share this post


Link to post

4 answers to this question

Recommended Posts

  • 1

Here you go:

https://zdoom.org/wiki/SBARINFO

 

Also keep in mind that sbarinfo is deprecated in gzdoom, meaning that it will be not further developed and expanded. Statusbar code in gzdoom is now handled by zscript, here is example of heavily customized zscript statusbar:

////////////////////////////////////////////////////////////////////////////////
// SoA statusbar definition ////////////////////////////////////////////////////
// credits: ramon.dexter ///////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
class soaStatusBar : BaseStatusBar {
	InventoryBarState diparms;
	InventoryBarState diparms_argsbar;

	// Number of tics to move the popscreen up and down.
	const POP_TIME = (Thinker.TICRATE/8);

	// Popscreen height when fully extended
	const POP_HEIGHT = 165;

	// Number of tics to scroll keys left
	const KEY_TIME = (Thinker.TICRATE/3);

	enum eImg {
		imgINVCURS,
		imgCURSOR01,
		imgINVPOP,
		imgINVPOP2,
		imgINVPBAK,
		imgINVPBAK2,
		imgFONY0,
		imgFONY1,
		imgFONY2,
		imgFONY3,
		imgFONY4,
		imgFONY5,
		imgFONY6,
		imgFONY7,
		imgFONY8,
		imgFONY9,
		imgFONY_PERCENT,
		imgSTFON0,
		imgSTFON1,
		imgSTFON2,
		imgSTFON3,
		imgSTFON4,
		imgSTFON5,
		imgSTFON6,
		imgSTFON7,
		imgSTFON8,
		imgSTFON9,
		imgSTFON_PERCENT,
		imgNEGATIVE,
	};
	
	TextureID Images[imgNEGATIVE + 1];
	int CursorImage;
	int CurrentPop, PendingPop, PopHeight, PopHeightChange;
	int KeyPopPos, KeyPopScroll;
	
	HUDFont mYelFont, mGrnFont, mBigFont, mSmlFont, mESfont;
	HUDFont mIndexFont;

	override void Init() {
		static const Name strifeLumpNames[] = {
			"INVCURS", "CURSOR01", "INVPOP", "INVPOP2",
			"INVPBAK", "INVPBAK2",
			"INVFONY0", "INVFONY1", "INVFONY2", "INVFONY3", "INVFONY4",
			"INVFONY5", "INVFONY6", "INVFONY7", "INVFONY8", "INVFONY9",
			"INVFONY%", 
			"STFON0", "STFON1", "STFON2", "STFON3", "STFON4", 
			"STFON5", "STFON6", "STFON7", "STFON8", "STFON9", "STFON%", ""

		};
		
		Super.Init();
		SetSize(0, 320, 200); //size
		Reset();
		
		for(int i = 0; i <= imgNEGATIVE; i++) {
			Images[i] = TexMan.CheckForTexture(strifeLumpNames[i], TexMan.TYPE_MiscPatch);
		}

		CursorImage = Images[imgINVCURS].IsValid() ? imgINVCURS : imgCURSOR01;
		Font fnt = "INDEXFONT";
		mYelFont = HUDFont.Create(fnt, fnt.GetCharWidth("0"), true, 1, 1);
		mGrnFont = HUDFont.Create(fnt, fnt.GetCharWidth("0"), true, 1, 1);
		mBigFont = HUDFont.Create("BigFont", 0, false, 2, 2);
		mSmlFont = HUDFont.Create("SmallFont", 0, false, 2, 2);
		mESfont = HUDFont.Create("ESFONT", 0, false, 1, 1);

diparms_argsbar = InventoryBarState.CreateNoBox(mYelFont, boxsize:(36, 30), innersize:(40, 30), arrowoffs:(0, 0));
	}

	override void NewGame () {
		Super.NewGame();
		Reset ();
	}

	override int GetProtrusion(double scaleratio) const {
		return 10;
	}

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

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

			// Draw pop screen (log, keys, and status)
			if (CurrentPop != POP_None && PopHeight < 0) {
				// This uses direct low level draw commands and would otherwise require calling
				// BeginStatusBar(true);
				DrawPopScreen (screen.GetHeight(), TicFrac);
			}
		}
	}

	override void ShowPop (int popnum) {
		Super.ShowPop(popnum);
		if (popnum == CurrentPop || (popnum == POP_LOG && MustDrawLog(0))) {
			if (popnum == POP_Keys) {
				Inventory item;

				KeyPopPos += 10;
				KeyPopScroll = 280;

				int i = 0;
				for (item = CPlayer.mo.Inv; item != NULL; item = item.Inv) {
					if (item is "Key") {
						if (i == KeyPopPos) {
							return;
						}
						i++;
					}
				}
			}
			PendingPop = POP_None;
			// Do not scroll keys horizontally when dropping the popscreen
			KeyPopScroll = 0;
			KeyPopPos -= 10;
		}
		else {
			KeyPopPos = 0;
			PendingPop = popnum;
		}
	}

	override bool MustDrawLog(int state) {
		// Tell the base class to draw the log if the pop screen won't be displayed.
		return generic_ui || log_vgafont;
	}

	void Reset () {
		CurrentPop = POP_None;
		PendingPop = POP_NoChange;
		PopHeight = 0;
		KeyPopPos = 0;
		KeyPopScroll = 0;
	}

	override void Tick () {
		Super.Tick ();
		//mLampMagazine.Update(CPlayer.mo.GetAmount("lampMagazine"));

		PopHeightChange = 0;
		if (PendingPop != POP_NoChange) {
			if (PopHeight < 0) {
				PopHeightChange = POP_HEIGHT / POP_TIME;
				PopHeight += POP_HEIGHT / POP_TIME;
			}
			else {
				CurrentPop = PendingPop;
				PendingPop = POP_NoChange;
			}
		} else {
			if (CurrentPop == POP_None) {
				PopHeight = 0;
			} else if (PopHeight > -POP_HEIGHT) {
				PopHeight -= POP_HEIGHT / POP_TIME;
				if (PopHeight < -POP_HEIGHT) {
					PopHeight = -POP_HEIGHT;
				} else {
					PopHeightChange = -POP_HEIGHT / POP_TIME;
				}
			}
			if (KeyPopScroll > 0) {
				KeyPopScroll -= 280 / KEY_TIME;
				if (KeyPopScroll < 0) {
					KeyPopScroll = 0;
				}
			}
		}
	}

	// display health bar - simple indicator ///////////////////////////////////
	private void FillBar(double x, double y, double start, double stopp, Color color1, Color color2) {
		Fill(color1, x, y, (stopp-start)*2, 1);
		Fill(color2, x, y+1, (stopp-start)*2, 1);
	}
	
	protected void DrawHealthBar(int health, int x, int y) {
		//  only as health indicator  //////////////////////////////////////////
		Color green1 = Color(255, 180, 228, 128);	// light green
		Color green2 = Color(255, 128, 180, 80);	// dark green

		Color blue1 = Color(255, 196, 204, 252);	// light blue
		Color blue2 = Color(255, 148, 152, 200);	// dark blue

		Color gold1 = Color(255, 224, 188, 0);	// light gold
		Color gold2 = Color(255, 208, 128, 0);	// dark gold

		Color red1 = Color(255, 216, 44,  44);	// light red
		Color red2 = Color(255, 172, 28,  28);	// dark red

		Color grey1 = Color(255, 44, 44,  44);	// light grey
		Color grey2 = Color(255, 28, 28,  28);	// dark grey
		
		Color azure1 = Color(255, 143, 195, 211);
		Color azure2 = Color(255, 59, 127, 139);
		
		if (health == 999) {
				FillBar(x, y-2, 0, 16, azure2, azure2);
				FillBar(x, y, 0, 16, azure1, azure1);
				FillBar(x, y+2, 0, 16, azure2, azure2);
		}
		else {
			if (health == 0) {
				FillBar(x, y-2, 0, 16, grey2, grey2);
				FillBar(x, y, 0, 16, grey1, grey1);
				FillBar(x, y+2, 0, 16, grey2, grey2);
			} else if ( health <= 33 ) {
				FillBar(x, y-2, 0, 16, red2, red2);
				FillBar(x, y, 0, 16, red1, red1);
				FillBar(x, y+2, 0, 16, red2, red2);
			} else if ( health <= 66 ) {
				FillBar(x, y-2, 0, 16, gold2, gold2);
				FillBar(x, y, 0, 16, gold1, gold1);
				FillBar(x, y+2, 0, 16, gold2, gold2);
			} else if ( health<=88 ) {
				FillBar(x, y-2, 0, 16, blue2, blue2);
				FillBar(x, y, 0, 16, blue1, blue1);
				FillBar(x, y+2, 0, 16, blue2, blue2);
			} else {
				FillBar(x, y-2, 0, 16, green2, green2);
				FillBar(x, y, 0, 16, green1, green1);
				FillBar(x, y+2, 0, 16, green2, green2);
			}			
		}
	}

	//##########################################################################
	//## normal statusbar ######################################################
	//##########################################################################
	protected void DrawMainBar (double TicFrac) {
		Inventory item; //temp item variable holder
		int i; //temp counter variable
		// cast player to access his vars //
		let pawn = wastelandRanger(CPlayer.mo);
		
		item = Cplayer.mo.FindInventory("rangerHelmet_item");
		if ( item != null ) {		
			//  Pop screen (log, keys, and status)  ////////////////////////////////
			if (CurrentPop != POP_None && PopHeight < 0) {
				double tmp, h;
				[tmp, tmp, h] = StatusbarToRealCoords(0, 0, 8);
				DrawPopScreen (int(GetTopOfStatusBar() - h), TicFrac);
			}
			
			// statsubar frame & background ////////////////////////////////////////
			DrawImage("HGHUDF", (-54, 0), DI_ITEM_OFFSETS);
			DrawImage("HGinv", (-54, 0), DI_ITEM_OFFSETS, 0.5);
			
			// stamina bar /////////////////////////////////////////////////////////
			if ( CPlayer.cheats & CF_GODMODE || pawn.staminaImplant ) {
				DrawBar("stamBax", "stamBck", pawn.stamin, pawn.maxstamin, (301, 12), 0, 0);
			} else {
				DrawBar("stamBar", "stamBck", pawn.stamin, pawn.maxstamin, (301, 12), 0, 0);
			}
			////////////////////////////////////////////////////////////////////////
			
			// radiation bar  //////////////////////////////////////////////////////
			DrawBar("radbar", "radbck", CPlayer.mo.CountInv("radcount"), 100, (301, 24), false, false);
			////////////////////////////////////////////////////////////////////////
			
			//  Health  ////////////////////////////////////////////////////////////
			//DrawString(mGrnFont, FormatNumber(CPlayer.health, 3, 5), (337, 12), DI_TEXT_ALIGN_RIGHT, Font.CR_DARKRED);
			DrawString(mGrnFont, FormatNumber(CPlayer.health, 3, 5), (334, 14), DI_TEXT_ALIGN_RIGHT, Font.CR_DARKRED);
			int points;
			if (CPlayer.cheats & CF_GODMODE) {
				points = 999;
			} else {
				points = min(CPlayer.health, 200);				
			}
			DrawHealthBar (points, 269, 16);
			////////////////////////////////////////////////////////////////////////

			//  Armor  /////////////////////////////////////////////////////////////
			If(pawn.currentarmor > 0 && pawn.armoramount > 0) {
				string armortype[] = {
					"",
					"A_SVST",
					"A_MLAR",
					"A_KVAR",
					"A_CBAR",
					"A_RGA1",
					"A_RGA2",
					"A_SHLD",
					"A_PWAR"
				};
				DrawImage(armortype[pawn.currentarmor],(-37, 4),DI_ITEM_OFFSETS);
			}
			////////////////////////////////////////////////////////////////////////

			//  Ammo  //////////////////////////////////////////////////////////////
			// new magazine system & old item magazine system //////////////////////
			// normal ammo display + using class variables as magazine instead /////
			Inventory ammo1, ammo2; 
			[ ammo1, ammo2 ] = GetCurrentAmmo ();
			let wpn = augmentedWeapon(CPlayer.ReadyWeapon); 
			if (ammo2 != NULL) {
				DrawString(mGrnFont, FormatNumber(ammo1.Amount, 3, 5), (-3, 4), DI_TEXT_ALIGN_RIGHT, Font.CR_YELLOW);
				DrawString(mGrnFont, FormatNumber(ammo2.Amount, 3, 5), (-3, 15), DI_TEXT_ALIGN_RIGHT, Font.CR_GRAY);		
				// drawBar int vertical == 0 left>right; 1 right>left; 2 down>up; 3 up>down
				DrawBar("mgznBar", "mgznBck", ammo1.Amount, ammo1.MaxAmount, (-24, 32), 0, 3);				
				DrawInventoryIcon (ammo2, (-31, 3), DI_ITEM_OFFSETS);
			} else if ( ammo1 != NULL ) {
				DrawString(mGrnFont, FormatNumber(ammo1.Amount, 3, 5), (-3, 4), DI_TEXT_ALIGN_RIGHT, Font.CR_GOLD);
				DrawBar("mgznBar", "mgznBck", ammo1.Amount, ammo1.MaxAmount, (-24, 32), 0, 3);
				DrawInventoryIcon (ammo1, (-31, 3), DI_ITEM_OFFSETS);
			} else if ( wpn != null ) {
				inventory magtype = CPlayer.mo.FindInventory(wpn.magazinetype);
				if ( wpn.magazine > 0 && magtype ) {
					DrawString(mGrnFont, FormatNumber(wpn.magazine, 3, 5), (-3, 4), DI_TEXT_ALIGN_RIGHT, Font.CR_YELLOW);
					DrawString(mGrnFont, FormatNumber(magtype.Amount, 3, 5), (-3, 15), DI_TEXT_ALIGN_RIGHT, Font.CR_GRAY);
					DrawBar("mgznBar", "mgznBck", wpn.magazine, wpn.magazinemax, (-24, 32), 0, 3);
					DrawInventoryIcon (magtype, (-31, 3), DI_ITEM_OFFSETS);
				} else if ( wpn.magazine == 0 && magtype ) {
					DrawString(mGrnFont, "0", (-3, 4), DI_TEXT_ALIGN_RIGHT, Font.CR_YELLOW);
					DrawString(mGrnFont, FormatNumber(magtype.Amount, 3, 5), (-3, 15), DI_TEXT_ALIGN_RIGHT, Font.CR_GRAY);
					DrawBar("mgznBar", "mgznBck", wpn.magazine, wpn.magazinemax, (-24, 32), 0, 3);
					DrawInventoryIcon (magtype, (-31, 3), DI_ITEM_OFFSETS);
				} else if ( wpn.magazine > 0 && !magtype ) {
					DrawString(mGrnFont, FormatNumber(wpn.magazine, 3, 5), (-3, 4), DI_TEXT_ALIGN_RIGHT, Font.CR_YELLOW);
					DrawBar("mgznBar", "mgznBck", wpn.magazine, wpn.magazinemax, (-24, 32), 0, 3);
					DrawInventoryIcon (magtype, (-31, 3), DI_ITEM_OFFSETS);
				}
			}
			////////////////////////////////////////////////////////////////////////

			// grenades & flares display for weapon.slot 3 ////////////////////////
			if ( wpn is "dexAssaultRifle" ) {
				inventory customAmmo = CPlayer.mo.FindInventory("flare");
				if ( customAmmo != null ) {
					DrawInventoryIcon (customAmmo, (44, -7), DI_ITEM_OFFSETS);
					DrawString(mYelFont, FormatNumber(customAmmo.amount, 3, 5), (66, 6), DI_TEXT_ALIGN_RIGHT, Font.CR_YELLOW);
				}
			}
			if ( wpn is "OICWrifle" ) {
				inventory customAmmo = CPlayer.mo.FindInventory("thumperammo");
				if ( customAmmo != null ) {
					DrawInventoryIcon (customAmmo, (0, 1), DI_ITEM_OFFSETS);
					DrawString(mYelFont, FormatNumber(customAmmo.amount, 3, 5), (12, 16), DI_TEXT_ALIGN_RIGHT, Font.CR_YELLOW);
				}
			}
			////////////////////////////////////////////////////////////////////////

			// clock ///////////////////////////////////////////////////////////////
			DrawString(mYelFont/*mESFont*/, string.format("%02d%s%02d", pawn.playHour, " ", pawn.playMinute), (366, 37), DI_TEXT_ALIGN_RIGHT, Font.CR_GREEN);
			////////////////////////////////////////////////////////////////////////
			
			//  weapon icon  ///////////////////////////////////////////////////////
			item = CPlayer.ReadyWeapon;
			if ( item != null ) {
				DrawInventoryIcon(CPlayer.ReadyWeapon, (10, 1), DI_ITEM_OFFSETS);
			}
			////////////////////////////////////////////////////////////////////////

			//  shoulderGun icon + ammo display  ///////////////////////////////////
			//inventory shldGun;
			//inventory shldGunAmmo;
			inventory shldGun = CPlayer.mo.FindInventory("shoulderGun");
			inventory shldGunAmmo = CPlayer.mo.FindInventory("shoulderGunMag");
			if ( shldGun != null ) {
				drawImage ("HUDshgf", (-54, 0), DI_ITEM_OFFSETS);
				if ( shldGunAmmo != null ) {
					DrawString (mGrnFont, FormatNumber(shldGunAmmo.Amount, 3, 5), (-42, 55), DI_TEXT_ALIGN_RIGHT, Font.CR_YELLOW);
				}
			}
			////////////////////////////////////////////////////////////////////////

			//  selected inventory display  ////////////////////////////////////////
			if (CPlayer.mo.InvSel != null) {
				DrawInventoryIcon(CPlayer.mo.InvSel, (354, 18), DI_ARTIFLASH|DI_ITEM_CENTER, boxsize:(28, 28));
				item = CPlayer.mo.InvSel;
				if (item.Amount > 1) {					
					DrawString(mYelFont, FormatNumber(CPlayer.mo.InvSel.Amount, 3, 5, 0, ""), (371, 26), DI_TEXT_ALIGN_RIGHT, Font.CR_YELLOW);
				}
			}
			////////////////////////////////////////////////////////////////////////

			//  inventory  pop - up  ///////////////////////////////////////////////
			if ( isInventoryBarVisible() ) {
				// frame&background ////////////////////////////////////////////////
				drawImage("HGINVB", (-54, 0), DI_ITEM_OFFSETS, 0.5);
				drawImage("HGINVF", (-54, 0), DI_ITEM_OFFSETS);
				// How much scrap does the player have? ////////////////////////////
				let scrap = CPlayer.mo.FindInventory("credit");
				if ( scrap != null ) {
					DrawString(mSmlFont, string.format( "%s%04d", stringtable.localize("$MSBAR_scrapAmount"), scrap.Amount ), (63, 66), DI_TEXT_ALIGN_LEFT, Font.CR_UNTRANSLATED); //mESFont
				}
				// display all items overall weight in open inventory //////////////
				let pawn = wastelandRanger(CPlayer.mo);
				if ( pawn != NULL ) {
					DrawString(mSmlFont, string.format("%s%i%s%i", stringtable.localize("$MSBAR_weight"), pawn.encumbrance, "\c[green]/\c[yellow]", pawn.weightmax), (142, 66), DI_TEXT_ALIGN_LEFT, Font.CR_GREEN);
				}
				// display inventory bar ///////////////////////////////////////////
				CPlayer.mo.InvFirst = ValidateInvFirst (5);
				i = 0;
				for (item = CPlayer.mo.InvFirst; item != NULL && i < 5; item = item.NextInv()) {
					int flags = item.Amount <= 0? DI_ITEM_OFFSETS|DI_DIM : DI_ITEM_OFFSETS;
					if (item == CPlayer.mo.InvSel) {
						DrawTexture (Images[CursorImage], (68 + 35*i, 25), flags, 1. - itemflashFade);
					}
					DrawInventoryIcon (item, (74 + 35*i, 27), flags);
					//display item weight
					if (item.Mass > 0) {
						DrawString(mESfont, string.format("%s%01d", stringtable.localize("$MSBAR_weightitem"), item.Mass), (105 + 35*i, 29), DI_TEXT_ALIGN_RIGHT, Font.CR_GREEN);
						//connect strings by simple: "W:"..FormatNumber(item.Mass, 3, 5)
					}
					//display item amount
					if (item.Amount > 1) {
						DrawString(mESfont, string.format("%s%01d", stringtable.localize("$MSBAR_amountitem"), item.Amount), (106 + 35*i, 49), DI_TEXT_ALIGN_RIGHT, Font.CR_YELLOW);
					}
					i++;
				}
			}
			////////////////////////////////////////////////////////////////////////
		}
	}
	//##########################################################################
	//##########################################################################
	//##########################################################################
	
	//##########################################################################
	//## fullscreen statusbar replaced with standard statusbar #################
	//##########################################################################	
	
	//##########################################################################
	//## popscreen stuff #######################################################
	//##########################################################################
	protected void DrawPopScreen (int bottom, double TicFrac) {
		String buff;
		String label;
		int i;
		Inventory item;
		Inventory item2; //temp item2 variable holder
		int xscale, yscale, left, top;
		int bars = (CurrentPop == POP_Status) ? imgINVPOP : imgINVPOP2;
		int back = (CurrentPop == POP_Status) ? imgINVPBAK : imgINVPBAK2;
		// Extrapolate the height of the popscreen for smoother movement
		int height = clamp (PopHeight + int(TicFrac * PopHeightChange), -POP_HEIGHT, 0);

		xscale = CleanXfac;
		yscale = CleanYfac;
		left = screen.GetWidth()/2 - 160*CleanXfac;
		top = bottom + height * yscale;

		//  odstranit defaultni background&border  /////////////////////////////
		//screen.DrawTexture (Images[back], true, left, top, DTA_CleanNoMove, true, DTA_Alpha, 0.75);
		//screen.DrawTexture (Images[bars], true, left, top, DTA_CleanNoMove, true);
		let pawn = wastelandRanger(CPlayer.mo);

		switch (CurrentPop) {	

			////////////////////////////////////////////////////////////////////	
			// POP Status //////////////////////////////////////////////////////
			////////////////////////////////////////////////////////////////////
			case POP_Status:				
				//  show backrground & foreground text&border  /////////////////
				screen.DrawTexture (TexMan.CheckForTexture("HGPSTBK", 0, 0), true, left, top-60, DTA_CleanNoMove, true, DTA_Alpha, 0.75);
				screen.DrawTexture (TexMan.CheckForTexture("HGPSTAT", 0, 0), true, left, top-60, DTA_CleanNoMove, true);
				////////////////////////////////////////////////////////////////
				
				//  What weapons does the player have?  ////////////////////////
				// header //
				screen.DrawText(SmallFont, Font.CR_GREEN, left + 46 * xscale, top - 12 * yscale, "$MSBAR_weapons", DTA_CleanNoMove, true);
				static const class<Weapon> WeaponList[] = {
					"dexPistol", // 66, 1
					"StaffBlaster", // 20, 28
					"dexAssaultRifle", // 79, 16
					"SA24Riotgun", // 20, 43 
					"BloodSawedoff", // 70, 46
					"dexSniperRifle", // 40, 60
					"ashesNapalmGun", // 20, 76
					"Thumper", // 20, 95
					"GatLaser", // 20, 109
					"maulerPrototype", // 20, 131
					"plasmaCaster", // 20, -2
					"OICWrifle", // 77, 108
					"ashesFALrifle" // 72, 83
				};
				static const int WeaponX[] = {66, 20, 79, 20, 70, 40, 20, 20, 20, 20, 20, 77, 72};
				static const int WeaponY[] = {1, 28, 16, 43, 46, 60, 76, 95, 109, 131, -2, 108, 83};
				for (i = 0; i < 13; ++i) {
					item = CPlayer.mo.FindInventory (WeaponList[i]);
					if (item != NULL) {
						screen.DrawTexture (item.Icon, true,
							left + WeaponX[i] * xscale,
							top + WeaponY[i] * yscale,
							DTA_CleanNoMove, true,
							DTA_LeftOffset, 0,
							DTA_TopOffset, 0);
					}
				}
				////////////////////////////////////////////////////////////////
					
				//  Does the player have shouldergun?  /////////////////////////
				item = CPlayer.mo.FindInventory ("shoulderGun");
				if (item != NULL) {
					screen.DrawTexture (item.Icon, true, 
						left + 97*xscale,
						top - 12*yscale,
						DTA_CleanNoMove, true
					);
				}
				////////////////////////////////////////////////////////////////

				// selected grenade display ////////////////////////////////////
				if( pawn.grenadeType != 0 ) {
					// header //
					//screen.DrawText(SmallFont, Font.CR_GREEN, left + 78 * xscale, top + 152 * yscale, "$MSBAR_handgrenade", DTA_CleanNoMove, true);				
					if ( pawn.grenadeType == 1 && pawn.countInv("grenadeExplosive") > 0 ) {
						screen.DrawTexture( TexMan.CheckForTexture("I_GRE1", 0, 0), true, left + 93*xscale, top + 134*yscale, DTA_CleanNoMove, true );
						screen.DrawText(SmallFont, Font.CR_YELLOW, left + 110 * xscale, top + 153 * yscale, string.format("%i", pawn.countInv("grenadeExplosive")), DTA_CleanNoMove, true);
					} else if ( pawn.grenadeType == 2 && pawn.countInv("grenadeFire") > 0 ) {
						screen.DrawTexture( TexMan.CheckForTexture("I_GRF1", 0, 0), true, left + 93*xscale, top + 134*yscale, DTA_CleanNoMove, true );
						screen.DrawText(SmallFont, Font.CR_YELLOW, left + 110 * xscale, top + 153 * yscale, string.format("%i", pawn.countInv("grenadeFire")), DTA_CleanNoMove, true);
					} else if ( pawn.grenadeType == 3 && pawn.countInv("grenadePlasma") > 0 ) {
						screen.DrawTexture( TexMan.CheckForTexture("I_PLGR", 0, 0), true, left + 93*xscale, top + 134*yscale, DTA_CleanNoMove, true );
						screen.DrawText(SmallFont, Font.CR_YELLOW, left + 110 * xscale, top + 153 * yscale, string.format("%i", pawn.countInv("grenadePlasma")), DTA_CleanNoMove, true);
					}
				}			
				////////////////////////////////////////////////////////////////
				
				// equipped armor //////////////////////////////////////////////
				// header //
				screen.DrawText(SmallFont, Font.CR_GREEN, left + 160 * xscale, top - 12 * yscale, "$MSBAR_armor", DTA_CleanNoMove, true);
				if ( pawn.currentarmor > 0 && pawn.armoramount > 0 ) {
					TextureID id_armorWorn[9] = {
						TexMan.CheckForTexture("TNT1A0", 0, 0),
						TexMan.CheckForTexture("A_SVST", 0, 0),
						TexMan.CheckForTexture("A_MLAR", 0, 0),
						TexMan.CheckForTexture("A_KVAR", 0, 0),
						TexMan.CheckForTexture("A_CBAR", 0, 0),
						TexMan.CheckForTexture("A_RGA1", 0, 0),
						TexMan.CheckForTexture("A_RGA2", 0, 0),
						TexMan.CheckForTexture("A_SHLD", 0, 0),
						TexMan.CheckForTexture("A_PWAR", 0, 0)
					};
					screen.DrawTexture(id_armorWorn[pawn.currentarmor], true,
						left + 182*xscale,
						top + 3*yscale,
						DTA_CleanNoMove, true
					);	
					screen.DrawText(SmallFont, Font.CR_YELLOW, left + 160 * xscale, top + 28 * yscale, string.format("%s%i", stringtable.localize("$MSBAR_armorac"), pawn.armorclass ), DTA_CleanNoMove, true);	
					screen.DrawText(SmallFont, Font.CR_YELLOW, left + 160 * xscale, top + 36 * yscale, string.format("%s%i", stringtable.localize("$MSBAR_armorq"), pawn.armoramount ), DTA_CleanNoMove, true);
				}			
				////////////////////////////////////////////////////////////////

				//  Print stats  ///////////////////////////////////////////////
				// header //
				screen.DrawText(SmallFont, Font.CR_GREEN, left + 230 * xscale, top - 12 * yscale, "$MSBAR_stats", DTA_CleanNoMove, true); //
				// accuracy //
				screen.DrawText(SmallFont, Font.CR_YELLOW, left + 217 * xscale, top - 0 * yscale, stringtable.localize("$MSBAR_accuracy"), DTA_CleanNoMove, true);
				screen.DrawText(SmallFont, Font.CR_YELLOW, left + 280 * xscale, top - 0 * yscale, string.format("%i", CPlayer.mo.accuracy), DTA_CleanNoMove, true);
				// stamina //
				screen.DrawText(SmallFont, Font.CR_YELLOW, left + 217 * xscale, top + 9 * yscale, stringtable.localize("$MSBAR_stamina"), DTA_CleanNoMove, true);
				screen.DrawText(SmallFont, Font.CR_YELLOW, left + 280 * xscale, top + 9 * yscale, string.format("%i", CPlayer.mo.stamina), DTA_CleanNoMove, true);
				// mind //
				screen.DrawText(SmallFont, Font.CR_YELLOW, left + 217 * xscale, top + 18 * yscale, stringtable.localize("$MSBAR_mind"), DTA_CleanNoMove, true);
				screen.DrawText(SmallFont, Font.CR_YELLOW, left + 280 * xscale, top + 18 * yscale, string.format("%i", pawn.mindValue), DTA_CleanNoMove, true);
				// level //
				screen.DrawText(SmallFont, Font.CR_YELLOW, left + 217 * xscale, top + 33 * yscale, stringtable.localize("$MSBAR_level"), DTA_CleanNoMove, true);
				screen.DrawText(SmallFont, Font.CR_YELLOW, left + 280 * xscale, top + 33 * yscale, string.format("%i", pawn.playerLevel), DTA_CleanNoMove, true);
				// xp //
				screen.DrawText(SmallFont, Font.CR_YELLOW, left + 217 * xscale, top + 42 * yscale, stringtable.localize("$MSBAR_xp"), DTA_CleanNoMove, true);
				screen.DrawText(SmallFont, Font.CR_YELLOW, left + 240 * xscale, top + 42 * yscale, string.format(" %i", pawn.playerXP), DTA_CleanNoMove, true);
				////////////////////////////////////////////////////////////////

				//  How much ammo does the player have?  ///////////////////////
				// header //
				screen.DrawText(SmallFont, Font.CR_GREEN, left + 151 * xscale, top + 57 * yscale, "$MSBAR_ammo", DTA_CleanNoMove, true);
				static const class<Ammo> AmmoList[] = {
					"ammo57mm",			
					"ammoShell",
					"fusionCell",	
					"ThumperAmmo",		
					"napalmAmmo"
				};
				string ammoNames[] = {
					"$MSBAR_naboje",
					"$MSBAR_patrony",
					"$MSBAR_fclanky",
					"$MSBAR_granaty",
					"$MSBAR_napalm"
				};
				static const int AmmoY[] = {66, 75, 84, 93, 102}; // ammo y coordinate	
				for (i = 0; i < 5; ++i) {
					item = CPlayer.mo.FindInventory (AmmoList[i]);
					if (item == NULL) {
						screen.DrawText(
							SmallFont, 
							Font.CR_YELLOW, 
							left + 165 * xscale, 
							top + AmmoY[i] * yscale, 
							string.Format("%s%s%s%s", stringtable.localize(ammoNames[i]), "\c[green]0", "\c[yellow] /\c[white]", formatNumber(GetDefaultByType(AmmoList[i]).MaxAmount, 3, 5)), 
							DTA_CleanNoMove, 
							true
						);
					}
					else {
						screen.DrawText(
							SmallFont, 
							Font.CR_YELLOW, 
							left + 165 * xscale, 
							top + AmmoY[i] * yscale, 
							string.format("%s%s%s%s", stringtable.localize(ammoNames[i]), formatNumber(item.Amount, 3, 5), "\c[yellow] /\c[white]", formatNumber(item.MaxAmount, 3, 5) ), 
							DTA_CleanNoMove, 
							true
						);
					}
				}
				////////////////////////////////////////////////////////////////

				// worn backpack display ///////////////////////////////////////
				if( pawn.playerBackpack != 0 ) {
					// header //
					screen.DrawText(SmallFont, Font.CR_GREEN, left + 145 * xscale, top + 115 * yscale, "$MSBAR_backpack", DTA_CleanNoMove, true);
					if( pawn.playerBackpack == 1 ) {
						screen.DrawTexture( TexMan.CheckForTexture("I_SBPK", 0, 0), true, left + 153*xscale, top + 122*yscale, DTA_CleanNoMove, true );
					} else if ( pawn.playerBackpack == 2 ) {
						screen.DrawTexture( TexMan.CheckForTexture("I_MBPK", 0, 0), true, left + 153*xscale, top + 122*yscale, DTA_CleanNoMove, true );
					} else if ( pawn.playerBackpack == 3 ) {
						screen.DrawTexture( TexMan.CheckForTexture("I_BBPK", 0, 0), true, left + 153*xscale, top + 122*yscale, DTA_CleanNoMove, true );
					}
 				}
				////////////////////////////////////////////////////////////////

				// implants display ////////////////////////////////////////////			
				item = CPlayer.mo.FindInventory ("implant_health");
				item2 = CPlayer.mo.FindInventory ("implant_stamina");
				if ( item != NULL || item2 != NULL ) {
					// header //
					screen.DrawText(SmallFont, Font.CR_GREEN, left + 212 * xscale, top + 115 * yscale, "$MSBAR_implants", DTA_CleanNoMove, true);
					if ( item != NULL ) {
						screen.DrawText(SmallFont, Font.CR_YELLOW, left + 228 * xscale, top + 125 * yscale, "$MSBAR_impregenerate", DTA_CleanNoMove, true);
						screen.DrawTexture (item.Icon, true,
							left + 202*xscale,
							top + 125*yscale,
							DTA_CleanNoMove, true);
					}
					if ( item2 != NULL ) {
						screen.DrawText(SmallFont, Font.CR_YELLOW, left + 228 * xscale, top + 154 * yscale, "$MSBAR_impenergy", DTA_CleanNoMove, true);
						screen.DrawTexture (item2.Icon, true,
							left + 202*xscale,
							top + 145*yscale,
							DTA_CleanNoMove, true);
					}
				}				
				////////////////////////////////////////////////////////////////
			break;
			////////////////////////////////////////////////////////////////////
			
			////////////////////////////////////////////////////////////////////
			// POP Log - Informace /////////////////////////////////////////////
			////////////////////////////////////////////////////////////////////
			case POP_Log:
				// background //////////////////////////////////////////////////
				screen.DrawTexture (TexMan.CheckForTexture("IPOPMb", 0, 0), true, left, top-60, DTA_CleanNoMove, true, DTA_Alpha, 0.75);
				screen.DrawTexture (TexMan.CheckForTexture("IPOPMf", 0, 0), true, left, top-60, DTA_CleanNoMove, true);
								
				// nadpis menu /////////////////////////////////////////////////
				screen.DrawText(SmallFont, Font.CR_GREEN, left + 116 * xscale, top - 12 * yscale, "$MSBAR_worldmap", DTA_CleanNoMove, true);				
				// datum ///////////////////////////////////////////////////////
				screen.DrawText(
					SmallFont, 
					Font.CR_UNTRANSLATED, 
					left + 18 * xscale, 
					top + 0 * yscale, 
					"\c[green][ \c[yellow]"..string.format("%01d%s%01d%s%04d", pawn.gameDay, ". ", pawn.gameMonth, ". ", pawn.gameYear).."\c[green] ]", 
					DTA_CleanNoMove, 
					true
				);
				// map name ////////////////////////////////////////////////////
				screen.DrawText(
					SmallFont, 
					Font.CR_UNTRANSLATED, 
					left + 18 * xscale, 
					top + 10 * yscale, 
					"\c[green][ "..string.format("%s%s", stringtable.localize("$MSBAR_location"), level.FormatMapName(2)).."\c[green] ]", 
					DTA_CleanNoMove, 
					true
				);
				// survival ////////////////////////////////////////////////////
				if ( pawn.survivalEnabled ) {
					// nadpis //
					screen.DrawText(SmallFont, Font.CR_GREEN, left+ 96 *xscale, top+ 140 *yscale, stringtable.localize("$MSBAR_survival"), DTA_CleanNoMove, true);
					// hunger //
					screen.DrawText(SmallFont, Font.CR_YELLOW, left+ 64 *xscale, top+ 152 *yscale, string.format("%s%i", stringtable.localize("$MSBAR_hunger"), pawn.playerHunger), DTA_CleanNoMove, true);
					// thirst //
					screen.DrawText(SmallFont, Font.CR_YELLOW, left+ 136 *xscale, top+ 152 *yscale, string.format("%s%i", stringtable.localize("$MSBAR_thirst"), pawn.playerThirst), DTA_CleanNoMove, true);
					// fatigue //
					screen.DrawText(SmallFont, Font.CR_YELLOW, left+ 200 *xscale, top+ 152 *yscale, string.format("%s%i", stringtable.localize("$MSBAR_tired"), pawn.playerTired), DTA_CleanNoMove, true);
				}
				
			break;
			////////////////////////////////////////////////////////////////////
			
			////////////////////////////////////////////////////////////////////
			// POP Keys ////////////////////////////////////////////////////////
			////////////////////////////////////////////////////////////////////
			case POP_Keys:
				//  show backrground & foreground text&border  /////////////////
				screen.DrawTexture (TexMan.CheckForTexture("IPOPMb", 0, 0), true, left, top-60, DTA_CleanNoMove, true, DTA_Alpha, 0.75);
				screen.DrawTexture (TexMan.CheckForTexture("IPOPMf", 0, 0), true, left, top-60, DTA_CleanNoMove, true);
				// header //////////////////////////////////////////////////////
				screen.DrawText(SmallFont, Font.CR_GREEN, left + 80 * xscale, top - 12 * yscale, "$MSBAR_keyslist", DTA_CleanNoMove, true);
				
				// List the keys the player has. ///////////////////////////////
				int pos, endpos, leftcol;
				int clipleft, clipright;
				
				pos = KeyPopPos;
				endpos = pos + 10;
				leftcol = 20; //20
				clipleft = left + 17*xscale;
				clipright = left + (320-17)*xscale;
				if (KeyPopScroll > 0) {
					// Extrapolate the scroll position for smoother scrolling
					int scroll = MAX (0, KeyPopScroll - int(TicFrac * (280./KEY_TIME)));
					pos -= 10;
					leftcol = leftcol - 280 + scroll;
				}
				i = 0;
				for (item = CPlayer.mo.Inv; i < endpos && item != NULL; item = item.Inv) {
					if (!(item is "Key"))
						continue;
					
					if (i < pos) {
						i++;
						continue;
					}

					label = item.GetTag();

					//int colnum = ((i-pos) / 5) & (KeyPopScroll > 0 ? 3 : 1);
					//int rownum = (i % 5) * 18;
					int colnum = ((i-pos) / 7) & (KeyPopScroll > 0 ? 3 : 1);
					int rownum = (i % 7) * 22;

					screen.DrawTexture (item.Icon, true,
						left + (colnum * 140 + leftcol)*xscale,
						top + (6 + rownum)*yscale,
						DTA_CleanNoMove, true,
						DTA_ClipLeft, clipleft,
						DTA_ClipRight, clipright);
					screen.DrawText (SmallFont, Font.CR_YELLOW,
						left + (colnum * 140 + leftcol + 17)*xscale,
						top + (11 + rownum)*yscale,
						label,
						DTA_CleanNoMove, true,
						DTA_ClipLeft, clipleft,
						DTA_ClipRight, clipright);
					i++;
				}
			break;
			////////////////////////////////////////////////////////////////////
		}
	}
	//##########################################################################
	//##########################################################################
	//##########################################################################

	void DrINumber2 (int val, int x, int y, int width, int imgBase) const {
		x -= width;
		if (val == 0) {
			screen.DrawTexture (Images[imgBase], true, x, y, DTA_CleanNoMove, true);
		} else {
			while (val != 0) {
				screen.DrawTexture (Images[imgBase+val%10], true, x, y, DTA_CleanNoMove, true);
				val /= 10;
				x -= width;
			}
		}
	}
}
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////

It looks more complicated, but once you get a touch at it and understand how it works, it allows things that are impossible in sbarinfo (like drawing customised variables from player, or drawing customised inventory icons, or anything you can imagine).

Edited by ramon.dexter

Share this post


Link to post
  • 0
2 hours ago, Dexiaz said:

 

I've seen HUD change in PSX Doom TC, it was an almost simple idea - there was an actor-token (for PSX Final Doom HUD), which was added in your inventory by the ACS script on the level start. And you can remove this actor-token and the HUD comes back to PSX Ultimate Doom HUD.

 

And you use the same method for changing HUD. at least in gzdoom. You give a player token for hud1, hud2, hud3, etc. In sbarinfo you chek for ownership of said token and then draw the hud only if player has said token.

Share this post


Link to post
  • 0
57 minutes ago, ramon.dexter said:

And you use the same method for changing HUD. at least in gzdoom. You give a player token for hud1, hud2, hud3, etc. In sbarinfo you chek for ownership of said token and then draw the hud only if player has said token.

 

I need a step-by-step guide about this. I know nothing about making such things. Maybe I do know how to script things in ACS, but that doesn't mean, that I understand things related to sbarinfo.

Share this post


Link to post
  • 0
1 hour ago, ramon.dexter said:

It looks more complicated, but once you get a touch at it and understand how it works, it allows things that are impossible in sbarinfo (like drawing customised variables from player, or drawing customised inventory icons, or anything you can imagine).

 

Thank you very much!

Share this post


Link to post

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Answer this question...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...