tutorial HP Bars 2016

msmalik681

OpenBOR Developer
Staff member
I have just updated my HP Bar script it now shows a non image yellow bar above enemies head.  Again set its height by adding a MP value for each enemy.  New feature it now shows damage when enemy is hit there will be a red damage indicator that catches up the current hp just like in most modern fighting games this give you a feel for how damaging your combo was (but as it works on a percentage not that accurate as each enemy has different health lol).


to apply it save the below script to a .c text file then declare in enemy header with: ondrawscript data/scripts/hpbar.c or whatever you named it. be aware this script uses entity var 0 and 1 you can change if you have reserved these also rgb colours can be changed to customize and finally you can edit the value for timer to make damage drain slower or faster.



Code:
void main()
{
void self = getlocalvar("self");		//get calling entity
float x = getentityproperty(self, "x") - openborvariant("xpos") - 25;	//get caller x value minus 25
float z = getentityproperty(self, "z");		//get caller z value
float a = getentityproperty(self, "a");		//get caller a value
float y = z - a - openborvariant("ypos") - getentityproperty(self, "maxmp");	// get caller y position and move it up by entity max mp value
int maxhp = getentityproperty(self,"maxhealth");	// get caller max hp
int hp = getentityproperty(self,"health");		// get caller current hp
int health = hp / 0.01 / maxhp / 2;			// work out current hp percentage and half it
if(getentityvar(self,0)==NULL()){setentityvar(self,0, health);}	//set enity var to 0 if no value (null)


drawbox(x,y,health,5,z+2,rgbcolor(223,214,73),0);		//draw hp box using x and y cords also z value is +2 so its on top of other 2 boxes
drawbox(x,y,getentityvar(self,0),5,z+1,rgbcolor(181,26,0),0);	//second box to show damage with a z+1 value so its under hp bar and entity var 0 controls its size
drawbox(x,y,50,5,z,0,0);					//black box in background to show how much original life bar was


if(health<getentityvar(self,0))		// if hp box smaller then damage box
   {
if(getentityvar(self,1)==NULL()){setentityvar(self,1,0);}	//set entity var 1 to zero if null this is a timer
setentityvar(self,1,getentityvar(self,1)+1);			//add 1 to timer this will run every game tic		
 if(getentityvar(self,1) > 50)					//if timer over 50
    {
 setentityvar(self,0,getentityvar(self,0)-1);	//reduce displayed damage by 1
 setentityvar(self,1,0);			//reset timer to zero this will cause a loop untill damage is the same as hp
  }
 }
}

**Edit by DC**: Use Code tags for posting script and text files.
 
msmalik681, thanks for the post. Just make sure to use Code tags when you want to post script and text files. It will make it much easier on everyone, including you. :)

I've already edited your post so you can see how it works.

DC
 
Thanks for the share, MSMalik. This is what I had wanted to use for enemies. This is going to be very helpful/useful when I get to this.
 
Hey, msmalik. I want to know how I could make a living enemy's HP bar disappear after the player dies. I'd use death script only for players. Enemy's HP shown after player's dead. Could you do it? Attachments below.

[attachment deleted by admin]
 
O Ilusionista said:
if(hp==0)
{
killentity(self);
}

It's quite possible to go below 0 HP too. You should account for that.

Code:
if(hp <= 0)
{
     killentity(self);
}
 
if the above solution do not work try this:


Code:
void main()
{
void self = getlocalvar("self");		//get calling entity
float x = getentityproperty(self, "x") - 25;	//get caller x value minus 25
float z = getentityproperty(self, "z");		//get caller z value
int y = z - getentityproperty(self, "maxmp");	// get caller z position and move it up by max mp value
int maxhp = getentityproperty(self,"maxhealth");	// get caller max hp
int hp = getentityproperty(self,"health");		// get caller current hp
int health = hp / 0.01 / maxhp / 2;						// work out current hp percentage and half it
if(hp==maxhp || getentityvar(self,0)==NULL()){setentityvar(self,0, health);}	//set enity var to 0 if no value (null)


if(health >=1) //only run the below code if hp is 1 or above!
{
drawbox(x,y,health,5,z+2,rgbcolor(223,214,73),0);		//draw hp box using x and y cords also z value is +2 so its on top of other 2 boxes
drawbox(x,y,getentityvar(self,0),5,z+1,rgbcolor(181,26,0),0);	//second box to show damage with a z+1 value so its under hp bar and entity var 0 controls its size
drawbox(x,y,50,5,z,0,0);					//black box in background to show how much original life bar was


if(health<getentityvar(self,0))		// if hp box smaller then damage box
{
if(getentityvar(self,1)==NULL()){setentityvar(self,1,0);}	//set entity var 1 to zero if null this is a timer
setentityvar(self,1,getentityvar(self,1)+1);			//add 1 to timer this will run every game tic		
 if(getentityvar(self,1) > 50)					//if timer over 50
 {
 setentityvar(self,0,getentityvar(self,0)-1);	//reduce displayed damage by 1
 setentityvar(self,1,0);			//reset timer to zero this will cause a loop untill damage is the same as hp
   }
  }
 }
}


this is the exact same code wrapped in this if statement:



if(health >=1) //only run the below code if hp is 1 or above!
{
hp display code here
}


tested and the hp bar stops the second the entity dies. HTH
 
The enemy's hp bar displays while I have ondeathscript for Billy and Jimmy. Is it because it is used with ondrawscript? Here's what I like to see if player dies (during continue). Either player falls to holes or gets defeated to death by enemy, enemy's hp bar should disappear during continue until player continues the game and the hp bar will return to its state of its "parent" (enemy entity). The enemies are still walking around with their HP bar active.

death.c:

Code:
void main(){
	setglobalvar("elapsed_time", openborvariant("elapsed_time"));
	setglobalvar("crd", getplayerproperty(0, "credits"));
	setglobalvar("crd2", getplayerproperty(1, "credits"));
}

update.c:
Code:
void main(){
	PlayerLifeBar();
	continuey();
}

void PlayerLifeBar(){
	int P1 = getplayerproperty(0, "entity");
	int P2 = getplayerproperty(1, "entity");
	void LBar = getglobalvar("LBar");
	void Shadow = getglobalvar("Shadow");
	
	if(P1){ //Player 1
		drawsprite(LBar,42,12,100000);
		void P1Name = getentityproperty(P1, "name"); //Calling name
		if(P1Name == "Billy"){ //Calling Billy's name
			int LPB1 = getentityproperty(P1, "health"); //P1 Billy's health
			int TPB1 = getentityproperty(P1, "maxhealth"); //P1 Billy's fullest health
			int HPB1 = 100*LPB1/TPB1; //100 pixels of width if it's place in width times entity's health over entity's fullest health
			
			//Blue color shaded lifebars
			drawbox(85,17,HPB1,2,90000,rgbcolor(117,124,255),0); //Lightest blue shaded color
			drawbox(85,19,HPB1,1,90000,rgbcolor(99,106,248),0); //Second lightest blue
			drawbox(85,20,HPB1,1,90000,rgbcolor(79,86,226),0); //Third lightest blue
			drawbox(85,21,HPB1,1,90000,rgbcolor(61,67,198),0); //Third darkest blue
			drawbox(85,22,HPB1,1,90000,rgbcolor(52,57,170),0); //Second darkest blue
			drawbox(85,23,HPB1,2,90000,rgbcolor(36,40,122),0); //Darkest blue
		}
		else if(P1Name == "Jimmy"){ //Calling out Jimmy's name
			int LPJ1 = getentityproperty(P1, "health"); //P1 Jimmy's health
			int TPJ1 = getentityproperty(P1, "maxhealth"); //P1 Jimmy's fullest health
			int HPJ1 = 100*LPJ1/TPJ1;
			
			//Red colored lifebars
			drawbox(85,17,HPJ1,2,90000,rgbcolor(221,85,85),0); //Lightest red
			drawbox(85,19,HPJ1,1,90000,rgbcolor(210,59,59),0); //Second lightest red
			drawbox(85,20,HPJ1,1,90000,rgbcolor(192,38,38),0); //Third lightest red
			drawbox(85,21,HPJ1,1,90000,rgbcolor(171,31,31),0); //Third darkest red
			drawbox(85,22,HPJ1,1,90000,rgbcolor(151,24,24),0); //Second darkest red
			drawbox(85,23,HPJ1,2,90000,rgbcolor(123,19,19),0); //Darkest red
		}
		
		int SP1 = getentityproperty(P1, "mp"); //P1's MP
		int MM1 = getentityproperty(P1, "maxmp"); //Max MP
		int MP1 = 78*SP1/MM1;
		
		drawbox(85,35,MP1,1,90000,rgbcolor(229,229,109),0);
		drawbox(85,36,MP1,1,90000,rgbcolor(227,192,58),0);
		drawbox(85,37,MP1,1,90000,rgbcolor(229,135,55),0);
		
		if(getentityproperty(P1,"exists")){
		//Black shadow for Player 1's lifebar
		drawbox(85,17,100,8,300,rgbcolor(0,0,0),0);
		
		//Black shadow for Player 1's MP
		drawbox(85,35,78,3,300,rgbcolor(0,0,0),0);
		}
		
	}
	if(P2){
		drawsprite(LBar,290,12,100000);
		void P2Name = getentityproperty(P2, "name");
		if(P2Name == "Billy"){
			int LPB2 = getentityproperty(P2, "health");
			int TPB2 = getentityproperty(P2, "maxhealth");
			int HPB2 = 100*LPB2/TPB2;
			
			drawbox(333,17,HPB2,2,90000,rgbcolor(117,124,255),0);
			drawbox(333,19,HPB2,1,90000,rgbcolor(99,106,248),0);
			drawbox(333,20,HPB2,1,90000,rgbcolor(79,86,226),0);
			drawbox(333,21,HPB2,1,90000,rgbcolor(61,67,198),0);
			drawbox(333,22,HPB2,1,90000,rgbcolor(52,57,170),0);
			drawbox(333,23,HPB2,2,90000,rgbcolor(36,40,122),0);
		}
		if(P2Name == "Jimmy"){
			int LPJ2 = getentityproperty(P2, "health");
			int TPJ2 = getentityproperty(P2, "maxhealth");
			int HPJ2 = 100*LPJ2/TPJ2;
		
			drawbox(333,17,HPJ2,2,90000,rgbcolor(221,85,85),0);
			drawbox(333,19,HPJ2,1,90000,rgbcolor(210,59,59),0);
			drawbox(333,20,HPJ2,1,90000,rgbcolor(192,38,38),0);
			drawbox(333,21,HPJ2,1,90000,rgbcolor(171,31,31),0);
			drawbox(333,22,HPJ2,1,90000,rgbcolor(151,24,24),0);
			drawbox(333,23,HPJ2,2,90000,rgbcolor(123,19,19),0);
		}
		
		int SP2 = getentityproperty(P2, "mp");
		int MM2 = getentityproperty(P2, "maxmp"); //Max MP
		int MP2 = 78*SP2/MM2;
		
		drawbox(333,35,MP2,1,90000,rgbcolor(229,229,109),0);
		drawbox(333,36,MP2,1,90000,rgbcolor(227,192,58),0);
		drawbox(333,37,MP2,1,90000,rgbcolor(229,135,55),0);
		
		if(getentityproperty(P2,"exists")){
		drawbox(333,17,100,8,300,rgbcolor(0,0,0),0); //Black shadow for player 2 lifebar
		drawbox(333,35,78,3,300,rgbcolor(0,0,0),0); //Black shadow for player 2 MP bar
		}
	}

}

void oncreate()
{
    void LBar;
	void Shadow;

	LBar = loadsprite("data/sprites/dragonhud.png");
	setglobalvar("LBar", LBar);
	Shadow = loadsprite("data/sprites/shadowshortcut.png");
	setglobalvar("Shadow", Shadow);
}

void ondestroy(){
	void LBar = getglobalvar("LBar");
	void Shadow = getglobalvar("Shadow");
	
	free(LBar);
	setglobalvar("LBar", NULL());
	
	free(Shadow);
	setglobalvar("Shadow", NULL());
}

/*
void UndisplayEnemyLifeBar(){
	void vSelf = getplayerproperty(0, "entity");
	void vSelf2 = getplayerproperty(1, "entity");
	void Exist1 = getentityproperty(vSelf, "exists");
	void Exist2 = getentityproperty(vSelf2, "exists");
	int  iMax       = openborvariant("ent_max");
	if (vSelf == NULL() && vSelf2 == NULL()){
		if (getglobalvar("crd") >= 1 || getglobalvar("crd2") >= 1){
			for(){
			}
		}
	}
}
*/


void continuey(){
	void vSelf = getplayerproperty(0, "entity");
	void vSelf2 = getplayerproperty(1, "entity");
	int time = openborvariant("elapsed_time");//Calling time
    int  iMax       = openborvariant("ent_max");            //Entity count.
    int  iEntity;                                           //Loop counter.
    void vEntity;                                           //Target entity.

	if (vSelf == NULL() && vSelf2 == NULL()){
		if (getglobalvar("crd") >= 1 || getglobalvar("crd2") >= 1){
			drawstring(125, 100, 4, "continue");
		if (time >= getglobalvar("elapsed_time") + 600 && time <= getglobalvar("elapsed_time") + 999){
			drawstring(155, 120, 3, "9");
		}if (time >= getglobalvar("elapsed_time") + 1000 && time <= getglobalvar("elapsed_time") + 1399){
			drawstring(155, 120, 3, "8");
		}if (time >= getglobalvar("elapsed_time") + 1400 && time <= getglobalvar("elapsed_time") + 1799){
			drawstring(155, 120, 3, "7");
		}if (time >= getglobalvar("elapsed_time") + 1800 && time <= getglobalvar("elapsed_time") + 2099){
			drawstring(155, 120, 3, "6");
		}if (time >= getglobalvar("elapsed_time") + 2100 && time <= getglobalvar("elapsed_time") + 2399){
			drawstring(155, 120, 3, "5");
		}if (time >= getglobalvar("elapsed_time") + 2400 && time <= getglobalvar("elapsed_time") + 2699){
			drawstring(155, 120, 3, "4");
		}if (time >= getglobalvar("elapsed_time") + 2700 && time <= getglobalvar("elapsed_time") + 2999){
			drawstring(155, 120, 4, "3");
		}if (time >= getglobalvar("elapsed_time") + 3000 && time <= getglobalvar("elapsed_time") + 3299){
			drawstring(155, 120, 4, "2");
		}if (time >= getglobalvar("elapsed_time") + 3300 && time <= getglobalvar("elapsed_time") + 3599){
			drawstring(155, 120, 4, "1");
		}if (time >= getglobalvar("elapsed_time") + 3600){
			drawstring(155, 120, 4, "0");
		}if (time >= getglobalvar("elapsed_time") + 4200){
			jumptobranch("end", 1);
		}
	}
	}
}
 
so again added a if statement but this time to check is both player 1 and 2 do not exist if so nothing will happen then pushed the entire HP BAR code into the else clause.

Code:
void main()
{
if(getplayerproperty(0, "entity") == NULL() && getplayerproperty(1, "entity") == NULL())
{
//dont do anything if no players exist
}
else //if at least 1 player exists run normal script
 {


void self = getlocalvar("self");		//get calling entity
float x = getentityproperty(self, "x") - 25;	//get caller x value minus 25
float z = getentityproperty(self, "z");		//get caller z value
int y = z - getentityproperty(self, "maxmp");	// get caller z position and move it up by max mp value
int maxhp = getentityproperty(self,"maxhealth");	// get caller max hp
int hp = getentityproperty(self,"health");		// get caller current hp
int health = hp / 0.01 / maxhp / 2;						// work out current hp percentage and half it
if(hp==maxhp || getentityvar(self,0)==NULL()){setentityvar(self,0, health);}	//set enity var to 0 if no value (null)


if(health >=1) //only run the below code if hp is above 1
  {
drawbox(x,y,health,5,z+2,rgbcolor(223,214,73),0);		//draw hp box using x and y cords also z value is +2 so its on top of other 2 boxes
drawbox(x,y,getentityvar(self,0),5,z+1,rgbcolor(181,26,0),0);	//second box to show damage with a z+1 value so its under hp bar and entity var 0 controls its size
drawbox(x,y,50,5,z,0,0);					//black box in background to show how much original life bar was


if(health<getentityvar(self,0))		// if hp box smaller then damage box
   {
if(getentityvar(self,1)==NULL()){setentityvar(self,1,0);}	//set entity var 1 to zero if null this is a timer
setentityvar(self,1,getentityvar(self,1)+1);			//add 1 to timer this will run every game tic		
 if(getentityvar(self,1) > 50)					//if timer over 50
    {
 setentityvar(self,0,getentityvar(self,0)-1);	//reduce displayed damage by 1
 setentityvar(self,1,0);			//reset timer to zero this will cause a loop untill damage is the same as hp
    }
   }
  }
 }
}


did the last update fix your pit fall bug ?

"void UndisplayEnemyLifeBar()" can be removed from your update.c
 
Perfect! Yep. It got fixed. This is what I wanted. Thank you very much, msmalik. Problem solved for me.

I noticed only one error before I posted this. That's the one with 2 0 indexes for player 1's. But it's okay, I corrected it by replacing one of them with 1, "entity" for player 2, so both players can die.
 
just noticed a bug with my own script when i spawned a text entity the hp bars were flying all over the stage fixed this by using a part of orochi x's trailer code making use of xpos and ypos I dont fully understand the logic behind it but it works.


Code:
void main()
{
void self = getlocalvar("self");		//get calling entity
float x = getentityproperty(self, "x") - openborvariant("xpos") - 25;	//get caller x value minus 25
float z = getentityproperty(self, "z");		//get caller z value
float a = getentityproperty(self, "a");		//get caller a value
float y = z - a - openborvariant("ypos") - getentityproperty(self, "maxmp");	// get caller y position and move it up by entity max mp value
int maxhp = getentityproperty(self,"maxhealth");	// get caller max hp
int hp = getentityproperty(self,"health");		// get caller current hp
int health = hp / 0.01 / maxhp / 2;			// work out current hp percentage and half it
if(getentityvar(self,0)==NULL()){setentityvar(self,0, health);}	//set enity var to 0 if no value (null)


drawbox(x,y,health,5,z+2,rgbcolor(223,214,73),0);		//draw hp box using x and y cords also z value is +2 so its on top of other 2 boxes
drawbox(x,y,getentityvar(self,0),5,z+1,rgbcolor(181,26,0),0);	//second box to show damage with a z+1 value so its under hp bar and entity var 0 controls its size
drawbox(x,y,50,5,z,0,0);					//black box in background to show how much original life bar was


if(health<getentityvar(self,0))		// if hp box smaller then damage box
   {
if(getentityvar(self,1)==NULL()){setentityvar(self,1,0);}	//set entity var 1 to zero if null this is a timer
setentityvar(self,1,getentityvar(self,1)+1);			//add 1 to timer this will run every game tic		
 if(getentityvar(self,1) > 50)					//if timer over 50
    {
 setentityvar(self,0,getentityvar(self,0)-1);	//reduce displayed damage by 1
 setentityvar(self,1,0);			//reset timer to zero this will cause a loop untill damage is the same as hp
  }
 }
}


the above code does not have the filters requested by maxman as i dont use them in my mod.
 
Here is another mod to my hp bar script also requested by maxman this time the hp bars deplete from the front of entity to their back regardless of which way they face.


Code:
void main()
{
void self = getlocalvar("self");		//get calling entity
float x = getentityproperty(self, "x") - openborvariant("xpos") - 25;	//get caller x value minus 25
float z = getentityproperty(self, "z");		//get caller z value
float a = getentityproperty(self, "a");		//get caller a value
float y = z - a - openborvariant("ypos") - getentityproperty(self, "maxmp");	// get caller y position and move it up by entity max mp value
int maxhp = getentityproperty(self,"maxhealth");	// get caller max hp
int hp = getentityproperty(self,"health");		// get caller current hp
int health = hp / 0.01 / maxhp / 2;			// work out current hp percentage and half it
if(getentityvar(self,0)==NULL()){setentityvar(self,0, health);}	//set enity var to 0 if no value (null)


if(getentityproperty(self, "direction") == 1)
{
drawbox(x,y,health,5,z+2,rgbcolor(223,214,73),0);		//draw hp box using x and y cords also z value is +2 so its on top of other 2 boxes
drawbox(x,y,getentityvar(self,0),5,z+1,rgbcolor(181,26,0),0);	//second box to show damage with a z+1 value so its under hp bar and entity var 0 controls its size
drawbox(x,y,50,5,z,0,0);					//black box in background to show how much original life bar was
}
else
{
drawbox(x+(50-health),y,health,5,z+2,rgbcolor(223,214,73),0);		//draw hp box using x and y cords also z value is +2 so its on top of other 2 boxes
drawbox(x+(49.50-getentityvar(self,0)),y,getentityvar(self,0),5,z+1,rgbcolor(181,26,0),0);	//second box to show damage with a z+1 value so its under hp bar and entity var 0 controls its size
drawbox(x,y,49,5,z,0,0);									//black box in background to show how much original life bar was
}					


if(health<getentityvar(self,0))		// if hp box smaller then damage box
   {
if(getentityvar(self,1)==NULL()){setentityvar(self,1,0);}	//set entity var 1 to zero if null this is a timer
setentityvar(self,1,getentityvar(self,1)+1);			//add 1 to timer this will run every game tic		
 if(getentityvar(self,1) > 50)					//if timer over 50
    {
 setentityvar(self,0,getentityvar(self,0)-1);	//reduce displayed damage by 1
 setentityvar(self,1,0);			//reset timer to zero this will cause a loop untill damage is the same as hp
  }
 }
}
 
That's better than nothing, man. That script gives me ideas what to edit for enemies. I will try my best to edit to see how it works to suit my taste. Thank you so much for your time.

I believe double custom lifebar would be possible to create thanks to your contribution.

EDIT: Got a very great news of what I succeeded so far. I succeeded in fixing position of direction for enemy's lifebar depending on which player the enemy's hostile to just like Sengoku 3, Final Fight 2 and 3.

I share this on what I got so far though I will edit this for mine later:

Code:
void main()
{
void self = getlocalvar("self");		//get calling entity
//float x = getentityproperty(self, "x") - openborvariant("xpos") - 25;	//get caller x value minus 25
float z = getentityproperty(self, "z");		//get caller z value
//float a = getentityproperty(self, "a");		//get caller a value
//float y = z - a - openborvariant("ypos") - getentityproperty(self, "maxmp");	// get caller y position and move it up by entity max mp value
int maxhp = getentityproperty(self,"maxhealth");	// get caller max hp
int hp = getentityproperty(self,"health");		// get caller current hp
int health = hp / 0.01 / maxhp / 2;			// work out current hp percentage and half it
if(getentityvar(self,0)==NULL()){setentityvar(self,0, health);}	//set enity var to 0 if no value (null)


if(findtarget(getplayerproperty(0, "entity"))) //Hostile to player 1
{
drawbox(39,40,health,5,z+2,rgbcolor(223,214,73),0);		//draw hp box using x and y cords also z value is +2 so its on top of other 2 boxes
drawbox(39,40,getentityvar(self,0),5,z+1,rgbcolor(181,26,0),0);	//second box to show damage with a z+1 value so its under hp bar and entity var 0 controls its size
drawbox(39,40,50,5,z,0,0);					//black box in background to show how much original life bar was
}
else if(findtarget(getplayerproperty(1, "entity"))) //Hostile to player 2
{
drawbox(229+(50-health),40,health,5,z+2,rgbcolor(223,214,73),0);		//draw hp box using x and y cords also z value is +2 so its on top of other 2 boxes
drawbox(229+(49.50-getentityvar(self,0)),40,getentityvar(self,0),5,z+1,rgbcolor(181,26,0),0);	//second box to show damage with a z+1 value so its under hp bar and entity var 0 controls its size
drawbox(229,40,49,5,z,0,0);									//black box in background to show how much original life bar was
}					


if(health<getentityvar(self,0))		// if hp box smaller then damage box
   {
if(getentityvar(self,1)==NULL()){setentityvar(self,1,0);}	//set entity var 1 to zero if null this is a timer
setentityvar(self,1,getentityvar(self,1)+1);			//add 1 to timer this will run every game tic		
 if(getentityvar(self,1) > 50)					//if timer over 50
    {
 setentityvar(self,0,getentityvar(self,0)-1);	//reduce displayed damage by 1
 setentityvar(self,1,0);			//reset timer to zero this will cause a loop untill damage is the same as hp
  }
 }
}

EDIT2: I thought it was helpful but this is not exactly like Sengoku 3 where player 1 attacks enemy with its lifebar display on P1's side and the other. Player 2 attacks enemy after Player 1 attacks, but enemy's lifebar remains on player 1's side. I need to fix it.
 
Back
Top Bottom