Example #1
0
// ------------------------------------------------------------------
// hud_shield_equalize()
//
// Equalize the four shield quadrants for an object
//
void hud_shield_equalize(object* objp, player* pl)
{
	float strength;
	int idx;
	int all_equal;

	Assert(objp != NULL);
	if (objp == NULL)
		return;

	Assert(pl != NULL);
	if (pl == NULL)
		return;

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

	// Goober5000 - quick out if we have no shields
	if (objp->flags & OF_NO_SHIELDS)
		return;

	// are all quadrants equal?
	all_equal = 1;
	for (idx = 0; idx < MAX_SHIELD_SECTIONS - 1; idx++)
	{
		if (objp->shield_quadrant[idx] != objp->shield_quadrant[idx + 1])
		{
			all_equal = 0;
			break;
		}
	}

	if (all_equal)
		return;

	strength = shield_get_strength(objp);
	if (strength == 0.0f)
		return;

	// maybe impose a 2% penalty - server side and single player only
	if (!MULTIPLAYER_CLIENT && (pl->shield_penalty_stamp < 0) || timestamp_elapsed_safe(pl->shield_penalty_stamp,
		1000))
	{
		strength *= 0.98f;

		// reset the penalty timestamp
		pl->shield_penalty_stamp = timestamp(1000);
	}

	shield_set_strength(objp, strength);

	// beep
	if (objp == Player_obj)
	{
		snd_play(&Snds[SND_SHIELD_XFER_OK]);
	}
}
// -------------------------------------------------------------------------------------------------
// transfer_energy_to_shields() will transfer ENERGY_DIVERT_DELTA percent of weapon energy
// to shield energy.
void transfer_energy_to_shields(object* obj)
{
	ship*			ship_p = &Ships[obj->instance];

	if (ship_p->flags & SF_DYING)
		return;

	if ( !ship_has_energy_weapons(ship_p) || obj->flags & OF_NO_SHIELDS )
	{
		return;
	}

	transfer_energy_weapon_common(obj, ship_p->weapon_energy, shield_get_strength(obj), &ship_p->target_weapon_energy_delta, &ship_p->target_shields_delta, ship_p->ship_max_shield_strength, 0.5f);
}
void shield_balance(object *objp, float rate, float penalty) {
	Assert(objp);
	if (objp->flags[Object::Object_Flags::No_shields]) {
		// No shields, bail
		return;
	}

	float shield_hp;
	shield_hp = shield_get_strength(objp);
	if (shield_hp == 0.0f) {
		// Shields are down, bail
		return;

	} else if (shield_hp == Ships[objp->instance].ship_max_shield_strength) {
		// Shields are maxed, bail
		return;
	}

	// Are all quadrants equal?
	bool all_equal = true;
	for (int idx = 0; idx < objp->n_quadrants - 1; idx++) {
		if (objp->shield_quadrant[idx] != objp->shield_quadrant[idx + 1]) {
			all_equal = false;
			break;
		}
	}

	if (all_equal) {
		// Quadrants are equal, bail
		return;
	}

	Assert((rate > 0.0f) && (rate <= 1.0f));
	Assert((penalty >= 0.0f) && (penalty <= 1.0f));

	float shield_hp_avg = shield_hp / objp->n_quadrants;
	shield_hp_avg *= 1 - penalty;

	for (int i = 0; i < objp->n_quadrants; ++i) {
		if (fabsf(objp->shield_quadrant[i] - shield_hp_avg) < 0.01f) {
			// Very close, so clamp
			objp->shield_quadrant[i] = shield_hp_avg;

		} else {
			// Else, smoothly balance towards target
			objp->shield_quadrant[i] += rate * (shield_hp_avg - objp->shield_quadrant[i]);
		}
	}
}
// -------------------------------------------------------------------------------------------------
// transfer_energy_to_weapons() will transfer ENERGY_DIVERT_DELTA percent of shield energy
// to weapon energy.
void transfer_energy_to_weapons(object* obj)
{
	ship*			ship_p = &Ships[obj->instance];
	ship_info*	sinfo_p = &Ship_info[ship_p->ship_info_index];

	if (ship_p->flags & SF_DYING)
		return;

	if ( !ship_has_energy_weapons(ship_p) || obj->flags & OF_NO_SHIELDS )
	{
		return;
	}

	transfer_energy_weapon_common(obj, shield_get_strength(obj), ship_p->weapon_energy, &ship_p->target_shields_delta, &ship_p->target_weapon_energy_delta, sinfo_p->max_weapon_reserve, 1.0f);
}
Example #5
0
/**
 * Returns true if the shield presents any opposition to something trying to force through it.
 *
 * @return If quadrant is -1, looks at entire shield, otherwise just one quadrant
 */
int ship_is_shield_up( object *obj, int quadrant )
{
    if ( (quadrant >= 0) && (quadrant < MAX_SHIELD_SECTIONS))	{
        // Just check one quadrant
        if (obj->shield_quadrant[quadrant] > MAX(2.0f, 0.1f * get_max_shield_quad(obj)))	{
            return 1;
        }
    } else {
        // Check all quadrants
        float strength = shield_get_strength(obj);

        if ( strength > MAX(2.0f*4.0f, 0.1f * Ships[obj->instance].ship_max_shield_strength ))	{
            return 1;
        }
    }
    return 0;	// no shield strength
}
int shield_is_up(object *objp, int quadrant_num) {
	Assert(objp);

	if ((quadrant_num >= 0) && (quadrant_num < objp->n_quadrants)) {
		// Just check one quadrant
		float quad = shield_get_quad(objp, quadrant_num);

		if (quad > MAX(2.0f, 0.1f * shield_get_max_quad(objp)))	// [z64555] Where the heck does this 2HP come from?
			return 1;
	} else {
		// Check all quadrants
		float strength = shield_get_strength(objp);

		if (strength > MAX(2.0f * objp->n_quadrants, 0.1f * shield_get_max_strength(objp)))	// [z64555] Where the heck does this 2HP come from?
			return 1;
	}

	return 0;	// no shield strength
}
Example #7
0
// Returns true if the shield presents any opposition to something 
// trying to force through it.
// If quadrant is -1, looks at entire shield, otherwise
// just one quadrant
int shield_is_up(object* objp, int quadrant_num)
{
	if ((quadrant_num >= 0) && (quadrant_num < MAX_SHIELD_SECTIONS))
	{
		// Just check one quadrant
		float quad = shield_get_quad(objp, quadrant_num);

		if (quad > MAX(2.0f, 0.1f * shield_get_max_quad(objp)))
			return 1;
	}
	else
	{
		// Check all quadrants
		float strength = shield_get_strength(objp);

		if (strength > MAX(2.0f * MAX_SHIELD_SECTIONS, 0.1f * shield_get_max_strength(objp)))
			return 1;
	}

	return 0;	// no shield strength
}
void shield_add_strength(object *objp, float delta) {
	Assert(objp);

	// if we aren't going to change anything anyway then just bail
	if (delta == 0.0f)
		return;

	float shield_str = shield_get_strength(objp);
	float shield_recharge_limit = shield_get_max_strength(objp);

	if ((delta > 0.0f) && (shield_str >= shield_recharge_limit))
		return;

	if (!(Ai_info[Ships[objp->instance].ai_index].ai_profile_flags[AI::Profile_Flags::Smart_shield_management])
		|| delta <= 0.0f) //SUSHI: We don't want smart shield management for negative delta
	{
		// set the limit for the shield recharge
		if ((delta > 0.0f) && ((shield_str + delta) > shield_recharge_limit))
			delta = shield_recharge_limit - shield_str;

		for (int i = 0; i < objp->n_quadrants; i++)
			shield_add_quad(objp, i, delta / objp->n_quadrants);
	}
	else
	{
		float section_max = shield_get_max_quad(objp);

		// smart shield repair
		while (delta > 0.0f)
		{
			//WMC - Set to INT_MAX so that this is set to something
			float weakest = i2fl(INT_MAX);
			int weakest_idx = -1;

			// find weakest shield quadrant
			for (int i = 0; i < objp->n_quadrants; i++)
			{
				float quad = shield_get_quad(objp, i);
				if (weakest_idx < 0 || quad < weakest)
				{
					weakest = quad;
					weakest_idx = i;
				}
			}

			// all quads are at full strength
			if (weakest >= section_max)
				break;

			// set the limit for the shield recharge
			if ((delta > 0.0f) && ((shield_str + delta) > shield_recharge_limit))
				delta = shield_recharge_limit - shield_str;

			// throw all possible shield power at this quadrant
			// if there's any left over then apply it to the next weakest on the next pass
			float xfer_amount;
			if (weakest + delta > section_max)
				xfer_amount = section_max - weakest;
			else
				xfer_amount = delta;

			shield_add_quad(objp, weakest_idx, xfer_amount);
			delta -= xfer_amount;
		}
	}
}
// -------------------------------------------------------------------------------------------------
// update_ets() is called once per frame for every OBJ_SHIP in the game.  The amount of energy
// to send to the weapons and shields is calculated, and the top ship speed is calculated.  The
// amount of time elapsed from the previous call is passed in as the parameter fl_frametime.
//
// parameters:   obj          ==> object that is updating their energy system
//               fl_frametime ==> game frametime (in seconds)
//
void update_ets(object* objp, float fl_frametime)
{
	float max_new_shield_energy, max_new_weapon_energy, _ss;

	if ( fl_frametime <= 0 ){
		return;
	}

	ship* ship_p = &Ships[objp->instance];
	ship_info* sinfo_p = &Ship_info[ship_p->ship_info_index];
	float max_g=sinfo_p->max_weapon_reserve,
		  max_s=ship_p->ship_max_shield_strength;

	if ( ship_p->flags & SF_DYING ){
		return;
	}

	if ( sinfo_p->power_output == 0 ){
		return;
	}

//	new_energy = fl_frametime * sinfo_p->power_output;

	// update weapon energy
	max_new_weapon_energy = fl_frametime * sinfo_p->max_weapon_regen_per_second * max_g;
	if ( objp->flags & OF_PLAYER_SHIP ) {
		ship_p->weapon_energy += Energy_levels[ship_p->weapon_recharge_index] * max_new_weapon_energy * The_mission.ai_profile->weapon_energy_scale[Game_skill_level];
	} else {
		ship_p->weapon_energy += Energy_levels[ship_p->weapon_recharge_index] * max_new_weapon_energy;
	}

	if ( ship_p->weapon_energy > sinfo_p->max_weapon_reserve ){
		ship_p->weapon_energy = sinfo_p->max_weapon_reserve;
	}

	float shield_delta;
	max_new_shield_energy = fl_frametime * sinfo_p->max_shield_regen_per_second * max_s;
	if ( objp->flags & OF_PLAYER_SHIP ) {
		shield_delta = Energy_levels[ship_p->shield_recharge_index] * max_new_shield_energy * The_mission.ai_profile->shield_energy_scale[Game_skill_level];
	} else {
		shield_delta = Energy_levels[ship_p->shield_recharge_index] * max_new_shield_energy;
	}

	shield_add_strength(objp, shield_delta);

	if ( (_ss = shield_get_strength(objp)) > ship_p->ship_max_shield_strength ){
		for (int i=0; i<objp->n_quadrants; i++){
			objp->shield_quadrant[i] *= ship_p->ship_max_shield_strength / _ss;
		}
	}

	// calculate the top speed of the ship based on the energy flow to engines
	float y = Energy_levels[ship_p->engine_recharge_index];

	ship_p->current_max_speed = ets_get_max_speed(objp, y);

	// AL 11-15-97: Rules for engine strength affecting max speed:
	//						1. if strength >= 0.5 no affect 
	//						2. if strength < 0.5 then max_speed = sqrt(strength)
	//					 
	//					 This will translate to 71% max speed at 50% engines, and 31% max speed at 10% engines
	//
	float strength = ship_get_subsystem_strength(ship_p, SUBSYSTEM_ENGINE);

	// don't let engine strength affect max speed when playing on lowest skill level
	if ( (objp != Player_obj) || (Game_skill_level > 0) ) {
		if ( strength < SHIP_MIN_ENGINES_FOR_FULL_SPEED ) {
			ship_p->current_max_speed *= fl_sqrt(strength);
		}
	}

	if ( timestamp_elapsed(ship_p->next_manage_ets) ) {
		if ( !(objp->flags & OF_PLAYER_SHIP) ) {
			ai_manage_ets(objp);
			ship_p->next_manage_ets = timestamp(AI_MODIFY_ETS_INTERVAL);
		}
		else {
			if ( Weapon_energy_cheat ){
				ship_p->weapon_energy = sinfo_p->max_weapon_reserve;
			}
		}
	}
}