/** * @brief Checks to see if can equip/remove an outfit from a slot. * * @param p Pilot to check if can equip. * @param s Slot being checked to see if it can equip/remove an outfit. * @param o Outfit to check (NULL if being removed). * @return NULL if can swap, or error message if can't. */ const char* pilot_canEquip( Pilot *p, PilotOutfitSlot *s, Outfit *o ) { Outfit *o_old; const char *err; double pa, ps, pe, pf; /* Just in case. */ if ((p==NULL) || (s==NULL)) return "Nothing selected."; if (o!=NULL) { /* Check slot type. */ if (!outfit_fitsSlot( o, &s->sslot->slot )) return "Does not fit slot."; /* Check outfit limit. */ if ((o->limit != NULL) && pilot_hasOutfitLimit( p, o->limit )) return "Already have an outfit of this type installed"; } else { /* Check fighter bay. */ if ((o==NULL) && (s!=NULL) && (s->u.ammo.deployed > 0)) return "Recall the fighters first"; } /* Store health. */ pa = p->armour; ps = p->shield; pe = p->energy; pf = p->fuel; /* Swap outfit. */ o_old = s->outfit; s->outfit = o; /* Check sanity. */ pilot_calcStats( p ); /* can now equip outfit even if ship won't be spaceworthy * err = pilot_checkSpaceworthy( p );*/ /* actually, this is also redundant */ if (!pilot_slotsCheckSanity(p)) err = "Does not fit in slot"; else err = NULL; /* Swap back. */ s->outfit = o_old; /* Recalc. */ pilot_calcStats( p ); /* Recover health. */ p->armour = pa; p->shield = ps; p->energy = pe; p->fuel = pf; return err; }
/** * @brief Pilot slot sanity check - makes sure stats are sane. * * @param p Pilot to check. * @return 0 if a slot doesn't fit, !0 otherwise. */ int pilot_slotsCheckSanity( Pilot *p ) { int i; for (i=0; i<p->noutfits; i++) if ((p->outfits[i]->outfit != NULL) && !outfit_fitsSlot( p->outfits[i]->outfit, &p->outfits[i]->sslot->slot )) return 0; return 1; }
/** * @brief Pilot sanity check - makes sure stats are sane. * * @param p Pilot to check. * @return The reason why the pilot is not sane (or NULL if sane). */ const char* pilot_checkSanity( Pilot *p ) { int i; for (i=0; i<p->noutfits; i++) if ((p->outfits[i]->outfit != NULL) && !outfit_fitsSlot( p->outfits[i]->outfit, &p->outfits[i]->sslot->slot )) return "Doesn't fit slot"; if (p->cpu < 0) return "Negative CPU"; /* Movement. */ if (p->thrust < 0.) return "Negative Thrust"; if (p->speed < 0.) return "Negative Speed"; if (p->turn < 0.) return "Negative Turn"; /* Health. */ if (p->armour_max < 0.) return "Negative Armour"; if (p->armour_regen < 0.) return "Negative Armour Regeneration"; if (p->shield_max < 0.) return "Negative Shield"; if (p->shield_regen < 0.) return "Negative Shield Regeneration"; if (p->energy_max < 0.) return "Negative Energy"; if (p->energy_regen < 0.) return "Negative Energy Regeneration"; /* Misc. */ if (p->fuel_max < 0.) return "Negative Fuel Maximum"; /* All OK. */ return NULL; }
/** * @brief Checks to see if can equip/remove an outfit from a slot. * * @param p Pilot to check if can equip. * @param s Slot being checked to see if it can equip/remove an outfit. * @param o Outfit to check (NULL if being removed). * @return NULL if can swap, or error message if can't. */ const char* pilot_canEquip( Pilot *p, PilotOutfitSlot *s, Outfit *o ) { /* Just in case. */ if ((p==NULL) || (s==NULL)) return "Nothing selected."; if (o!=NULL) { /* Check slot type. */ if (!outfit_fitsSlot( o, &s->sslot->slot )) return "Does not fit slot."; /* Check outfit limit. */ if ((o->limit != NULL) && pilot_hasOutfitLimit( p, o->limit )) return "Already have an outfit of this type installed"; } else { /* Check fighter bay. */ if ((o==NULL) && (s!=NULL) && (s->u.ammo.deployed > 0)) return "Recall the fighters first"; } return NULL; }
/** * @brief Checks to see if can equip/remove an outfit from a slot. * * @param p Pilot to check if can equip. * @param s Slot being checked to see if it can equip/remove an outfit. * @param o Outfit to check. * @param add Whether or not to consider it's being added or removed. * @return NULL if can swap, or error message if can't. */ const char* pilot_canEquip( Pilot *p, PilotOutfitSlot *s, Outfit *o, int add ) { /* Just in case. */ if ((p==NULL) || (o==NULL)) return "Nothing selected."; /* Check slot type. */ if ((s != NULL) && !outfit_fitsSlot( o, &s->sslot->slot )) return "Does not fit slot."; /* Adding outfit. */ if (add) { if ((outfit_cpu(o) > 0) && (p->cpu < outfit_cpu(o))) return "Insufficient CPU"; /* Can't add more than one outfit of the same type if the outfit type is limited. */ if ((o->limit != NULL) && pilot_hasOutfitLimit( p, o->limit )) return "Already have an outfit of this type installed"; /* Must not drive some things negative. */ if (outfit_isMod(o)) { /* * Movement. */ /* TODO fix this to work with ship stats. CHECK_STAT_R( o->u.mod.thrust, o->u.mod.thrust_rel, p->ship->thrust, "Insufficient thrust" ); CHECK_STAT_R( o->u.mod.turn, o->u.mod.turn_rel, p->ship->turn, "Insufficient turn" ); CHECK_STAT_R( o->u.mod.speed, o->u.mod.speed_rel, p->ship->speed, "Insufficient speed" ); */ /* * Health. */ /* Max. */ /* TODO fix this to work with ship stats. CHECK_STAT_R( o->u.mod.armour, o->u.mod.armour_rel, p->armour_max, "Insufficient armour" ); CHECK_STAT_R( o->u.mod.shield, o->u.mod.shield_rel, p->shield_max, "Insufficient shield" ); CHECK_STAT_R( o->u.mod.energy, o->u.mod.energy_rel, p->energy_max, "Insufficient energy" ); */ /* Regen. */ /* TODO fix this to work with ship stats. CHECK_STAT( o->u.mod.armour_regen, p->armour_regen, "Insufficient armour regeneration" ); CHECK_STAT( o->u.mod.shield_regen, p->shield_regen, "Insufficient shield regeneration" ); CHECK_STAT( o->u.mod.energy_regen, p->energy_regen, "Insufficient energy regeneration" ); */ /* * Misc. */ CHECK_STAT( o->u.mod.fuel, p->fuel_max, "Insufficient fuel" ); CHECK_STAT( o->u.mod.cargo, p->cargo_free, "Insufficient cargo space" ); } } /* Removing outfit. */ else { if ((outfit_cpu(o) < 0) && (p->cpu < fabs(outfit_cpu(o)))) return "Lower CPU usage first"; /* Must not drive some things negative. */ if (outfit_isMod(o)) { /* * Movement. */ /* TODO fix this to work with ship stats. if (((o->u.mod.thrust + o->u.mod.thrust_rel * p->ship->thrust) > 0) && (o->u.mod.thrust + o->u.mod.thrust_rel * p->ship->thrust > p->thrust)) return "Increase thrust first"; if (((o->u.mod.speed + o->u.mod.speed_rel * p->ship->speed) > 0) && (o->u.mod.speed + o->u.mod.speed_rel * p->ship->speed > p->speed)) return "Increase speed first"; if (((o->u.mod.turn + o->u.mod.turn_rel * p->ship->turn * p->ship->mass/p->solid->mass) > 0) && (fabs(o->u.mod.turn + o->u.mod.turn_rel * p->ship->turn * p->ship->mass/p->solid->mass) > p->turn_base)) return "Increase turn first"; */ /* * Health. */ /* Max. */ /* TODO fix this to work with ship stats. if ((o->u.mod.armour > 0) && (o->u.mod.armour > p->armour_max)) return "Increase armour first"; if ((o->u.mod.shield > 0) && (o->u.mod.shield > p->shield_max)) return "Increase shield first"; if ((o->u.mod.energy > 0) && (o->u.mod.energy > p->energy_max)) return "Increase energy first"; */ /* Regen. */ /* TODO fix this to work with ship stats. if ((o->u.mod.armour_regen > 0) && (o->u.mod.armour_regen > p->armour_regen)) return "Lower energy usage first"; if ((o->u.mod.shield_regen > 0) && (o->u.mod.shield_regen > p->shield_regen)) return "Lower shield usage first"; if ((o->u.mod.energy_regen > 0) && (o->u.mod.energy_regen > p->energy_regen)) return "Lower energy usage first"; */ /* * Misc. */ if ((o->u.mod.fuel > 0) && (o->u.mod.fuel > p->fuel_max)) return "Increase fuel first"; if ((o->u.mod.cargo > 0) && (o->u.mod.cargo > p->cargo_free)) return "Increase free cargo space first"; } else if (outfit_isFighterBay(o)) { if ((s!=NULL) && (s->u.ammo.deployed > 0)) return "Recall the fighters first"; } } /* Can equip. */ return NULL; }
/** * @brief Checks to see if can equip/remove an outfit from a slot. * * @return NULL if can swap, or error message if can't. */ const char* pilot_canEquip( Pilot *p, PilotOutfitSlot *s, Outfit *o, int add ) { /* Just in case. */ if ((p==NULL) || (o==NULL)) return "Nothing selected."; /* Check slot type. */ if ((s != NULL) && !outfit_fitsSlot( o, &s->slot )) return "Does not fit slot."; /* Adding outfit. */ if (add) { if ((outfit_cpu(o) > 0) && (p->cpu < outfit_cpu(o))) return "Insufficient CPU"; /* Can't add more than one afterburner. */ if (outfit_isAfterburner(o) && (p->afterburner != NULL)) return "Already have an afterburner"; /* Must not drive some things negative. */ if (outfit_isMod(o)) { /* * Movement. */ if (((o->u.mod.thrust + o->u.mod.thrust_rel * p->ship->thrust) < 0) && (fabs(o->u.mod.thrust + o->u.mod.thrust_rel * p->ship->thrust) > p->thrust)) return "Insufficient thrust"; if (((o->u.mod.speed + o->u.mod.speed_rel * p->ship->speed) < 0) && (fabs(o->u.mod.speed + o->u.mod.speed_rel * p->ship->speed) > p->speed)) return "Insufficient speed"; if (((o->u.mod.turn + o->u.mod.turn_rel * p->ship->turn * p->ship->mass/p->solid->mass) < 0) && (fabs(o->u.mod.turn + o->u.mod.turn_rel * p->ship->turn * p->ship->mass/p->solid->mass) > p->turn_base)) return "Insufficient turn"; /* * Health. */ /* Max. */ if ((o->u.mod.armour < 0) && (fabs(o->u.mod.armour) > p->armour_max)) return "Insufficient armour"; if ((o->u.mod.armour_rel < 0.) && (fabs(o->u.mod.armour_rel * p->ship->armour) > p->armour_max)) return "Insufficient armour"; if ((o->u.mod.shield < 0) && (fabs(o->u.mod.shield) > p->shield_max)) return "Insufficient shield"; if ((o->u.mod.shield_rel < 0.) && (fabs(o->u.mod.shield_rel * p->ship->shield) > p->shield_max)) return "Insufficient shield"; if ((o->u.mod.energy < 0) && (fabs(o->u.mod.energy) > p->armour_max)) return "Insufficient energy"; if ((o->u.mod.energy_rel < 0.) && (fabs(o->u.mod.energy_rel * p->ship->energy) > p->energy_max)) return "Insufficient energy"; /* Regen. */ if ((o->u.mod.armour_regen < 0) && (fabs(o->u.mod.armour_regen) > p->armour_regen)) return "Insufficient energy regeneration"; if ((o->u.mod.shield_regen < 0) && (fabs(o->u.mod.shield_regen) > p->shield_regen)) return "Insufficient shield regeneration"; if ((o->u.mod.energy_regen < 0) && (fabs(o->u.mod.energy_regen) > p->energy_regen)) return "Insufficient energy regeneration"; /* * Misc. */ if ((o->u.mod.fuel < 0) && (fabs(o->u.mod.fuel) > p->fuel_max)) return "Insufficient fuel"; if ((o->u.mod.cargo < 0) && (fabs(o->u.mod.cargo) > p->cargo_free)) return "Insufficient cargo space"; } } /* Removing outfit. */ else { if ((outfit_cpu(o) < 0) && (p->cpu < fabs(outfit_cpu(o)))) return "Lower CPU usage first"; /* Must not drive some things negative. */ if (outfit_isMod(o)) { /* * Movement. */ if (((o->u.mod.thrust + o->u.mod.thrust_rel * p->ship->thrust) > 0) && (o->u.mod.thrust + o->u.mod.thrust_rel * p->ship->thrust > p->thrust)) return "Increase thrust first"; if (((o->u.mod.speed + o->u.mod.speed_rel * p->ship->speed) > 0) && (o->u.mod.speed + o->u.mod.speed_rel * p->ship->speed > p->speed)) return "Increase speed first"; if (((o->u.mod.turn + o->u.mod.turn_rel * p->ship->turn * p->ship->mass/p->solid->mass) > 0) && (fabs(o->u.mod.turn + o->u.mod.turn_rel * p->ship->turn * p->ship->mass/p->solid->mass) > p->turn_base)) return "Increase turn first"; /* * Health. */ /* Max. */ if ((o->u.mod.armour > 0) && (o->u.mod.armour > p->armour_max)) return "Increase armour first"; if ((o->u.mod.shield > 0) && (o->u.mod.shield > p->shield_max)) return "Increase shield first"; if ((o->u.mod.energy > 0) && (o->u.mod.energy > p->energy_max)) return "Increase energy first"; /* Regen. */ if ((o->u.mod.armour_regen > 0) && (o->u.mod.armour_regen > p->armour_regen)) return "Lower energy usage first"; if ((o->u.mod.shield_regen > 0) && (o->u.mod.shield_regen > p->shield_regen)) return "Lower shield usage first"; if ((o->u.mod.energy_regen > 0) && (o->u.mod.energy_regen > p->energy_regen)) return "Lower energy usage first"; /* * Misc. */ if ((o->u.mod.fuel > 0) && (o->u.mod.fuel > p->fuel_max)) return "Increase fuel first"; if ((o->u.mod.cargo > 0) && (o->u.mod.cargo > p->cargo_free)) return "Increase free cargo space first"; } else if (outfit_isFighterBay(o)) { if ((s!=NULL) && (s->u.ammo.deployed > 0)) return "Recall the fighters first"; } } /* Can equip. */ return NULL; }