forked from github/server
sanity-checks for potential divisions by zero (u->number)
This commit is contained in:
parent
6eaca764fe
commit
94966e8eda
|
@ -1624,6 +1624,8 @@ make_cmd(unit * u, struct order * ord)
|
||||||
const char *s;
|
const char *s;
|
||||||
const struct locale * lang = u->faction->locale;
|
const struct locale * lang = u->faction->locale;
|
||||||
|
|
||||||
|
if (u->number==NULL) return;
|
||||||
|
|
||||||
init_tokens(ord);
|
init_tokens(ord);
|
||||||
skip_token();
|
skip_token();
|
||||||
s = getstrtoken();
|
s = getstrtoken();
|
||||||
|
|
|
@ -338,7 +338,7 @@ age_unit(region * r, unit * u)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
++u->age;
|
++u->age;
|
||||||
if (u->race->age) {
|
if (u->number>0 && u->race->age) {
|
||||||
u->race->age(u);
|
u->race->age(u);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -309,6 +309,7 @@ static void
|
||||||
get_allies(region * r, unit * u)
|
get_allies(region * r, unit * u)
|
||||||
{
|
{
|
||||||
unit *newunit = NULL;
|
unit *newunit = NULL;
|
||||||
|
assert(u->number);
|
||||||
|
|
||||||
switch (rterrain(r)) {
|
switch (rterrain(r)) {
|
||||||
|
|
||||||
|
@ -422,27 +423,24 @@ void
|
||||||
encounters(void)
|
encounters(void)
|
||||||
{
|
{
|
||||||
region *r;
|
region *r;
|
||||||
unit *u;
|
|
||||||
int n;
|
|
||||||
int c;
|
|
||||||
int i;
|
|
||||||
|
|
||||||
for (r = regions; r; r = r->next) {
|
for (r = regions; r; r = r->next) {
|
||||||
if (!fval(r->terrain, SEA_REGION) && fval(r, RF_ENCOUNTER)) {
|
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) {
|
for (u = r->units; u; u = u->next) {
|
||||||
c += u->number;
|
c += u->number;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (c > 0) {
|
if (c > 0) {
|
||||||
n = rng_int() % c;
|
int i = 0;
|
||||||
u = r->units;
|
int n = rng_int() % c;
|
||||||
|
|
||||||
for (i = u->number; i < n; i += u->number) {
|
for (u = r->units; u; u = u->next) {
|
||||||
u = u->next;
|
if (i+u->number>c) break;
|
||||||
}
|
}
|
||||||
|
assert(u && u->number);
|
||||||
encounter(r, u);
|
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 *hp = malloc(u->number * sizeof(int));
|
||||||
int h;
|
int h;
|
||||||
int i, dead = 0, hp_rem = 0, heiltrank;
|
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]) {
|
if (fval(u->race, RCF_ILLUSIONARY) || u->race == new_race[RC_SPELL]) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (u->number==0) return 0;
|
|
||||||
h = u->hp/u->number;
|
h = u->hp/u->number;
|
||||||
/* HP verteilen */
|
/* HP verteilen */
|
||||||
for (i=0; i<u->number; i++) hp[i] = h;
|
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 */
|
/* Schaden */
|
||||||
for (i=0; i<u->number; i++) {
|
for (i=0; i<u->number; i++) {
|
||||||
int damage = dice_rand(dam);
|
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);
|
if (physical) damage -= nb_armor(u, i);
|
||||||
hp[i] -= damage;
|
hp[i] -= damage;
|
||||||
}
|
}
|
||||||
|
@ -766,19 +765,21 @@ volcano_outbreak(region *r)
|
||||||
|
|
||||||
for (up=&r->units; *up;) {
|
for (up=&r->units; *up;) {
|
||||||
unit * u = *up;
|
unit * u = *up;
|
||||||
int dead = damage_unit(u, "4d10", true, false);
|
if (u->number) {
|
||||||
if (dead) {
|
int dead = damage_unit(u, "4d10", true, false);
|
||||||
ADDMSG(&u->faction->msgs, msg_message("volcano_dead",
|
if (dead) {
|
||||||
"unit region dead", u, r, 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 (!fval(u->faction, FL_DH)) {
|
||||||
if (rn) {
|
fset(u->faction, FL_DH);
|
||||||
ADDMSG(&u->faction->msgs, msg_message("volcanooutbreak",
|
if (rn) {
|
||||||
"regionv regionn", r, rn));
|
ADDMSG(&u->faction->msgs, msg_message("volcanooutbreak",
|
||||||
} else {
|
"regionv regionn", r, rn));
|
||||||
ADDMSG(&u->faction->msgs, msg_message("volcanooutbreaknn",
|
} else {
|
||||||
"region", r));
|
ADDMSG(&u->faction->msgs, msg_message("volcanooutbreaknn",
|
||||||
|
"region", r));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (u==*up) up=&u->next;
|
if (u==*up) up=&u->next;
|
||||||
|
@ -805,10 +806,12 @@ volcano_outbreak(region *r)
|
||||||
/* Personen bekommen 3W10 Punkte Schaden. */
|
/* Personen bekommen 3W10 Punkte Schaden. */
|
||||||
for (up=&rn->units; *up;) {
|
for (up=&rn->units; *up;) {
|
||||||
unit * u = *up;
|
unit * u = *up;
|
||||||
int dead = damage_unit(u, "3d10", true, false);
|
if (u->number) {
|
||||||
if (dead) {
|
int dead = damage_unit(u, "3d10", true, false);
|
||||||
ADDMSG(&u->faction->msgs, msg_message("volcano_dead",
|
if (dead) {
|
||||||
"unit region dead", u, r, dead));
|
ADDMSG(&u->faction->msgs, msg_message("volcano_dead",
|
||||||
|
"unit region dead", u, r, dead));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (u==*up) up=&u->next;
|
if (u==*up) up=&u->next;
|
||||||
}
|
}
|
||||||
|
|
|
@ -446,11 +446,7 @@ learn_cmd(unit * u, order * ord)
|
||||||
int p;
|
int p;
|
||||||
magic_t mtyp;
|
magic_t mtyp;
|
||||||
int l;
|
int l;
|
||||||
int studycost;
|
int studycost, days;
|
||||||
|
|
||||||
/* lernen nach lehren */
|
|
||||||
|
|
||||||
int days;
|
|
||||||
double multi = 1.0;
|
double multi = 1.0;
|
||||||
attrib * a = NULL;
|
attrib * a = NULL;
|
||||||
teaching_info * teach = NULL;
|
teaching_info * teach = NULL;
|
||||||
|
@ -458,6 +454,7 @@ learn_cmd(unit * u, order * ord)
|
||||||
skill_t sk;
|
skill_t sk;
|
||||||
int maxalchemy = 0;
|
int maxalchemy = 0;
|
||||||
|
|
||||||
|
if (u->number==0) return;
|
||||||
if (fval(r->terrain, SEA_REGION)) {
|
if (fval(r->terrain, SEA_REGION)) {
|
||||||
/* sonderbehandlung aller die auf Ozeanen lernen können */
|
/* sonderbehandlung aller die auf Ozeanen lernen können */
|
||||||
if (u->race!=new_race[RC_AQUARIAN] && !(u->race->flags & RCF_SWIM)) {
|
if (u->race!=new_race[RC_AQUARIAN] && !(u->race->flags & RCF_SWIM)) {
|
||||||
|
|
|
@ -911,6 +911,7 @@ terminate(troop dt, troop at, int type, const char *damage, boolean missile)
|
||||||
boolean magic = false;
|
boolean magic = false;
|
||||||
int da = dice_rand(damage);
|
int da = dice_rand(damage);
|
||||||
|
|
||||||
|
assert(du->number>0);
|
||||||
#ifdef SHOW_KILLS
|
#ifdef SHOW_KILLS
|
||||||
++at.fighter->hits;
|
++at.fighter->hits;
|
||||||
#endif
|
#endif
|
||||||
|
@ -2914,6 +2915,7 @@ make_fighter(battle * b, unit * u, side * s1, boolean attack)
|
||||||
static boolean init = false;
|
static boolean init = false;
|
||||||
unsigned int flags = 0;
|
unsigned int flags = 0;
|
||||||
|
|
||||||
|
assert(u->number);
|
||||||
if (fval(u, UFL_PARTEITARNUNG)!=0) flags |= SIDE_STEALTH;
|
if (fval(u, UFL_PARTEITARNUNG)!=0) flags |= SIDE_STEALTH;
|
||||||
#ifdef SIMPLE_COMBAT
|
#ifdef SIMPLE_COMBAT
|
||||||
if (attack) flags |= SIDE_ATTACKER;
|
if (attack) flags |= SIDE_ATTACKER;
|
||||||
|
|
|
@ -452,6 +452,7 @@ build_road(region * r, unit * u, int size, direction_t d)
|
||||||
int n, left;
|
int n, left;
|
||||||
region * rn = rconnect(r,d);
|
region * rn = rconnect(r,d);
|
||||||
|
|
||||||
|
assert(u->number);
|
||||||
if (!eff_skill(u, SK_ROAD_BUILDING, r)) {
|
if (!eff_skill(u, SK_ROAD_BUILDING, r)) {
|
||||||
cmistake(u, u->thisorder, 103, MSG_PRODUCE);
|
cmistake(u, u->thisorder, 103, MSG_PRODUCE);
|
||||||
return;
|
return;
|
||||||
|
@ -611,6 +612,7 @@ build(unit * u, const construction * ctype, int completed, int want)
|
||||||
int made = 0;
|
int made = 0;
|
||||||
int basesk, effsk;
|
int basesk, effsk;
|
||||||
|
|
||||||
|
assert(u->number);
|
||||||
if (want<=0) return 0;
|
if (want<=0) return 0;
|
||||||
if (type==NULL) return 0;
|
if (type==NULL) return 0;
|
||||||
if (type->improvement==NULL && completed==type->maxsize)
|
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;
|
order * new_order = NULL;
|
||||||
const struct locale * lang = u->faction->locale;
|
const struct locale * lang = u->faction->locale;
|
||||||
|
|
||||||
|
assert(u->number);
|
||||||
if (eff_skill(u, SK_BUILDING, r) == 0) {
|
if (eff_skill(u, SK_BUILDING, r) == 0) {
|
||||||
cmistake(u, ord, 101, MSG_PRODUCE);
|
cmistake(u, ord, 101, MSG_PRODUCE);
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -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,
|
/* hier müssen alle c-typen, die auf Einheiten gezaubert werden können,
|
||||||
* berücksichtigt werden */
|
* berücksichtigt werden */
|
||||||
|
|
||||||
void
|
static void
|
||||||
do_transfer_curse(curse *c, unit * u, unit * u2, int n)
|
do_transfer_curse(curse *c, unit * u, unit * u2, int n)
|
||||||
{
|
{
|
||||||
int flag = c->flag;
|
int flag = c->flag;
|
||||||
|
|
|
@ -881,7 +881,7 @@ scale_number (unit * u, int n)
|
||||||
int remain;
|
int remain;
|
||||||
|
|
||||||
if (n == u->number) return;
|
if (n == u->number) return;
|
||||||
if (n && u->number) {
|
if (n && u->number>0) {
|
||||||
int full;
|
int full;
|
||||||
remain = ((u->hp%u->number) * (n % u->number)) % u->number;
|
remain = ((u->hp%u->number) * (n % u->number)) % u->number;
|
||||||
|
|
||||||
|
@ -894,17 +894,19 @@ scale_number (unit * u, int n)
|
||||||
remain = 0;
|
remain = 0;
|
||||||
u->hp = 0;
|
u->hp = 0;
|
||||||
}
|
}
|
||||||
for (a = a_find(u->attribs, &at_effect);a && a->type==&at_effect;a=a->next) {
|
if (u->number>0) {
|
||||||
effect_data * data = (effect_data *)a->data.v;
|
for (a = a_find(u->attribs, &at_effect);a && a->type==&at_effect;a=a->next) {
|
||||||
int snew = data->value / u->number * n;
|
effect_data * data = (effect_data *)a->data.v;
|
||||||
if (n) {
|
int snew = data->value / u->number * n;
|
||||||
remain = data->value - snew / n * u->number;
|
if (n) {
|
||||||
snew += remain * n / u->number;
|
remain = data->value - snew / n * u->number;
|
||||||
remain = (remain * n) % u->number;
|
snew += remain * n / u->number;
|
||||||
if ((rng_int() % u->number) < remain)
|
remain = (remain * n) % u->number;
|
||||||
++snew; /* Nachkommastellen */
|
if ((rng_int() % u->number) < remain)
|
||||||
|
++snew; /* Nachkommastellen */
|
||||||
|
}
|
||||||
|
data->value = snew;
|
||||||
}
|
}
|
||||||
data->value = snew;
|
|
||||||
}
|
}
|
||||||
if (u->number==0 || n==0) {
|
if (u->number==0 || n==0) {
|
||||||
for (sk = 0; sk < MAXSKILLS; sk++) {
|
for (sk = 0; sk < MAXSKILLS; sk++) {
|
||||||
|
|
|
@ -1085,6 +1085,7 @@ magic_resistance(unit *target)
|
||||||
|
|
||||||
/* Bonus durch Rassenmagieresistenz */
|
/* Bonus durch Rassenmagieresistenz */
|
||||||
double probability = target->race->magres;
|
double probability = target->race->magres;
|
||||||
|
assert(target->number>0);
|
||||||
|
|
||||||
/* Magier haben einen Resistenzbonus vom Magietalent * 5%*/
|
/* Magier haben einen Resistenzbonus vom Magietalent * 5%*/
|
||||||
probability += effskill(target, SK_MAGIC)*0.05;
|
probability += effskill(target, SK_MAGIC)*0.05;
|
||||||
|
|
|
@ -1249,6 +1249,7 @@ movement_speed(unit * u)
|
||||||
static boolean init = false;
|
static boolean init = false;
|
||||||
double dk = u->race->speed;
|
double dk = u->race->speed;
|
||||||
|
|
||||||
|
assert(u->number);
|
||||||
/* dragons have a fixed speed, and no other effects work on them: */
|
/* dragons have a fixed speed, and no other effects work on them: */
|
||||||
switch (old_race(u->race)) {
|
switch (old_race(u->race)) {
|
||||||
case RC_DRAGON:
|
case RC_DRAGON:
|
||||||
|
@ -2051,6 +2052,7 @@ move(unit * u, boolean move_on_land)
|
||||||
{
|
{
|
||||||
region_list * route = NULL;
|
region_list * route = NULL;
|
||||||
|
|
||||||
|
assert(u->number);
|
||||||
if (u->ship && fval(u, UFL_OWNER)) {
|
if (u->ship && fval(u, UFL_OWNER)) {
|
||||||
sail(u, u->thisorder, move_on_land, &route);
|
sail(u, u->thisorder, move_on_land, &route);
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -132,6 +132,7 @@ hp_status(const unit * u)
|
||||||
void
|
void
|
||||||
report_item(const unit * owner, const item * i, const faction * viewer, const char ** name, const char ** basename, int * number, boolean singular)
|
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 (owner->faction == viewer) {
|
||||||
if (name) *name = locale_string(viewer->locale, resourcename(i->type->rtype, ((i->number!=1 && !singular)?GR_PLURAL:0)));
|
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);
|
if (basename) *basename = resourcename(i->type->rtype, 0);
|
||||||
|
|
|
@ -1077,16 +1077,18 @@ readunit(FILE * F)
|
||||||
assert(u->race);
|
assert(u->race);
|
||||||
if (global.data_version<NEWSKILL_VERSION) {
|
if (global.data_version<NEWSKILL_VERSION) {
|
||||||
/* convert old data */
|
/* convert old data */
|
||||||
while ((sk = (skill_t) ri(F)) != NOSKILL) {
|
if (u->number) {
|
||||||
int days = ri(F) / u->number;
|
while ((sk = (skill_t) ri(F)) != NOSKILL) {
|
||||||
int lvl = level(days);
|
int days = ri(F) / u->number;
|
||||||
int weeks = lvl + 1 - (days - level_days(lvl))/30;
|
int lvl = level(days);
|
||||||
assert(weeks>0 && weeks<=lvl+1);
|
int weeks = lvl + 1 - (days - level_days(lvl))/30;
|
||||||
if (lvl) {
|
assert(weeks>0 && weeks<=lvl+1);
|
||||||
skill * sv = add_skill(u, sk);
|
if (lvl) {
|
||||||
sv->level = sv->old = (unsigned char)lvl;
|
skill * sv = add_skill(u, sk);
|
||||||
sv->weeks = (unsigned char)weeks;
|
sv->level = sv->old = (unsigned char)lvl;
|
||||||
}
|
sv->weeks = (unsigned char)weeks;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
while ((sk = (skill_t) ri(F)) != NOSKILL) {
|
while ((sk = (skill_t) ri(F)) != NOSKILL) {
|
||||||
|
|
|
@ -782,8 +782,8 @@ transfermen(unit * u, unit * u2, int n)
|
||||||
int hp = u->hp;
|
int hp = u->hp;
|
||||||
region * r = u->region;
|
region * r = u->region;
|
||||||
|
|
||||||
if (!n) return;
|
if (n==0) return;
|
||||||
|
assert(n > 0);
|
||||||
/* "hat attackiert"-status wird übergeben */
|
/* "hat attackiert"-status wird übergeben */
|
||||||
|
|
||||||
if (u2) {
|
if (u2) {
|
||||||
|
|
|
@ -31,7 +31,7 @@
|
||||||
void
|
void
|
||||||
age_firedragon(unit *u)
|
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);
|
double q = (double) u->hp / (double) (unit_max_hp(u) * u->number);
|
||||||
u->race = new_race[RC_DRAGON];
|
u->race = new_race[RC_DRAGON];
|
||||||
u->irace = new_race[RC_DRAGON];
|
u->irace = new_race[RC_DRAGON];
|
||||||
|
@ -43,7 +43,7 @@ age_firedragon(unit *u)
|
||||||
void
|
void
|
||||||
age_dragon(unit *u)
|
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);
|
double q = (double) u->hp / (double) (unit_max_hp(u) * u->number);
|
||||||
u->race = new_race[RC_WYRM];
|
u->race = new_race[RC_WYRM];
|
||||||
u->irace = new_race[RC_WYRM];
|
u->irace = new_race[RC_WYRM];
|
||||||
|
|
|
@ -4708,7 +4708,7 @@ sp_headache(castorder *co)
|
||||||
countspells(mage, 1);
|
countspells(mage, 1);
|
||||||
|
|
||||||
/* wenn kein Ziel gefunden, Zauber abbrechen */
|
/* 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 */
|
target = pa->param[0]->data.u; /* Zieleinheit */
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue