Jump to content
Sign in to follow this  
A-SUICIDAL

Health status HUD/Dialog MP issue

Recommended Posts

I created a health status HUD feature for a coop mission. It's currently working great for single player, but there is an issue in multiplayer where if a teammate gets hit, his or her current health status is updated across each players health HUD/dialog. I have been trying my best to figure out how to fix this.

Basically it's a very simple dialog in design. It just shows "Health: 100" in the bottom right corner of the screen at mission start and remains there throughout the game. It gets recreated when the player respawns. There are few different things that will update the health status like, an addEventHandler "Hit" that detects when the player is hit and calculates and converts the damage and then updates the HUD, then there is a heal script that will also update the HUD, there is also a trigger that will detect if the players health == 0 and update the HUD, and finally there is a trigger that detects when the player is alive(after respawning) and recreates the HUD.

I need to find out a way to update the status of each players health HUD locally without it updating every players HUD.

2 basic things get updated. The color of the word "Health:" and the number value of their damage.

Currently I am using the following code to do this:

(_ui displayCtrl 1002) ctrlSetTextColor [0.25, 1, 0, 1];
(_ui displayCtrl 1003) ctrlSetText format ["%1", _hp];

Is there a way to update this info locally?

My whole approach to making this health HUD possible might not have been the best route to take, but I am trying my best.

I've discussed the HUD idea in other threads a little, but I wanted to create a new thread that relates specifically to what it is I am trying to accomplish.

Here's an editor sample mission. It incorporates additional body armor, heal scripts, a vehicle to heal at, one invincible enemy rifleman, an ammo box so you can throw frags near yourself to test the updated health status. Oh, and a hide body script.

health_hud_sample.Desert_E.zip

I hope somebody can help. I care more about making this health HUD thing possible than anything else I've ever worked on for this game.

=====================================================

These are the scripts and stuff used in the sample mission:

Trigger to create the HUD:

null = [] execVM "dialog\health_status.sqf";

description.ext:

#include "dialog\dialog.cpp"

dialog.cpp:

#define CT_STATIC           0
#define ST_LEFT           0x00

class RscTitles
{
class Health_Hud
  	{
     	idd = 1000;
    	movingEnable=0;
     	duration=1e+011;
     	name = "Health_Hud_Name";
     	onLoad = "uiNamespace setVariable ['HUD', _this select 0];";
onUnLoad = "uiNamespace setVariable ['HUD', nil]";
     	controlsBackground[] = {};
     	objects[] = {};
     	class controls
	{
		class bkgrnd
		{
			type = CT_STATIC;
			idc = 1001;
			style = ST_LEFT;
			x = 0.911977 * safezoneW + safezoneX;
			y = 0.949074 * safezoneH + safezoneY;
			w = 0.0625 * safezoneW;
			h = 0.025 * safezoneH;
			font = "Zeppelin32";
			sizeEx = 0.03;
			colorBackground[] = {0,0,0,0.7843};
			colorText[] = {1, 1, 1, 1};
			text = "";
		};
		class health
		{
			type = CT_STATIC;
			idc = 1002;
			style = ST_LEFT;
			x = 0.920836 * safezoneW + safezoneX;
			y = 0.95 * safezoneH + safezoneY;
			w = 0.03125 * safezoneW;
			h = 0.025 * safezoneH;
			font = "Zeppelin32";
			sizeEx = 0.03;
			colorBackground[] = {0, 0, 0, 0};
			colorText[] = {0.25,1,0,1};
			text = "Health: ";
		};
		class status
		{
			type = CT_STATIC;
			idc = 1003;
			style = ST_LEFT;
			x = 0.951044 * safezoneW + safezoneX;
			y = 0.95 * safezoneH + safezoneY;
			w = 0.0166639 * safezoneW;
			h = 0.0252316 * safezoneH;
			font = "Zeppelin32";
			sizeEx = 0.03;
			colorBackground[] = {0, 0, 0, 0};
			colorText[] = {1,1,1,1};
			text = "100";
		};
	};
};
};

dialog\health_status.sqf:

disableSerialization;
cutRsc ["Health_Hud","PLAIN"];
_ui = uiNamespace getVariable "HUD";
_bkgrnd = _ui displayCtrl 1001;
_health = _ui displayCtrl 1002;
_status = _ui displayCtrl 1003;
_array_hud = [_bkgrnd,_health,_status];
{_x ctrlShow true} foreach _array_hud;

player init:

this setVariable ["selections", []];
this setVariable ["gethit", []];
this addEventHandler 
[
"HandleDamage",
   	{
   		if (_this select 1 == "") then
   		{
   			_unit = _this select 0;
   			_selections = _unit getVariable ["selections", []];
   			_gethit = _unit getVariable ["gethit", []];
   			_selection = _this select 1;
   			if !(_selection in _selections) then
   			{
   				_selections set [count _selections, _selection];
   				_gethit set [count _gethit, 0];
   			};    
   			_i = _selections find _selection;
   			_olddamage = _gethit select _i;
   			_damage = _olddamage + ((_this select 2) - _olddamage) * 0.25;
   			_gethit set [_i, _damage];
   			_damage;
   		};
   	}
];
this addEventHandler 
[
   	"Hit",
   	{
	_unit = _this select 0;
   		_dam = getDammage _unit;
   		_dif = 1 - _dam;
   		_total = _dif * 100;
   		_hp = round _total;
	_ui = uiNamespace getVariable "HUD";

   		if ((_hp <=100) && (_hp >80)) then 
   		{
		(_ui displayCtrl 1002) ctrlSetTextColor [0.25, 1, 0, 1];
		(_ui displayCtrl 1003) ctrlSetText format ["%1", _hp];
   			_unit setHit ["hands", 0.9];
   		};
   		if ((_hp <80) && (_hp >60)) then 
   		{
		(_ui displayCtrl 1002) ctrlSetTextColor [0.75, 1, 0, 1];
		(_ui displayCtrl 1003) ctrlSetText format ["%1", _hp];
   			_unit setHit ["body", 0.9];
   		}; 
   		if ((_hp <60) && (_hp >40)) then 
   		{
		(_ui displayCtrl 1002) ctrlSetTextColor [1, 1, 0, 1];
		(_ui displayCtrl 1003) ctrlSetText format ["%1", _hp];
   				_unit setHit ["legs", 0.9];
   		};
   		if ((_hp <40) && (_hp >20)) then 
   		{
		(_ui displayCtrl 1002) ctrlSetTextColor [1, 0.5, 0, 1];
		(_ui displayCtrl 1003) ctrlSetText format ["%1", _hp];
   				_unit setHit ["head", 0.9];
   		};
   		if ((_hp <20) && (_hp >0)) then 
   		{
		(_ui displayCtrl 1002) ctrlSetTextColor [1, 0, 0, 1];
		(_ui displayCtrl 1003) ctrlSetText format ["%1", _hp];
		_unit setHit ["legs", 1];
   		};
	if (!alive _unit) then 
	{
		(_ui displayCtrl 1002) ctrlSetTextColor [1, 0, 0, 1];
		(_ui displayCtrl 1003) ctrlSetText "0";
   			_unit setHit ["hands", 1];
		_unit setHit ["body", 1];
		_unit setHit ["head", 1];
	};
   	}
];
this addEventHandler 
[
"killed",
{
	(_this select 0) execVM "scripts\removeWestBody.sqf"
}
];

Share this post


Link to post
Share on other sites

I am still unable to figure out how to get this working. I've tried creating a dialog specific to each player and it still doesn't seem to work correctly. Honestly I thought that somebody would have known how to make this work correctly and offered some help, but I guess either it's just not possible or nobody knows how to do it, or maybe nobody feels like helping me, :p heh. When it comes to dialogs that have buttons and other interaction, usually the player cannot move at all until the dialog is closed and in most cases the changes the player makes in the dialog only effect the player locally. The dialog/HUD that I created does not open from an action and there is no option to "close" the dialog and the player has no ability to interact with the dialog, but when the player takes damage - the dialog/HUD is then updated with the players current health value. Seems simple enough, but one of my teammates gets hurt and their health value is sent across all players, so suddenly my little health HUD shows my teammates damage, which is not what I want to have happen.

I thought that maybe the problem might reside in how I use cutRsc to bring the hud up for each player. Is there a way to script cutRsc ["Health_Hud","PLAIN"]; so that it would appear for only 1 player? Then maybe I could try to make it so each player sees their own dialog.

Around the time I started trying to figure out how to create a dialog, the OFPEC site was working fine and I was able to view the dialog tutorial that was written by HeliJunkie, but then later that same day the site was suddenly under construction and since then I have not been able to view any tutorials there. I've searched high and low for other tutorials, but everything I was able to find seemed to relate mostly to dialogs that use buttons and etc, which isn't really what I am trying to do. If anybody knows of a tutorial or a sample mission or any kind of mission that incorporates some kind of HUD that is similar to what I am trying to do, please help me out and throw me a link. Thanks.

Share this post


Link to post
Share on other sites

Since you have your dialog updates in "Init" of units, there will be event handlers for each unit for each client. Init executes on all units, no matter if this is your unit or not. Wrap it into

if(local this) then { ... };

This will add dialog handling stuff only if unit is played by client.

---

Also i would recommend to avoid "Init" and use init.sqf instead:

true spawn {
//Wait until player is initialized
waitUntil {player == player};

//Your HUD code here with "player" instead of "this"
}

Edited by SaMatra

Share this post


Link to post
Share on other sites

Thank you SaMatra. I will try implementing what you suggested right now.

Share this post


Link to post
Share on other sites

I did what you said, but I am still having the same problems with the dialog itself where I can't seem to get it to update locally for each player when they take damage.

Share this post


Link to post
Share on other sites

So it doesn't updates hud at all or still updates it when any playable unit takes damage?

---------- Post added at 11:10 ---------- Previous post was at 10:27 ----------

Alright, I did few changes to your mission and now HUD looks to be working properly. Not sure how it behaves with second player but I think it should work fine too.

http://picacid.com/arma2/_FILES/health_hud_sample.Desert_E.rar

There is also a mess with setHit's depending on your _hp but its up to you to sort this out.

I moved hud update stuff into player_updateHUD function so when you need to update hud (using medkit, etc.) call

true call player_updateHUD;

Also hud looks bad with my resolution: Screenshot

Edited by SaMatra

Share this post


Link to post
Share on other sites

Before your last reply, the changes I made were working fine for the host(me) but my teammate friend's HUD was not updating correctly. Also, if I was currently at a health of like 83, when my friend respawned my HUD would suddenly say 100 even though I was still at a health of 83. So the way I had it setup to detect when a player is alive and then reset their health to 100 - was also updating across all players HUDs.

I am going to try your sample mission now. I appreciate all the help you are giving me so much. When I saw the screenshot you posted I thought "eeks!" lol. I definitely need to get it so looks good at any resolution. I didn't know it was going to do that.

Share this post


Link to post
Share on other sites

It works great now. OMG thank you! I made a few changes to the setHit stuff and that's working correctly now too. I got the medkits working as well as the heal at vehicle HUD update. The only thing I need to do now is align the text better. I had another problem with the damage stuff, but that is unrelated to the HUD. Basically both players have additional armor, but for some reason my friend seems to die much faster than I do and I don't really understand why since we are both using the same script. I'm going to try to get everything sorted out. I will repost a new sample mission soon.

Share this post


Link to post
Share on other sites

Armor level might differ for different units and this may be the case.

Share this post


Link to post
Share on other sites

I wish I new why the armor acts differently for some units. I'm going to keep testing it.

Here's a new sample mission with working Health HUD.

I changed the HUD positioning and realigned the text. I tested at 800x600, 1024x768 and 1920x1080 and it looked good. I removed the background and added shadow that surrounds the text. I also tried to match the changing text colors to be consistent with colors seen in the game. The additional armor given to the units still needs a bit more testing since my friend seemed to die easier with fewer hits taken than me when I was hosting. It might actually work smoother on a dedicated server.

health_hud_sample_2.Desert_E.zip

For anybody that wants to test it, you can change the armor value by doing the following:

The files called "EH_handlers.sqf", line 17:

_damage = _olddamage + ((_this select 2) - _olddamage) * 0.25;

you can change * 0.25

a value of * 1 would equal normal "overall" damage.

Special thanks to SaMatra for all his help.

I owe you big time.

Edited by A-SUICIDAL

Share this post


Link to post
Share on other sites

Please sign in to comment

You will be able to leave a comment after signing in



Sign In Now
Sign in to follow this  

×