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 faction *sf;
const char *prefix; const char *prefix;
assert(u); assert(u && u->number);
if (!u || fval(u_race(u), RCF_INVISIBLE)) if (u != NULL || fval(u_race(u), RCF_INVISIBLE))
return; return;
if (!init) { if (!init) {
@ -755,11 +755,10 @@ static void cr_output_unit(FILE * F, const region * r, const faction * f,
itemcloak_ct = ct_find("itemcloak"); itemcloak_ct = ct_find("itemcloak");
} }
if (itemcloak_ct != NULL) { 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, "EINHEIT %d\n", u->no);
fprintf(F, "\"%s\";Name\n", unit_getname(u)); fprintf(F, "\"%s\";Name\n", unit_getname(u));
str = u_description(u, f->locale); 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) 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(); int maxt = max_transfers();
assert(u); assert(u);
@ -409,7 +408,7 @@ void give_unit(unit * u, unit * u2, order * ord)
return; return;
} }
if (u && unit_has_cursed_item(u)) { if (unit_has_cursed_item(u)) {
cmistake(u, ord, 78, MSG_COMMERCE); cmistake(u, ord, 78, MSG_COMMERCE);
return; return;
} }
@ -424,6 +423,7 @@ void give_unit(unit * u, unit * u2, order * ord)
} }
if (u2 == NULL) { if (u2 == NULL) {
region *r = u->region;
message *msg; message *msg;
if (fval(r->terrain, SEA_REGION)) { if (fval(r->terrain, SEA_REGION)) {
msg = disband_men(u->number, u, ord); 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) { void it_set_appearance(item_type *itype, const char *appearance) {
assert(itype && itype->rtype && appearance); assert(itype);
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. assert(itype->rtype);
itype->_appearance[1] = appearance ? if (appearance) {
strcat(strcpy((char *)malloc(strlen((char *)appearance) + 3), (char *)appearance), "_p") : 0; 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) 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) void writeregion(struct gamedata *data, const region * r)
{ {
assert(r);
assert(data);
WRITE_INT(data->store, r->uid); WRITE_INT(data->store, r->uid);
WRITE_STR(data->store, region_getinfo(r)); WRITE_STR(data->store, region_getinfo(r));
WRITE_TOK(data->store, r->terrain->_name); WRITE_TOK(data->store, r->terrain->_name);
@ -989,8 +992,8 @@ void writeregion(struct gamedata *data, const region * r)
struct demand *demand; struct demand *demand;
rawmaterial *res = r->resources; rawmaterial *res = r->resources;
assert(r->land); 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. WRITE_STR(data->store, (const char *)r->land->name);
assert(rtrees(r, 0) >= 0); assert(rtrees(r, 0) >= 0);
assert(rtrees(r, 1) >= 0); assert(rtrees(r, 1) >= 0);
assert(rtrees(r, 2) >= 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, rherbs(r));
WRITE_INT(data->store, rpeasants(r)); WRITE_INT(data->store, rpeasants(r));
WRITE_INT(data->store, rmoney(r)); WRITE_INT(data->store, rmoney(r));
if (r->land) { for (demand = r->land->demands; demand; demand = demand->next) {
for (demand = r->land->demands; demand; demand = demand->next) { WRITE_TOK(data->store, resourcename(demand->type->itype->rtype, 0));
WRITE_TOK(data->store, resourcename(demand->type->itype->rtype, 0)); WRITE_INT(data->store, demand->value);
WRITE_INT(data->store, demand->value);
}
} }
WRITE_TOK(data->store, "end"); WRITE_TOK(data->store, "end");
write_items(data->store, r->land->items); write_items(data->store, r->land->items);

View file

@ -1738,10 +1738,11 @@ int name_cmd(struct unit *u, struct order *ord)
} }
else { else {
const struct locale *lang = locales; const struct locale *lang = locales;
size_t f_len = strlen(f->name);
for (; lang; lang = nextlocale(lang)) { for (; lang; lang = nextlocale(lang)) {
const char *fdname = LOC(lang, "factiondefault"); const char *fdname = LOC(lang, "factiondefault");
size_t fdlen = strlen(fdname); 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; break;
} }
} }
@ -1775,18 +1776,17 @@ int name_cmd(struct unit *u, struct order *ord)
} }
else { else {
const struct locale *lang = locales; const struct locale *lang = locales;
size_t sh_len = strlen(sh->name);
for (; lang; lang = nextlocale(lang)) { for (; lang; lang = nextlocale(lang)) {
const char *sdname = LOC(lang, sh->type->_name); const char *sdname = LOC(lang, sh->type->_name);
size_t sdlen = strlen(sdname); 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. if (sh_len >= sdlen && strncmp(sh->name, sdname, sdlen) == 0) {
&& strncmp(sh->name, sdname, sdlen) == 0) {
break; break;
} }
sdname = LOC(lang, parameters[P_SHIP]); sdname = LOC(lang, parameters[P_SHIP]);
sdlen = strlen(sdname); 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. if (sh_len >= sdlen && strncmp(sh->name, sdname, sdlen) == 0) {
&& strncmp(sh->name, sdname, sdlen) == 0) {
break; break;
} }
@ -2713,13 +2713,15 @@ void update_guards(void)
int guard_on_cmd(unit * u, struct order *ord) int guard_on_cmd(unit * u, struct order *ord)
{ {
assert(getkeyword(ord) == K_GUARD); assert(getkeyword(ord) == K_GUARD);
assert(u && u->faction); assert(u);
assert(u->faction);
init_order(ord); init_order(ord);
/* GUARD NOT is handled in goard_off_cmd earlier in the turn */ /* 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; return 0;
}
if (fval(u->region->terrain, SEA_REGION)) { if (fval(u->region->terrain, SEA_REGION)) {
cmistake(u, ord, 2, MSG_EVENT); cmistake(u, ord, 2, MSG_EVENT);

View file

@ -1789,9 +1789,10 @@ static void free_spellparameter(spellparameter * pa)
{ {
int i; int i;
/* Elemente free'en */ assert(pa->param);
for (i = 0; i < pa->length; i++) {
for (i = 0; i < pa->length; i++) {
assert(pa->param[i]);
switch (pa->param[i]->typ) { switch (pa->param[i]->typ) {
case SPP_STRING: case SPP_STRING:
free(pa->param[i]->data.s); free(pa->param[i]->data.s);
@ -1799,12 +1800,9 @@ static void free_spellparameter(spellparameter * pa)
default: default:
break; 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]);
} }
free(pa->param);
if (pa->param)
free(pa->param);
/* struct free'en */
free(pa); free(pa);
} }

View file

@ -31,8 +31,7 @@ extern "C" {
void make_zombie(struct unit * u); void make_zombie(struct unit * u);
#define MONSTER_ID 666 #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 #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) static void describe(stream *out, const seen_region * sr, faction * f)
{ {
const region *r = sr->r; const region *r;
int n; int n;
bool dh; bool dh;
direction_t d; direction_t d;
@ -862,6 +862,11 @@ static void describe(stream *out, const seen_region * sr, faction * f)
size_t size = sizeof(buf); size_t size = sizeof(buf);
int bytes; int bytes;
assert(out);
assert(f);
assert(sr);
r = sr->r;
for (d = 0; d != MAXDIRECTIONS; d++) { for (d = 0; d != MAXDIRECTIONS; d++) {
/* Nachbarregionen, die gesehen werden, ermitteln */ /* Nachbarregionen, die gesehen werden, ermitteln */
region *r2 = rconnect(r, d); 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); bytes = (int)strlcpy(bufp, LOC(f->locale, "nr_tree"), size);
} }
else { 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) if (wrptr(&bufp, &size, bytes) != 0)
WARN_STATIC_BUFFER(); WARN_STATIC_BUFFER();
@ -953,7 +958,7 @@ static void describe(stream *out, const seen_region * sr, faction * f)
} }
/* iron & stone */ /* iron & stone */
if (sr->mode == see_unit && f != (faction *)NULL) { if (sr->mode == see_unit) {
resource_report result[MAX_RAWMATERIALS]; resource_report result[MAX_RAWMATERIALS];
int n, numresults = report_resources(sr, result, MAX_RAWMATERIALS, f); 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 (size > 0) {
if (maxtravel == 1) { if (maxtravel == 1) {
bytes = _snprintf(bufp, size, " %s", LOC(f->locale, "has_moved_one")); 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) { else if (skilldiff < 0) {
/* tell the unit that the attempt was detected: */ /* 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)); "ship unit", sh, u));
/* tell the enemy whodunit: */ /* tell the enemy whodunit: */
if (u2) { if (u2) {

View file

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