Merge branch 'develop' into order_id

This commit is contained in:
Enno Rehling 2017-11-20 18:23:33 +01:00
commit 67318950d5
20 changed files with 92 additions and 77 deletions

View File

@ -13,6 +13,7 @@ addons:
- libsqlite3-dev
- libxml2-dev
- valgrind
- cppcheck
os:
- linux
notifications:

View File

@ -22,6 +22,8 @@ s/cmake-init
s/build
cd $ROOT
inifile
cppcheck --version
cppcheck --quiet --error-exitcode=1 src
s/runtests -V
integration_tests

View File

@ -135,7 +135,13 @@ static void dict_upgrade(attrib **alist, attrib *abegin) {
assert(!"invalid input");
}
if (i == 4) {
keys = realloc(keys, sizeof(int) * (n + i + 1));
int *k;
k = realloc(keys, sizeof(int) * (n + i + 1));
if (!k) {
free(keys);
abort();
}
keys = k;
memcpy(keys + n + 1, val, sizeof(val));
n += i;
i = 0;

View File

@ -123,8 +123,14 @@ static int a_readkeys(attrib * a, void *owner, gamedata *data) {
if (e != n) {
int sz = keys_size(n);
if (e > sz) {
int *k;
sz = keys_size(e);
keys = realloc(keys, sizeof(int)*(2 * sz + 1));
k = realloc(keys, sizeof(int)*(2 * sz + 1));
if (!k) {
free(keys);
abort();
}
keys = k;
keys[0] = e;
}
}

View File

@ -30,5 +30,6 @@ extern "C"
extern const char * directions[];
#ifdef __cplusplus
}
#endif
#endif

View File

@ -217,7 +217,7 @@ static unit *setup_trade_unit(CuTest *tc, region *r, const struct race *rc) {
}
static void test_trade_insect(CuTest *tc) {
/* Insekten können in Wüsten und Sümpfen auch ohne Burgen handeln. */
/* Insekten k<EFBFBD>nnen in W<>sten und S<>mpfen auch ohne Burgen handeln. */
unit *u;
region *r;
const item_type *it_luxury;
@ -239,6 +239,8 @@ static void test_trade_insect(CuTest *tc) {
LOC(u->faction->locale, resourcename(it_luxury->rtype, 0))));
set_item(u, it_silver, 10);
CuAssertPtrEquals(tc, r, u->region);
CuAssertPtrEquals(tc, (void *)it_luxury, (void *)r_luxury(u->region));
produce(u->region);
CuAssertIntEquals(tc, 1, get_item(u, it_luxury));
CuAssertIntEquals(tc, 5, get_item(u, it_silver));

View File

@ -89,7 +89,8 @@ alliance *new_alliance(int id, const char *name) {
al->flags |= ALF_NON_ALLIED;
}
al->next = alliances;
return alliances = al;
alliances = al;
return al;
}
alliance *findalliance(int id)

View File

@ -207,7 +207,7 @@ static void test_build_building_with_golem(CuTest *tc) {
const building_type *btype;
u = setup_build(&bf);
bf.rc->flags |= RCF_STONEGOLEM;
bf.rc->ec_flags |= ECF_STONEGOLEM;
btype = bt_find("castle");
assert(btype);
assert(btype->construction);

View File

@ -105,10 +105,10 @@ static int res_changepeasants(unit * u, const resource_type * rtype, int delta)
}
static int golem_factor(const unit *u, const resource_type *rtype) {
if (rtype == get_resourcetype(R_STONE) && (u_race(u)->flags & RCF_STONEGOLEM)) {
if (rtype == get_resourcetype(R_STONE) && (u_race(u)->ec_flags & ECF_STONEGOLEM)) {
return GOLEM_STONE;
}
if (rtype == get_resourcetype(R_IRON) && (u_race(u)->flags & RCF_IRONGOLEM)) {
if (rtype == get_resourcetype(R_IRON) && (u_race(u)->ec_flags & ECF_IRONGOLEM)) {
return GOLEM_IRON;
}
return 0;
@ -340,8 +340,10 @@ void it_set_appearance(item_type *itype, const char *appearance) {
assert(itype);
assert(itype->rtype);
if (appearance) {
char plural[32];
itype->_appearance[0] = strdup(appearance);
itype->_appearance[1] = strcat(strcpy((char *)malloc(strlen((char *)appearance) + 3), (char *)appearance), "_p");
snprintf(plural, sizeof(plural), "%s_p", appearance);
itype->_appearance[1] = strdup(plural);
} else {
itype->_appearance[0] = 0;
itype->_appearance[1] = 0;
@ -665,7 +667,7 @@ static int
mod_dwarves_only(const unit * u, const region * r, skill_t sk, int value)
{
UNUSED_ARG(r);
if (u_race(u) == get_race(RC_DWARF) || (u_race(u)->flags & RCF_IRONGOLEM)) {
if (u_race(u) == get_race(RC_DWARF) || (u_race(u)->ec_flags & ECF_IRONGOLEM)) {
return value;
}
return -118;

View File

@ -199,14 +199,11 @@ static int create_data(keyword_t kwd, const char *s,
return id;
}
static order *create_order_i(order *ord, const struct locale *lang,
keyword_t kwd, const char *sptr, bool persistent, bool noerror)
static void create_order_i(order *ord, keyword_t kwd, const char *sptr, bool persistent,
bool noerror, const struct locale *lang)
{
assert(ord);
if (kwd == NOKEYWORD || keyword_disabled(kwd)) {
log_error("trying to create an order for disabled keyword %s.", keyword(kwd));
return NULL;
}
assert(kwd != NOKEYWORD && !keyword_disabled(kwd));
ord->command = (int)kwd;
if (persistent) ord->command |= CMD_PERSIST;
@ -216,7 +213,6 @@ static order *create_order_i(order *ord, const struct locale *lang,
while (isspace(*(unsigned char *)sptr)) ++sptr;
ord->id = create_data(kwd, sptr, lang);
return ord;
}
order *create_order(keyword_t kwd, const struct locale * lang,
@ -274,10 +270,7 @@ order *create_order(keyword_t kwd, const struct locale * lang,
zBuffer[0] = 0;
}
ord = (order *)malloc(sizeof(order));
if (create_order_i(ord, lang, kwd, zBuffer, false, false) == NULL) {
free(ord);
return NULL;
}
create_order_i(ord, kwd, zBuffer, false, false, lang);
return ord;
}
@ -310,11 +303,7 @@ order *parse_order(const char *s, const struct locale * lang)
}
if (kwd != NOKEYWORD) {
order *ord = (order *)malloc(sizeof(order));
if (create_order_i(ord, lang, kwd, sptr, persistent, noerror)
== NULL) {
free(ord);
return NULL;
}
create_order_i(ord, kwd, sptr, persistent, noerror, lang);
return ord;
}
}

View File

@ -88,9 +88,9 @@ int get_reservation(const unit * u, const item_type * itype)
{
reservation *res = u->reservations;
if (itype->rtype == get_resourcetype(R_STONE) && (u_race(u)->flags & RCF_STONEGOLEM))
if (itype->rtype == get_resourcetype(R_STONE) && (u_race(u)->ec_flags & ECF_STONEGOLEM))
return (u->number * GOLEM_STONE);
if (itype->rtype == get_resourcetype(R_IRON) && (u_race(u)->flags & RCF_IRONGOLEM))
if (itype->rtype == get_resourcetype(R_IRON) && (u_race(u)->ec_flags & ECF_IRONGOLEM))
return (u->number * GOLEM_IRON);
while (res && res->type != itype)
res = res->next;

View File

@ -106,17 +106,18 @@ static void rc_setoption(race *rc, int k, const char *value) {
rc->options->key[1] = RCO_NONE;
v = rc->options->value;
} else {
for (i=0;!v && i < MAXOPTIONS && rc->options->key[i]!=RCO_NONE;++i) {
for (i=0;!v && i < MAXOPTIONS;++i) {
if (rc->options->key[i]==key) {
v = rc->options->value+i;
break;
}
}
if (!v) {
assert(i<MAXOPTIONS || !"MAXOPTIONS too small for race");
v = rc->options->value+i;
rc->options->key[i] = key;
if (i+1<MAXOPTIONS) {
rc->options->key[i+1]=RCO_NONE;
if (rc->options->key[i]==RCO_NONE) {
v = rc->options->value+i;
rc->options->key[i] = key;
if (i+1 < MAXOPTIONS) {
rc->options->key[i+1]=RCO_NONE;
}
break;
}
}
}

View File

@ -226,11 +226,9 @@ extern "C" {
#define RCF_CANSAIL (1<<24) /* Einheit darf Schiffe betreten */
#define RCF_INVISIBLE (1<<25) /* not visible in any report */
#define RCF_SHIPSPEED (1<<26) /* race gets +1 on shipspeed */
#define RCF_STONEGOLEM (1<<27) /* race gets stonegolem properties */
#define RCF_IRONGOLEM (1<<28) /* race gets irongolem properties */
#define RCF_MIGRANTS (1<<27) /* may have migrant units (human bonus) */
#define RCF_FAMILIAR (1<<28) /* may be a familiar */
#define RCF_ATTACK_MOVED (1<<29) /* may attack if it has moved */
#define RCF_MIGRANTS (1<<30) /* may have migrant units (human bonus) */
#define RCF_FAMILIAR (1<<31) /* may be a familiar */
/* Economic flags */
#define ECF_GIVEPERSON (1<<2) /* <20>bergibt Personen */
@ -238,6 +236,8 @@ extern "C" {
#define ECF_GETITEM (1<<4) /* nimmt Gegenst<73>nde an */
#define ECF_REC_ETHEREAL (1<<7) /* Rekrutiert aus dem Nichts */
#define ECF_REC_UNLIMITED (1<<8) /* Rekrutiert ohne Limit */
#define ECF_STONEGOLEM (1<<9) /* race gets stonegolem properties */
#define ECF_IRONGOLEM (1<<10) /* race gets irongolem properties */
/* Battle-Flags */
#define BF_EQUIPMENT (1<<0) /* Kann Ausr<73>stung benutzen */

View File

@ -1434,10 +1434,6 @@ static int parse_races(xmlDocPtr doc)
rc->flags |= RCF_DRAGON;
if (xml_bvalue(node, "shipspeed", false))
rc->flags |= RCF_SHIPSPEED;
if (xml_bvalue(node, "stonegolem", false))
rc->flags |= RCF_STONEGOLEM;
if (xml_bvalue(node, "irongolem", false))
rc->flags |= RCF_IRONGOLEM;
if (xml_bvalue(node, "giveperson", false))
rc->ec_flags |= ECF_GIVEPERSON;
@ -1449,6 +1445,10 @@ static int parse_races(xmlDocPtr doc)
rc->ec_flags |= ECF_REC_ETHEREAL;
if (xml_bvalue(node, "recruitunlimited", false))
rc->ec_flags |= ECF_REC_UNLIMITED;
if (xml_bvalue(node, "stonegolem", false))
rc->ec_flags |= ECF_STONEGOLEM;
if (xml_bvalue(node, "irongolem", false))
rc->ec_flags |= ECF_IRONGOLEM;
if (xml_bvalue(node, "equipment", false))
rc->battle_flags |= BF_EQUIPMENT; /* TODO: invert this flag, so rc_get_or_create gets simpler */

View File

@ -87,5 +87,6 @@ extern "C"
const char *keyword(keyword_t kwd);
#ifdef __cplusplus
}
#endif
#endif

View File

@ -155,7 +155,7 @@ newfaction *read_newfactions(const char *filename)
email[0] = '\0';
password[0] = '\0';
if (sscanf(buf, "%54s %20s %8s %16s %d %d", email, race, lang,
if (sscanf(buf, "%54s %19s %7s %15s %d %d", email, race, lang,
password, &subscription, &alliance) < 3) {
break;
}

View File

@ -9,7 +9,7 @@
* based on:
*
* Atlantis v1.0 13 September 1993 Copyright 1993 by Russell Wallace
* Atlantis v1.7 Copyright 1996 by Alex Schröder
* Atlantis v1.7 Copyright 1996 by Alex Schr<EFBFBD>der
*
* This program may not be used, modified or distributed without
* prior permission by the authors of Eressea.
@ -74,7 +74,7 @@
#include <string.h>
#include <assert.h>
#define DRAGON_RANGE 20 /* max. Distanz zum nächsten Drachenziel */
#define DRAGON_RANGE 20 /* max. Distanz zum n<EFBFBD>chsten Drachenziel */
#define MOVE_PERCENT 25 /* chance fuer bewegung */
#define MAXILLUSION_TEXTS 3
@ -359,11 +359,11 @@ static direction_t random_neighbour(region * r, unit * u)
}
}
/* Zufällig eine auswählen */
/* Zuf<EFBFBD>llig eine ausw<73>hlen */
rr = rng_int() % c;
/* Durchzählen */
/* Durchz<EFBFBD>hlen */
c = 0;
for (i = 0; i != MAXDIRECTIONS; i++) {
@ -400,11 +400,11 @@ static direction_t treeman_neighbour(region * r)
if (c == 0) {
return NODIRECTION;
}
/* Zufällig eine auswählen */
/* Zuf<EFBFBD>llig eine ausw<73>hlen */
rr = rng_int() % c;
/* Durchzählen */
/* Durchz<EFBFBD>hlen */
c = -1;
for (i = 0; i != MAXDIRECTIONS; i++) {
@ -559,7 +559,7 @@ static order *monster_learn(unit * u)
return NULL;
}
/* Monster lernt ein zufälliges Talent aus allen, in denen es schon
/* Monster lernt ein zuf<EFBFBD>lliges Talent aus allen, in denen es schon
* Lerntage hat. */
for (sv = u->skills; sv != u->skills + u->skill_size; ++sv) {
if (sv->level > 0)
@ -605,7 +605,6 @@ static void recruit_dracoids(unit * dragon, int size)
faction *f = dragon->faction;
region *r = dragon->region;
const struct item *weapon = NULL;
order *new_order = NULL;
unit *un = create_unit(r, f, size, get_race(RC_DRACOID), 0, NULL, NULL);
fset(un, UFL_ISNEW | UFL_MOVED);
@ -617,15 +616,10 @@ static void recruit_dracoids(unit * dragon, int size)
setstatus(un, ST_FIGHT);
for (weapon = un->items; weapon; weapon = weapon->next) {
const weapon_type *wtype = weapon->type->rtype->wtype;
if (wtype && (wtype->flags & WTF_MISSILE)) {
if (wtype && wtype->flags & WTF_MISSILE) {
setstatus(un, ST_BEHIND);
break;
}
new_order = create_order(K_STUDY, f->locale, "'%s'",
skillname(weapon->type->rtype->wtype->skill, f->locale));
}
if (new_order != NULL) {
addlist(&un->orders, new_order);
}
}
@ -653,7 +647,7 @@ static order *plan_dragon(unit * u)
if (rc == rc_wyrm && !move) {
unit *u2;
for (u2 = r->units; u2; u2 = u2->next) {
/* wyrme sind einzelgänger */
/* wyrme sind einzelg<EFBFBD>nger */
if (u2 == u) {
/* we do not make room for newcomers, so we don't need to look at them */
break;
@ -750,11 +744,11 @@ void plan_monsters(faction * f)
attrib *ta;
order *long_order = NULL;
/* Ab hier nur noch Befehle für NPC-Einheiten. */
/* Ab hier nur noch Befehle f<EFBFBD>r NPC-Einheiten. */
if (u->faction!=f)
continue;
/* Befehle müssen jede Runde neu gegeben werden: */
/* Befehle m<EFBFBD>ssen jede Runde neu gegeben werden: */
free_orders(&u->orders);
if (skill_enabled(SK_PERCEPTION)) {
/* Monster bekommen jede Runde ein paar Tage Wahrnehmung dazu */
@ -823,7 +817,7 @@ void plan_monsters(faction * f)
}
}
if (long_order == NULL && unit_can_study(u)) {
/* Einheiten, die Waffenlosen Kampf lernen könnten, lernen es um
/* Einheiten, die Waffenlosen Kampf lernen k<EFBFBD>nnten, lernen es um
* zu bewachen: */
if (rc->bonus[SK_WEAPONLESS] != -99) {
if (effskill(u, SK_WEAPONLESS, 0) < 1) {
@ -868,7 +862,7 @@ unit *spawn_seaserpent(region *r, faction *f) {
}
/**
* Drachen und Seeschlangen können entstehen
* Drachen und Seeschlangen k<EFBFBD>nnen entstehen
*/
void spawn_dragons(void)
{
@ -917,7 +911,7 @@ void spawn_dragons(void)
}
}
/** Untote können entstehen */
/** Untote k<EFBFBD>nnen entstehen */
void spawn_undead(void)
{
region *r;
@ -937,7 +931,7 @@ void spawn_undead(void)
message *msg;
unit *u;
/* es ist sinnfrei, wenn irgendwo im Wald 3er-Einheiten Untote entstehen.
* Lieber sammeln lassen, bis sie mindestens 5% der Bevölkerung sind, und
* Lieber sammeln lassen, bis sie mindestens 5% der Bev<EFBFBD>lkerung sind, und
* dann erst auferstehen. */
int undead = unburied / (rng_int() % 2 + 1);
const race *rc = NULL;
@ -995,7 +989,7 @@ void spawn_undead(void)
else {
int i = deathcount(r);
if (i) {
/* Gräber verwittern, 3% der Untoten finden die ewige Ruhe */
/* Gr<EFBFBD>ber verwittern, 3% der Untoten finden die ewige Ruhe */
deathcounts(r, (int)(-i * 0.03));
}
}

View File

@ -101,7 +101,7 @@ static unit *unitorders(input *in, faction *f)
}
}
}
/* Nun wird der Befehl erzeut und eingehängt */
/* Nun wird der Befehl erzeut und eingeh<EFBFBD>ngt */
*ordp = parse_order(s, u->faction->locale);
if (*ordp) {
ordp = &(*ordp)->next;
@ -136,7 +136,7 @@ static faction *factionorders(void)
return 0;
}
/* Die Partei hat sich zumindest gemeldet, so dass sie noch
* nicht als untätig gilt */
* nicht als unt<EFBFBD>tig gilt */
f->lastorders = turn;
}
@ -151,6 +151,7 @@ int read_orders(input *in)
const char *b;
int nfactions = 0;
struct faction *f = NULL;
const struct locale *lang = default_locale;
/* TODO: recognize UTF8 BOM */
b = in->getbuf(in->data);
@ -160,7 +161,6 @@ int read_orders(input *in)
while (b) {
char token[128];
const struct locale *lang = f ? f->locale : default_locale;
param_t p;
const char *s;
init_tokens_str(b);
@ -171,6 +171,7 @@ int read_orders(input *in)
case P_FACTION:
f = factionorders();
if (f) {
lang = f->locale;
++nfactions;
}
@ -200,12 +201,13 @@ int read_orders(input *in)
/* Falls in unitorders() abgebrochen wird, steht dort entweder eine neue
* Partei, eine neue Einheit oder das File-Ende. Das switch() wird erneut
* durchlaufen, und die entsprechende Funktion aufgerufen. Man darf buf
* auf alle Fälle nicht überschreiben! Bei allen anderen Einträgen hier
* muss buf erneut gefüllt werden, da die betreffende Information in nur
* einer Zeile steht, und nun die nächste gelesen werden muss. */
* auf alle F<EFBFBD>lle nicht <EFBFBD>berschreiben! Bei allen anderen Eintr<EFBFBD>gen hier
* muss buf erneut gef<EFBFBD>llt werden, da die betreffende Information in nur
* einer Zeile steht, und nun die n<EFBFBD>chste gelesen werden muss. */
case P_NEXT:
f = NULL;
lang = default_locale;
b = in->getbuf(in->data);
break;

View File

@ -119,7 +119,12 @@ int a_readstring(attrib * a, void *owner, struct gamedata *data)
do {
e = READ_STR(data->store, buf, sizeof(buf));
if (result) {
result = realloc(result, len + DISPLAYSIZE - 1);
char *tmp = realloc(result, len + DISPLAYSIZE - 1);
if (!tmp) {
free(result);
abort();
}
result = tmp;
strcpy(result + len, buf);
len += DISPLAYSIZE - 1;
}

View File

@ -61,7 +61,7 @@ arg_type *find_argtype(const char *name)
message_type *mt_new(const char *name, const char *args[])
{
int i, nparameters = 0;
message_type *mtype = (message_type *)malloc(sizeof(message_type));
message_type *mtype;
assert(name != NULL);
if (name == NULL) {
@ -72,6 +72,7 @@ message_type *mt_new(const char *name, const char *args[])
/* count the number of parameters */
while (args[nparameters]) ++nparameters;
}
mtype = (message_type *)malloc(sizeof(message_type));
mtype->key = 0;
mtype->name = strdup(name);
mtype->nparameters = nparameters;
@ -143,13 +144,14 @@ static void free_arg(const arg_type * atype, variant data)
message *msg_create(const struct message_type *mtype, variant args[])
{
int i;
message *msg = (message *)malloc(sizeof(message));
message *msg;
assert(mtype != NULL);
if (mtype == NULL) {
log_error("Trying to create message with type=0x0\n");
return NULL;
}
msg = (message *)malloc(sizeof(message));
msg->type = mtype;
msg->parameters = (variant *)(mtype->nparameters ? calloc(mtype->nparameters, sizeof(variant)) : NULL);
msg->refcount = 1;