Ejemplo n.º 1
0
int ship_weapon_check_collision(object *ship_objp, object *weapon_objp, float time_limit = 0.0f, int *next_hit = NULL)
{
	mc_info mc, mc_shield, mc_hull;
	ship	*shipp;
	ship_info *sip;
	weapon	*wp;
	weapon_info	*wip;

	Assert( ship_objp != NULL );
	Assert( ship_objp->type == OBJ_SHIP );
	Assert( ship_objp->instance >= 0 );

	shipp = &Ships[ship_objp->instance];
	sip = &Ship_info[shipp->ship_info_index];

	Assert( weapon_objp != NULL );
	Assert( weapon_objp->type == OBJ_WEAPON );
	Assert( weapon_objp->instance >= 0 );

	wp = &Weapons[weapon_objp->instance];
	wip = &Weapon_info[wp->weapon_info_index];


	Assert( shipp->objnum == OBJ_INDEX(ship_objp));

	// Make ships that are warping in not get collision detection done
	if ( shipp->flags & SF_ARRIVING ) return 0;

	// if one object is a capital, only check player and player weapons with
	// the capital -- too slow for now otherwise.
//	if ( Polygon_models[Ships[num].modelnum].use_grid && !( (other_objp == Player_obj) || (&Objects[other_objp->parent] == Player_obj)) )
//		return 0;

	//	If either of these objects doesn't get collision checks, abort.
	if (Ship_info[shipp->ship_info_index].flags & SIF_NO_COLLIDE)
		return 0;

	//	Return information for AI to detect incoming fire.
	//	Could perhaps be done elsewhere at lower cost --MK, 11/7/97
	float	dist = vm_vec_dist_quick(&ship_objp->pos, &weapon_objp->pos);
	if (dist < weapon_objp->phys_info.speed) {
		update_danger_weapon(ship_objp, weapon_objp);
	}
	
	ship_model_start(ship_objp);

	int	valid_hit_occurred = 0;				// If this is set, then hitpos is set
	int	quadrant_num = -1;
	polymodel *pm = model_get(sip->model_num);

	//	total time is flFrametime + time_limit (time_limit used to predict collisions into the future)
	vec3d weapon_end_pos;
	vm_vec_scale_add( &weapon_end_pos, &weapon_objp->pos, &weapon_objp->phys_info.vel, time_limit );


	// Goober5000 - I tried to make collision code here much saner... here begin the (major) changes

	// set up collision structs
	mc.model_num = sip->model_num;
	mc.submodel_num = -1;
	mc.orient = &ship_objp->orient;
	mc.pos = &ship_objp->pos;
	mc.p0 = &weapon_objp->last_pos;
	mc.p1 = &weapon_end_pos;
	memcpy(&mc_shield, &mc, sizeof(mc_info));
	memcpy(&mc_hull, &mc, sizeof(mc_info));

	// (btw, these are leftover comments from below...)
	//
	//	Note: This code is obviously stupid. We want to add the shield point if there is shield to hit, but:
	//		1. We want the size/color of the hit effect to indicate shield damage done.  (i.e., for already-weak shield, smaller effect)
	//		2. Currently (8/9/97), apply_damage_to_shield() passes lefer damage to hull, which might not make sense.  If
	//			wouldn't have collided with hull, shouldn't do damage.  Once this is fixed, the code below needs to cast the
	//			vector through to the hull if there is leftover damage.
	//
	// WIF2_PIERCE_SHIELDS pierces shields
	// AL 1-14-97: "Puncture" doesn't mean penetrate shield anymore, it means that it punctures
	//					hull to inflict maximum subsystem damage
	//
	// _argv[-1], 16 Jan 2005: Surface shields.
	// Surface shields allow for shields on a ship without a shield mesh.  Good for putting real shields
	// on the Lucifer.  This also fixes the strange bug where shots will occasionally go through the
	// shield mesh when they shouldn't.  I don't know what causes this, but this fixes that -- shields
	// will absorb it when it hits the hull instead.  This has no fancy graphical effect, though.
	// Someone should make one.

	// set flags
	mc_shield.flags = MC_CHECK_SHIELD;
	mc_hull.flags = MC_CHECK_MODEL;

	// check both kinds of collisions
	int shield_collision = (pm->shield.ntris > 0) ? model_collide(&mc_shield) : 0;
	int hull_collision = model_collide(&mc_hull);

	// check shields for impact
	if (!(ship_objp->flags & OF_NO_SHIELDS))
	{
		// pick out the shield quadrant
		if (shield_collision)
			quadrant_num = get_quadrant(&mc_shield.hit_point);
		else if (hull_collision && (sip->flags2 & SIF2_SURFACE_SHIELDS))
			quadrant_num = get_quadrant(&mc_hull.hit_point);

		// make sure that the shield is active in that quadrant
		if ((quadrant_num >= 0) && ((shipp->flags & SF_DYING) || !ship_is_shield_up(ship_objp, quadrant_num)))
			quadrant_num = -1;

		// see if we hit the shield
		if (quadrant_num >= 0)
		{
			// do the hit effect
			if (shield_collision)
				add_shield_point(OBJ_INDEX(ship_objp), mc_shield.shield_hit_tri, &mc_shield.hit_point);
			else
				/* TODO */;

			// if this weapon pierces the shield, then do the hit effect, but act like a shield collision never occurred;
			// otherwise, we have a valid hit on this shield
			if (wip->wi_flags2 & WIF2_PIERCE_SHIELDS)
				quadrant_num = -1;
			else
				valid_hit_occurred = 1;
		}
	}

	// see which impact we use
	if (shield_collision && valid_hit_occurred)
	{
		memcpy(&mc, &mc_shield, sizeof(mc_info));
		Assert(quadrant_num >= 0);
	}
	else if (hull_collision)
	{
		memcpy(&mc, &mc_hull, sizeof(mc_info));
		valid_hit_occurred = 1;
	}


	//nprintf(("AI", "Frame %i, Hit tri = %i\n", Framecount, mc.shield_hit_tri));
	ship_model_stop(ship_objp);

	// deal with predictive collisions.  Find their actual hit time and see if they occured in current frame
	if (next_hit && valid_hit_occurred) {
		// find hit time
		*next_hit = (int) (1000.0f * (mc.hit_dist*(flFrametime + time_limit) - flFrametime) );
		if (*next_hit > 0)
			// if hit occurs outside of this frame, do not do damage 
			return 1;
	}

	if ( valid_hit_occurred )
	{
		Script_system.SetHookObjects(4, "Ship", ship_objp, "Weapon", weapon_objp, "Self",ship_objp, "Object", weapon_objp);
		bool ship_override = Script_system.IsConditionOverride(CHA_COLLIDEWEAPON, ship_objp);

		Script_system.SetHookObjects(2, "Self",weapon_objp, "Object", ship_objp);
		bool weapon_override = Script_system.IsConditionOverride(CHA_COLLIDESHIP, weapon_objp);

		if(!ship_override && !weapon_override) {
			ship_weapon_do_hit_stuff(ship_objp, weapon_objp, &mc.hit_point_world, &mc.hit_point, quadrant_num, mc.hit_submodel, mc.hit_normal);
		}

		Script_system.SetHookObjects(2, "Self",ship_objp, "Object", weapon_objp);
		if(!(weapon_override && !ship_override))
			Script_system.RunCondition(CHA_COLLIDEWEAPON, '\0', NULL, ship_objp);

		Script_system.SetHookObjects(2, "Self",weapon_objp, "Object", ship_objp);
		if((weapon_override && !ship_override) || (!weapon_override && !ship_override))
			Script_system.RunCondition(CHA_COLLIDESHIP, '\0', NULL, weapon_objp);

		Script_system.RemHookVars(4, "Ship", "Weapon", "Self","Object");
		/*
		if(!Script_system.IsOverride(wip->sc_collide_ship)) {
			ship_weapon_do_hit_stuff(ship_objp, weapon_objp, &mc.hit_point_world, &mc.hit_point, quadrant_num, mc.hit_submodel, mc.hit_normal);
		}

		if(wip->sc_collide_ship.IsValid()) {
			ade_odata lua_self_obj = l_Weapon.Set(object_h(weapon_objp));
			ade_odata lua_ship_obj = l_Ship.Set(object_h(ship_objp));
			
			Script_system.SetHookVar("Self", 'o', &lua_self_obj);
			Script_system.SetHookVar("Ship", 'o', &lua_ship_obj);

			Script_system.RunBytecode(wip->sc_collide_ship);

			Script_system.RemHookVar("Self");
			Script_system.RemHookVar("Ship");
		}*/
	}
	else if ((Missiontime - wp->creation_time > F1_0/2) && (wip->wi_flags & WIF_HOMING) && (wp->homing_object == ship_objp)) {
		if (dist < wip->shockwave.inner_rad) {
			vec3d	vec_to_ship;

			vm_vec_normalized_dir(&vec_to_ship, &ship_objp->pos, &weapon_objp->pos);

			if (vm_vec_dot(&vec_to_ship, &weapon_objp->orient.vec.fvec) < 0.0f) {
				// check if we're colliding against "invisible" ship
				if (!(shipp->flags2 & SF2_DONT_COLLIDE_INVIS)) {
					wp->lifeleft = 0.001f;
					if (ship_objp == Player_obj)
						nprintf(("Jim", "Frame %i: Weapon %i set to detonate, dist = %7.3f.\n", Framecount, OBJ_INDEX(weapon_objp), dist));
					valid_hit_occurred = 1;
				}
			}

		}
	}

	return valid_hit_occurred;
}
Ejemplo n.º 2
0
void hud_shield_show(object* objp)
{

	KeepAspectRatio keep(true);

	//	static int fod_model = -1;
	float max_shield;
	int hud_color_index, range;
	int sx, sy, i;
	ship* sp;
	ship_info* sip;
	hud_frames* sgp = NULL;

	if (objp->type != OBJ_SHIP)
		return;

	// Goober5000 - don't show if primitive sensors
	if (Ships[Player_obj->instance].flags2 & SF2_PRIMITIVE_SENSORS)
		return;

	sp = &Ships[objp->instance];
	sip = &Ship_info[sp->ship_info_index];

	//	bool digitus_improbus = (fod_model != -2 && strstr(sp->ship_name, "Sathanas") != NULL);
	if (sip->shield_icon_index == 255 && !(sip->flags2 & SIF2_GENERATE_HUD_ICON)/*&& !digitus_improbus*/)
	{
		return;
	}

	if (objp == Player_obj)
	{
		hud_set_gauge_color(HUD_PLAYER_SHIELD_ICON);
	}
	else
	{
		hud_set_gauge_color(HUD_TARGET_SHIELD_ICON);
	}

	// load in shield frames if not already loaded
	if (sip->shield_icon_index != 255)
	{
		sgp = &Shield_gauges[sip->shield_icon_index];

		if (sgp->first_frame == -1 && sip->shield_icon_index < Hud_shield_filename_count)
		{
			sgp->first_frame = bm_load_animation(Hud_shield_filenames[sip->shield_icon_index], &sgp->num_frames);
			if (sgp->first_frame == -1)
			{
				if (!shield_ani_warning_displayed_already)
				{
					shield_ani_warning_displayed_already = true;
					Warning(LOCATION, "Could not load in the HUD shield ani: %s\n",
						Hud_shield_filenames[sip->shield_icon_index]);
				}
				return;
			}
		}
	}

	if (objp == Player_obj)
	{
		sx = current_hud->Player_shield_coords[0];
		sy = current_hud->Player_shield_coords[1];
	}
	else
	{
		sx = current_hud->Target_shield_coords[0];
		sy = current_hud->Target_shield_coords[1];
	}

	sx += fl2i(HUD_offset_x);
	sy += fl2i(HUD_offset_y);

	// draw the ship first
	if (objp == Player_obj)
	{
		hud_shield_maybe_flash(HUD_PLAYER_SHIELD_ICON, SHIELD_HIT_PLAYER, HULL_HIT_OFFSET);
	}
	else
	{
		hud_shield_maybe_flash(HUD_TARGET_SHIELD_ICON, SHIELD_HIT_TARGET, HULL_HIT_OFFSET);
	}

	if (sip->shield_icon_index != 255)
	{
		hud_aabitmap(sgp->first_frame, sx, sy);
	}
	else
	{
		bool g3_yourself = !g3_in_frame();
		angles rot_angles =
		{
			-1.570796327f,
			0.0f,
			0.0f
		};
		matrix object_orient;

		vm_angles_2_matrix(&object_orient, &rot_angles);

		gr_screen.clip_width = 112;
		gr_screen.clip_height = 93;

		//Fire it up
		if (g3_yourself)
			g3_start_frame(1);
		hud_save_restore_camera_data(1);
		HUD_set_clip(sx, sy, 112, 93);
		model_set_detail_level(1);

		//if(!digitus_improbus)
		g3_set_view_matrix(&sip->closeup_pos, &vmd_identity_matrix, sip->closeup_zoom * 3.25f);
		/*else
		{
			vec3d finger_vec = {0.0f, 0.0f, 176.0f};
			g3_set_view_matrix( &finger_vec, &vmd_identity_matrix, 1.0f);
		}*/

		if (!Cmdline_nohtl)
		{
			gr_set_proj_matrix(0.5f * Proj_fov, gr_screen.clip_aspect, Min_draw_distance, Max_draw_distance);
			gr_set_view_matrix(&Eye_position, &Eye_matrix);
		}

		//We're ready to show stuff
		ship_model_start(objp);
		//if(!digitus_improbus)
		{
			model_render(sip->model_num, &object_orient, &vmd_zero_vector, MR_NO_LIGHTING | MR_LOCK_DETAIL |
				MR_AUTOCENTER | MR_NO_FOGGING, -1, -1, sp->ship_replacement_textures);
		}
		/*else
		{
			if(fod_model == -1)
			{
				fod_model = model_load(NOX("FoD.pof"), 0, NULL);
				if(fod_model == -1)
				{
					fod_model = -2;
					return;
				}
			}
			model_render(fod_model, &object_orient, &vmd_zero_vector, MR_NO_LIGHTING | MR_LOCK_DETAIL | MR_AUTOCENTER | MR_NO_FOGGING, -1, -1);
		}*/
		ship_model_stop(objp);

		//We're done
		if (!Cmdline_nohtl)
		{
			gr_end_view_matrix();
			gr_end_proj_matrix();
		}
		if (g3_yourself)
			g3_end_frame();
		hud_save_restore_camera_data(0);

		HUD_reset_clip();
	}

	if (!sip->max_shield_strength)
		return;

	// draw the four quadrants
	//
	// Draw shield quadrants at one of NUM_SHIELD_LEVELS
	max_shield = get_max_shield_quad(objp);

	int j, x_val, y_val, mid_val;

	for (i = 0; i < MAX_SHIELD_SECTIONS; i++)
	{

		if (objp->flags & OF_NO_SHIELDS)
		{
			break;
		}

		if (objp->shield_quadrant[Quadrant_xlate[i]] < 0.1f)
		{
			continue;
		}

		range = MAX(HUD_COLOR_ALPHA_MAX, HUD_color_alpha + 4);
		hud_color_index = fl2i((objp->shield_quadrant[Quadrant_xlate[i]] / max_shield) * range);
		Assert(hud_color_index >= 0 && hud_color_index <= range);

		if (hud_color_index < 0)
		{
			hud_color_index = 0;
		}
		if (hud_color_index >= HUD_NUM_COLOR_LEVELS)
		{
			hud_color_index = HUD_NUM_COLOR_LEVELS - 1;
		}

		int flash = 0;
		if (objp == Player_obj)
		{
			flash = hud_shield_maybe_flash(HUD_PLAYER_SHIELD_ICON, SHIELD_HIT_PLAYER, i);
		}
		else
		{
			flash = hud_shield_maybe_flash(HUD_TARGET_SHIELD_ICON, SHIELD_HIT_TARGET, i);
		}

		if (!flash)
		{
			// gr_set_color_fast(&HUD_color_defaults[hud_color_index]);
			if (objp == Player_obj)
			{
				hud_set_gauge_color(HUD_PLAYER_SHIELD_ICON, hud_color_index);
			}
			else
			{
				hud_set_gauge_color(HUD_TARGET_SHIELD_ICON, hud_color_index);
			}

			if (sip->shield_icon_index != 255)
			{
				hud_aabitmap(sgp->first_frame + i + 1, sx, sy);
			}
			else
			{
				//Ugh, draw four shield quadrants
				switch (i)
				{
					//Top
				case 0:
					sy += 3;
					for (j = 0; j < 6; j++)
					{
						y_val = sy + 10;
						gr_gradient(sx + j,
							sy,
							sx + j,
							y_val - j);
					}
					mid_val = sy + 5;
					for (; j < 106; j++)
					{
						gr_gradient(sx + j,
							sy,
							sx + j,
							mid_val);
					}
					for (; j < 112; j++)
					{
						gr_gradient(sx + j,
							sy,
							sx + j,
							sy + (j - 101));
					}
					y_val = sy - 1;
					sy -= 3;
					for (j = 0; j < 112; j++)
						gr_gradient(sx + j, y_val, sx + j, sy);
					break;
					//Left
				case 1:
					sx += 1;
					x_val = sx + 10;
					y_val = sy + 15;
					for (j = 0; j < 6; j++)
					{
						gr_gradient(sx,
							y_val + j,
							x_val - j,
							y_val + j);
					}
					mid_val = sx + 5;
					for (; j < 48; j++)
					{
						gr_gradient(sx,
							y_val + j,
							mid_val,
							y_val + j);
					}
					for (; j < 54; j++)
					{
						gr_gradient(sx,
							y_val + j,
							sx + (j - 43),
							y_val + j);
					}
					x_val = sx;
					sx -= 3;
					for (j = 0; j < 54; j++)
						gr_gradient(x_val, y_val + j, sx, y_val + j);
					sx += 2;
					break;
					//Right
				case 2:
					x_val = sx + 109;	//-3 for border
					y_val = sy + 15;
					for (j = 0; j < 6; j++)
					{
						gr_gradient(x_val,
							y_val + j,
							x_val - (10 - j),
							y_val + j);
					}
					mid_val = x_val - 5;
					for (; j < 48; j++)
					{
						gr_gradient(x_val,
							y_val + j,
							mid_val,
							y_val + j);
					}
					for (; j < 54; j++)
					{
						gr_gradient(x_val,
							y_val + j,
							x_val - (j - 43),
							y_val + j);
					}
					mid_val = x_val;
					x_val += 3;
					for (j = 0; j < 54; j++)
						gr_gradient(mid_val, y_val + j, x_val, y_val + j);
					break;
					//Bottom
				case 3:
					y_val = sy + 80; //-3 for border
					for (j = 0; j < 6; j++)
						gr_gradient(sx + j,
							y_val,
							sx + j,
							y_val - (10 - j));
					mid_val = y_val - 5;
					for (; j < 106; j++)
						gr_gradient(sx + j,
							y_val,
							sx + j,
							mid_val);
					for (; j < 112; j++)
						gr_gradient(sx + j,
							y_val,
							sx + j,
							y_val - (j - 101));
					mid_val = y_val + 1;
					y_val += 3;
					for (j = 0; j < 112; j++)
						gr_gradient(sx + j, mid_val, sx + j, y_val);
				}
			}
		}
	}

	// hud_set_default_color();
}
Ejemplo n.º 3
0
void HudGaugeShield::showShields(object *objp, int mode)
{
//	static int fod_model = -1;
	float			max_shield;
	int			hud_color_index, range;
	int			sx, sy, i;
	ship			*sp;
	ship_info	*sip;
	hud_frames	*sgp=NULL;

	if ( objp->type != OBJ_SHIP )
		return;

	// Goober5000 - don't show if primitive sensors
	if ( Ships[Player_obj->instance].flags2 & SF2_PRIMITIVE_SENSORS )
		return;

	sp = &Ships[objp->instance];
	sip = &Ship_info[sp->ship_info_index];

//	bool digitus_improbus = (fod_model != -2 && strstr(sp->ship_name, "Sathanas") != NULL);
	if ( sip->shield_icon_index == 255 && !(sip->flags2 & SIF2_GENERATE_HUD_ICON) /*&& !digitus_improbus*/) {
		return;
	}

	setGaugeColor();

	// load in shield frames if not already loaded
	if (sip->shield_icon_index != 255) {
		sgp = &Shield_gauges.at(sip->shield_icon_index);

		if ( (sgp->first_frame == -1) && (sip->shield_icon_index < Hud_shield_filenames.size()) ) {
			sgp->first_frame = bm_load_animation(Hud_shield_filenames.at(sip->shield_icon_index).c_str(), &sgp->num_frames);
			if (sgp->first_frame == -1) {
				if (!shield_ani_warning_displayed_already) {
					shield_ani_warning_displayed_already = true;
					Warning(LOCATION, "Could not load in the HUD shield ani: %s\n", Hud_shield_filenames.at(sip->shield_icon_index).c_str());
				}
				return;
			}
		}
	}

	sx = position[0];
	sy = position[1];

	sx += fl2i(HUD_offset_x);
	sy += fl2i(HUD_offset_y);

	// draw the ship first
	maybeFlashShield(SHIELD_HIT_PLAYER, Shield_hit_data[SHIELD_HIT_PLAYER].hull_hit_index);

	if(sip->shield_icon_index != 255)
	{
		renderBitmap(sgp->first_frame, sx, sy);
	}
	else
	{
		bool g3_yourself = !g3_in_frame();
		angles rot_angles = {-1.570796327f,0.0f,0.0f};
		matrix	object_orient;

		vm_angles_2_matrix(&object_orient, &rot_angles);

		gr_screen.clip_width = 112;
		gr_screen.clip_height = 93;

		//Fire it up
		if(g3_yourself)
			g3_start_frame(1);
		hud_save_restore_camera_data(1);
		setClip(sx, sy, 112, 93);

		//if(!digitus_improbus)
			g3_set_view_matrix( &sip->closeup_pos, &vmd_identity_matrix, sip->closeup_zoom * 2.5f);
		/*else
		{
			vec3d finger_vec = {0.0f, 0.0f, 176.0f};
			g3_set_view_matrix( &finger_vec, &vmd_identity_matrix, 1.0f);
		}*/

		if (!Cmdline_nohtl) {
			gr_set_proj_matrix(0.5f*Proj_fov, gr_screen.clip_aspect, Min_draw_distance, Max_draw_distance);
			gr_set_view_matrix(&Eye_position, &Eye_matrix);
		}

		//We're ready to show stuff
		ship_model_start(objp);
		//if(!digitus_improbus)
		{
			model_render_params render_info;

			render_info.set_flags(MR_NO_LIGHTING | MR_AUTOCENTER | MR_NO_FOGGING);
			render_info.set_replacement_textures(sp->ship_replacement_textures);
			render_info.set_detail_level_lock(1);

			model_render_immediate( &render_info, sip->model_num, &object_orient, &vmd_zero_vector );
		}
		/*else
		{
			if(fod_model == -1)
			{
				fod_model = model_load(NOX("FoD.pof"), 0, NULL);
				if(fod_model == -1)
				{
					fod_model = -2;
					return;
				}
			}
			model_render(fod_model, &object_orient, &vmd_zero_vector, MR_NO_LIGHTING | MR_LOCK_DETAIL | MR_AUTOCENTER | MR_NO_FOGGING, -1, -1);
		}*/
		ship_model_stop( objp );

		//We're done
		if(!Cmdline_nohtl)
		{
			gr_end_view_matrix();
			gr_end_proj_matrix();
		}
		if(g3_yourself)
			g3_end_frame();
		hud_save_restore_camera_data(0);

		resetClip();
	}

	if(!sip->max_shield_strength)
		return;

	// draw the quadrants
	//
	// Draw shield quadrants at one of NUM_SHIELD_LEVELS
	max_shield = get_max_shield_quad(objp);

	coord2d shield_icon_coords[6];

	for ( i = 0; i < objp->n_quadrants; i++ ) {

		if ( objp->flags & OF_NO_SHIELDS ) {
			break;
		}

		if ( !(sip->flags2 & SIF2_MODEL_POINT_SHIELDS) ) {
			if ( objp->shield_quadrant[Quadrant_xlate[i]] < 0.1f )
				continue;
		} else {
			if ( objp->shield_quadrant[i] < 0.1f )
				continue;
		}

		range = MAX(HUD_COLOR_ALPHA_MAX, HUD_color_alpha + objp->n_quadrants);

		if ( !(sip->flags2 & SIF2_MODEL_POINT_SHIELDS) )
			hud_color_index = fl2i( (objp->shield_quadrant[Quadrant_xlate[i]] / max_shield) * range);
		else
			hud_color_index = fl2i( (objp->shield_quadrant[i] / max_shield) * range);

		Assert(hud_color_index >= 0 && hud_color_index <= range);

		if ( hud_color_index < 0 ) {
			hud_color_index = 0;
		}
		if ( hud_color_index >= HUD_NUM_COLOR_LEVELS ) {
			hud_color_index = HUD_NUM_COLOR_LEVELS - 1;
		}

		int flash=0;
		flash = maybeFlashShield(mode, i);
		
				
		if ( !flash ) {
			// gr_set_color_fast(&HUD_color_defaults[hud_color_index]);
			setGaugeColor(hud_color_index);
			

			if(sip->shield_icon_index != 255)
			{
				int framenum = sgp->first_frame+i+1;
				if (framenum < sgp->first_frame+sgp->num_frames)
					renderBitmap(framenum, sx, sy);
			}
			else
			{
				//Ugh, draw four shield quadrants
				static const int TRI_EDGE = 6;
				static const int BAR_LENGTH = 112;
				static const int BAR_HEIGHT = 54;
				static const int BAR_WIDTH = 6;
				static const int SHIELD_OFFSET = BAR_WIDTH + TRI_EDGE + 3;

				switch(i)
				{
					//Top
					case 0:
						shield_icon_coords[0].x = sx;                     shield_icon_coords[0].y = sy+BAR_WIDTH+TRI_EDGE;
						shield_icon_coords[1].x = sx;                     shield_icon_coords[1].y = sy;
						shield_icon_coords[2].x = sx+TRI_EDGE;            shield_icon_coords[2].y = sy+BAR_WIDTH;
						shield_icon_coords[3].x = sx+BAR_LENGTH;          shield_icon_coords[3].y = sy;
						shield_icon_coords[4].x = sx+BAR_LENGTH-TRI_EDGE; shield_icon_coords[4].y = sy+BAR_WIDTH;
						shield_icon_coords[5].x = sx+BAR_LENGTH;          shield_icon_coords[5].y = sy+BAR_WIDTH+TRI_EDGE;
						renderShieldIcon(shield_icon_coords);
						break;
					//Left
					case 3:
						sy += SHIELD_OFFSET;
						shield_icon_coords[0].x = sx+BAR_WIDTH+TRI_EDGE; shield_icon_coords[0].y = sy+BAR_HEIGHT;
						shield_icon_coords[1].x = sx;                    shield_icon_coords[1].y = sy+BAR_HEIGHT;
						shield_icon_coords[2].x = sx+BAR_WIDTH;          shield_icon_coords[2].y = sy+BAR_HEIGHT-TRI_EDGE;
						shield_icon_coords[3].x = sx;                    shield_icon_coords[3].y = sy;
						shield_icon_coords[4].x = sx+BAR_WIDTH;          shield_icon_coords[4].y = sy+TRI_EDGE;
						shield_icon_coords[5].x = sx+BAR_WIDTH+TRI_EDGE; shield_icon_coords[5].y = sy;
						renderShieldIcon(shield_icon_coords);
						sy -= SHIELD_OFFSET + BAR_WIDTH + TRI_EDGE;
						break;
					//Right
					case 1:
						sx += BAR_LENGTH;
						sy += SHIELD_OFFSET;
						shield_icon_coords[0].x = sx-BAR_WIDTH-TRI_EDGE; shield_icon_coords[0].y = sy;
						shield_icon_coords[1].x = sx;                    shield_icon_coords[1].y = sy;
						shield_icon_coords[2].x = sx-BAR_WIDTH;          shield_icon_coords[2].y = sy+TRI_EDGE;
						shield_icon_coords[3].x = sx;                    shield_icon_coords[3].y = sy+BAR_HEIGHT;
						shield_icon_coords[4].x = sx-BAR_WIDTH;          shield_icon_coords[4].y = sy+BAR_HEIGHT-TRI_EDGE;
						shield_icon_coords[5].x = sx-BAR_WIDTH-TRI_EDGE; shield_icon_coords[5].y = sy+BAR_HEIGHT;
						renderShieldIcon(shield_icon_coords);
						sx -= BAR_LENGTH;
						sy -= SHIELD_OFFSET;
						break;
					//Bottom
					case 2:
						sy += BAR_HEIGHT + SHIELD_OFFSET*2 - BAR_WIDTH - TRI_EDGE;
						shield_icon_coords[0].x = sx+BAR_LENGTH;          shield_icon_coords[0].y = sy;
						shield_icon_coords[1].x = sx+BAR_LENGTH;          shield_icon_coords[1].y = sy+BAR_WIDTH+TRI_EDGE;
						shield_icon_coords[2].x = sx+BAR_LENGTH-TRI_EDGE; shield_icon_coords[2].y = sy+TRI_EDGE;
						shield_icon_coords[3].x = sx;                     shield_icon_coords[3].y = sy+BAR_WIDTH+TRI_EDGE;
						shield_icon_coords[4].x = sx+TRI_EDGE;            shield_icon_coords[4].y = sy+TRI_EDGE;
						shield_icon_coords[5].x = sx;                     shield_icon_coords[5].y = sy;
						renderShieldIcon(shield_icon_coords);
						sy -= BAR_HEIGHT + SHIELD_OFFSET*2 - BAR_WIDTH - TRI_EDGE;
						break;
					//Whoops?
					default:
						nprintf(("HUD", "Invalid shield quadrant %d specified!\n", i));
						break;
				}
			}
		}
	}

	// hud_set_default_color();
}