float shield_get_max_quad(object *objp) { Assert(objp); if (objp->type != OBJ_SHIP) { return 0.0f; } return shield_get_max_strength(objp, true) / objp->n_quadrants; }
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 }
// 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; } } }
void shield_transfer(object *objp, int quadrant, float rate) { Assert(objp); Assert(objp->type == OBJ_SHIP); Assert(quadrant >= 0 && quadrant < objp->n_quadrants); Assert((0.0f < rate) && (rate <= 1.0f)); // The energy to Xfer to the quadrant float xfer_amount = shield_get_max_strength(objp) * rate; // The max amount of energy a quad can have float max_quadrant_val = shield_get_max_quad(objp); if ((objp->shield_quadrant[quadrant] + xfer_amount) > max_quadrant_val) { xfer_amount = max_quadrant_val - objp->shield_quadrant[quadrant]; } Assert(xfer_amount >= 0); if (xfer_amount == 0) { // TODO: provide a feedback sound return; } else if (objp == Player_obj) { snd_play(gamesnd_get_game_sound(SND_SHIELD_XFER_OK)); } float energy_avail = 0.0f; // Energy available from the other quadrants that we can transfer for (int i = 0; i < objp->n_quadrants; i++) { if (i == quadrant) continue; energy_avail += objp->shield_quadrant[i]; } // Percent energy to take from each quadrant float percent_to_take = xfer_amount / energy_avail; if (percent_to_take > 1.0f) { percent_to_take = 1.0f; } for (int i = 0; i < objp->n_quadrants; i++) { float delta; if (i == quadrant) { // Don't take energy from our target continue; } delta = percent_to_take * objp->shield_quadrant[i]; objp->shield_quadrant[i] -= delta; Assert(objp->shield_quadrant[i] >= 0); objp->shield_quadrant[quadrant] += delta; if (objp->shield_quadrant[quadrant] > max_quadrant_val) { // Already reached the max quadrant value. Clamp and bail before losing more any energy. objp->shield_quadrant[quadrant] = max_quadrant_val; break; } } }
void shield_transfer(object *objp, int quadrant, float rate) { Assert(objp); Assert(objp->type == OBJ_SHIP); ship *shipp = &Ships[objp->instance]; ship_info *sip = &Ship_info[shipp->ship_info_index]; if (sip->flags[Ship::Info_Flags::Model_point_shields]) { // Using model point shields, so map to the correct quadrant quadrant = sip->shield_point_augment_ctrls[quadrant]; if (quadrant < 0) { // This quadrant cannot be augmented, bail return; } } Assert(quadrant >= 0 && quadrant < objp->n_quadrants); Assert((0.0f < rate) && (rate <= 1.0f)); // The energy to Xfer to the quadrant float xfer_amount = shield_get_max_strength(objp) * rate; // The max amount of energy a quad can have float max_quadrant_val = shield_get_max_quad(objp); if ((objp->shield_quadrant[quadrant] + xfer_amount) > max_quadrant_val) { xfer_amount = max_quadrant_val - objp->shield_quadrant[quadrant]; } Assert(xfer_amount >= 0); if (xfer_amount == 0) { // TODO: provide a feedback sound return; } else if (objp == Player_obj) { snd_play(&Snds[SND_SHIELD_XFER_OK]); } float energy_avail = 0.0f; // Energy available from the other quadrants that we can transfer for (int i = 0; i < objp->n_quadrants; i++) { if (i == quadrant) continue; energy_avail += objp->shield_quadrant[i]; } // Percent energy to take from each quadrant float percent_to_take = xfer_amount / energy_avail; if (percent_to_take > 1.0f) { percent_to_take = 1.0f; } for (int i = 0; i < objp->n_quadrants; i++) { float delta; if (i == quadrant) { // Don't take energy from our target continue; } delta = percent_to_take * objp->shield_quadrant[i]; objp->shield_quadrant[i] -= delta; Assert(objp->shield_quadrant[i] >= 0); objp->shield_quadrant[quadrant] += delta; if (objp->shield_quadrant[quadrant] > max_quadrant_val) { // Already reached the max quadrant value. Clamp and bail before losing more any energy. objp->shield_quadrant[quadrant] = max_quadrant_val; break; } } }
// Goober5000 float shield_get_max_quad(object* objp) { return shield_get_max_strength(objp) / MAX_SHIELD_SECTIONS; }
// Goober5000 float shield_get_max_quad(object *objp) { return shield_get_max_strength(objp) / objp->n_quadrants; }