Copy to Clipboard Test

Final Fight Health Bar Code

//From the sand the moldorm rises.
//Fear his enlightened form.

//Optional setting. If 1, higher level bars will be solid colors.
const int FINALFIGHT_BAR_SOLIDBARS = 0;

//X and Y position of the bar on the screen. Names appear above and portrait to the left
const int FINALFIGHT_BAR_X = 32;
const int FINALFIGHT_BAR_Y = 16;
//Width and height of the bar. A border is drawn around it.
const int FINALFIGHT_BAR_WIDTH = 80;
const int FINALFIGHT_BAR_HEIGHT = 6;

//Colors of the outline and background
const int C_FINALFIGHT_BAR_OUTLINE = 0x01;
const int C_FINALFIGHT_BAR_BG = 0x81;

//Colors of the name and name's shadow
const int C_FINALFIGHT_BAR_NAME = 0x04;
const int C_FINALFIGHT_BAR_NAME_BG = 0x03;

//Max HP and colors for each of the health bars.
const int MAXHP_FINALFIGHT_BAR1 = 16;
const int C_FINALFIGHT_BAR1 = 0x12;

const int MAXHP_FINALFIGHT_BAR2 = 32;
const int C_FINALFIGHT_BAR2 = 0x75;

const int MAXHP_FINALFIGHT_BAR3 = 64;
const int C_FINALFIGHT_BAR3 = 0x72;

const int MAXHP_FINALFIGHT_BAR4 = 96;
const int C_FINALFIGHT_BAR4 = 0xC6;

const int MAXHP_FINALFIGHT_BAR5 = 128;
const int C_FINALFIGHT_BAR5 = 0x77;

const int MAXHP_FINALFIGHT_BAR6 = 160;
const int C_FINALFIGHT_BAR6 = 0xA8; 

const int MAXHP_FINALFIGHT_BAR7 = 196;
const int C_FINALFIGHT_BAR7 = 0x01;

const int NPCM_FINALFIGHTHEALTHBAR = 11; //npc->Misc used for healthbars

//D0: The ID of the enemy to check for
//D1: A ZQuest string with the boss's name. 0 for none.
//D2: A tile for the boss's portrait. 0 for none.
//D3: The CSet to use for the portrait. 14 is the boss CSet.
//D4: Set to 1 to make HP ranges on bars dynamic, based on the boss's initial HP.
//D5: Set to the number of bars to use for dynamic health bars
//D6: Special exception cases for calculating group enemy HP
//		1: Summoner. Enemies spawned after the first HP check will be excluded.
ffc script FinalFightHealthBar{
	void run(int enemyID, int nameSTR, int portraitTIL, int portraitCS, int dynamicBars, int dynamicBarsCount, int specialCases){
		int ranges[] = {0, MAXHP_FINALFIGHT_BAR1, MAXHP_FINALFIGHT_BAR2, MAXHP_FINALFIGHT_BAR3, MAXHP_FINALFIGHT_BAR4, MAXHP_FINALFIGHT_BAR5, MAXHP_FINALFIGHT_BAR6, MAXHP_FINALFIGHT_BAR7};
		dynamicBarsCount = Clamp(dynamicBarsCount, 1, 7);
		
		Waitframes(4);
		int initHP;
		npc boss;
		if(enemyID>0){
			boss = LoadNPCOf(enemyID);
			if(!boss->isValid())
				Quit();
			initHP = boss->HP;
		}
		else{
			initHP = FFHB_ScreenHPTotal(specialCases, true);
		}
		if(dynamicBars)
			FFHB_SetBarRanges(ranges, initHP, dynamicBarsCount);
		
		int str_name[145] = "";
		if(nameSTR){
			Game->GetMessage(nameSTR, str_name);
		}
		
		int hp;
		int healthbarRemainFrames = 16;
		while(healthbarRemainFrames>0){
			if(enemyID==0){
				hp = FFHB_ScreenHPTotal(specialCases, false);
			}
			else{
				if(boss->isValid())
					hp = boss->HP;
				else
					hp = 0;
			}
			FFHB_Draw(ranges, FINALFIGHT_BAR_X, FINALFIGHT_BAR_Y, str_name, portraitTIL, portraitCS, hp);
			if(hp<=0)
				--healthbarRemainFrames;
			Waitframe();
		}
	}
	void FFHB_SetBarRanges(int ranges, int initHP, int numBars){
		int hpPerBar = initHP/numBars;
		for(int i=1; i<=7; ++i){
			ranges[i] = Round(hpPerBar*i);
			if(i==numBars)
				ranges[i] = initHP;
		}
	}
	void FFHB_Draw(int ranges, int x, int y, int str_name, int portraitTIL, int portraitCS, int hp){
		int c_bg = C_FINALFIGHT_BAR_BG;
		int c_fg = C_FINALFIGHT_BAR1;
		
		int barW;
		if(hp>=ranges[0]&&hp<ranges[1]){
			barW = Clamp(hp/(ranges[1]-ranges[0])*FINALFIGHT_BAR_WIDTH, 0, FINALFIGHT_BAR_WIDTH);
		}
		else if(hp>=ranges[1]&&hp<ranges[2]){
			barW = Clamp((hp-ranges[1])/(ranges[2]-ranges[1])*FINALFIGHT_BAR_WIDTH, 0, FINALFIGHT_BAR_WIDTH);
			c_bg = C_FINALFIGHT_BAR1;
			c_fg = C_FINALFIGHT_BAR2;
			if(FINALFIGHT_BAR_SOLIDBARS)
				barW = FINALFIGHT_BAR_WIDTH;
		}
		else if(hp>=ranges[2]&&hp<ranges[3]){
			barW = Clamp((hp-ranges[2])/(ranges[3]-ranges[2])*FINALFIGHT_BAR_WIDTH, 0, FINALFIGHT_BAR_WIDTH);
			c_bg = C_FINALFIGHT_BAR2;
			c_fg = C_FINALFIGHT_BAR3;
			if(FINALFIGHT_BAR_SOLIDBARS)
				barW = FINALFIGHT_BAR_WIDTH;
		}
		else if(hp>=ranges[3]&&hp<ranges[4]){
			barW = Clamp((hp-ranges[3])/(ranges[4]-ranges[3])*FINALFIGHT_BAR_WIDTH, 0, FINALFIGHT_BAR_WIDTH);
			c_bg = C_FINALFIGHT_BAR3;
			c_fg = C_FINALFIGHT_BAR4;
			if(FINALFIGHT_BAR_SOLIDBARS)
				barW = FINALFIGHT_BAR_WIDTH;
		}
		else if(hp>=ranges[4]&&hp<ranges[5]){
			barW = Clamp((hp-ranges[4])/(ranges[5]-ranges[4])*FINALFIGHT_BAR_WIDTH, 0, FINALFIGHT_BAR_WIDTH);
			c_bg = C_FINALFIGHT_BAR4;
			c_fg = C_FINALFIGHT_BAR5;
			if(FINALFIGHT_BAR_SOLIDBARS)
				barW = FINALFIGHT_BAR_WIDTH;
		}
		else if(hp>=ranges[5]&&hp<ranges[6]){
			barW = Clamp((hp-ranges[5])/(ranges[6]-ranges[5])*FINALFIGHT_BAR_WIDTH, 0, FINALFIGHT_BAR_WIDTH);
			c_bg = C_FINALFIGHT_BAR5;
			c_fg = C_FINALFIGHT_BAR6;
			if(FINALFIGHT_BAR_SOLIDBARS)
				barW = FINALFIGHT_BAR_WIDTH;
		}
		else if(hp>=ranges[6]){
			barW = Clamp((hp-ranges[6])/(ranges[7]-ranges[6])*FINALFIGHT_BAR_WIDTH, 0, FINALFIGHT_BAR_WIDTH);
			c_bg = C_FINALFIGHT_BAR6;
			c_fg = C_FINALFIGHT_BAR7;
			if(FINALFIGHT_BAR_SOLIDBARS)
				barW = FINALFIGHT_BAR_WIDTH;
		}
		
		//Draw the outline
		Screen->Rectangle(6, x-1, y, x+FINALFIGHT_BAR_WIDTH, y+FINALFIGHT_BAR_HEIGHT-1, C_FINALFIGHT_BAR_OUTLINE, 1, 0, 0, 0, true, 128);
		Screen->Rectangle(6, x, y-1, x+FINALFIGHT_BAR_WIDTH-1, y+FINALFIGHT_BAR_HEIGHT, C_FINALFIGHT_BAR_OUTLINE, 1, 0, 0, 0, true, 128);
		
		//Draw the bar itself
		Screen->Rectangle(6, x, y, x+FINALFIGHT_BAR_WIDTH-1, y+FINALFIGHT_BAR_HEIGHT-1, c_bg, 1, 0, 0, 0, true, 128);
		if(barW>0)
			Screen->Rectangle(6, x, y, x+barW-1, y+FINALFIGHT_BAR_HEIGHT-1, c_fg, 1, 0, 0, 0, true, 128);
	
		//Draw the name
		FFHB_DrawStringShadowed(6, x+8, y-10, FONT_Z1, C_FINALFIGHT_BAR_NAME, C_FINALFIGHT_BAR_NAME_BG, TF_NORMAL, str_name, 128);
		
		//Draw the portrait
		if(portraitTIL){
			Screen->FastTile(6, x-16, y-(16-FINALFIGHT_BAR_HEIGHT-1), portraitTIL, portraitCS, 128);
		}
	}
	void FFHB_DrawStringShadowed(int layer, int x, int y, int font, int c1, int c2, int format, int ptr, int op){
		Screen->DrawString(layer, x+1, y, font, c2, -1, format, ptr, op);
		Screen->DrawString(layer, x, y+1, font, c2, -1, format, ptr, op);
		Screen->DrawString(layer, x+1, y+1, font, c2, -1, format, ptr, op);
		
		Screen->DrawString(layer, x, y, font, c1, -1, format, ptr, op);
	}
	int FFHB_ScreenHPTotal(int exceptionType, bool firstCheck){
		int total;
		for(int i=Screen->NumNPCs(); i>0; --i){
			npc n = Screen->LoadNPC(i);
			if(n->Type==NPCT_GUY)
				continue;
			if(n->Type==NPCT_TRAP)
				continue;
			if(n->Type==NPCT_PROJECTILE)
				continue;
			if(n->Type==NPCT_FAIRY)
				continue;
			if((n->MiscFlags&NPCMF_NOT_BEATABLE)!=0)
				continue;
			if(n->HP>=900)
				continue;
			if(exceptionType==1){
				if(firstCheck)
					n->Misc[NPCM_FINALFIGHTHEALTHBAR] = 1;
				else if(!n->Misc[NPCM_FINALFIGHTHEALTHBAR])
					continue;
			}
			if(n->Type==NPCT_MANHANDLA){
				if(n->ID>7)
					continue;
			}
			total += n->HP;
		}
		return total;
	}
}