Fix a bug reporting DETROY messages to the correct unit.

Add missing not-null assertions before accessing function parameters.
Eliminate all of the PVS-Studio warnings.
This commit is contained in:
Enno Rehling 2015-07-07 00:49:12 +02:00
parent 05ec74f9ec
commit e25d3c8ed1
12 changed files with 253 additions and 245 deletions

View File

@ -746,8 +746,8 @@ static void cr_output_unit(FILE * F, const region * r, const faction * f,
const faction *sf;
const char *prefix;
assert(u);
if (!u || fval(u_race(u), RCF_INVISIBLE))
assert(u && u->number);
if (u != NULL || fval(u_race(u), RCF_INVISIBLE))
return;
if (!init) {
@ -755,11 +755,10 @@ static void cr_output_unit(FILE * F, const region * r, const faction * f,
itemcloak_ct = ct_find("itemcloak");
}
if (itemcloak_ct != NULL) {
itemcloak = curse_active(get_curse(u->attribs, itemcloak_ct)); //TODO: V595 http://www.viva64.com/en/V595 The 'u' pointer was utilized before it was verified against nullptr. Check lines: 758, 761.
curse * cu = get_curse(u->attribs, itemcloak_ct);
itemcloak = cu && curse_active(cu);
}
assert(u && u->number);
fprintf(F, "EINHEIT %d\n", u->no);
fprintf(F, "\"%s\";Name\n", unit_getname(u));
str = u_description(u, f->locale);

View File

@ -400,7 +400,6 @@ message * disband_men(int n, unit * u, struct order *ord) {
void give_unit(unit * u, unit * u2, order * ord)
{
region *r = u->region; //TODO: V595 http://www.viva64.com/en/V595 The 'u' pointer was utilized before it was verified against nullptr. Check lines: 403, 406.
int maxt = max_transfers();
assert(u);
@ -409,7 +408,7 @@ void give_unit(unit * u, unit * u2, order * ord)
return;
}
if (u && unit_has_cursed_item(u)) {
if (unit_has_cursed_item(u)) {
cmistake(u, ord, 78, MSG_COMMERCE);
return;
}
@ -424,6 +423,7 @@ void give_unit(unit * u, unit * u2, order * ord)
}
if (u2 == NULL) {
region *r = u->region;
message *msg;
if (fval(r->terrain, SEA_REGION)) {
msg = disband_men(u->number, u, ord);

View File

@ -332,10 +332,15 @@ potion_type *new_potiontype(item_type * itype, int level)
}
void it_set_appearance(item_type *itype, const char *appearance) {
assert(itype && itype->rtype && appearance);
itype->_appearance[0] = _strdup(appearance); //TODO: V595 http://www.viva64.com/en/V595 The 'appearance' pointer was utilized before it was verified against nullptr. Check lines: 336, 337.
itype->_appearance[1] = appearance ?
strcat(strcpy((char *)malloc(strlen((char *)appearance) + 3), (char *)appearance), "_p") : 0;
assert(itype);
assert(itype->rtype);
if (appearance) {
itype->_appearance[0] = _strdup(appearance);
itype->_appearance[1] = strcat(strcpy((char *)malloc(strlen((char *)appearance) + 3), (char *)appearance), "_p");
} else {
itype->_appearance[0] = 0;
itype->_appearance[1] = 0;
}
}
const resource_type *item2resource(const item_type * itype)

View File

@ -978,6 +978,9 @@ static region *readregion(struct gamedata *data, int x, int y)
void writeregion(struct gamedata *data, const region * r)
{
assert(r);
assert(data);
WRITE_INT(data->store, r->uid);
WRITE_STR(data->store, region_getinfo(r));
WRITE_TOK(data->store, r->terrain->_name);
@ -989,8 +992,8 @@ void writeregion(struct gamedata *data, const region * r)
struct demand *demand;
rawmaterial *res = r->resources;
assert(r->land);
WRITE_STR(data->store, (const char *)r->land->name); //TODO: V595 http://www.viva64.com/en/V595 The 'r->land' pointer was utilized before it was verified against nullptr. Check lines: 993, 1023.
assert(r->land);
WRITE_STR(data->store, (const char *)r->land->name);
assert(rtrees(r, 0) >= 0);
assert(rtrees(r, 1) >= 0);
assert(rtrees(r, 2) >= 0);
@ -1020,11 +1023,9 @@ void writeregion(struct gamedata *data, const region * r)
WRITE_INT(data->store, rherbs(r));
WRITE_INT(data->store, rpeasants(r));
WRITE_INT(data->store, rmoney(r));
if (r->land) {
for (demand = r->land->demands; demand; demand = demand->next) {
WRITE_TOK(data->store, resourcename(demand->type->itype->rtype, 0));
WRITE_INT(data->store, demand->value);
}
for (demand = r->land->demands; demand; demand = demand->next) {
WRITE_TOK(data->store, resourcename(demand->type->itype->rtype, 0));
WRITE_INT(data->store, demand->value);
}
WRITE_TOK(data->store, "end");
write_items(data->store, r->land->items);

View File

@ -1738,10 +1738,11 @@ int name_cmd(struct unit *u, struct order *ord)
}
else {
const struct locale *lang = locales;
size_t f_len = strlen(f->name);
for (; lang; lang = nextlocale(lang)) {
const char *fdname = LOC(lang, "factiondefault");
size_t fdlen = strlen(fdname);
if (strlen(f->name) >= fdlen && strncmp(f->name, fdname, fdlen) == 0) { //TODO: V814 http://www.viva64.com/en/V814 Decreased performance. The 'strlen' function was called multiple times inside the body of a loop.
if (f_len >= fdlen && strncmp(f->name, fdname, fdlen) == 0) {
break;
}
}
@ -1775,18 +1776,17 @@ int name_cmd(struct unit *u, struct order *ord)
}
else {
const struct locale *lang = locales;
size_t sh_len = strlen(sh->name);
for (; lang; lang = nextlocale(lang)) {
const char *sdname = LOC(lang, sh->type->_name);
size_t sdlen = strlen(sdname);
if (strlen(sh->name) >= sdlen //TODO: V814 http://www.viva64.com/en/V814 Decreased performance. The 'strlen' function was called multiple times inside the body of a loop.
&& strncmp(sh->name, sdname, sdlen) == 0) {
if (sh_len >= sdlen && strncmp(sh->name, sdname, sdlen) == 0) {
break;
}
sdname = LOC(lang, parameters[P_SHIP]);
sdlen = strlen(sdname);
if (strlen(sh->name) >= sdlen //TODO: V814 http://www.viva64.com/en/V814 Decreased performance. The 'strlen' function was called multiple times inside the body of a loop.
&& strncmp(sh->name, sdname, sdlen) == 0) {
if (sh_len >= sdlen && strncmp(sh->name, sdname, sdlen) == 0) {
break;
}
@ -2713,13 +2713,15 @@ void update_guards(void)
int guard_on_cmd(unit * u, struct order *ord)
{
assert(getkeyword(ord) == K_GUARD);
assert(u && u->faction);
assert(u);
assert(u->faction);
init_order(ord);
/* GUARD NOT is handled in goard_off_cmd earlier in the turn */
if (getparam(u->faction->locale) == P_NOT) //TODO: V595 http://www.viva64.com/en/V595 The 'u->faction' pointer was utilized before it was verified against nullptr. Check lines: 2721, 2737.
if (getparam(u->faction->locale) == P_NOT) {
return 0;
}
if (fval(u->region->terrain, SEA_REGION)) {
cmistake(u, ord, 2, MSG_EVENT);

View File

@ -1789,9 +1789,10 @@ static void free_spellparameter(spellparameter * pa)
{
int i;
/* Elemente free'en */
for (i = 0; i < pa->length; i++) {
assert(pa->param);
for (i = 0; i < pa->length; i++) {
assert(pa->param[i]);
switch (pa->param[i]->typ) {
case SPP_STRING:
free(pa->param[i]->data.s);
@ -1799,12 +1800,9 @@ static void free_spellparameter(spellparameter * pa)
default:
break;
}
free(pa->param[i]); //TODO: V595 http://www.viva64.com/en/V595 The 'pa->param' pointer was utilized before it was verified against nullptr. Check lines: 1802, 1805.
free(pa->param[i]);
}
if (pa->param)
free(pa->param);
/* struct free'en */
free(pa->param);
free(pa);
}

View File

@ -31,8 +31,7 @@ extern "C" {
void make_zombie(struct unit * u);
#define MONSTER_ID 666
#define is_monsters(f) (f && fval(f, FFL_NPC) && f==get_monsters())
#define is_monsters(f) (fval(f, FFL_NPC) && f==get_monsters())
#ifdef __cplusplus
}

View File

@ -840,7 +840,7 @@ bool see_border(const connection * b, const faction * f, const region * r)
static void describe(stream *out, const seen_region * sr, faction * f)
{
const region *r = sr->r;
const region *r;
int n;
bool dh;
direction_t d;
@ -862,6 +862,11 @@ static void describe(stream *out, const seen_region * sr, faction * f)
size_t size = sizeof(buf);
int bytes;
assert(out);
assert(f);
assert(sr);
r = sr->r;
for (d = 0; d != MAXDIRECTIONS; d++) {
/* Nachbarregionen, die gesehen werden, ermitteln */
region *r2 = rconnect(r, d);
@ -945,7 +950,7 @@ static void describe(stream *out, const seen_region * sr, faction * f)
bytes = (int)strlcpy(bufp, LOC(f->locale, "nr_tree"), size);
}
else {
bytes = (int)strlcpy(bufp, LOC(f->locale, "nr_tree_p"), size); //TODO: V595 http://www.viva64.com/en/V595 The 'f' pointer was utilized before it was verified against nullptr. Check lines: 948, 956.
bytes = (int)strlcpy(bufp, LOC(f->locale, "nr_tree_p"), size);
}
if (wrptr(&bufp, &size, bytes) != 0)
WARN_STATIC_BUFFER();
@ -953,7 +958,7 @@ static void describe(stream *out, const seen_region * sr, faction * f)
}
/* iron & stone */
if (sr->mode == see_unit && f != (faction *)NULL) {
if (sr->mode == see_unit) {
resource_report result[MAX_RAWMATERIALS];
int n, numresults = report_resources(sr, result, MAX_RAWMATERIALS, f);
@ -1410,7 +1415,6 @@ static void durchreisende(stream *out, const region * r, const faction * f)
}
}
}
/* TODO: finish localization */
if (size > 0) {
if (maxtravel == 1) {
bytes = _snprintf(bufp, size, " %s", LOC(f->locale, "has_moved_one"));

View File

@ -375,7 +375,7 @@ static int try_destruction(unit * u, unit * u2, const ship * sh, int skilldiff)
}
else if (skilldiff < 0) {
/* tell the unit that the attempt was detected: */
ADDMSG(&u2->faction->msgs, msg_message(destruction_detected_msg, //TODO: V595 http://www.viva64.com/en/V595 The 'u2' pointer was utilized before it was verified against nullptr. Check lines: 378, 381.
ADDMSG(&u->faction->msgs, msg_message(destruction_detected_msg,
"ship unit", sh, u));
/* tell the enemy whodunit: */
if (u2) {

View File

@ -542,6 +542,9 @@ int learn_cmd(unit * u, order * ord)
int maxalchemy = 0;
int speed_rule = (study_rule_t)get_param_int(global.parameters, "study.speedup", 0);
static int learn_newskills = -1;
struct building *b = inside_building(u);
const struct building_type *btype = b ? b->type : NULL;
if (learn_newskills < 0) {
const char *str = get_param(global.parameters, "study.newskills");
if (str && strcmp(str, "false") == 0)
@ -603,220 +606,217 @@ int learn_cmd(unit * u, order * ord)
return 0;
}
/* Akademie: */
{
struct building *b = inside_building(u);
const struct building_type *btype = b ? b->type : NULL;
b = inside_building(u);
btype = b ? b->type : NULL;
if (btype && btype == bt_find("academy")) {
studycost = _max(50, studycost * 2);
}
}
if (btype && btype == bt_find("academy")) {
studycost = _max(50, studycost * 2);
}
if (sk == SK_MAGIC) {
if (u->number > 1) {
cmistake(u, ord, 106, MSG_MAGIC);
return 0;
}
if (is_familiar(u)) {
/* Vertraute zaehlen nicht zu den Magiern einer Partei,
* koennen aber nur Graue Magie lernen */
mtyp = M_GRAY;
if (!is_mage(u))
create_mage(u, mtyp);
}
else if (!has_skill(u, SK_MAGIC)) {
int mmax = skill_limit(u->faction, SK_MAGIC);
/* Die Einheit ist noch kein Magier */
if (count_skill(u->faction, SK_MAGIC) + u->number > mmax) {
ADDMSG(&u->faction->msgs, msg_feedback(u, ord, "error_max_magicians",
"amount", mmax));
return 0;
}
mtyp = getmagicskill(u->faction->locale);
if (mtyp == M_NONE || mtyp == M_GRAY) {
/* wurde kein Magiegebiet angegeben, wird davon
* ausgegangen, dass das normal gelernt werden soll */
if (u->faction->magiegebiet != 0) {
mtyp = u->faction->magiegebiet;
}
else {
/* Es wurde kein Magiegebiet angegeben und die Partei
* hat noch keins gewaehlt. */
mtyp = getmagicskill(u->faction->locale);
if (mtyp == M_NONE) {
cmistake(u, ord, 178, MSG_MAGIC);
return 0;
}
}
}
if (mtyp != u->faction->magiegebiet) {
/* Es wurde versucht, ein anderes Magiegebiet zu lernen
* als das der Partei */
if (u->faction->magiegebiet != 0) {
cmistake(u, ord, 179, MSG_MAGIC);
return 0;
}
else {
/* Lernt zum ersten mal Magie und legt damit das
* Magiegebiet der Partei fest */
u->faction->magiegebiet = mtyp;
}
}
if (!is_mage(u))
create_mage(u, mtyp);
}
else {
/* ist schon ein Magier und kein Vertrauter */
if (u->faction->magiegebiet == 0) {
/* die Partei hat noch kein Magiegebiet gewaehlt. */
mtyp = getmagicskill(u->faction->locale);
if (mtyp == M_NONE) {
mtyp = getmagicskill(u->faction->locale);
if (mtyp == M_NONE) {
cmistake(u, ord, 178, MSG_MAGIC);
return 0;
}
}
/* Legt damit das Magiegebiet der Partei fest */
u->faction->magiegebiet = mtyp;
}
}
}
if (sk == SK_ALCHEMY) {
maxalchemy = eff_skill(u, SK_ALCHEMY, r);
if (!has_skill(u, SK_ALCHEMY)) {
int amax = skill_limit(u->faction, SK_ALCHEMY);
if (count_skill(u->faction, SK_ALCHEMY) + u->number > amax) {
ADDMSG(&u->faction->msgs, msg_feedback(u, ord, "error_max_alchemists",
"amount", amax));
return 0;
}
}
}
if (studycost) {
int cost = studycost * u->number;
money = get_pooled(u, get_resourcetype(R_SILVER), GET_DEFAULT, cost);
money = _min(money, cost);
}
if (money < studycost * u->number) {
studycost = p; /* Ohne Univertreurung */
money = _min(money, studycost);
if (p > 0 && money < studycost * u->number) {
cmistake(u, ord, 65, MSG_EVENT);
multi = money / (double)(studycost * u->number);
}
}
if (sk == SK_MAGIC) {
if (u->number > 1) {
cmistake(u, ord, 106, MSG_MAGIC);
return 0;
}
if (is_familiar(u)) {
/* Vertraute zaehlen nicht zu den Magiern einer Partei,
* koennen aber nur Graue Magie lernen */
mtyp = M_GRAY;
if (!is_mage(u))
create_mage(u, mtyp);
}
else if (!has_skill(u, SK_MAGIC)) {
int mmax = skill_limit(u->faction, SK_MAGIC);
/* Die Einheit ist noch kein Magier */
if (count_skill(u->faction, SK_MAGIC) + u->number > mmax) {
ADDMSG(&u->faction->msgs, msg_feedback(u, ord, "error_max_magicians",
"amount", mmax));
return 0;
}
mtyp = getmagicskill(u->faction->locale);
if (mtyp == M_NONE || mtyp == M_GRAY) {
/* wurde kein Magiegebiet angegeben, wird davon
* ausgegangen, dass das normal gelernt werden soll */
if (u->faction->magiegebiet != 0) {
mtyp = u->faction->magiegebiet;
}
else {
/* Es wurde kein Magiegebiet angegeben und die Partei
* hat noch keins gewaehlt. */
mtyp = getmagicskill(u->faction->locale);
if (mtyp == M_NONE) {
cmistake(u, ord, 178, MSG_MAGIC);
return 0;
}
}
}
if (mtyp != u->faction->magiegebiet) {
/* Es wurde versucht, ein anderes Magiegebiet zu lernen
* als das der Partei */
if (u->faction->magiegebiet != 0) {
cmistake(u, ord, 179, MSG_MAGIC);
return 0;
}
else {
/* Lernt zum ersten mal Magie und legt damit das
* Magiegebiet der Partei fest */
u->faction->magiegebiet = mtyp;
}
}
if (!is_mage(u))
create_mage(u, mtyp);
}
else {
/* ist schon ein Magier und kein Vertrauter */
if (u->faction->magiegebiet == 0) {
/* die Partei hat noch kein Magiegebiet gewaehlt. */
mtyp = getmagicskill(u->faction->locale);
if (mtyp == M_NONE) {
mtyp = getmagicskill(u->faction->locale);
if (mtyp == M_NONE) {
cmistake(u, ord, 178, MSG_MAGIC);
return 0;
}
}
/* Legt damit das Magiegebiet der Partei fest */
u->faction->magiegebiet = mtyp;
}
}
}
if (sk == SK_ALCHEMY) {
maxalchemy = eff_skill(u, SK_ALCHEMY, r);
if (!has_skill(u, SK_ALCHEMY)) {
int amax = skill_limit(u->faction, SK_ALCHEMY);
if (count_skill(u->faction, SK_ALCHEMY) + u->number > amax) {
ADDMSG(&u->faction->msgs, msg_feedback(u, ord, "error_max_alchemists",
"amount", amax));
return 0;
}
}
}
if (studycost) {
int cost = studycost * u->number;
money = get_pooled(u, get_resourcetype(R_SILVER), GET_DEFAULT, cost);
money = _min(money, cost);
}
if (money < studycost * u->number) {
studycost = p; /* Ohne Univertreurung */
money = _min(money, studycost);
if (p > 0 && money < studycost * u->number) {
cmistake(u, ord, 65, MSG_EVENT);
multi = money / (double)(studycost * u->number);
}
}
if (teach == NULL) {
a = a_add(&u->attribs, a_new(&at_learning));
teach = (teaching_info *)a->data.v;
teach->teachers[0] = 0;
}
if (money > 0) {
use_pooled(u, get_resourcetype(R_SILVER), GET_DEFAULT, money);
ADDMSG(&u->faction->msgs, msg_message("studycost",
"unit region cost skill", u, u->region, money, sk));
}
if (teach == NULL) {
a = a_add(&u->attribs, a_new(&at_learning));
teach = (teaching_info *)a->data.v;
assert(teach);
teach->teachers[0] = 0;
}
if (money > 0) {
use_pooled(u, get_resourcetype(R_SILVER), GET_DEFAULT, money);
ADDMSG(&u->faction->msgs, msg_message("studycost",
"unit region cost skill", u, u->region, money, sk));
}
if (get_effect(u, oldpotiontype[P_WISE])) {
l = _min(u->number, get_effect(u, oldpotiontype[P_WISE]));
teach->value += l * 10;
change_effect(u, oldpotiontype[P_WISE], -l);
}
if (get_effect(u, oldpotiontype[P_FOOL])) {
l = _min(u->number, get_effect(u, oldpotiontype[P_FOOL]));
teach->value -= l * 30;
change_effect(u, oldpotiontype[P_FOOL], -l);
}
if (get_effect(u, oldpotiontype[P_WISE])) {
l = _min(u->number, get_effect(u, oldpotiontype[P_WISE]));
teach->value += l * 10;
change_effect(u, oldpotiontype[P_WISE], -l);
}
if (get_effect(u, oldpotiontype[P_FOOL])) {
l = _min(u->number, get_effect(u, oldpotiontype[P_FOOL]));
teach->value -= l * 30;
change_effect(u, oldpotiontype[P_FOOL], -l);
}
if (p != studycost) {
/* ist_in_gebaeude(r, u, BT_UNIVERSITAET) == 1) { */
/* p ist Kosten ohne Uni, studycost mit; wenn
* p!=studycost, ist die Einheit zwangsweise
* in einer Uni */
teach->value += u->number * 10;
}
if (p != studycost) {
/* ist_in_gebaeude(r, u, BT_UNIVERSITAET) == 1) { */
/* p ist Kosten ohne Uni, studycost mit; wenn
* p!=studycost, ist die Einheit zwangsweise
* in einer Uni */
teach->value += u->number * 10;
}
if (is_cursed(r->attribs, C_BADLEARN, 0)) {
teach->value -= u->number * 10;
}
if (is_cursed(r->attribs, C_BADLEARN, 0)) {
teach->value -= u->number * 10;
}
multi *= study_speedup(u, sk, speed_rule);
days = study_days(u, sk);
days = (int)((days + teach->value) * multi); //TODO: V595 http://www.viva64.com/en/V595 The 'teach' pointer was utilized before it was verified against nullptr. Check lines: 746, 772.
multi *= study_speedup(u, sk, speed_rule);
days = study_days(u, sk);
days = (int)((days + teach->value) * multi);
/* the artacademy currently improves the learning of entertainment
of all units in the region, to be able to make it cumulative with
with an academy */
/* the artacademy currently improves the learning of entertainment
of all units in the region, to be able to make it cumulative with
with an academy */
if (sk == SK_ENTERTAINMENT
&& buildingtype_exists(r, bt_find("artacademy"), false)) {
days *= 2;
}
if (sk == SK_ENTERTAINMENT
&& buildingtype_exists(r, bt_find("artacademy"), false)) {
days *= 2;
}
if (fval(u, UFL_HUNGER))
days /= 2;
if (fval(u, UFL_HUNGER))
days /= 2;
while (days) {
if (days >= u->number * 30) {
learn_skill(u, sk, 1.0);
days -= u->number * 30;
}
else {
double chance = (double)days / u->number / 30;
learn_skill(u, sk, chance);
days = 0;
}
}
if (a != NULL) {
if (teach != NULL) {
int index = 0;
while (teach->teachers[index] && index != MAXTEACHERS) {
unit *teacher = teach->teachers[index++];
if (teacher->faction != u->faction) {
bool feedback = alliedunit(u, teacher->faction, HELP_GUARD);
if (feedback) {
ADDMSG(&teacher->faction->msgs, msg_message("teach_teacher",
"teacher student skill level", teacher, u, sk,
effskill(u, sk)));
}
ADDMSG(&u->faction->msgs, msg_message("teach_student",
"teacher student skill", teacher, u, sk));
}
}
}
a_remove(&u->attribs, a);
a = NULL;
}
fset(u, UFL_LONGACTION | UFL_NOTMOVING);
while (days) {
if (days >= u->number * 30) {
learn_skill(u, sk, 1.0);
days -= u->number * 30;
}
else {
double chance = (double)days / u->number / 30;
learn_skill(u, sk, chance);
days = 0;
}
}
if (a != NULL) {
int index = 0;
while (teach->teachers[index] && index != MAXTEACHERS) {
unit *teacher = teach->teachers[index++];
if (teacher->faction != u->faction) {
bool feedback = alliedunit(u, teacher->faction, HELP_GUARD);
if (feedback) {
ADDMSG(&teacher->faction->msgs, msg_message("teach_teacher",
"teacher student skill level", teacher, u, sk,
effskill(u, sk)));
}
ADDMSG(&u->faction->msgs, msg_message("teach_student",
"teacher student skill", teacher, u, sk));
}
}
a_remove(&u->attribs, a);
a = NULL;
}
fset(u, UFL_LONGACTION | UFL_NOTMOVING);
/* Anzeigen neuer Traenke */
/* Spruchlistenaktualiesierung ist in Regeneration */
/* Anzeigen neuer Traenke */
/* Spruchlistenaktualiesierung ist in Regeneration */
if (sk == SK_ALCHEMY) {
const potion_type *ptype;
faction *f = u->faction;
int skill = eff_skill(u, SK_ALCHEMY, r);
if (skill > maxalchemy) {
for (ptype = potiontypes; ptype; ptype = ptype->next) {
if (skill == ptype->level * 2) {
attrib *a = a_find(f->attribs, &at_showitem);
while (a && a->type == &at_showitem && a->data.v != ptype)
a = a->next;
if (a == NULL || a->type != &at_showitem) {
a = a_add(&f->attribs, a_new(&at_showitem));
a->data.v = (void *)ptype->itype;
}
}
}
}
}
else if (sk == SK_MAGIC) {
sc_mage *mage = get_mage(u);
if (!mage) {
mage = create_mage(u, u->faction->magiegebiet);
}
}
if (sk == SK_ALCHEMY) {
const potion_type *ptype;
faction *f = u->faction;
int skill = eff_skill(u, SK_ALCHEMY, r);
if (skill > maxalchemy) {
for (ptype = potiontypes; ptype; ptype = ptype->next) {
if (skill == ptype->level * 2) {
attrib *a = a_find(f->attribs, &at_showitem);
while (a && a->type == &at_showitem && a->data.v != ptype)
a = a->next;
if (a == NULL || a->type != &at_showitem) {
a = a_add(&f->attribs, a_new(&at_showitem));
a->data.v = (void *)ptype->itype;
}
}
}
}
}
else if (sk == SK_MAGIC) {
sc_mage *mage = get_mage(u);
if (!mage) {
mage = create_mage(u, u->faction->magiegebiet);
}
}
return 0;
return 0;
}

View File

@ -356,7 +356,7 @@ summary *make_summary(void)
const struct resource_type *rhorse = get_resourcetype(R_HORSE);
for (f = factions; f; f = f->next) {
const struct locale *lang = f->locale; //TODO: V595 http://www.viva64.com/en/V595 The 'f' pointer was utilized before it was verified against nullptr. Check lines: 359, 376.
const struct locale *lang = f->locale;
struct language *plang = s->languages;
while (plang && plang->locale != lang)
plang = plang->next;

View File

@ -110,11 +110,11 @@ const attrib *a_findc(const attrib * a, const attrib_type * at)
static attrib *a_insert(attrib * head, attrib * a)
{
attrib **pa = &head->next; //TODO: V595 http://www.viva64.com/en/V595 The 'head' pointer was utilized before it was verified against nullptr. Check lines: 113, 116.
attrib **pa;
assert(!(a->type->flags & ATF_UNIQUE));
assert(head && head->type == a->type);
pa = &head->next;
while (*pa && (*pa)->type == a->type) {
pa = &(*pa)->next;
}