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 struct locale * lang = u->faction->locale;
|
||||
|
||||
if (u->number==NULL) return;
|
||||
|
||||
init_tokens(ord);
|
||||
skip_token();
|
||||
s = getstrtoken();
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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)) {
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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++) {
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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];
|
||||
|
|
|
@ -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 */
|
||||
|
||||
|
|
Loading…
Reference in New Issue