sanity-checks for potential divisions by zero (u->number)

This commit is contained in:
Enno Rehling 2006-10-15 14:09:59 +00:00
parent 6eaca764fe
commit 94966e8eda
15 changed files with 78 additions and 63 deletions

View File

@ -1624,6 +1624,8 @@ make_cmd(unit * u, struct order * ord)
const char *s;
const struct locale * lang = u->faction->locale;
if (u->number==NULL) return;
init_tokens(ord);
skip_token();
s = getstrtoken();

View File

@ -338,7 +338,7 @@ age_unit(region * r, unit * u)
}
} else {
++u->age;
if (u->race->age) {
if (u->number>0 && u->race->age) {
u->race->age(u);
}
}

View File

@ -309,6 +309,7 @@ static void
get_allies(region * r, unit * u)
{
unit *newunit = NULL;
assert(u->number);
switch (rterrain(r)) {
@ -422,27 +423,24 @@ void
encounters(void)
{
region *r;
unit *u;
int n;
int c;
int i;
for (r = regions; r; r = r->next) {
if (!fval(r->terrain, SEA_REGION) && fval(r, RF_ENCOUNTER)) {
c = 0;
int c = 0;
unit * u;
for (u = r->units; u; u = u->next) {
c += u->number;
}
if (c > 0) {
n = rng_int() % c;
u = r->units;
int i = 0;
int n = rng_int() % c;
for (i = u->number; i < n; i += u->number) {
u = u->next;
for (u = r->units; u; u = u->next) {
if (i+u->number>c) break;
}
encounter(r, u);
assert(u && u->number);
encounter(r, u);
}
}
}
@ -609,12 +607,13 @@ damage_unit(unit *u, const char *dam, boolean physical, boolean magic)
int *hp = malloc(u->number * sizeof(int));
int h;
int i, dead = 0, hp_rem = 0, heiltrank;
double magres = magic_resistance(u);
assert(u->number);
if (fval(u->race, RCF_ILLUSIONARY) || u->race == new_race[RC_SPELL]) {
return 0;
}
if (u->number==0) return 0;
h = u->hp/u->number;
/* HP verteilen */
for (i=0; i<u->number; i++) hp[i] = h;
@ -624,7 +623,7 @@ damage_unit(unit *u, const char *dam, boolean physical, boolean magic)
/* Schaden */
for (i=0; i<u->number; i++) {
int damage = dice_rand(dam);
if (magic) damage = (int)(damage * (1.0 - magic_resistance(u)));
if (magic) damage = (int)(damage * (1.0 - magres));
if (physical) damage -= nb_armor(u, i);
hp[i] -= damage;
}
@ -766,19 +765,21 @@ volcano_outbreak(region *r)
for (up=&r->units; *up;) {
unit * u = *up;
int dead = damage_unit(u, "4d10", true, false);
if (dead) {
ADDMSG(&u->faction->msgs, msg_message("volcano_dead",
"unit region dead", u, r, dead));
}
if (!fval(u->faction, FL_DH)) {
fset(u->faction, FL_DH);
if (rn) {
ADDMSG(&u->faction->msgs, msg_message("volcanooutbreak",
"regionv regionn", r, rn));
} else {
ADDMSG(&u->faction->msgs, msg_message("volcanooutbreaknn",
"region", r));
if (u->number) {
int dead = damage_unit(u, "4d10", true, false);
if (dead) {
ADDMSG(&u->faction->msgs, msg_message("volcano_dead",
"unit region dead", u, r, dead));
}
if (!fval(u->faction, FL_DH)) {
fset(u->faction, FL_DH);
if (rn) {
ADDMSG(&u->faction->msgs, msg_message("volcanooutbreak",
"regionv regionn", r, rn));
} else {
ADDMSG(&u->faction->msgs, msg_message("volcanooutbreaknn",
"region", r));
}
}
}
if (u==*up) up=&u->next;
@ -805,10 +806,12 @@ volcano_outbreak(region *r)
/* Personen bekommen 3W10 Punkte Schaden. */
for (up=&rn->units; *up;) {
unit * u = *up;
int dead = damage_unit(u, "3d10", true, false);
if (dead) {
ADDMSG(&u->faction->msgs, msg_message("volcano_dead",
"unit region dead", u, r, dead));
if (u->number) {
int dead = damage_unit(u, "3d10", true, false);
if (dead) {
ADDMSG(&u->faction->msgs, msg_message("volcano_dead",
"unit region dead", u, r, dead));
}
}
if (u==*up) up=&u->next;
}

View File

@ -446,11 +446,7 @@ learn_cmd(unit * u, order * ord)
int p;
magic_t mtyp;
int l;
int studycost;
/* lernen nach lehren */
int days;
int studycost, days;
double multi = 1.0;
attrib * a = NULL;
teaching_info * teach = NULL;
@ -458,6 +454,7 @@ learn_cmd(unit * u, order * ord)
skill_t sk;
int maxalchemy = 0;
if (u->number==0) return;
if (fval(r->terrain, SEA_REGION)) {
/* sonderbehandlung aller die auf Ozeanen lernen können */
if (u->race!=new_race[RC_AQUARIAN] && !(u->race->flags & RCF_SWIM)) {

View File

@ -911,6 +911,7 @@ terminate(troop dt, troop at, int type, const char *damage, boolean missile)
boolean magic = false;
int da = dice_rand(damage);
assert(du->number>0);
#ifdef SHOW_KILLS
++at.fighter->hits;
#endif
@ -2914,6 +2915,7 @@ make_fighter(battle * b, unit * u, side * s1, boolean attack)
static boolean init = false;
unsigned int flags = 0;
assert(u->number);
if (fval(u, UFL_PARTEITARNUNG)!=0) flags |= SIDE_STEALTH;
#ifdef SIMPLE_COMBAT
if (attack) flags |= SIDE_ATTACKER;

View File

@ -452,6 +452,7 @@ build_road(region * r, unit * u, int size, direction_t d)
int n, left;
region * rn = rconnect(r,d);
assert(u->number);
if (!eff_skill(u, SK_ROAD_BUILDING, r)) {
cmistake(u, u->thisorder, 103, MSG_PRODUCE);
return;
@ -611,6 +612,7 @@ build(unit * u, const construction * ctype, int completed, int want)
int made = 0;
int basesk, effsk;
assert(u->number);
if (want<=0) return 0;
if (type==NULL) return 0;
if (type->improvement==NULL && completed==type->maxsize)
@ -796,6 +798,7 @@ build_building(unit * u, const building_type * btype, int want, order * ord)
order * new_order = NULL;
const struct locale * lang = u->faction->locale;
assert(u->number);
if (eff_skill(u, SK_BUILDING, r) == 0) {
cmistake(u, ord, 101, MSG_PRODUCE);
return;

View File

@ -546,7 +546,7 @@ create_curse(unit *magician, attrib **ap, const curse_type *ct, double vigour,
/* hier müssen alle c-typen, die auf Einheiten gezaubert werden können,
* berücksichtigt werden */
void
static void
do_transfer_curse(curse *c, unit * u, unit * u2, int n)
{
int flag = c->flag;

View File

@ -881,7 +881,7 @@ scale_number (unit * u, int n)
int remain;
if (n == u->number) return;
if (n && u->number) {
if (n && u->number>0) {
int full;
remain = ((u->hp%u->number) * (n % u->number)) % u->number;
@ -894,17 +894,19 @@ scale_number (unit * u, int n)
remain = 0;
u->hp = 0;
}
for (a = a_find(u->attribs, &at_effect);a && a->type==&at_effect;a=a->next) {
effect_data * data = (effect_data *)a->data.v;
int snew = data->value / u->number * n;
if (n) {
remain = data->value - snew / n * u->number;
snew += remain * n / u->number;
remain = (remain * n) % u->number;
if ((rng_int() % u->number) < remain)
++snew; /* Nachkommastellen */
if (u->number>0) {
for (a = a_find(u->attribs, &at_effect);a && a->type==&at_effect;a=a->next) {
effect_data * data = (effect_data *)a->data.v;
int snew = data->value / u->number * n;
if (n) {
remain = data->value - snew / n * u->number;
snew += remain * n / u->number;
remain = (remain * n) % u->number;
if ((rng_int() % u->number) < remain)
++snew; /* Nachkommastellen */
}
data->value = snew;
}
data->value = snew;
}
if (u->number==0 || n==0) {
for (sk = 0; sk < MAXSKILLS; sk++) {

View File

@ -1085,6 +1085,7 @@ magic_resistance(unit *target)
/* Bonus durch Rassenmagieresistenz */
double probability = target->race->magres;
assert(target->number>0);
/* Magier haben einen Resistenzbonus vom Magietalent * 5%*/
probability += effskill(target, SK_MAGIC)*0.05;

View File

@ -1249,6 +1249,7 @@ movement_speed(unit * u)
static boolean init = false;
double dk = u->race->speed;
assert(u->number);
/* dragons have a fixed speed, and no other effects work on them: */
switch (old_race(u->race)) {
case RC_DRAGON:
@ -2051,6 +2052,7 @@ move(unit * u, boolean move_on_land)
{
region_list * route = NULL;
assert(u->number);
if (u->ship && fval(u, UFL_OWNER)) {
sail(u, u->thisorder, move_on_land, &route);
} else {

View File

@ -132,6 +132,7 @@ hp_status(const unit * u)
void
report_item(const unit * owner, const item * i, const faction * viewer, const char ** name, const char ** basename, int * number, boolean singular)
{
assert(owner->number);
if (owner->faction == viewer) {
if (name) *name = locale_string(viewer->locale, resourcename(i->type->rtype, ((i->number!=1 && !singular)?GR_PLURAL:0)));
if (basename) *basename = resourcename(i->type->rtype, 0);

View File

@ -1077,16 +1077,18 @@ readunit(FILE * F)
assert(u->race);
if (global.data_version<NEWSKILL_VERSION) {
/* convert old data */
while ((sk = (skill_t) ri(F)) != NOSKILL) {
int days = ri(F) / u->number;
int lvl = level(days);
int weeks = lvl + 1 - (days - level_days(lvl))/30;
assert(weeks>0 && weeks<=lvl+1);
if (lvl) {
skill * sv = add_skill(u, sk);
sv->level = sv->old = (unsigned char)lvl;
sv->weeks = (unsigned char)weeks;
}
if (u->number) {
while ((sk = (skill_t) ri(F)) != NOSKILL) {
int days = ri(F) / u->number;
int lvl = level(days);
int weeks = lvl + 1 - (days - level_days(lvl))/30;
assert(weeks>0 && weeks<=lvl+1);
if (lvl) {
skill * sv = add_skill(u, sk);
sv->level = sv->old = (unsigned char)lvl;
sv->weeks = (unsigned char)weeks;
}
}
}
} else {
while ((sk = (skill_t) ri(F)) != NOSKILL) {

View File

@ -782,8 +782,8 @@ transfermen(unit * u, unit * u2, int n)
int hp = u->hp;
region * r = u->region;
if (!n) return;
if (n==0) return;
assert(n > 0);
/* "hat attackiert"-status wird übergeben */
if (u2) {

View File

@ -31,7 +31,7 @@
void
age_firedragon(unit *u)
{
if (rng_int()%100 < age_chance(u->age, DRAGONAGE, 1)) {
if (u->number>0 && rng_int()%100 < age_chance(u->age, DRAGONAGE, 1)) {
double q = (double) u->hp / (double) (unit_max_hp(u) * u->number);
u->race = new_race[RC_DRAGON];
u->irace = new_race[RC_DRAGON];
@ -43,7 +43,7 @@ age_firedragon(unit *u)
void
age_dragon(unit *u)
{
if (rng_int()%100 < age_chance(u->age, WYRMAGE, 1)) {
if (u->number>0 && rng_int()%100 < age_chance(u->age, WYRMAGE, 1)) {
double q = (double) u->hp / (double) (unit_max_hp(u) * u->number);
u->race = new_race[RC_WYRM];
u->irace = new_race[RC_WYRM];

View File

@ -4708,7 +4708,7 @@ sp_headache(castorder *co)
countspells(mage, 1);
/* wenn kein Ziel gefunden, Zauber abbrechen */
if(pa->param[0]->flag == TARGET_NOTFOUND) return 0;
if (target->number==0 || pa->param[0]->flag == TARGET_NOTFOUND) return 0;
target = pa->param[0]->data.u; /* Zieleinheit */