From d73a629e79ed7a7af09792671c9021a43c044c31 Mon Sep 17 00:00:00 2001
From: Enno Rehling <enno.rehling@gmail.com>
Date: Mon, 14 Nov 2016 20:01:44 +0100
Subject: [PATCH 01/42] add a test for regular give_cmd. also, speed up the
 function a little bit.

---
 src/give.c      | 11 +++++---
 src/give.test.c | 70 +++++++++++++++++++++++++++++++++++--------------
 2 files changed, 57 insertions(+), 24 deletions(-)

diff --git a/src/give.c b/src/give.c
index 8f87cded3..b973b90f3 100644
--- a/src/give.c
+++ b/src/give.c
@@ -600,16 +600,19 @@ void give_cmd(unit * u, order * ord)
     }
 
     if (u2 && u_race(u2) == get_race(RC_SPELL)) {
-        ADDMSG(&u->faction->msgs, msg_feedback(u, ord, "feedback_unit_not_found",
-            ""));
+        ADDMSG(&u->faction->msgs, msg_feedback(u, ord,
+            "feedback_unit_not_found", ""));
         return;
     }
-
     else if (u2 && !alliedunit(u2, u->faction, HELP_GIVE) && !ucontact(u2, u)) {
         cmistake(u, ord, 40, MSG_COMMERCE);
         return;
     }
-
+    else if (p == NOKEYWORD) {
+        /* the most likely case: giving items to someone.
+         * let's catch this and save ourselves the rest of the param_t checks.
+         */
+    } 
     else if (p == P_HERBS) {
         bool given = false;
         if ((u_race(u)->ec_flags & ECF_KEEP_ITEM) && u2 != NULL) {
diff --git a/src/give.test.c b/src/give.test.c
index c719ddd5c..0d6149750 100644
--- a/src/give.test.c
+++ b/src/give.test.c
@@ -23,6 +23,7 @@
 #include <assert.h>
 
 struct give {
+    struct locale * lang;
     struct unit *src, *dst;
     struct region *r;
     struct faction *f1, *f2;
@@ -46,10 +47,15 @@ static void setup_give(struct give *env) {
         ally * al = ally_add(&env->f2->allies, env->f1);
         al->status = HELP_GIVE;
     }
+    if (env->lang) {
+        locale_setstring(env->lang, env->itype->rtype->_name, "SILBER");
+        init_locale(env->lang);
+        env->f1->locale = env->lang;
+    }
 }
 
 static void test_give_unit_to_peasants(CuTest * tc) {
-    struct give env;
+    struct give env = { 0 };
     test_setup();
     env.f1 = test_create_faction(0);
     env.f2 = 0;
@@ -62,7 +68,7 @@ static void test_give_unit_to_peasants(CuTest * tc) {
 }
 
 static void test_give_unit(CuTest * tc) {
-    struct give env;
+    struct give env = { 0 };
     test_setup();
     env.f1 = test_create_faction(0);
     env.f2 = test_create_faction(0);
@@ -81,7 +87,7 @@ static void test_give_unit(CuTest * tc) {
 }
 
 static void test_give_unit_in_ocean(CuTest * tc) {
-    struct give env;
+    struct give env = { 0 };
     test_setup();
     env.f1 = test_create_faction(0);
     env.f2 = 0;
@@ -93,7 +99,7 @@ static void test_give_unit_in_ocean(CuTest * tc) {
 }
 
 static void test_give_men(CuTest * tc) {
-    struct give env;
+    struct give env = { 0 };
     test_setup();
     env.f2 = env.f1 = test_create_faction(0);
     setup_give(&env);
@@ -104,7 +110,7 @@ static void test_give_men(CuTest * tc) {
 }
 
 static void test_give_men_magicians(CuTest * tc) {
-    struct give env;
+    struct give env = { 0 };
     int p;
     message * msg;
 
@@ -135,7 +141,7 @@ static void test_give_men_magicians(CuTest * tc) {
 }
 
 static void test_give_men_limit(CuTest * tc) {
-    struct give env;
+    struct give env = { 0 };
     message *msg;
     test_setup();
     env.f2 = test_create_faction(0);
@@ -165,7 +171,7 @@ static void test_give_men_limit(CuTest * tc) {
 }
 
 static void test_give_men_in_ocean(CuTest * tc) {
-    struct give env;
+    struct give env = { 0 };
     message * msg;
 
     test_setup();
@@ -181,7 +187,7 @@ static void test_give_men_in_ocean(CuTest * tc) {
 }
 
 static void test_give_men_too_many(CuTest * tc) {
-    struct give env;
+    struct give env = { 0 };
     test_setup();
     env.f2 = env.f1 = test_create_faction(0);
     setup_give(&env);
@@ -192,7 +198,7 @@ static void test_give_men_too_many(CuTest * tc) {
 }
 
 static void test_give_men_none(CuTest * tc) {
-    struct give env;
+    struct give env = { 0 };
     message * msg;
 
     test_setup();
@@ -207,7 +213,7 @@ static void test_give_men_none(CuTest * tc) {
 }
 
 static void test_give_men_other_faction(CuTest * tc) {
-    struct give env;
+    struct give env = { 0 };
     message * msg;
 
     test_setup();
@@ -224,7 +230,7 @@ static void test_give_men_other_faction(CuTest * tc) {
 }
 
 static void test_give_men_requires_contact(CuTest * tc) {
-    struct give env;
+    struct give env = { 0 };
     message * msg;
     order *ord;
     char cmd[32];
@@ -251,7 +257,7 @@ static void test_give_men_requires_contact(CuTest * tc) {
 }
 
 static void test_give_men_not_to_self(CuTest * tc) {
-    struct give env;
+    struct give env = { 0 };
     message * msg;
     test_setup();
     env.f2 = env.f1 = test_create_faction(0);
@@ -264,7 +270,7 @@ static void test_give_men_not_to_self(CuTest * tc) {
 }
 
 static void test_give_peasants(CuTest * tc) {
-    struct give env;
+    struct give env = { 0 };
     message * msg;
 
     test_setup();
@@ -281,7 +287,7 @@ static void test_give_peasants(CuTest * tc) {
 }
 
 static void test_give(CuTest * tc) {
-    struct give env;
+    struct give env = { 0 };
 
     test_setup();
     env.f2 = env.f1 = test_create_faction(0);
@@ -298,8 +304,31 @@ static void test_give(CuTest * tc) {
     test_cleanup();
 }
 
+static void test_give_cmd(CuTest * tc) {
+    struct give env = { 0 };
+    struct order *ord;
+    char cmd[32];
+
+    test_setup();
+    env.lang = test_create_locale();
+    env.f2 = env.f1 = test_create_faction(0);
+    setup_give(&env);
+
+    i_change(&env.src->items, env.itype, 10);
+
+    _snprintf(cmd, sizeof(cmd), "%s 5 %s", itoa36(env.dst->no), LOC(env.f1->locale, env.itype->rtype->_name));
+    ord = create_order(K_GIVE, env.f1->locale, cmd);
+    assert(ord);
+    give_cmd(env.src, ord);
+    CuAssertIntEquals(tc, 5, i_get(env.src->items, env.itype));
+    CuAssertIntEquals(tc, 5, i_get(env.dst->items, env.itype));
+
+    free_order(ord);
+    test_cleanup();
+}
+
 static void test_give_herbs(CuTest * tc) {
-    struct give env;
+    struct give env = { 0 };
     struct order *ord;
     char cmd[32];
 
@@ -321,7 +350,7 @@ static void test_give_herbs(CuTest * tc) {
 }
 
 static void test_give_okay(CuTest * tc) {
-    struct give env;
+    struct give env = { 0 };
 
     test_setup();
     env.f2 = env.f1 = test_create_faction(0);
@@ -333,7 +362,7 @@ static void test_give_okay(CuTest * tc) {
 }
 
 static void test_give_denied_by_rules(CuTest * tc) {
-    struct give env;
+    struct give env = { 0 };
     struct message *msg;
 
     test_setup();
@@ -348,7 +377,7 @@ static void test_give_denied_by_rules(CuTest * tc) {
 }
 
 static void test_give_dead_unit(CuTest * tc) {
-    struct give env;
+    struct give env = { 0 };
     struct message *msg;
 
     test_setup();
@@ -363,7 +392,7 @@ static void test_give_dead_unit(CuTest * tc) {
 }
 
 static void test_give_new_unit(CuTest * tc) {
-    struct give env;
+    struct give env = { 0 };
 
     test_setup();
     env.f1 = test_create_faction(0);
@@ -377,7 +406,7 @@ static void test_give_new_unit(CuTest * tc) {
 
 static void test_give_invalid_target(CuTest *tc) {
     // bug https://bugs.eressea.de/view.php?id=1685
-    struct give env;
+    struct give env = { 0 };
     order *ord;
 
     test_setup();
@@ -400,6 +429,7 @@ CuSuite *get_give_suite(void)
 {
     CuSuite *suite = CuSuiteNew();
     SUITE_ADD_TEST(suite, test_give);
+    SUITE_ADD_TEST(suite, test_give_cmd);
     SUITE_ADD_TEST(suite, test_give_men);
     SUITE_ADD_TEST(suite, test_give_men_magicians);
     SUITE_ADD_TEST(suite, test_give_men_limit);

From e2937419970e1af6998f342a0793a62dfc675e0e Mon Sep 17 00:00:00 2001
From: Enno Rehling <enno.rehling@gmail.com>
Date: Mon, 14 Nov 2016 20:33:26 +0100
Subject: [PATCH 02/42] wrong enum, thanks gcc

---
 src/give.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/give.c b/src/give.c
index b973b90f3..781f39ca6 100644
--- a/src/give.c
+++ b/src/give.c
@@ -608,7 +608,7 @@ void give_cmd(unit * u, order * ord)
         cmistake(u, ord, 40, MSG_COMMERCE);
         return;
     }
-    else if (p == NOKEYWORD) {
+    else if (p == NOPARAM) {
         /* the most likely case: giving items to someone.
          * let's catch this and save ourselves the rest of the param_t checks.
          */

From c512d180f84e6d8484188bb281964c177c1ec91a Mon Sep 17 00:00:00 2001
From: Enno Rehling <enno@eressea.de>
Date: Mon, 14 Nov 2016 22:15:52 +0100
Subject: [PATCH 03/42] prevent atoip setting errno on mac. only call atoi when
 string starts with a digit

---
 src/util/parser.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/util/parser.c b/src/util/parser.c
index 741fd573f..b13e266a6 100644
--- a/src/util/parser.c
+++ b/src/util/parser.c
@@ -250,7 +250,7 @@ unsigned int atoip(const char *s)
     int n;
 
     assert(s);
-    n = atoi(s);
+    n = isdigit(s[0]) ? atoi(s) : 0;
 
     if (n < 0)
         n = 0;

From b48b80a1e96e486de7491cdcde5d0c5519e2b8a1 Mon Sep 17 00:00:00 2001
From: Enno Rehling <enno@eressea.de>
Date: Mon, 14 Nov 2016 22:21:32 +0100
Subject: [PATCH 04/42] verify errno in test_atoip

---
 src/util/parser.test.c | 14 ++++++++------
 1 file changed, 8 insertions(+), 6 deletions(-)

diff --git a/src/util/parser.test.c b/src/util/parser.test.c
index da0d8dacb..c7ac0bb05 100644
--- a/src/util/parser.test.c
+++ b/src/util/parser.test.c
@@ -2,8 +2,16 @@
 #include "parser.h"
 
 #include <string.h>
+#include <errno.h>
 #include <CuTest.h>
 
+static void test_atoip(CuTest *tc) {
+    CuAssertIntEquals(tc, 0, atoip("ALLES"));
+    CuAssertIntEquals(tc, 0, errno);
+    CuAssertIntEquals(tc, 42, atoip("42"));
+    CuAssertIntEquals(tc, 0, atoip("-1"));
+}
+
 static void test_parse_token(CuTest *tc) {
     char lbuf[8];
     const char *tok;
@@ -103,12 +111,6 @@ static void test_getstrtoken(CuTest *tc) {
     CuAssertPtrEquals(tc, NULL, (void *)getstrtoken());
 }
 
-static void test_atoip(CuTest *tc) {
-    CuAssertIntEquals(tc, 42, atoip("42"));
-    CuAssertIntEquals(tc, 0, atoip("-42"));
-    CuAssertIntEquals(tc, 0, atoip("NOPE"));
-}
-
 CuSuite *get_parser_suite(void)
 {
     CuSuite *suite = CuSuiteNew();

From ce4a3c14b3d57e26ea94a27e82f2141de708470a Mon Sep 17 00:00:00 2001
From: Enno Rehling <enno@eressea.de>
Date: Mon, 14 Nov 2016 22:27:44 +0100
Subject: [PATCH 05/42] convert from atoi to atoip. most numbers in commands
 cannot be negative.

---
 src/economy.c | 6 +++---
 src/laws.c    | 4 ++--
 src/magic.c   | 2 +-
 3 files changed, 6 insertions(+), 6 deletions(-)

diff --git a/src/economy.c b/src/economy.c
index 36e8de109..bc0970ff2 100644
--- a/src/economy.c
+++ b/src/economy.c
@@ -1278,7 +1278,7 @@ int make_cmd(unit * u, struct order *ord)
     s = gettoken(token, sizeof(token));
 
     if (s) {
-        m = atoi((const char *)s);
+        m = atoip(s);
         sprintf(ibuf, "%d", m);
         if (!strcmp(ibuf, (const char *)s)) {
             /* a quantity was given */
@@ -1882,7 +1882,7 @@ static bool sell(unit * u, request ** sellorders, struct order *ord)
         }
     }
     else {
-        n = s ? atoi(s) : 0;
+        n = s ? atoip(s) : 0;
         if (n == 0) {
             cmistake(u, ord, 27, MSG_COMMERCE);
             return false;
@@ -2274,7 +2274,7 @@ static void breed_cmd(unit * u, struct order *ord)
     (void)init_order(ord);
     s = gettoken(token, sizeof(token));
 
-    m = s ? atoi((const char *)s) : 0;
+    m = s ? atoip(s) : 0;
     if (m != 0) {
         /* first came a want-paramter */
         s = gettoken(token, sizeof(token));
diff --git a/src/laws.c b/src/laws.c
index 0838ba6a2..a2db8e4a0 100644
--- a/src/laws.c
+++ b/src/laws.c
@@ -3693,7 +3693,7 @@ int use_cmd(unit * u, struct order *ord)
         cmistake(u, ord, 43, MSG_PRODUCE);
         return err;
     }
-    n = atoi((const char *)t);
+    n = atoip((const char *)t);
     if (n == 0) {
         if (isparam(t, u->faction->locale, P_ANY)) {
             /* BENUTZE ALLES Yanxspirit */
@@ -3841,7 +3841,7 @@ int claim_cmd(unit * u, struct order *ord)
 
     t = gettoken(token, sizeof(token));
     if (t) {
-        n = atoi((const char *)t);
+        n = atoip((const char *)t);
         if (n == 0) {
             n = 1;
         }
diff --git a/src/magic.c b/src/magic.c
index 1ac2255c1..803f20c78 100644
--- a/src/magic.c
+++ b/src/magic.c
@@ -376,7 +376,7 @@ static int read_seenspell(attrib * a, void *owner, struct gamedata *data)
     char token[32];
 
     READ_TOK(store, token, sizeof(token));
-    i = atoi(token);
+    i = atoip(token);
     if (i != 0) {
         sp = find_spellbyid((unsigned int)i);
     }

From 49e5b5b67e73120eaa5f960eb28facec297efdac Mon Sep 17 00:00:00 2001
From: Enno Rehling <enno.rehling@gmail.com>
Date: Mon, 14 Nov 2016 23:19:28 +0100
Subject: [PATCH 06/42] gcc missing include

---
 src/util/parser.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/src/util/parser.c b/src/util/parser.c
index b13e266a6..0fbde6769 100644
--- a/src/util/parser.c
+++ b/src/util/parser.c
@@ -6,6 +6,7 @@
 
 #include <assert.h>
 #include <stdlib.h>
+#include <ctype.h>
 #include <wctype.h>
 #include <memory.h>
 

From c1f468ceb000ad69587a963ca6638a7401c4777c Mon Sep 17 00:00:00 2001
From: Enno Rehling <enno.rehling@gmail.com>
Date: Tue, 15 Nov 2016 20:43:36 +0100
Subject: [PATCH 07/42] begin to declutter config.c

---
 src/economy.c       |  4 ++--
 src/kernel/config.c |  7 -------
 src/kernel/config.h |  1 -
 src/kernel/region.c |  9 ++++++++-
 src/kernel/region.h |  1 +
 src/kernel/types.h  |  8 --------
 src/keyword.h       |  2 +-
 src/laws.c          | 12 ++++++------
 8 files changed, 18 insertions(+), 26 deletions(-)

diff --git a/src/economy.c b/src/economy.c
index 36e8de109..1ee34fb9a 100644
--- a/src/economy.c
+++ b/src/economy.c
@@ -2908,7 +2908,7 @@ void auto_work(region * r)
         }
     }
     if (nextworker != workers) {
-        expandwork(r, workers, nextworker, maxworkingpeasants(r));
+        expandwork(r, workers, nextworker, region_maxworkers(r));
     }
 }
 
@@ -3112,7 +3112,7 @@ void produce(struct region *r)
     if (entertaining)
         expandentertainment(r);
     if (!rule_autowork()) {
-        expandwork(r, workers, nextworker, maxworkingpeasants(r));
+        expandwork(r, workers, nextworker, region_maxworkers(r));
     }
     if (taxorders)
         expandtax(r, taxorders);
diff --git a/src/kernel/config.c b/src/kernel/config.c
index 42dcc5e09..78af1ad02 100644
--- a/src/kernel/config.c
+++ b/src/kernel/config.c
@@ -433,13 +433,6 @@ int newcontainerid(void)
     return random_no;
 }
 
-int maxworkingpeasants(const struct region *r)
-{
-    int size = production(r);
-    int treespace = (rtrees(r, 2) + rtrees(r, 1) / 2) * TREESIZE;
-    return _max(size - treespace, _min(size / 10, 200));
-}
-
 static const char * parameter_key(int i)
 {
     assert(i < MAXPARAMS && i >= 0);
diff --git a/src/kernel/config.h b/src/kernel/config.h
index 8c46e4185..0d0506b47 100644
--- a/src/kernel/config.h
+++ b/src/kernel/config.h
@@ -114,7 +114,6 @@ struct param;
 #define GF_PURE 64
     /* untranslated */
 
-    int maxworkingpeasants(const struct region *r);
     bool markets_module(void);
     int wage(const struct region *r, const struct faction *f,
         const struct race *rc, int in_turn);
diff --git a/src/kernel/region.c b/src/kernel/region.c
index e05bd76c1..d937f8b68 100644
--- a/src/kernel/region.c
+++ b/src/kernel/region.c
@@ -134,6 +134,13 @@ const char *regionname(const region * r, const faction * f)
     return write_regionname(r, f, buf[index], sizeof(buf[index]));
 }
 
+int region_maxworkers(const region *r)
+{
+    int size = production(r);
+    int treespace = (rtrees(r, 2) + rtrees(r, 1) / 2) * TREESIZE;
+    return _max(size - treespace, _min(size / 10, 200));
+}
+
 int deathcount(const region * r)
 {
     attrib *a = a_find(r->attribs, &at_deathcount);
@@ -1207,7 +1214,7 @@ void terraform_region(region * r, const terrain_type * terrain)
 
         if (!fval(r, RF_CHAOTIC)) {
             int peasants;
-            peasants = (maxworkingpeasants(r) * (20 + dice_rand("6d10"))) / 100;
+            peasants = (region_maxworkers(r) * (20 + dice_rand("6d10"))) / 100;
             rsetpeasants(r, _max(100, peasants));
             rsetmoney(r, rpeasants(r) * ((wage(r, NULL, NULL,
                 INT_MAX) + 1) + rng_int() % 5));
diff --git a/src/kernel/region.h b/src/kernel/region.h
index eb7066cc6..fcc5f08b0 100644
--- a/src/kernel/region.h
+++ b/src/kernel/region.h
@@ -264,6 +264,7 @@ extern "C" {
 
     const char *regionname(const struct region *r, const struct faction *f);
 
+	int region_maxworkers(const struct region *r);
     const char *region_getname(const struct region *self);
     void region_setname(struct region *self, const char *name);
     const char *region_getinfo(const struct region *self);
diff --git a/src/kernel/types.h b/src/kernel/types.h
index e0521635e..5187f9aec 100644
--- a/src/kernel/types.h
+++ b/src/kernel/types.h
@@ -19,14 +19,6 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 #ifndef ERESSEA_TYPES_H
 #define ERESSEA_TYPES_H
 
-/*
- * Features enabled:
- * If you are lacking the settings.h, create a new file common/settings.h,
- * and write #include <settings-config.h> (or whatever settings you want
- * your game to use) in there.
- * !!! DO NOT COMMIT THE SETTINGS.H FILE TO CVS !!!
- * settings.h should always be the first thing you include (after platform.h).
- */
 #include <settings.h>
 #include <util/variant.h>
 
diff --git a/src/keyword.h b/src/keyword.h
index 9d5e20f64..e60d0731f 100644
--- a/src/keyword.h
+++ b/src/keyword.h
@@ -70,7 +70,7 @@ extern "C"
         K_PAY,
         K_LOOT,
         MAXKEYWORDS,
-        NOKEYWORD = -1
+        NOKEYWORD
     } keyword_t;
 
     extern const char *keywords[MAXKEYWORDS];
diff --git a/src/laws.c b/src/laws.c
index 0838ba6a2..f5d65efc5 100644
--- a/src/laws.c
+++ b/src/laws.c
@@ -221,7 +221,7 @@ static void live(region * r)
 static void calculate_emigration(region * r)
 {
     int i;
-    int maxp = maxworkingpeasants(r);
+    int maxp = region_maxworkers(r);
     int rp = rpeasants(r);
     int max_immigrants = MAX_IMMIGRATION(maxp - rp);
 
@@ -236,7 +236,7 @@ static void calculate_emigration(region * r)
 
         if (rc != NULL && fval(rc->terrain, LAND_REGION)) {
             int rp2 = rpeasants(rc);
-            int maxp2 = maxworkingpeasants(rc);
+            int maxp2 = region_maxworkers(rc);
             int max_emigration = MAX_EMIGRATION(rp2 - maxp2);
 
             if (max_emigration > 0) {
@@ -419,7 +419,7 @@ static void horses(region * r)
     direction_t n;
 
     /* Logistisches Wachstum, Optimum bei halbem Maximalbesatz. */
-    maxhorses = maxworkingpeasants(r) / 10;
+    maxhorses = region_maxworkers(r) / 10;
     maxhorses = _max(0, maxhorses);
     horses = rhorses(r);
     if (horses > 0) {
@@ -621,7 +621,7 @@ growing_trees(region * r, const int current_season, const int last_weeks_season)
                  * verfügbaren Fläche ab. In Gletschern gibt es weniger
                  * Möglichkeiten als in Ebenen. */
                 sprout = 0;
-                seedchance = (1000 * maxworkingpeasants(r2)) / r2->terrain->size;
+                seedchance = (1000 * region_maxworkers(r2)) / r2->terrain->size;
                 for (i = 0; i < seeds / MAXDIRECTIONS; i++) {
                     if (rng_int() % 10000 < seedchance)
                         sprout++;
@@ -720,7 +720,7 @@ void immigration(void)
         if (repopulate) {
             int peasants = rpeasants(r);
             int income = wage(r, NULL, NULL, turn) - maintenance_cost(NULL) + 1;
-            if (income >= 0 && r->land && (peasants < repopulate) && maxworkingpeasants(r) >(peasants + 30) * 2) {
+            if (income >= 0 && r->land && (peasants < repopulate) && region_maxworkers(r) >(peasants + 30) * 2) {
                 int badunit = 0;
                 unit *u;
                 for (u = r->units; u; u = u->next) {
@@ -816,7 +816,7 @@ void demographics(void)
                 calculate_emigration(r);
                 peasants(r);
                 if (r->age > 20) {
-                    double mwp = _max(maxworkingpeasants(r), 1);
+                    double mwp = _max(region_maxworkers(r), 1);
                     double prob =
                         pow(rpeasants(r) / (mwp * wage(r, NULL, NULL, turn) * 0.13), 4.0)
                         * PLAGUE_CHANCE;

From 17365edff76824acc3c91796eb5090bf453e1005 Mon Sep 17 00:00:00 2001
From: Enno Rehling <enno.rehling@gmail.com>
Date: Tue, 15 Nov 2016 23:34:20 +0100
Subject: [PATCH 08/42] move renumber command to a separate module.

---
 scripts/tests/bindings.lua |   1 -
 scripts/tests/orders.lua   |   2 +-
 src/CMakeLists.txt         |   1 +
 src/bind_process.c         |   5 -
 src/laws.c                 | 181 +--------------------------------
 src/laws.h                 |   2 -
 src/process.pkg            |   1 -
 src/process.pkg.c          |  25 -----
 src/renumber.c             | 198 +++++++++++++++++++++++++++++++++++++
 src/renumber.h             |  12 +++
 10 files changed, 213 insertions(+), 215 deletions(-)
 create mode 100644 src/renumber.c
 create mode 100644 src/renumber.h

diff --git a/scripts/tests/bindings.lua b/scripts/tests/bindings.lua
index 189d34769..9aab6fd57 100644
--- a/scripts/tests/bindings.lua
+++ b/scripts/tests/bindings.lua
@@ -34,7 +34,6 @@ function test_process()
 	assert_equal("function", _G.type(eressea.process.siege))
 	assert_equal("function", _G.type(eressea.process.leave))
 	assert_equal("function", _G.type(eressea.process.promote))
-	assert_equal("function", _G.type(eressea.process.renumber))
 	assert_equal("function", _G.type(eressea.process.restack))
 	assert_equal("function", _G.type(eressea.process.set_spells))
 	assert_equal("function", _G.type(eressea.process.set_help))
diff --git a/scripts/tests/orders.lua b/scripts/tests/orders.lua
index a0b03f825..dde9508e9 100644
--- a/scripts/tests/orders.lua
+++ b/scripts/tests/orders.lua
@@ -165,7 +165,7 @@ end
 
 function test_process_renumber()
     u:add_order("NUMMER EINHEIT 'ii'")
-    eressea.process.renumber()
+    process_orders()
     assert_equal(666, u.id)
 end
 
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index b4e600e0d..4616fc8e3 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -115,6 +115,7 @@ set (ERESSEA_SRC
   morale.c
   monster.c
   randenc.c
+  renumber.c
   volcano.c
   chaos.c
   spy.c
diff --git a/src/bind_process.c b/src/bind_process.c
index e8420c654..2b44eb19d 100755
--- a/src/bind_process.c
+++ b/src/bind_process.c
@@ -182,11 +182,6 @@ void process_promote(void) {
     process_cmd(K_PROMOTION, promotion_cmd, 0);
 }
 
-void process_renumber(void) {
-    process_cmd(K_NUMBER, renumber_cmd, 0);
-    renumber_factions();
-}
-
 void process_restack(void) {
     restack_units();
 }
diff --git a/src/laws.c b/src/laws.c
index 33fd56779..cf365fc7a 100644
--- a/src/laws.c
+++ b/src/laws.c
@@ -32,6 +32,7 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 #include "monster.h"
 #include "move.h"
 #include "randenc.h"
+#include "renumber.h"
 #include "spy.h"
 #include "study.h"
 #include "wormhole.h"
@@ -2742,74 +2743,6 @@ void sinkships(struct region * r)
     }
 }
 
-static attrib_type at_number = {
-    "faction_renum",
-    NULL, NULL, NULL, NULL, NULL, NULL,
-    ATF_UNIQUE
-};
-
-void renumber_factions(void)
-/* gibt parteien neue nummern */
-{
-    struct renum {
-        struct renum *next;
-        int want;
-        faction *faction;
-        attrib *attrib;
-    } *renum = NULL, *rp;
-    faction *f;
-    for (f = factions; f; f = f->next) {
-        attrib *a = a_find(f->attribs, &at_number);
-        int want;
-        struct renum **rn;
-        faction *old;
-
-        if (!a)
-            continue;
-        want = a->data.i;
-        if (fval(f, FFL_NEWID)) {
-            ADDMSG(&f->msgs, msg_message("renumber_twice", "id", want));
-            continue;
-        }
-        old = findfaction(want);
-        if (old) {
-            a_remove(&f->attribs, a);
-            ADDMSG(&f->msgs, msg_message("renumber_inuse", "id", want));
-            continue;
-        }
-        if (!faction_id_is_unused(want)) {
-            a_remove(&f->attribs, a);
-            ADDMSG(&f->msgs, msg_message("renumber_inuse", "id", want));
-            continue;
-        }
-        for (rn = &renum; *rn; rn = &(*rn)->next) {
-            if ((*rn)->want >= want)
-                break;
-        }
-        if (*rn && (*rn)->want == want) {
-            ADDMSG(&f->msgs, msg_message("renumber_inuse", "id", want));
-        }
-        else {
-            struct renum *r = calloc(sizeof(struct renum), 1);
-            r->next = *rn;
-            r->attrib = a;
-            r->faction = f;
-            r->want = want;
-            *rn = r;
-        }
-    }
-    for (rp = renum; rp; rp = rp->next) {
-        f = rp->faction;
-        a_remove(&f->attribs, rp->attrib);
-        renumber_faction(f, rp->want);
-    }
-    while (renum) {
-        rp = renum->next;
-        free(renum);
-        renum = rp;
-    }
-}
-
 void restack_units(void)
 {
     region *r;
@@ -2897,118 +2830,6 @@ void restack_units(void)
     }
 }
 
-int renumber_cmd(unit * u, order * ord)
-{
-    char token[128];
-    const char *s;
-    int i = 0;
-    faction *f = u->faction;
-
-    init_order(ord);
-    s = gettoken(token, sizeof(token));
-    switch (findparam_ex(s, u->faction->locale)) {
-
-    case P_FACTION:
-        s = gettoken(token, sizeof(token));
-        if (s && *s) {
-            int id = atoi36((const char *)s);
-            attrib *a = a_find(f->attribs, &at_number);
-            if (!a)
-                a = a_add(&f->attribs, a_new(&at_number));
-            a->data.i = id;
-        }
-        break;
-
-    case P_UNIT:
-        s = gettoken(token, sizeof(token));
-        if (s && *s) {
-            i = atoi36((const char *)s);
-            if (i <= 0 || i > MAX_UNIT_NR) {
-                cmistake(u, ord, 114, MSG_EVENT);
-                break;
-            }
-
-            if (forbiddenid(i)) {
-                cmistake(u, ord, 116, MSG_EVENT);
-                break;
-            }
-
-            if (findunitg(i, u->region)) {
-                cmistake(u, ord, 115, MSG_EVENT);
-                break;
-            }
-        }
-        renumber_unit(u, i);
-        break;
-
-    case P_SHIP:
-        if (!u->ship) {
-            cmistake(u, ord, 144, MSG_EVENT);
-            break;
-        }
-        if (ship_owner(u->ship) != u) {
-            cmistake(u, ord, 146, MSG_EVENT);
-            break;
-        }
-        if (u->ship->coast != NODIRECTION) {
-            cmistake(u, ord, 116, MSG_EVENT);
-            break;
-        }
-        s = gettoken(token, sizeof(token));
-        if (s == NULL || *s == 0) {
-            i = newcontainerid();
-        }
-        else {
-            i = atoi36((const char *)s);
-            if (i <= 0 || i > MAX_CONTAINER_NR) {
-                cmistake(u, ord, 114, MSG_EVENT);
-                break;
-            }
-            if (findship(i) || findbuilding(i)) {
-                cmistake(u, ord, 115, MSG_EVENT);
-                break;
-            }
-        }
-        sunhash(u->ship);
-        u->ship->no = i;
-        shash(u->ship);
-        break;
-    case P_BUILDING:
-    case P_GEBAEUDE:
-        if (!u->building) {
-            cmistake(u, ord, 145, MSG_EVENT);
-            break;
-        }
-        if (building_owner(u->building) != u) {
-            cmistake(u, ord, 148, MSG_EVENT);
-            break;
-        }
-        s = gettoken(token, sizeof(token));
-        if (*s == 0) {
-            i = newcontainerid();
-        }
-        else {
-            i = atoi36((const char *)s);
-            if (i <= 0 || i > MAX_CONTAINER_NR) {
-                cmistake(u, ord, 114, MSG_EVENT);
-                break;
-            }
-            if (findship(i) || findbuilding(i)) {
-                cmistake(u, ord, 115, MSG_EVENT);
-                break;
-            }
-        }
-        bunhash(u->building);
-        u->building->no = i;
-        bhash(u->building);
-        break;
-
-    default:
-        cmistake(u, ord, 239, MSG_EVENT);
-    }
-    return 0;
-}
-
 /* blesses stone circles create an astral protection in the astral region
  * above the shield, which prevents chaos suction and other spells.
  * The shield is created when a magician enters the blessed stone circle,
diff --git a/src/laws.h b/src/laws.h
index c5e9d573c..5406a50d4 100755
--- a/src/laws.h
+++ b/src/laws.h
@@ -59,7 +59,6 @@ extern "C" {
     void defaultorders(void);
     void quit(void);
     void monthly_healing(void);
-    void renumber_factions(void);
     void restack_units(void);
     void update_long_order(struct unit *u);
     void sinkships(struct region * r);
@@ -83,7 +82,6 @@ extern "C" {
     int leave_cmd(struct unit *u, struct order *ord);
     int pay_cmd(struct unit *u, struct order *ord);
     int promotion_cmd(struct unit *u, struct order *ord);
-    int renumber_cmd(struct unit *u, struct order *ord);
     int combatspell_cmd(struct unit *u, struct order *ord);
     int contact_cmd(struct unit *u, struct order *ord);
     int guard_on_cmd(struct unit *u, struct order *ord);
diff --git a/src/process.pkg b/src/process.pkg
index 5db5c7344..a81917293 100755
--- a/src/process.pkg
+++ b/src/process.pkg
@@ -25,7 +25,6 @@ module eressea {
         void process_leave @ leave(void); /* LEAVE */
         void process_maintenance @ maintenance(void); /* PAY */
         void process_promote @ promote(void); /* PROMOTE */
-        void process_renumber @ renumber(void); /* RENUMBER */
         void process_restack @ restack(void); /* SORT */
         void process_setspells @ set_spells(void); /* COMBATSPELL */
         void process_sethelp @ set_help(void); /* HELP */
diff --git a/src/process.pkg.c b/src/process.pkg.c
index 787258a96..42dff20ff 100644
--- a/src/process.pkg.c
+++ b/src/process.pkg.c
@@ -531,30 +531,6 @@ static int tolua_process_eressea_process_promote00(lua_State* tolua_S)
 #endif
 }
 
-/* function: process_renumber */
-static int tolua_process_eressea_process_renumber00(lua_State* tolua_S)
-{
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (
- !tolua_isnoobj(tolua_S,1,&tolua_err)
- )
- goto tolua_lerror;
- else
-#endif
- {
- {
-  process_renumber();
- }
- }
- return 0;
-#ifndef TOLUA_RELEASE
- tolua_lerror:
- tolua_error(tolua_S,"#ferror in function 'renumber'.",&tolua_err);
- return 0;
-#endif
-}
-
 /* function: process_restack */
 static int tolua_process_eressea_process_restack00(lua_State* tolua_S)
 {
@@ -1021,7 +997,6 @@ LUALIB_API int luaopen_process (lua_State* tolua_S)
  tolua_function(tolua_S,"leave",tolua_process_eressea_process_leave00);
  tolua_function(tolua_S,"maintenance",tolua_process_eressea_process_maintenance00);
  tolua_function(tolua_S,"promote",tolua_process_eressea_process_promote00);
- tolua_function(tolua_S,"renumber",tolua_process_eressea_process_renumber00);
  tolua_function(tolua_S,"restack",tolua_process_eressea_process_restack00);
  tolua_function(tolua_S,"set_spells",tolua_process_eressea_process_set_spells00);
  tolua_function(tolua_S,"set_help",tolua_process_eressea_process_set_help00);
diff --git a/src/renumber.c b/src/renumber.c
new file mode 100644
index 000000000..259dfcc2b
--- /dev/null
+++ b/src/renumber.c
@@ -0,0 +1,198 @@
+#include <platform.h>
+#include "renumber.h"
+
+#include <kernel/config.h>
+#include <kernel/faction.h>
+#include <kernel/building.h>
+#include <kernel/ship.h>
+#include <kernel/unit.h>
+#include <kernel/order.h>
+#include <kernel/messages.h>
+
+#include <util/attrib.h>
+#include <util/base36.h>
+#include <util/parser.h>
+
+#include <assert.h>
+#include <stdlib.h>
+
+static attrib_type at_number = {
+    "faction_renum",
+    NULL, NULL, NULL, NULL, NULL, NULL,
+    ATF_UNIQUE
+};
+
+void renumber_factions(void)
+/* gibt parteien neue nummern */
+{
+    struct renum {
+        struct renum *next;
+        int want;
+        faction *faction;
+        attrib *attrib;
+    } *renum = NULL, *rp;
+    faction *f;
+    for (f = factions; f; f = f->next) {
+        attrib *a = a_find(f->attribs, &at_number);
+        int want;
+        struct renum **rn;
+        faction *old;
+
+        if (!a)
+            continue;
+        want = a->data.i;
+        if (fval(f, FFL_NEWID)) {
+            ADDMSG(&f->msgs, msg_message("renumber_twice", "id", want));
+            continue;
+        }
+        old = findfaction(want);
+        if (old) {
+            a_remove(&f->attribs, a);
+            ADDMSG(&f->msgs, msg_message("renumber_inuse", "id", want));
+            continue;
+        }
+        if (!faction_id_is_unused(want)) {
+            a_remove(&f->attribs, a);
+            ADDMSG(&f->msgs, msg_message("renumber_inuse", "id", want));
+            continue;
+        }
+        for (rn = &renum; *rn; rn = &(*rn)->next) {
+            if ((*rn)->want >= want)
+                break;
+        }
+        if (*rn && (*rn)->want == want) {
+            ADDMSG(&f->msgs, msg_message("renumber_inuse", "id", want));
+        }
+        else {
+            struct renum *r = calloc(sizeof(struct renum), 1);
+            r->next = *rn;
+            r->attrib = a;
+            r->faction = f;
+            r->want = want;
+            *rn = r;
+        }
+    }
+    for (rp = renum; rp; rp = rp->next) {
+        f = rp->faction;
+        a_remove(&f->attribs, rp->attrib);
+        renumber_faction(f, rp->want);
+    }
+    while (renum) {
+        rp = renum->next;
+        free(renum);
+        renum = rp;
+    }
+}
+
+int renumber_cmd(unit * u, order * ord)
+{
+    char token[128];
+    const char *s;
+    int i = 0;
+    faction *f = u->faction;
+
+    init_order(ord);
+    s = gettoken(token, sizeof(token));
+    switch (findparam_ex(s, u->faction->locale)) {
+
+    case P_FACTION:
+        s = gettoken(token, sizeof(token));
+        if (s && *s) {
+            int id = atoi36((const char *)s);
+            attrib *a = a_find(f->attribs, &at_number);
+            if (!a)
+                a = a_add(&f->attribs, a_new(&at_number));
+            a->data.i = id;
+        }
+        break;
+
+    case P_UNIT:
+        s = gettoken(token, sizeof(token));
+        if (s && *s) {
+            i = atoi36((const char *)s);
+            if (i <= 0 || i > MAX_UNIT_NR) {
+                cmistake(u, ord, 114, MSG_EVENT);
+                break;
+            }
+
+            if (forbiddenid(i)) {
+                cmistake(u, ord, 116, MSG_EVENT);
+                break;
+            }
+
+            if (findunitg(i, u->region)) {
+                cmistake(u, ord, 115, MSG_EVENT);
+                break;
+            }
+        }
+        renumber_unit(u, i);
+        break;
+
+    case P_SHIP:
+        if (!u->ship) {
+            cmistake(u, ord, 144, MSG_EVENT);
+            break;
+        }
+        if (ship_owner(u->ship) != u) {
+            cmistake(u, ord, 146, MSG_EVENT);
+            break;
+        }
+        if (u->ship->coast != NODIRECTION) {
+            cmistake(u, ord, 116, MSG_EVENT);
+            break;
+        }
+        s = gettoken(token, sizeof(token));
+        if (s == NULL || *s == 0) {
+            i = newcontainerid();
+        }
+        else {
+            i = atoi36((const char *)s);
+            if (i <= 0 || i > MAX_CONTAINER_NR) {
+                cmistake(u, ord, 114, MSG_EVENT);
+                break;
+            }
+            if (findship(i) || findbuilding(i)) {
+                cmistake(u, ord, 115, MSG_EVENT);
+                break;
+            }
+        }
+        sunhash(u->ship);
+        u->ship->no = i;
+        shash(u->ship);
+        break;
+    case P_BUILDING:
+    case P_GEBAEUDE:
+        if (!u->building) {
+            cmistake(u, ord, 145, MSG_EVENT);
+            break;
+        }
+        if (building_owner(u->building) != u) {
+            cmistake(u, ord, 148, MSG_EVENT);
+            break;
+        }
+        s = gettoken(token, sizeof(token));
+        if (*s == 0) {
+            i = newcontainerid();
+        }
+        else {
+            i = atoi36((const char *)s);
+            if (i <= 0 || i > MAX_CONTAINER_NR) {
+                cmistake(u, ord, 114, MSG_EVENT);
+                break;
+            }
+            if (findship(i) || findbuilding(i)) {
+                cmistake(u, ord, 115, MSG_EVENT);
+                break;
+            }
+        }
+        bunhash(u->building);
+        u->building->no = i;
+        bhash(u->building);
+        break;
+
+    default:
+        cmistake(u, ord, 239, MSG_EVENT);
+    }
+    return 0;
+}
+
diff --git a/src/renumber.h b/src/renumber.h
new file mode 100644
index 000000000..244b8043f
--- /dev/null
+++ b/src/renumber.h
@@ -0,0 +1,12 @@
+#pragma once
+
+#ifndef H_RENUMBER
+#define H_RENUMBER
+
+	struct unit;
+	struct order;
+
+    void renumber_factions(void);
+    int renumber_cmd(struct unit *u, struct order *ord);
+
+#endif

From 83ea1077a3a7093456acc5f67e0ba7e72a528e6c Mon Sep 17 00:00:00 2001
From: Enno Rehling <enno.rehling@gmail.com>
Date: Tue, 15 Nov 2016 23:37:30 +0100
Subject: [PATCH 09/42] delete default terrain. github issue #538

---
 conf/e3/terrains.json | 8 --------
 1 file changed, 8 deletions(-)

diff --git a/conf/e3/terrains.json b/conf/e3/terrains.json
index 7b5ea980d..5aa876950 100644
--- a/conf/e3/terrains.json
+++ b/conf/e3/terrains.json
@@ -223,13 +223,5 @@
                 }
             }
         },
-        "default": {
-            "size": 0,
-            "herbs": [],
-            "seed": 0,
-            "road": 0,
-            "flags": [ "land", "walk", "sail", "fly" ],
-            "production": {}
-        }
     }
 }

From 360776f8b987b81ba13d9e47af8843228de264c6 Mon Sep 17 00:00:00 2001
From: Enno Rehling <enno.rehling@gmail.com>
Date: Tue, 15 Nov 2016 23:45:14 +0100
Subject: [PATCH 10/42] eliminate data_version variables, issue #479

---
 src/kernel/config.h | 1 -
 src/kernel/save.h   | 2 --
 2 files changed, 3 deletions(-)

diff --git a/src/kernel/config.h b/src/kernel/config.h
index 0d0506b47..ca83be114 100644
--- a/src/kernel/config.h
+++ b/src/kernel/config.h
@@ -138,7 +138,6 @@ struct param;
         struct attrib *attribs;
         unsigned int data_turn;
         void *vm_state;
-        int data_version; /* TODO: eliminate in favor of gamedata.version */
         struct _dictionary_ *inifile;
         struct global_functions {
             int(*wage) (const struct region * r, const struct faction * f,
diff --git a/src/kernel/save.h b/src/kernel/save.h
index 134fd8007..cfbcafd72 100644
--- a/src/kernel/save.h
+++ b/src/kernel/save.h
@@ -38,8 +38,6 @@ extern "C" {
     /* Nach MAX_INPUT_SIZE brechen wir das Einlesen der Zeile ab und nehmen an,
      * dass hier ein Fehler (fehlende ") vorliegt */
 
-    extern int data_version;
-
     // TODO: is this *really* still in use?
     extern int enc_gamedata;
 

From e50dfbf42bd4b3bb8a8fecd5eb3bbbeaa81617b9 Mon Sep 17 00:00:00 2001
From: Enno Rehling <enno.rehling@gmail.com>
Date: Tue, 15 Nov 2016 23:56:39 +0100
Subject: [PATCH 11/42] fix terrains.json, reduce config.h use

---
 conf/e3/terrains.json | 2 +-
 src/races/dragons.c   | 1 -
 src/races/illusion.c  | 1 -
 src/races/races.c     | 1 -
 src/races/races.h     | 1 +
 src/races/zombies.c   | 2 +-
 6 files changed, 3 insertions(+), 5 deletions(-)

diff --git a/conf/e3/terrains.json b/conf/e3/terrains.json
index 5aa876950..ee0eb0e37 100644
--- a/conf/e3/terrains.json
+++ b/conf/e3/terrains.json
@@ -222,6 +222,6 @@
                     "div": "100"
                 }
             }
-        },
+        }
     }
 }
diff --git a/src/races/dragons.c b/src/races/dragons.c
index 828e68c64..222d63c89 100644
--- a/src/races/dragons.c
+++ b/src/races/dragons.c
@@ -13,7 +13,6 @@
  */
 
 #include <platform.h>
-#include <kernel/config.h>
 
 /* kernel includes */
 #include <kernel/race.h>
diff --git a/src/races/illusion.c b/src/races/illusion.c
index e2a05cfd3..7411ae4d5 100644
--- a/src/races/illusion.c
+++ b/src/races/illusion.c
@@ -11,7 +11,6 @@
  */
 
 #include <platform.h>
-#include <kernel/config.h>
 
 /* kernel includes */
 #include <kernel/race.h>
diff --git a/src/races/races.c b/src/races/races.c
index 68b3c5ae2..2c6cfffa9 100644
--- a/src/races/races.c
+++ b/src/races/races.c
@@ -9,7 +9,6 @@
  */
 
 #include <platform.h>
-#include <kernel/config.h>
 #include "races.h"
 
 #include <kernel/building.h>
diff --git a/src/races/races.h b/src/races/races.h
index c0a516430..ea7be1337 100644
--- a/src/races/races.h
+++ b/src/races/races.h
@@ -14,6 +14,7 @@
 #ifdef __cplusplus
 extern "C" {
 #endif
+    struct unit;
 
     void register_races(void);
     void make_undead_unit(struct unit *);
diff --git a/src/races/zombies.c b/src/races/zombies.c
index d86074d26..ab4c89988 100644
--- a/src/races/zombies.c
+++ b/src/races/zombies.c
@@ -13,9 +13,9 @@
  */
 
 #include <platform.h>
-#include <kernel/config.h>
 
 /* kernel includes */
+#include <kernel/config.h>
 #include <kernel/race.h>
 #include <kernel/order.h>
 #include <kernel/unit.h>

From fbe846864d0b530f59c976e197715e4e9b106283 Mon Sep 17 00:00:00 2001
From: Enno Rehling <enno.rehling@gmail.com>
Date: Wed, 16 Nov 2016 18:08:10 +0100
Subject: [PATCH 12/42] arguments for test_setup that help debugging tests.

---
 src/give.test.c | 42 +++++++++++++++++++++---------------------
 src/tests.c     |  8 +++++++-
 src/tests.h     |  5 ++++-
 3 files changed, 32 insertions(+), 23 deletions(-)

diff --git a/src/give.test.c b/src/give.test.c
index 0d6149750..f2b0d60a9 100644
--- a/src/give.test.c
+++ b/src/give.test.c
@@ -56,7 +56,7 @@ static void setup_give(struct give *env) {
 
 static void test_give_unit_to_peasants(CuTest * tc) {
     struct give env = { 0 };
-    test_setup();
+    test_setup_ex(tc);
     env.f1 = test_create_faction(0);
     env.f2 = 0;
     setup_give(&env);
@@ -69,7 +69,7 @@ static void test_give_unit_to_peasants(CuTest * tc) {
 
 static void test_give_unit(CuTest * tc) {
     struct give env = { 0 };
-    test_setup();
+    test_setup_ex(tc);
     env.f1 = test_create_faction(0);
     env.f2 = test_create_faction(0);
     setup_give(&env);
@@ -88,7 +88,7 @@ static void test_give_unit(CuTest * tc) {
 
 static void test_give_unit_in_ocean(CuTest * tc) {
     struct give env = { 0 };
-    test_setup();
+    test_setup_ex(tc);
     env.f1 = test_create_faction(0);
     env.f2 = 0;
     setup_give(&env);
@@ -100,7 +100,7 @@ static void test_give_unit_in_ocean(CuTest * tc) {
 
 static void test_give_men(CuTest * tc) {
     struct give env = { 0 };
-    test_setup();
+    test_setup_ex(tc);
     env.f2 = env.f1 = test_create_faction(0);
     setup_give(&env);
     CuAssertPtrEquals(tc, 0, give_men(1, env.src, env.dst, NULL));
@@ -114,7 +114,7 @@ static void test_give_men_magicians(CuTest * tc) {
     int p;
     message * msg;
 
-    test_setup();
+    test_setup_ex(tc);
     env.f2 = env.f1 = test_create_faction(0);
     setup_give(&env);
     set_level(env.src, SK_MAGIC, 1);
@@ -143,7 +143,7 @@ static void test_give_men_magicians(CuTest * tc) {
 static void test_give_men_limit(CuTest * tc) {
     struct give env = { 0 };
     message *msg;
-    test_setup();
+    test_setup_ex(tc);
     env.f2 = test_create_faction(0);
     env.f1 = test_create_faction(0);
     setup_give(&env);
@@ -174,7 +174,7 @@ static void test_give_men_in_ocean(CuTest * tc) {
     struct give env = { 0 };
     message * msg;
 
-    test_setup();
+    test_setup_ex(tc);
     env.f1 = test_create_faction(0);
     env.f2 = 0;
     setup_give(&env);
@@ -188,7 +188,7 @@ static void test_give_men_in_ocean(CuTest * tc) {
 
 static void test_give_men_too_many(CuTest * tc) {
     struct give env = { 0 };
-    test_setup();
+    test_setup_ex(tc);
     env.f2 = env.f1 = test_create_faction(0);
     setup_give(&env);
     CuAssertPtrEquals(tc, 0, give_men(2, env.src, env.dst, NULL));
@@ -201,7 +201,7 @@ static void test_give_men_none(CuTest * tc) {
     struct give env = { 0 };
     message * msg;
 
-    test_setup();
+    test_setup_ex(tc);
     env.f2 = env.f1 = test_create_faction(0);
     setup_give(&env);
     msg = give_men(0, env.src, env.dst, NULL);
@@ -216,7 +216,7 @@ static void test_give_men_other_faction(CuTest * tc) {
     struct give env = { 0 };
     message * msg;
 
-    test_setup();
+    test_setup_ex(tc);
     env.f1 = test_create_faction(0);
     env.f2 = test_create_faction(0);
     setup_give(&env);
@@ -235,7 +235,7 @@ static void test_give_men_requires_contact(CuTest * tc) {
     order *ord;
     char cmd[32];
 
-    test_setup();
+    test_setup_ex(tc);
     env.f1 = test_create_faction(0);
     env.f2 = test_create_faction(0);
     setup_give(&env);
@@ -259,7 +259,7 @@ static void test_give_men_requires_contact(CuTest * tc) {
 static void test_give_men_not_to_self(CuTest * tc) {
     struct give env = { 0 };
     message * msg;
-    test_setup();
+    test_setup_ex(tc);
     env.f2 = env.f1 = test_create_faction(0);
     setup_give(&env);
     msg = give_men(1, env.src, env.src, NULL);
@@ -273,7 +273,7 @@ static void test_give_peasants(CuTest * tc) {
     struct give env = { 0 };
     message * msg;
 
-    test_setup();
+    test_setup_ex(tc);
     env.f1 = test_create_faction(0);
     env.f2 = 0;
     setup_give(&env);
@@ -289,7 +289,7 @@ static void test_give_peasants(CuTest * tc) {
 static void test_give(CuTest * tc) {
     struct give env = { 0 };
 
-    test_setup();
+    test_setup_ex(tc);
     env.f2 = env.f1 = test_create_faction(0);
     setup_give(&env);
 
@@ -309,7 +309,7 @@ static void test_give_cmd(CuTest * tc) {
     struct order *ord;
     char cmd[32];
 
-    test_setup();
+    test_setup_ex(tc);
     env.lang = test_create_locale();
     env.f2 = env.f1 = test_create_faction(0);
     setup_give(&env);
@@ -332,7 +332,7 @@ static void test_give_herbs(CuTest * tc) {
     struct order *ord;
     char cmd[32];
 
-    test_setup();
+    test_setup_ex(tc);
     test_create_world();
     env.f2 = env.f1 = test_create_faction(0);
     setup_give(&env);
@@ -352,7 +352,7 @@ static void test_give_herbs(CuTest * tc) {
 static void test_give_okay(CuTest * tc) {
     struct give env = { 0 };
 
-    test_setup();
+    test_setup_ex(tc);
     env.f2 = env.f1 = test_create_faction(0);
     setup_give(&env);
 
@@ -365,7 +365,7 @@ static void test_give_denied_by_rules(CuTest * tc) {
     struct give env = { 0 };
     struct message *msg;
 
-    test_setup();
+    test_setup_ex(tc);
     env.f1 = test_create_faction(0);
     env.f2 = test_create_faction(0);
     setup_give(&env);
@@ -380,7 +380,7 @@ static void test_give_dead_unit(CuTest * tc) {
     struct give env = { 0 };
     struct message *msg;
 
-    test_setup();
+    test_setup_ex(tc);
     env.f1 = test_create_faction(0);
     env.f2 = test_create_faction(0);
     setup_give(&env);
@@ -394,7 +394,7 @@ static void test_give_dead_unit(CuTest * tc) {
 static void test_give_new_unit(CuTest * tc) {
     struct give env = { 0 };
 
-    test_setup();
+    test_setup_ex(tc);
     env.f1 = test_create_faction(0);
     env.f2 = test_create_faction(0);
     setup_give(&env);
@@ -409,7 +409,7 @@ static void test_give_invalid_target(CuTest *tc) {
     struct give env = { 0 };
     order *ord;
 
-    test_setup();
+    test_setup_ex(tc);
     env.f1 = test_create_faction(0);
     env.f2 = 0;
     setup_give(&env);
diff --git a/src/tests.c b/src/tests.c
index 05855563a..15ae677fe 100644
--- a/src/tests.c
+++ b/src/tests.c
@@ -196,9 +196,15 @@ static void test_reset(void) {
     }
 }
 
-void test_setup(void) {
+void test_setup_test(CuTest *tc, const char *file, int line) {
     test_log_stderr(LOG_CPERROR);
     test_reset();
+    if (tc) {
+        log_debug("start test: %s", tc->name);
+    }
+    else {
+        log_debug("start test in %s:%d", file, line);
+    }
 }
 
 void test_cleanup(void)
diff --git a/src/tests.h b/src/tests.h
index cbc2a2511..c99147e6a 100644
--- a/src/tests.h
+++ b/src/tests.h
@@ -31,7 +31,10 @@ extern "C" {
 
     struct CuTest;
 
-    void test_setup(void);
+    void test_setup_test(struct CuTest *tc, const char *file, int line);
+#define test_setup() test_setup_test(NULL, __FILE__, __LINE__)
+#define test_setup_ex(tc) test_setup_test(tc, __FILE__, __LINE__)
+
     void test_cleanup(void);
     void test_log_stderr(int on);
     struct log_t * test_log_start(int flags, struct strlist **slist);

From 251c7bb55966bb30a4c9bb556036d01440b5f1fc Mon Sep 17 00:00:00 2001
From: Enno Rehling <enno.rehling@gmail.com>
Date: Wed, 16 Nov 2016 19:43:06 +0100
Subject: [PATCH 13/42] re-enable snowglobe assert.

---
 scripts/tests/xmas.lua | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/scripts/tests/xmas.lua b/scripts/tests/xmas.lua
index bbd4941f2..3667de0b6 100644
--- a/scripts/tests/xmas.lua
+++ b/scripts/tests/xmas.lua
@@ -52,7 +52,7 @@ function test_snowglobe()
     for k, v in pairs(xform) do
         r2.terrain = k
         process_orders()
-        -- TODO: re-enable! assert_equal(v, r2.terrain)
+        assert_equal(v, r2.terrain)
         if k~=v then
             have=have - 1 
         else

From 264fc0cb6fa2a35e658c62ea385e32585a466802 Mon Sep 17 00:00:00 2001
From: Enno Rehling <enno.rehling@gmail.com>
Date: Wed, 16 Nov 2016 20:03:34 +0100
Subject: [PATCH 14/42] test renumbering units and factions.

---
 src/CMakeLists.txt  |  1 +
 src/renumber.test.c | 53 +++++++++++++++++++++++++++++++++++++++++++++
 src/test_eressea.c  |  3 ++-
 3 files changed, 56 insertions(+), 1 deletion(-)
 create mode 100644 src/renumber.test.c

diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index 4616fc8e3..109a212f1 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -219,6 +219,7 @@ set(TESTS_SRC
   move.test.c
   piracy.test.c
   prefix.test.c
+  renumber.test.c
   skill.test.c
   spells.test.c
   spy.test.c
diff --git a/src/renumber.test.c b/src/renumber.test.c
new file mode 100644
index 000000000..5b8dc5e2c
--- /dev/null
+++ b/src/renumber.test.c
@@ -0,0 +1,53 @@
+#include "renumber.h"
+
+#include <tests.h>
+#include <kernel/unit.h>
+#include <kernel/faction.h>
+#include <kernel/order.h>
+#include <util/base36.h>
+#include <util/language.h>
+
+#include <stddef.h>
+#include <CuTest.h>
+
+static void test_renumber_faction(CuTest *tc) {
+    unit *u;
+    int uno, no;
+    const struct locale *lang;
+
+    test_setup_ex(tc);
+    u = test_create_unit(test_create_faction(0), test_create_region(0, 0, 0));
+    no = u->faction->no;
+    uno = (no > 1) ? no - 1 : no + 1;
+    lang = u->faction->locale;
+    u->thisorder = create_order(K_NUMBER, lang, "%s %s", LOC(lang, parameters[P_FACTION]), itoa36(uno));
+    renumber_cmd(u, u->thisorder);
+    renumber_factions();
+    CuAssertIntEquals(tc, uno, u->faction->no);
+    test_cleanup();
+}
+
+static void test_renumber_unit(CuTest *tc) {
+    unit *u;
+    int uno, no;
+    const struct locale *lang;
+
+    test_setup_ex(tc);
+    u = test_create_unit(test_create_faction(0), test_create_region(0, 0, 0));
+    no = u->no;
+    uno = (no > 1) ? no - 1 : no + 1;
+    lang = u->faction->locale;
+    u->thisorder = create_order(K_NUMBER, lang, "%s %s", LOC(lang, parameters[P_UNIT]), itoa36(uno));
+    renumber_cmd(u, u->thisorder);
+    CuAssertIntEquals(tc, uno, u->no);
+    CuAssertIntEquals(tc, -no, ualias(u)); // TODO: why is ualias negative?
+    test_cleanup();
+}
+
+CuSuite *get_renumber_suite(void)
+{
+    CuSuite *suite = CuSuiteNew();
+    SUITE_ADD_TEST(suite, test_renumber_unit);
+    SUITE_ADD_TEST(suite, test_renumber_faction);
+    return suite;
+}
diff --git a/src/test_eressea.c b/src/test_eressea.c
index 39ec90be6..330afd5bc 100644
--- a/src/test_eressea.c
+++ b/src/test_eressea.c
@@ -114,7 +114,6 @@ int RunAllTests(int argc, char *argv[])
     ADD_SUITE(guard);
     ADD_SUITE(report);
     ADD_SUITE(creport);
-    ADD_SUITE(prefix);
     ADD_SUITE(summary);
     ADD_SUITE(names);
     ADD_SUITE(battle);
@@ -130,6 +129,8 @@ int RunAllTests(int argc, char *argv[])
     ADD_SUITE(monsters);
     ADD_SUITE(move);
     ADD_SUITE(piracy);
+    ADD_SUITE(prefix);
+    ADD_SUITE(renumber);
     ADD_SUITE(key);
     ADD_SUITE(stealth);
     ADD_SUITE(otherfaction);

From 4a667326371761c32ff0a9a1ec78f759727f5e2f Mon Sep 17 00:00:00 2001
From: Enno Rehling <enno.rehling@gmail.com>
Date: Wed, 16 Nov 2016 20:41:48 +0100
Subject: [PATCH 15/42] renumber tests for building, ship

---
 src/renumber.test.c | 38 ++++++++++++++++++++++++++++++++++++++
 1 file changed, 38 insertions(+)

diff --git a/src/renumber.test.c b/src/renumber.test.c
index 5b8dc5e2c..3fabaf4c1 100644
--- a/src/renumber.test.c
+++ b/src/renumber.test.c
@@ -3,6 +3,8 @@
 #include <tests.h>
 #include <kernel/unit.h>
 #include <kernel/faction.h>
+#include <kernel/building.h>
+#include <kernel/ship.h>
 #include <kernel/order.h>
 #include <util/base36.h>
 #include <util/language.h>
@@ -27,6 +29,40 @@ static void test_renumber_faction(CuTest *tc) {
     test_cleanup();
 }
 
+static void test_renumber_building(CuTest *tc) {
+    unit *u;
+    int uno, no;
+    const struct locale *lang;
+
+    test_setup_ex(tc);
+    u = test_create_unit(test_create_faction(0), test_create_region(0, 0, 0));
+    u->building = test_create_building(u->region, 0);
+    no = u->building->no;
+    uno = (no > 1) ? no - 1 : no + 1;
+    lang = u->faction->locale;
+    u->thisorder = create_order(K_NUMBER, lang, "%s %s", LOC(lang, parameters[P_BUILDING]), itoa36(uno));
+    renumber_cmd(u, u->thisorder);
+    CuAssertIntEquals(tc, uno, u->building->no);
+    test_cleanup();
+}
+
+static void test_renumber_ship(CuTest *tc) {
+    unit *u;
+    int uno, no;
+    const struct locale *lang;
+
+    test_setup_ex(tc);
+    u = test_create_unit(test_create_faction(0), test_create_region(0, 0, 0));
+    u->ship = test_create_ship(u->region, 0);
+    no = u->ship->no;
+    uno = (no > 1) ? no - 1 : no + 1;
+    lang = u->faction->locale;
+    u->thisorder = create_order(K_NUMBER, lang, "%s %s", LOC(lang, parameters[P_SHIP]), itoa36(uno));
+    renumber_cmd(u, u->thisorder);
+    CuAssertIntEquals(tc, uno, u->ship->no);
+    test_cleanup();
+}
+
 static void test_renumber_unit(CuTest *tc) {
     unit *u;
     int uno, no;
@@ -48,6 +84,8 @@ CuSuite *get_renumber_suite(void)
 {
     CuSuite *suite = CuSuiteNew();
     SUITE_ADD_TEST(suite, test_renumber_unit);
+    SUITE_ADD_TEST(suite, test_renumber_building);
+    SUITE_ADD_TEST(suite, test_renumber_ship);
     SUITE_ADD_TEST(suite, test_renumber_faction);
     return suite;
 }

From 413f70d1a1b429813bcc0e9b141ecaf4c5ed1cc7 Mon Sep 17 00:00:00 2001
From: Enno Rehling <enno.rehling@gmail.com>
Date: Wed, 16 Nov 2016 22:30:59 +0100
Subject: [PATCH 16/42] move market function out of config.c

---
 src/creport.c          | 1 +
 src/kernel/config.c    | 5 -----
 src/kernel/config.h    | 1 -
 src/market.c           | 5 +++++
 src/market.h           | 3 ++-
 src/modules/autoseed.c | 2 ++
 src/report.c           | 3 ++-
 7 files changed, 12 insertions(+), 8 deletions(-)

diff --git a/src/creport.c b/src/creport.c
index becee2cb0..b74c5cdef 100644
--- a/src/creport.c
+++ b/src/creport.c
@@ -11,6 +11,7 @@ without prior permission by the authors of Eressea.
 #include <kernel/config.h>
 #include <kernel/version.h>
 #include "creport.h"
+#include "market.h"
 #include "guard.h"
 #include "travelthru.h"
 
diff --git a/src/kernel/config.c b/src/kernel/config.c
index 78af1ad02..d8be01ed9 100644
--- a/src/kernel/config.c
+++ b/src/kernel/config.c
@@ -1061,11 +1061,6 @@ int rule_give(void)
     return rule;
 }
 
-bool markets_module(void)
-{
-    return (bool)config_get_int("modules.markets", 0);
-}
-
 static struct param *configuration;
 static int config_cache_key = 1;
 
diff --git a/src/kernel/config.h b/src/kernel/config.h
index ca83be114..9a0d1d1fb 100644
--- a/src/kernel/config.h
+++ b/src/kernel/config.h
@@ -114,7 +114,6 @@ struct param;
 #define GF_PURE 64
     /* untranslated */
 
-    bool markets_module(void);
     int wage(const struct region *r, const struct faction *f,
         const struct race *rc, int in_turn);
 
diff --git a/src/market.c b/src/market.c
index efcaf0d98..cef84b9b2 100644
--- a/src/market.c
+++ b/src/market.c
@@ -85,6 +85,11 @@ static int rc_herb_trade(const struct race *rc)
 #define MAX_MARKETS 128
 #define MIN_PEASANTS 50         /* if there are at least this many peasants, you will get 1 good */
 
+bool markets_module(void)
+{
+    return (bool)config_get_int("modules.markets", 0);
+}
+
 void do_markets(void)
 {
     quicklist *traders = 0;
diff --git a/src/market.h b/src/market.h
index dd15253ef..a74c88391 100644
--- a/src/market.h
+++ b/src/market.h
@@ -17,7 +17,8 @@ extern "C" {
 #endif
     struct building;
 
-    extern void do_markets(void);
+    bool markets_module(void);
+    void do_markets(void);
 
 #ifdef __cplusplus
 }
diff --git a/src/modules/autoseed.c b/src/modules/autoseed.c
index 3bcf36848..5420406c0 100644
--- a/src/modules/autoseed.c
+++ b/src/modules/autoseed.c
@@ -14,6 +14,8 @@
 #include <kernel/config.h>
 #include "autoseed.h"
 
+#include "market.h"
+
 /* kernel includes */
 #include <kernel/alliance.h>
 #include <kernel/item.h>
diff --git a/src/report.c b/src/report.c
index 23dcadb34..80ac85974 100644
--- a/src/report.c
+++ b/src/report.c
@@ -25,8 +25,9 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 #include "reports.h"
 #include "guard.h"
 #include "laws.h"
-#include "travelthru.h"
+#include "market.h"
 #include "monster.h"
+#include "travelthru.h"
 
 /* modules includes */
 #include <modules/score.h>

From a88bfa7a9a4aa8f3c18a302bf627fde23307460d Mon Sep 17 00:00:00 2001
From: Enno Rehling <enno.rehling@gmail.com>
Date: Wed, 16 Nov 2016 22:46:01 +0100
Subject: [PATCH 17/42] decluttering config.c (rules go into laws.c)

---
 s/build             |  2 +-
 src/kernel/config.c | 31 -------------------------------
 src/kernel/config.h |  5 -----
 src/laws.c          | 26 ++++++++++++++++++++++++++
 src/laws.h          |  4 ++++
 src/study.c         | 13 ++++++++++++-
 6 files changed, 43 insertions(+), 38 deletions(-)

diff --git a/s/build b/s/build
index b59804626..363e3e5a6 100755
--- a/s/build
+++ b/s/build
@@ -39,5 +39,5 @@ echo "build eressea"
 cd $ROOT/$BUILD
 VERSION=$(git describe --match 'v*.*.*' --tags | sed 's/^v//')
 cmake -DERESSEA_VERSION="$VERSION" ..
-make $MAKEOPTS && make test
+make -k $MAKEOPTS && make test
 cd $OLDPWD
diff --git a/src/kernel/config.c b/src/kernel/config.c
index d8be01ed9..7ca8a5ba7 100644
--- a/src/kernel/config.c
+++ b/src/kernel/config.c
@@ -105,37 +105,6 @@ FILE *logfile;
 bool battledebug = false;
 int turn = -1;
 
-int NewbieImmunity(void)
-{
-    return config_get_int("NewbieImmunity", 0);
-}
-
-bool IsImmune(const faction * f)
-{
-    return !fval(f, FFL_NPC) && f->age < NewbieImmunity();
-}
-
-bool ExpensiveMigrants(void)
-{
-    return config_get_int("study.expensivemigrants", 0) != 0;
-}
-
-int LongHunger(const struct unit *u)
-{
-    if (u != NULL) {
-        if (!fval(u, UFL_HUNGER))
-            return false;
-        if (u_race(u) == get_race(RC_DAEMON))
-            return false;
-    }
-    return config_get_int("hunger.long", 0);
-}
-
-int NMRTimeout(void)
-{
-    return config_get_int("nmr.timeout", 0);
-}
-
 helpmode helpmodes[] = {
     { "all", HELP_ALL }
     ,
diff --git a/src/kernel/config.h b/src/kernel/config.h
index 9a0d1d1fb..84bc1ba75 100644
--- a/src/kernel/config.h
+++ b/src/kernel/config.h
@@ -164,11 +164,6 @@ struct param;
     bool config_changed(int *cache_key);
 
     char * join_path(const char *p1, const char *p2, char *dst, size_t len);
-    bool ExpensiveMigrants(void);
-    int NMRTimeout(void);
-    int LongHunger(const struct unit *u);
-    int NewbieImmunity(void);
-    bool IsImmune(const struct faction *f);
 
     struct order *default_order(const struct locale *lang);
 
diff --git a/src/laws.c b/src/laws.c
index cf365fc7a..0ba3f4077 100644
--- a/src/laws.c
+++ b/src/laws.c
@@ -117,6 +117,32 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 
 /* - exported global symbols ----------------------------------- */
 
+int NewbieImmunity(void)
+{
+    return config_get_int("NewbieImmunity", 0);
+}
+
+bool IsImmune(const faction * f)
+{
+    return !fval(f, FFL_NPC) && f->age < NewbieImmunity();
+}
+
+int NMRTimeout(void)
+{
+    return config_get_int("nmr.timeout", 0);
+}
+
+bool LongHunger(const struct unit *u)
+{
+    if (u != NULL) {
+        if (!fval(u, UFL_HUNGER))
+            return false;
+        if (u_race(u) == get_race(RC_DAEMON))
+            return false;
+    }
+    return config_get_int("hunger.long", 0) != 0;
+}
+
 static bool RemoveNMRNewbie(void)
 {
     int value = config_get_int("nmr.removenewbie", 0);
diff --git a/src/laws.h b/src/laws.h
index 5406a50d4..0adb010d2 100755
--- a/src/laws.h
+++ b/src/laws.h
@@ -108,6 +108,10 @@ extern "C" {
     #define FORCE_LEAVE_POSTCOMBAT 1
     #define FORCE_LEAVE_ALL 2
     bool rule_force_leave(int flag);
+    bool LongHunger(const struct unit *u);
+    int NMRTimeout(void);
+    int NewbieImmunity(void);
+    bool IsImmune(const struct faction *f);
     bool help_enter(struct unit *uo, struct unit *u);
 
 #ifdef __cplusplus
diff --git a/src/study.c b/src/study.c
index 59f1130ea..1cd8847be 100644
--- a/src/study.c
+++ b/src/study.c
@@ -22,6 +22,7 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 #include <platform.h>
 #include <kernel/config.h>
 #include "study.h"
+#include "laws.h"
 #include "move.h"
 #include "monster.h"
 #include "alchemy.h"
@@ -531,6 +532,16 @@ static double study_speedup(unit * u, skill_t s, study_rule_t rule)
     return 1.0;
 }
 
+static bool ExpensiveMigrants(void)
+{
+	static bool rule;
+	static int cache;
+	if (config_changed(&cache)) {
+		rule = config_get_int("study.expensivemigrants", 0) != 0;
+	}
+	return rule;
+}
+
 int study_cmd(unit * u, order * ord)
 {
     region *r = u->region;
@@ -772,7 +783,7 @@ int study_cmd(unit * u, order * ord)
         a_remove(&u->attribs, a);
         a = NULL;
     }
-    fset(u, UFL_LONGACTION | UFL_NOTMOVING);
+    u->flags |= (UFL_LONGACTION | UFL_NOTMOVING);
 
     /* Anzeigen neuer Traenke */
     /* Spruchlistenaktualiesierung ist in Regeneration */

From 6a75b20315fedb4e27d17fec7016fee71bb1466c Mon Sep 17 00:00:00 2001
From: Enno Rehling <enno.rehling@gmail.com>
Date: Wed, 16 Nov 2016 22:57:17 +0100
Subject: [PATCH 18/42] remove wdwpyramid

---
 src/spells.c | 5 -----
 1 file changed, 5 deletions(-)

diff --git a/src/spells.c b/src/spells.c
index 44bd07dec..da2b73c5e 100644
--- a/src/spells.c
+++ b/src/spells.c
@@ -107,10 +107,6 @@
 
 static double zero_effect = 0.0;
 
-attrib_type at_wdwpyramid = {
-    "wdwpyramid", NULL, NULL, NULL, NULL, NULL
-};
-
 /* ----------------------------------------------------------------------- */
 
 static void report_spell(unit * mage, region * r, message * msg)
@@ -6722,7 +6718,6 @@ void register_spells(void)
 {
     register_borders();
 
-    at_register(&at_wdwpyramid);
     at_register(&at_deathcloud_compat);
 
     /* init_firewall(); */

From 3a64a2f4048281e39373b5d2b01c05ef692a871d Mon Sep 17 00:00:00 2001
From: Enno Rehling <enno.rehling@gmail.com>
Date: Wed, 16 Nov 2016 23:09:07 +0100
Subject: [PATCH 19/42] stop spamming the log when using a listbox.

---
 src/listbox.c | 3 ---
 1 file changed, 3 deletions(-)

diff --git a/src/listbox.c b/src/listbox.c
index 3686cbba1..332041454 100644
--- a/src/listbox.c
+++ b/src/listbox.c
@@ -88,7 +88,6 @@ list_selection *do_selection(list_selection * sel, const char *title,
             width = (int)strlen(s->str);
         }
         ++height;
-        log_debug("s %s w %d h %d\n", s->str, width, height);
     }
     if (height == 0 || width == 0)
         return 0;
@@ -97,8 +96,6 @@ list_selection *do_selection(list_selection * sel, const char *title,
     if (height + 2 > SY)
         height = SY - 2;
 
-    log_debug("w %d h %d\n", width, height);
-
     wn =
         newwin(height + 2, width + 4, (SY - height - 2) / 2, (SX - width - 4) / 2);
 

From 42eff95ec28e301c83714a9c042afe02fc98039a Mon Sep 17 00:00:00 2001
From: Enno Rehling <enno@eressea.de>
Date: Thu, 17 Nov 2016 10:26:30 +0100
Subject: [PATCH 20/42] remove unused empty files

---
 src/bind_log.c | 0
 src/bind_log.h | 0
 2 files changed, 0 insertions(+), 0 deletions(-)
 delete mode 100644 src/bind_log.c
 delete mode 100644 src/bind_log.h

diff --git a/src/bind_log.c b/src/bind_log.c
deleted file mode 100644
index e69de29bb..000000000
diff --git a/src/bind_log.h b/src/bind_log.h
deleted file mode 100644
index e69de29bb..000000000

From f371a0c5f32b03e97e4ed2771431891ca4603db6 Mon Sep 17 00:00:00 2001
From: Enno Rehling <enno@eressea.de>
Date: Thu, 17 Nov 2016 10:32:20 +0100
Subject: [PATCH 21/42] eliminate unused callback module. what was I thinking
 when I wrote this?

---
 src/CMakeLists.txt  |  2 --
 src/callback.c      | 61 ---------------------------------------------
 src/callback.h      | 16 ------------
 src/callback.test.c | 51 -------------------------------------
 src/test_eressea.c  |  1 -
 5 files changed, 131 deletions(-)
 delete mode 100644 src/callback.c
 delete mode 100644 src/callback.h
 delete mode 100644 src/callback.test.c

diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index 109a212f1..34cea4037 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -99,7 +99,6 @@ set (ERESSEA_SRC
   prefix.c
   donations.c
   eressea.c
-  callback.c
   direction.c
   keyword.c
   skill.c
@@ -205,7 +204,6 @@ set(TESTS_SRC
   report.test.c
   summary.test.c
   travelthru.test.c
-  callback.test.c
   direction.test.c
   economy.test.c
   json.test.c
diff --git a/src/callback.c b/src/callback.c
deleted file mode 100644
index 79bd69b71..000000000
--- a/src/callback.c
+++ /dev/null
@@ -1,61 +0,0 @@
-#include <platform.h>
-#include "callback.h"
-#include <stdlib.h>
-#include <string.h>
-
-static struct reg {
-    struct reg * next;
-    HCALLBACK cb;
-    char *name;
-} *registry;
-
-HCALLBACK create_callback(void(*cbv)(va_list va)) {
-    HCALLBACK cb;
-    cb.cbv = cbv;
-    return cb;
-}
-
-void reset_callbacks(void) {
-    while (registry) {
-        struct reg *r = registry;
-        registry = r->next;
-        free(r->name);
-        free(r);
-    }
-    registry = 0;
-}
-
-HCALLBACK register_callback(const char *name, void(*cbv)(va_list va))
-{
-    struct reg * r = (struct reg *)malloc(sizeof(struct reg));
-    r->next = registry;
-    r->name = _strdup(name);
-    r->cb.cbv = cbv;
-    registry = r;
-    return r->cb;
-}
-
-int find_callback(const char *name, HCALLBACK *result) {
-    if (result && name) {
-        struct reg *r;
-        for (r = registry; r; r = r->next) {
-            if (strcmp(r->name, name) == 0) {
-                *result = r->cb;
-                return 0;
-            }
-        }
-    }
-    return -1;
-}
-
-int call_callback(HCALLBACK cb, const char *name, ...) {
-    va_list ap;
-    if (name) {
-        int err = find_callback(name, &cb);
-        if (err) return err;
-    }
-    va_start(ap, name);
-    cb.cbv(ap);
-    va_end(ap);
-    return 0;
-}
diff --git a/src/callback.h b/src/callback.h
deleted file mode 100644
index 288a148e9..000000000
--- a/src/callback.h
+++ /dev/null
@@ -1,16 +0,0 @@
-#ifndef H_CALLBACK_H
-#define H_CALLBACK_H
-
-#include <stdarg.h>
-
-typedef struct {
-    void(*cbv)(va_list va);
-} HCALLBACK;
-
-HCALLBACK register_callback(const char *name, void(*cbv)(va_list va));
-HCALLBACK create_callback(void(*cbv)(va_list va));
-int find_callback(const char *name, HCALLBACK *result);
-int call_callback(HCALLBACK cb, const char *name, ...);
-void reset_callbacks(void);
-
-#endif
diff --git a/src/callback.test.c b/src/callback.test.c
deleted file mode 100644
index 317cc6d50..000000000
--- a/src/callback.test.c
+++ /dev/null
@@ -1,51 +0,0 @@
-#include "callback.h"
-#include <stdlib.h>
-#include <CuTest.h>
-
-void callback(va_list ap) {
-    int i = (int)va_arg(ap, int);
-    int *p = va_arg(ap, int *);
-    *p += i;
-}
-
-static void test_find_callback(CuTest *tc) {
-    HCALLBACK cb;
-    reset_callbacks();
-    CuAssertIntEquals(tc, -1, find_callback("test", &cb));
-    cb = register_callback("test", callback);
-    CuAssertIntEquals(tc, 0, find_callback("test", &cb));
-    reset_callbacks();
-}
-
-static void test_call_by_handle(CuTest *tc) {
-    HCALLBACK cb;
-    int x = 0;
-    reset_callbacks();
-    cb = create_callback(callback);
-    CuAssertIntEquals(tc, 0, call_callback(cb, 0, 42, &x));
-    CuAssertIntEquals(tc, 42, x);
-    reset_callbacks();
-}
-
-static void test_call_by_name(CuTest *tc) {
-    HCALLBACK cb = { 0 };
-    HCALLBACK ca = { 0 };
-    int x = 0;
-    reset_callbacks();
-    CuAssertIntEquals(tc, -1, call_callback(cb, "test", 42, &x));
-    cb = register_callback("test", callback);
-    CuAssertIntEquals(tc, 0, call_callback(cb, "test", 42, &x));
-    CuAssertIntEquals(tc, 42, x);
-    CuAssertIntEquals(tc, 0, call_callback(ca, "test", 42, &x));
-    CuAssertIntEquals(tc, 84, x);
-    reset_callbacks();
-}
-
-CuSuite *get_callback_suite(void)
-{
-    CuSuite *suite = CuSuiteNew();
-    SUITE_ADD_TEST(suite, test_find_callback);
-    SUITE_ADD_TEST(suite, test_call_by_name);
-    SUITE_ADD_TEST(suite, test_call_by_handle);
-    return suite;
-}
diff --git a/src/test_eressea.c b/src/test_eressea.c
index 330afd5bc..71cf008f2 100644
--- a/src/test_eressea.c
+++ b/src/test_eressea.c
@@ -60,7 +60,6 @@ int RunAllTests(int argc, char *argv[])
 {
     /* self-test */
     ADD_SUITE(tests);
-    ADD_SUITE(callback);
     ADD_SUITE(json);
     ADD_SUITE(jsonconf);
     ADD_SUITE(direction);

From cbb18edb8fa074a0125e6014400071e3d85dc049 Mon Sep 17 00:00:00 2001
From: Enno Rehling <enno@eressea.de>
Date: Thu, 17 Nov 2016 10:38:09 +0100
Subject: [PATCH 22/42] declutter config.h, use it sparingly.

---
 src/bind_faction.c   | 18 +++++++++++-
 src/bind_message.c   |  2 --
 src/bind_order.c     |  1 -
 src/bind_storage.c   |  1 -
 src/chaos.c          | 29 +++++++++----------
 src/kernel/config.c  | 67 ++++----------------------------------------
 src/kernel/config.h  | 25 ++++-------------
 src/kernel/faction.h |  8 ++++--
 src/kernel/save.h    |  2 ++
 src/reports.c        | 16 +++++++++++
 src/reports.h        |  1 +
 11 files changed, 66 insertions(+), 104 deletions(-)

diff --git a/src/bind_faction.c b/src/bind_faction.c
index 688b093b5..36da798c1 100644
--- a/src/bind_faction.c
+++ b/src/bind_faction.c
@@ -19,7 +19,6 @@ without prior permission by the authors of Eressea.
 
 #include <kernel/alliance.h>
 #include <kernel/faction.h>
-#include <kernel/config.h>
 #include <kernel/unit.h>
 #include <kernel/item.h>
 #include <kernel/faction.h>
@@ -38,6 +37,23 @@ without prior permission by the authors of Eressea.
 #include <tolua.h>
 #include <string.h>
 
+typedef struct helpmode {
+    const char *name;
+    int status;
+} helpmode;
+
+static helpmode helpmodes[] = {
+    { "all", HELP_ALL },
+    { "money", HELP_MONEY },
+    { "fight", HELP_FIGHT },
+    { "observe", HELP_OBSERVE },
+    { "give", HELP_GIVE },
+    { "guard", HELP_GUARD },
+    { "stealth", HELP_FSTEALTH },
+    { "travel", HELP_TRAVEL },
+    { NULL, 0 }
+};
+
 int tolua_factionlist_next(lua_State * L)
 {
     faction **faction_ptr = (faction **)lua_touserdata(L, lua_upvalueindex(1));
diff --git a/src/bind_message.c b/src/bind_message.c
index 15673f4f6..a3ab95d39 100644
--- a/src/bind_message.c
+++ b/src/bind_message.c
@@ -1,6 +1,4 @@
 #include <platform.h>
-#include <kernel/config.h>
-
 #include "spells.h"
 
 /* kernel includes */
diff --git a/src/bind_order.c b/src/bind_order.c
index 90fc7d3b0..84399deec 100644
--- a/src/bind_order.c
+++ b/src/bind_order.c
@@ -1,5 +1,4 @@
 #include <platform.h>
-#include <kernel/config.h>
 
 /* kernel includes */
 #include <kernel/order.h>
diff --git a/src/bind_storage.c b/src/bind_storage.c
index 489255d3f..a81a3baeb 100644
--- a/src/bind_storage.c
+++ b/src/bind_storage.c
@@ -11,7 +11,6 @@ without prior permission by the authors of Eressea.
 */
 
 #include <platform.h>
-#include <kernel/config.h>
 #include "bind_storage.h"
 
 #include <kernel/save.h>
diff --git a/src/chaos.c b/src/chaos.c
index 7a1be7e56..942fb87bc 100644
--- a/src/chaos.c
+++ b/src/chaos.c
@@ -85,7 +85,7 @@ static const terrain_type *chaosterrain(void)
     if (numtypes == 0) {
         const terrain_type *terrain;
         for (terrain = terrains(); terrain != NULL; terrain = terrain->next) {
-            if (fval(terrain, LAND_REGION) && terrain->herbs) {
+            if ((terrain->flags & LAND_REGION) && terrain->herbs) {
                 ++numtypes;
             }
         }
@@ -93,7 +93,7 @@ static const terrain_type *chaosterrain(void)
             types = malloc(sizeof(terrain_type *) * numtypes);
             numtypes = 0;
             for (terrain = terrains(); terrain != NULL; terrain = terrain->next) {
-                if (fval(terrain, LAND_REGION) && terrain->herbs) {
+                if ((terrain->flags & LAND_REGION) && terrain->herbs) {
                     types[numtypes++] = terrain;
                 }
             }
@@ -139,7 +139,7 @@ static void chaos(region * r)
     if (rng_int() % 100 < 8) {
         switch (rng_int() % 3) {
         case 0:                  /* Untote */
-            if (!fval(r->terrain, SEA_REGION)) {
+            if (!(r->terrain->flags & SEA_REGION)) {
                 unit *u = random_unit(r);
                 if (u && playerrace(u_race(u))) {
                     ADDMSG(&u->faction->msgs, msg_message("chaos_disease", "unit", u));
@@ -161,29 +161,28 @@ static void chaos(region * r)
                     break;
                 case 1:
                     mfac = 500;
-                    u =
-                        create_unit(r, get_monsters(), rng_int() % 4 + 1,
+                    u = create_unit(r, get_monsters(), rng_int() % 4 + 1,
                         get_race(RC_DRAGON), 0, NULL, NULL);
                     break;
                 default:
                     mfac = 1000;
-                    u =
-                        create_unit(r, get_monsters(), rng_int() % 2 + 1,
+                    u = create_unit(r, get_monsters(), rng_int() % 2 + 1,
                         get_race(RC_WYRM), 0, NULL, NULL);
                     break;
                 }
-                if (mfac)
+                if (mfac) {
                     set_money(u, u->number * (rng_int() % mfac));
-                fset(u, UFL_ISNEW | UFL_MOVED);
+                }
+                u->flags |= (UFL_ISNEW | UFL_MOVED);
             }
             break;
-        case 2:                  /* Terrainver�nderung */
-            if (!fval(r->terrain, FORBIDDEN_REGION)) {
-                if (!fval(r->terrain, SEA_REGION)) {
+        case 2:                  /* Terrainver�nderung */
+            if (!(r->terrain->flags & FORBIDDEN_REGION)) {
+                if (!(r->terrain->flags & SEA_REGION)) {
                     direction_t dir;
                     for (dir = 0; dir != MAXDIRECTIONS; ++dir) {
                         region *rn = rconnect(r, dir);
-                        if (rn && fval(rn->terrain, SEA_REGION))
+                        if (rn && (rn->terrain->flags & SEA_REGION))
                             break;
                     }
                     if (dir != MAXDIRECTIONS) {
@@ -224,7 +223,7 @@ static void chaos(region * r)
                     direction_t dir;
                     for (dir = 0; dir != MAXDIRECTIONS; ++dir) {
                         region *rn = rconnect(r, dir);
-                        if (rn && fval(rn->terrain, SEA_REGION))
+                        if (rn && (rn->terrain->flags & SEA_REGION))
                             break;
                     }
                     if (dir != MAXDIRECTIONS) {
@@ -242,7 +241,7 @@ void chaos_update(void) {
     for (r = regions; r; r = r->next) {
         int i;
 
-        if (fval(r, RF_CHAOTIC)) {
+        if ((r->flags & RF_CHAOTIC)) {
             chaos(r);
         }
         i = get_chaoscount(r);
diff --git a/src/kernel/config.c b/src/kernel/config.c
index 7ca8a5ba7..10b35bce9 100644
--- a/src/kernel/config.c
+++ b/src/kernel/config.c
@@ -105,26 +105,6 @@ FILE *logfile;
 bool battledebug = false;
 int turn = -1;
 
-helpmode helpmodes[] = {
-    { "all", HELP_ALL }
-    ,
-    { "money", HELP_MONEY }
-    ,
-    { "fight", HELP_FIGHT }
-    ,
-    { "observe", HELP_OBSERVE }
-    ,
-    { "give", HELP_GIVE }
-    ,
-    { "guard", HELP_GUARD }
-    ,
-    { "stealth", HELP_FSTEALTH }
-    ,
-    { "travel", HELP_TRAVEL }
-    ,
-    { NULL, 0 }
-};
-
 const char *parameters[MAXPARAMS] = {
     "LOCALE",
     "ALLES",
@@ -148,7 +128,7 @@ const char *parameters[MAXPARAMS] = {
     "TEMP",
     "FLIEHE",
     "GEBAEUDE",
-    "GIB",                        /* F�r HELFE */
+    "GIB",                        /* F�r HELFE */
     "KAEMPFE",
     "DURCHREISE",
     "BEWACHE",
@@ -172,43 +152,6 @@ const char *parameters[MAXPARAMS] = {
     "ALLIANZ"
 };
 
-const char *report_options[MAX_MSG] = {
-    "Kampf",
-    "Ereignisse",
-    "Bewegung",
-    "Einkommen",
-    "Handel",
-    "Produktion",
-    "Orkvermehrung",
-    "Zauber",
-    "",
-    ""
-};
-
-const char *message_levels[ML_MAX] = {
-    "Wichtig",
-    "Debug",
-    "Fehler",
-    "Warnungen",
-    "Infos"
-};
-
-const char *options[MAXOPTIONS] = {
-    "AUSWERTUNG",
-    "COMPUTER",
-    "ZUGVORLAGE",
-    NULL,
-    "STATISTIK",
-    "DEBUG",
-    "ZIPPED",
-    "ZEITUNG",                    /* Option hat Sonderbehandlung! */
-    NULL,
-    "ADRESSEN",
-    "BZIP2",
-    "PUNKTE",
-    "SHOWSKCHANGE"
-};
-
 FILE *debug;
 
 void
@@ -711,8 +654,8 @@ char *_strdup(const char *s)
 }
 #endif
 
-/* Lohn bei den einzelnen Burgstufen f�r Normale Typen, Orks, Bauern,
- * Modifikation f�r St�dter. */
+/* Lohn bei den einzelnen Burgstufen f�r Normale Typen, Orks, Bauern,
+ * Modifikation f�r St�dter. */
 
 static const int wagetable[7][4] = {
     { 10, 10, 11, -7 },             /* Baustelle */
@@ -929,7 +872,7 @@ default_wage(const region * r, const faction * f, const race * rc, int in_turn)
             wage = _max(0, wage - 10);
         }
 
-        /* Bei einer D�rre verdient man nur noch ein Viertel  */
+        /* Bei einer D�rre verdient man nur noch ein Viertel  */
         if (drought_ct) {
             curse *c = get_curse(r->attribs, drought_ct);
             if (curse_active(c))
@@ -953,7 +896,7 @@ minimum_wage(const region * r, const faction * f, const race * rc, int in_turn)
     return default_wage(r, f, rc, in_turn);
 }
 
-/* Gibt Arbeitslohn f�r entsprechende Rasse zur�ck, oder f�r
+/* Gibt Arbeitslohn f�r entsprechende Rasse zur�ck, oder f�r
 * die Bauern wenn f == NULL. */
 int wage(const region * r, const faction * f, const race * rc, int in_turn)
 {
diff --git a/src/kernel/config.h b/src/kernel/config.h
index 84bc1ba75..ca2686a1b 100644
--- a/src/kernel/config.h
+++ b/src/kernel/config.h
@@ -27,17 +27,12 @@ extern "C" {
 #include "types.h"
 struct param;
 
-#define DISPLAYSIZE         8192        /* max. L�nge einer Beschreibung, incl trailing 0 */
+#define DISPLAYSIZE         8192        /* max. L�nge einer Beschreibung, incl trailing 0 */
 #define ORDERSIZE           (DISPLAYSIZE*2) /* max. length of an order */
-#define NAMESIZE            128 /* max. L�nge eines Namens, incl trailing 0 */
-#define IDSIZE              16  /* max. L�nge einer no (als String), incl trailing 0 */
-#define OBJECTIDSIZE        (NAMESIZE+5+IDSIZE) /* max. L�nge der Strings, die
-     * von struct unitname, etc. zur�ckgegeben werden. ohne die 0 */
-
-    /* ----------------- Befehle ----------------------------------- */
-
-#define want(option) (1<<option)
-    /* ------------------------------------------------------------- */
+#define NAMESIZE            128 /* max. L�nge eines Namens, incl trailing 0 */
+#define IDSIZE              16  /* max. L�nge einer no (als String), incl trailing 0 */
+#define OBJECTIDSIZE        (NAMESIZE+5+IDSIZE) /* max. L�nge der Strings, die
+     * von struct unitname, etc. zur�ckgegeben werden. ohne die 0 */
 
 #define i2b(i) ((bool)((i)?(true):(false)))
 
@@ -110,7 +105,7 @@ struct param;
 #define GF_SPECIFIC 16
     /* der, die, das vs. ein, eine */
 #define GF_DETAILED 32
-    /* mehr Informationen. z.b. stra�e zu 50% */
+    /* mehr Informationen. z.b. stra�e zu 50% */
 #define GF_PURE 64
     /* untranslated */
 
@@ -144,11 +139,6 @@ struct param;
         } functions;
     } settings;
 
-    typedef struct helpmode {
-        const char *name;
-        int status;
-    } helpmode;
-
     void set_param(struct param **p, const char *key, const char *value);
     const char *get_param(const struct param *p, const char *key);
     int get_param_int(const struct param *p, const char *key, int def);
@@ -173,7 +163,6 @@ struct param;
     void free_gamedata(void);
     void free_config(void);
 
-    extern struct helpmode helpmodes[];
     extern const char *parameters[];
     extern const char *localenames[];
     extern settings global;
@@ -184,8 +173,6 @@ struct param;
     extern int turn;
     extern bool getunitpeasants;
 
-    extern const char *options[MAXOPTIONS];    /* report options */
-
 #ifdef __cplusplus
 }
 #endif
diff --git a/src/kernel/faction.h b/src/kernel/faction.h
index de5524294..82ae89ea4 100644
--- a/src/kernel/faction.h
+++ b/src/kernel/faction.h
@@ -42,10 +42,10 @@ extern "C" {
 #define FFL_DEFENDER      (1<<10)
 #define FFL_SELECT        (1<<18)       /* ehemals f->dh, u->dh, r->dh, etc... */
 #define FFL_NOAID         (1<<21)       /* Hilfsflag Kampf */
-#define FFL_MARK          (1<<23)       /* f�r markierende algorithmen, die das 
-                                             * hinterher auch wieder l�schen m�ssen!
+#define FFL_MARK          (1<<23)       /* f�r markierende algorithmen, die das 
+                                             * hinterher auch wieder l�schen m�ssen!
                                              * (FFL_SELECT muss man vorher initialisieren,
-                                             * FL_MARK hinterher l�schen) */
+                                             * FL_MARK hinterher l�schen) */
 #define FFL_NOIDLEOUT     (1<<24)       /* Partei stirbt nicht an NMRs */
 #define FFL_NPC           (1<<25)       /* eine Partei mit Monstern */
 #define FFL_SAVEMASK (FFL_DEFENDER|FFL_NEWID|FFL_NPC|FFL_NOIDLEOUT|FFL_CURSED)
@@ -101,6 +101,8 @@ extern "C" {
 
     extern struct faction *factions;
 
+#define want(option) (1<<option)
+
     void fhash(struct faction *f);
     void funhash(struct faction *f);
 
diff --git a/src/kernel/save.h b/src/kernel/save.h
index cfbcafd72..be78b9c68 100644
--- a/src/kernel/save.h
+++ b/src/kernel/save.h
@@ -31,6 +31,8 @@ extern "C" {
     struct spellbook;
     struct unit;
     struct building;
+    struct faction;
+    struct region;
     struct ship;
     struct gamedata;
 
diff --git a/src/reports.c b/src/reports.c
index c183786b4..837ea1a31 100644
--- a/src/reports.c
+++ b/src/reports.c
@@ -105,6 +105,22 @@ const char *coasts[MAXDIRECTIONS] = {
     "coast::w"
 };
 
+const char *options[MAXOPTIONS] = {
+    "AUSWERTUNG",
+    "COMPUTER",
+    "ZUGVORLAGE",
+    NULL,
+    "STATISTIK",
+    "DEBUG",
+    "ZIPPED",
+    "ZEITUNG",                    /* Option hat Sonderbehandlung! */
+    NULL,
+    "ADRESSEN",
+    "BZIP2",
+    "PUNKTE",
+    "SHOWSKCHANGE"
+};
+
 bool omniscient(const faction *f)
 {
     static const race *rc_template, *rc_illusion;
diff --git a/src/reports.h b/src/reports.h
index 8684dfa3f..e5fd976e3 100644
--- a/src/reports.h
+++ b/src/reports.h
@@ -43,6 +43,7 @@ extern "C" {
     extern bool nocr;
     extern bool noreports;
     extern const char *visibility[];
+    extern const char *options[MAXOPTIONS];    /* report options */
 
     void reports_done(void);
 

From a601a675f606e91c2ac334ae6df8bd6959fb0b7a Mon Sep 17 00:00:00 2001
From: Enno Rehling <enno@eressea.de>
Date: Thu, 17 Nov 2016 10:42:20 +0100
Subject: [PATCH 23/42] reduce config.h even more. let's get all those global
 variables out of there.

---
 src/battle.c        | 155 ++++++++++++++++++++++----------------------
 src/battle.h        |  19 +++---
 src/kernel/config.c |   1 -
 src/kernel/config.h |   1 -
 src/main.c          |   1 +
 5 files changed, 89 insertions(+), 88 deletions(-)

diff --git a/src/battle.c b/src/battle.c
index 5ae215135..2facbb30f 100644
--- a/src/battle.c
+++ b/src/battle.c
@@ -76,16 +76,14 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 #include <stdlib.h>
 #include <sys/stat.h>
 
-static FILE *bdebug;
-
 #define TACTICS_BONUS 1         /* when undefined, we have a tactics round. else this is the bonus tactics give */
 #define TACTICS_MODIFIER 1      /* modifier for generals in the front/rear */
 
 #define CATAPULT_INITIAL_RELOAD 4       /* erster schuss in runde 1 + rng_int() % INITIAL */
 #define CATAPULT_STRUCTURAL_DAMAGE
 
-#define BASE_CHANCE    70       /* 70% Basis-�berlebenschance */
-#define TDIFF_CHANGE    5       /* 5% h�her pro Stufe */
+#define BASE_CHANCE    70       /* 70% Basis-�berlebenschance */
+#define TDIFF_CHANGE    5       /* 5% h�her pro Stufe */
 #define DAMAGE_QUOTIENT 2       /* damage += skilldiff/DAMAGE_QUOTIENT */
 
 #define DEBUG_SELECT            /* should be disabled if select_enemy works */
@@ -96,7 +94,10 @@ typedef enum combatmagic {
 } combatmagic_t;
 
 /* globals */
+bool battledebug = false;
+
 static int obs_count = 0;
+static FILE *bdebug;
 
 #define MINSPELLRANGE 1
 #define MAXSPELLRANGE 7
@@ -303,11 +304,11 @@ static int dead_fighters(const fighter * df)
 }
 
 fighter *select_corpse(battle * b, fighter * af)
-/* W�hlt eine Leiche aus, der af hilft. casualties ist die Anzahl der
+/* W�hlt eine Leiche aus, der af hilft. casualties ist die Anzahl der
  * Toten auf allen Seiten (im Array). Wenn af == NULL, wird die
- * Parteizugeh�rigkeit ignoriert, und irgendeine Leiche genommen.
+ * Parteizugeh�rigkeit ignoriert, und irgendeine Leiche genommen.
  *
- * Untote werden nicht ausgew�hlt (casualties, not dead) */
+ * Untote werden nicht ausgew�hlt (casualties, not dead) */
 {
     int si, maxcasualties = 0;
     fighter *df;
@@ -323,7 +324,7 @@ fighter *select_corpse(battle * b, fighter * af)
         side *s;
         for (s = b->sides; s != b->sides + b->nsides; ++s) {
             for (df = s->fighters; df; df = df->next) {
-                /* Geflohene haben auch 0 hp, d�rfen hier aber nicht ausgew�hlt
+                /* Geflohene haben auch 0 hp, d�rfen hier aber nicht ausgew�hlt
                  * werden! */
                 int dead = dead_fighters(df);
                 if (!playerrace(u_race(df->unit)))
@@ -617,7 +618,7 @@ weapon_skill(const weapon_type * wtype, const unit * u, bool attacking)
             }
         }
         else {
-            /* der rassen-defaultwert kann h�her sein als der Talentwert von
+            /* der rassen-defaultwert kann h�her sein als der Talentwert von
              * waffenloser kampf */
             if (attacking) {
                 if (skill < u_race(u)->at_default)
@@ -705,7 +706,7 @@ static int CavalryBonus(const unit * u, troop enemy, int type)
 static int
 weapon_effskill(troop t, troop enemy, const weapon * w, bool attacking,
 bool missile)
-/* effektiver Waffenskill w�hrend des Kampfes */
+/* effektiver Waffenskill w�hrend des Kampfes */
 {
     /* In dieser Runde alle die Modifier berechnen, die fig durch die
      * Waffen bekommt. */
@@ -770,16 +771,16 @@ bool missile)
 
     if (t.index < tf->elvenhorses) {
         /* Elfenpferde: Helfen dem Reiter, egal ob und welche Waffe. Das ist
-         * eleganter, und vor allem einfacher, sonst mu� man noch ein
+         * eleganter, und vor allem einfacher, sonst mu� man noch ein
          * WMF_ELVENHORSE einbauen. */
         skill += 2;
     }
 
     if (skill > 0 && !attacking && missile) {
         /*
-         * Wenn ich verteidige, und nicht direkt meinem Feind gegen�berstehe,
-         * halbiert sich mein Skill: (z.B. gegen Fernk�mpfer. Nahk�mpfer
-         * k�nnen mich eh nicht treffen)
+         * Wenn ich verteidige, und nicht direkt meinem Feind gegen�berstehe,
+         * halbiert sich mein Skill: (z.B. gegen Fernk�mpfer. Nahk�mpfer
+         * k�nnen mich eh nicht treffen)
          */
         skill /= 2;
     }
@@ -815,9 +816,9 @@ static const armor_type *select_armor(troop t, bool shield)
 }
 
 /* Hier ist zu beachten, ob und wie sich Zauber und Artefakte, die
- * R�stungschutz geben, addieren.
- * - Artefakt "trollbelt" gibt R�stung +1
- * - Zauber Rindenhaut gibt R�stung +3
+ * R�stungschutz geben, addieren.
+ * - Artefakt "trollbelt" gibt R�stung +1
+ * - Zauber Rindenhaut gibt R�stung +3
  */
 static int trollbelts(const unit *u) {
     const struct resource_type *belt = rt_find("trollbelt");
@@ -835,7 +836,7 @@ int select_magicarmor(troop t)
     return ma;
 }
 
-/* Sind side ds und Magier des meffect verb�ndet, dann return 1*/
+/* Sind side ds und Magier des meffect verb�ndet, dann return 1*/
 bool meffect_protection(battle * b, meffect * s, side * ds)
 {
     if (!s->magician->alive)
@@ -871,7 +872,7 @@ void rmfighter(fighter * df, int i)
     assert(df->alive >= i);
     assert(df->alive <= df->unit->number);
 
-    /* erst ziehen wir die Anzahl der Personen von den K�mpfern in der
+    /* erst ziehen wir die Anzahl der Personen von den K�mpfern in der
      * Schlacht, dann von denen auf dieser Seite ab*/
     df->side->alive -= i;
     df->side->battle->alive -= i;
@@ -1091,15 +1092,15 @@ int calculate_armor(troop dt, const weapon_type *dwtype, const weapon_type *awty
         }
     }
 
-    /* nat�rliche R�stung */
+    /* nat�rliche R�stung */
     an = natural_armor(du);
 
-    /* magische R�stung durch Artefakte oder Spr�che */
-    /* Momentan nur Trollg�rtel und Werwolf-Eigenschaft */
+    /* magische R�stung durch Artefakte oder Spr�che */
+    /* Momentan nur Trollg�rtel und Werwolf-Eigenschaft */
     am = select_magicarmor(dt);
 
     if (rule_nat_armor == 0) {
-        /* nat�rliche R�stung ist halbkumulativ */
+        /* nat�rliche R�stung ist halbkumulativ */
         if (ar > 0) {
             ar += an / 2;
         }
@@ -1133,7 +1134,7 @@ int calculate_armor(troop dt, const weapon_type *dwtype, const weapon_type *awty
                 res *= (1 - dwtype->magres);
         }
 
-        /* gegen Magie wirkt nur nat�rliche und magische R�stung */
+        /* gegen Magie wirkt nur nat�rliche und magische R�stung */
         ar = an + am;
         *magres = res > 0 ? res : 0;
     }
@@ -1273,7 +1274,7 @@ terminate(troop dt, troop at, int type, const char *damage, bool missile)
                     rda -= hp;
                     me->duration -= hp;
                 }
-                /* gibt R�stung +effect f�r duration Treffer */
+                /* gibt R�stung +effect f�r duration Treffer */
                 if (me->typ == SHIELD_ARMOR) {
                     rda = _max(rda - me->effect, 0);
                     me->duration--;
@@ -1296,7 +1297,7 @@ terminate(troop dt, troop at, int type, const char *damage, bool missile)
         }
 
     }
-    if (df->person[dt.index].hp > 0) {    /* Hat �berlebt */
+    if (df->person[dt.index].hp > 0) {    /* Hat �berlebt */
         if (bdebug) {
             fprintf(bdebug, "Damage %d, armor %d: %d -> %d HP\n",
                 da, ar, df->person[dt.index].hp + rda, df->person[dt.index].hp);
@@ -1702,7 +1703,7 @@ void do_combatmagic(battle * b, combatmagic_t was)
             unit *mage = fig->unit;
 
             if (fig->alive <= 0)
-                continue;               /* fighter kann im Kampf get�tet worden sein */
+                continue;               /* fighter kann im Kampf get�tet worden sein */
 
             level = effskill(mage, SK_MAGIC, r);
             if (level > 0) {
@@ -1811,12 +1812,12 @@ static void do_combatspell(troop at)
 
     sp = get_combatspell(caster, 1);
     if (sp == NULL) {
-        fi->magic = 0;              /* Hat keinen Kampfzauber, k�mpft nichtmagisch weiter */
+        fi->magic = 0;              /* Hat keinen Kampfzauber, k�mpft nichtmagisch weiter */
         return;
     }
     ord = create_order(K_CAST, lang, "'%s'", spell_name(sp, lang));
     if (!cancast(caster, sp, 1, 1, ord)) {
-        fi->magic = 0;              /* Kann nicht mehr Zaubern, k�mpft nichtmagisch weiter */
+        fi->magic = 0;              /* Kann nicht mehr Zaubern, k�mpft nichtmagisch weiter */
         return;
     }
 
@@ -1840,7 +1841,7 @@ static void do_combatspell(troop at)
         }
     }
 
-    /* Antimagie die Fehlschlag erh�ht */
+    /* Antimagie die Fehlschlag erh�ht */
     if (rng_int() % 100 < fumblechance) {
         report_failed_spell(b, caster, sp);
         pay_spell(caster, sp, level, 1);
@@ -1864,7 +1865,7 @@ static void do_combatspell(troop at)
 }
 
 /* Sonderattacken: Monster patzern nicht und zahlen auch keine
- * Spruchkosten. Da die Spruchst�rke direkt durch den Level bestimmt
+ * Spruchkosten. Da die Spruchst�rke direkt durch den Level bestimmt
  * wird, wirkt auch keine Antimagie (wird sonst in spellpower
  * gemacht) */
 
@@ -1916,7 +1917,7 @@ int skilldiff(troop at, troop dt, int dist)
             if (strongwall_ct) {
                 curse *c = get_curse(df->building->attribs, strongwall_ct);
                 if (curse_active(c)) {
-                    /* wirkt auf alle Geb�ude */
+                    /* wirkt auf alle Geb�ude */
                     skdiff -= curse_geteffect_int(c);
                     is_protected = 2;
                 }
@@ -2021,7 +2022,7 @@ int hits(troop at, troop dt, weapon * awp)
     }
 
     skdiff = skilldiff(at, dt, dist);
-    /* Verteidiger bekommt eine R�stung */
+    /* Verteidiger bekommt eine R�stung */
     armor = select_armor(dt, true);
     if (dwp == NULL || (dwp->type->flags & WTF_USESHIELD)) {
         shield = select_armor(dt, false);
@@ -2065,7 +2066,7 @@ void damage_building(battle * b, building * bldg, int damage_abs)
 {
     bldg->size = _max(1, bldg->size - damage_abs);
 
-    /* Wenn Burg, dann gucken, ob die Leute alle noch in das Geb�ude passen. */
+    /* Wenn Burg, dann gucken, ob die Leute alle noch in das Geb�ude passen. */
 
     if (bldg->type->protection) {
         side *s;
@@ -2123,7 +2124,7 @@ static void attack(battle * b, troop ta, const att * a, int numattack)
     switch (a->type) {
     case AT_COMBATSPELL:
         /* Magier versuchen immer erstmal zu zaubern, erst wenn das
-         * fehlschl�gt, wird af->magic == 0 und  der Magier k�mpft
+         * fehlschl�gt, wird af->magic == 0 und  der Magier k�mpft
          * konventionell weiter */
         if (numattack == 0 && af->magic > 0) {
             /* wenn der magier in die potenzielle Reichweite von Attacken des
@@ -2135,7 +2136,7 @@ static void attack(battle * b, troop ta, const att * a, int numattack)
             }
         }
         break;
-    case AT_STANDARD:          /* Waffen, mag. Gegenst�nde, Kampfzauber */
+    case AT_STANDARD:          /* Waffen, mag. Gegenst�nde, Kampfzauber */
         if (numattack > 0 || af->magic <= 0) {
             weapon *wp = ta.fighter->person[ta.index].missile;
             int melee =
@@ -2152,7 +2153,7 @@ static void attack(battle * b, troop ta, const att * a, int numattack)
                 bool standard_attack = true;
                 bool reload = false;
                 /* spezialattacken der waffe nur, wenn erste attacke in der runde.
-                 * sonst helden mit feuerschwertern zu m�chtig */
+                 * sonst helden mit feuerschwertern zu m�chtig */
                 if (numattack == 0 && wp && wp->type->attack) {
                     int dead = 0;
                     standard_attack = wp->type->attack(&ta, wp->type, &dead);
@@ -2200,7 +2201,7 @@ static void attack(battle * b, troop ta, const att * a, int numattack)
             }
         }
         break;
-    case AT_SPELL:             /* Extra-Spr�che. Kampfzauber in AT_COMBATSPELL! */
+    case AT_SPELL:             /* Extra-Spr�che. Kampfzauber in AT_COMBATSPELL! */
         do_extra_spell(ta, a);
         break;
     case AT_NATURAL:
@@ -2285,14 +2286,14 @@ void do_attack(fighter * af)
 
     assert(au && au->number);
     /* Da das Zuschlagen auf Einheiten und nicht auf den einzelnen
-     * K�mpfern beruht, darf die Reihenfolge und Gr��e der Einheit keine
+     * K�mpfern beruht, darf die Reihenfolge und Gr��e der Einheit keine
      * Rolle spielen, Das tut sie nur dann, wenn jeder, der am Anfang der
-     * Runde lebte, auch zuschlagen darf. Ansonsten ist der, der zuf�llig
-     * mit einer gro�en Einheit zuerst drankommt, extrem bevorteilt. */
+     * Runde lebte, auch zuschlagen darf. Ansonsten ist der, der zuf�llig
+     * mit einer gro�en Einheit zuerst drankommt, extrem bevorteilt. */
     ta.index = af->fighting;
 
     while (ta.index--) {
-        /* Wir suchen eine beliebige Feind-Einheit aus. An der k�nnen
+        /* Wir suchen eine beliebige Feind-Einheit aus. An der k�nnen
          * wir feststellen, ob noch jemand da ist. */
         int apr, attacks = attacks_per_round(ta);
         if (!count_enemies(b, af, FIGHT_ROW, LAST_ROW, SELECT_FIND))
@@ -2317,7 +2318,7 @@ void do_attack(fighter * af)
             }
         }
     }
-    /* Der letzte Katapultsch�tze setzt die
+    /* Der letzte Katapultsch�tze setzt die
      * Ladezeit neu und generiert die Meldung. */
     if (af->catmsg >= 0) {
         struct message *m =
@@ -2391,7 +2392,7 @@ double fleechance(unit * u)
 {
     double c = 0.20;              /* Fluchtwahrscheinlichkeit in % */
     attrib *a = a_find(u->attribs, &at_fleechance);
-    /* Einheit u versucht, dem Get�mmel zu entkommen */
+    /* Einheit u versucht, dem Get�mmel zu entkommen */
 
     c += (effskill(u, SK_STEALTH, 0) * 0.05);
     c += horse_fleeing_bonus(u);
@@ -2679,7 +2680,7 @@ static void aftermath(battle * b)
     for (s = b->sides; s != b->sides + b->nsides; ++s) {
         int snumber = 0;
         fighter *df;
-        bool relevant = false;   /* Kampf relevant f�r diese Partei? */
+        bool relevant = false;   /* Kampf relevant f�r diese Partei? */
         if (!fval(s, SIDE_HASGUARDS)) {
             relevant = true;
         }
@@ -2719,7 +2720,7 @@ static void aftermath(battle * b)
                     /* Report the casualties */
                     reportcasualties(b, df, dead);
 
-                    /* Zuerst d�rfen die Feinde pl�ndern, die mitgenommenen Items
+                    /* Zuerst d�rfen die Feinde pl�ndern, die mitgenommenen Items
                      * stehen in fig->run.items. Dann werden die Fliehenden auf
                      * die leere (tote) alte Einheit gemapt */
                     if (!fval(df, FIG_NOLOOT)) {
@@ -2754,7 +2755,7 @@ static void aftermath(battle * b)
             }
             else {
                 if (df->alive == 0) {
-                    /* alle sind tot, niemand geflohen. Einheit aufl�sen */
+                    /* alle sind tot, niemand geflohen. Einheit aufl�sen */
                     df->run.number = 0;
                     df->run.hp = 0;
 
@@ -2816,7 +2817,7 @@ static void aftermath(battle * b)
 
     /* Wir benutzen drifted, um uns zu merken, ob ein Schiff
      * schonmal Schaden genommen hat. (moved und drifted
-     * sollten in flags �berf�hrt werden */
+     * sollten in flags �berf�hrt werden */
 
     for (s = b->sides; s != b->sides + b->nsides; ++s) {
         fighter *df;
@@ -2837,7 +2838,7 @@ static void aftermath(battle * b)
             }
 
             /* Wenn sich die Einheit auf einem Schiff befindet, wird
-             * dieses Schiff besch�digt. Andernfalls ein Schiff, welches
+             * dieses Schiff besch�digt. Andernfalls ein Schiff, welches
              * evt. zuvor verlassen wurde. */
             if (ships_damaged) {
                 if (du->ship)
@@ -3210,8 +3211,8 @@ fighter *make_fighter(battle * b, unit * u, side * s1, bool attack)
         else if (!stealthfaction) {
             s1->stealthfaction = NULL;
         }
-        /* Zu diesem Zeitpunkt ist attacked noch 0, da die Einheit f�r noch
-         * keinen Kampf ausgew�hlt wurde (sonst w�rde ein fighter existieren) */
+        /* Zu diesem Zeitpunkt ist attacked noch 0, da die Einheit f�r noch
+         * keinen Kampf ausgew�hlt wurde (sonst w�rde ein fighter existieren) */
     }
     fig = (struct fighter*)calloc(1, sizeof(struct fighter));
 
@@ -3219,8 +3220,8 @@ fighter *make_fighter(battle * b, unit * u, side * s1, bool attack)
     s1->fighters = fig;
 
     fig->unit = u;
-    /* In einer Burg mu� man a) nicht Angreifer sein, und b) drin sein, und
-     * c) noch Platz finden. d) menschan�hnlich sein */
+    /* In einer Burg mu� man a) nicht Angreifer sein, und b) drin sein, und
+     * c) noch Platz finden. d) menschan�hnlich sein */
     if (attack) {
         set_attacker(fig);
     }
@@ -3246,7 +3247,7 @@ fighter *make_fighter(battle * b, unit * u, side * s1, bool attack)
     assert(h);
     rest = u->hp % u->number;
 
-    /* Effekte von Spr�chen */
+    /* Effekte von Spr�chen */
 
     if (u->attribs) {
         const curse_type *speed_ct;
@@ -3267,7 +3268,7 @@ fighter *make_fighter(battle * b, unit * u, side * s1, bool attack)
     /* Effekte von Artefakten */
     strongmen = _min(fig->unit->number, trollbelts(u));
 
-    /* Hitpoints, Attack- und Defence-Boni f�r alle Personen */
+    /* Hitpoints, Attack- und Defence-Boni f�r alle Personen */
     for (i = 0; i < fig->alive; i++) {
         assert(i < fig->unit->number);
         fig->person[i].hp = h;
@@ -3288,8 +3289,8 @@ fighter *make_fighter(battle * b, unit * u, side * s1, bool attack)
         }
     }
 
-    /* F�r alle Waffengattungen wird bestimmt, wie viele der Personen mit
-     * ihr k�mpfen k�nnten, und was ihr Wert darin ist. */
+    /* F�r alle Waffengattungen wird bestimmt, wie viele der Personen mit
+     * ihr k�mpfen k�nnten, und was ihr Wert darin ist. */
     if (u_race(u)->battle_flags & BF_EQUIPMENT) {
         int oi = 0, di = 0, w = 0;
         for (itm = u->items; itm && w != WMAX; itm = itm->next) {
@@ -3407,12 +3408,12 @@ fighter *make_fighter(battle * b, unit * u, side * s1, bool attack)
         }
     }
 
-    /* Jetzt mu� noch geschaut werden, wo die Einheit die jeweils besten
-     * Werte hat, das kommt aber erst irgendwo sp�ter. Ich entscheide
-     * w�rend des Kampfes, welche ich nehme, je nach Gegner. Deswegen auch
+    /* Jetzt mu� noch geschaut werden, wo die Einheit die jeweils besten
+     * Werte hat, das kommt aber erst irgendwo sp�ter. Ich entscheide
+     * w�rend des Kampfes, welche ich nehme, je nach Gegner. Deswegen auch
      * keine addierten boni. */
 
-    /* Zuerst mal die Spezialbehandlung gewisser Sonderf�lle. */
+    /* Zuerst mal die Spezialbehandlung gewisser Sonderf�lle. */
     fig->magic = effskill(u, SK_MAGIC, 0);
 
     if (fig->horses) {
@@ -3577,7 +3578,7 @@ battle *make_battle(region * r)
 
     b->region = r;
     b->plane = getplane(r);
-    /* Finde alle Parteien, die den Kampf beobachten k�nnen: */
+    /* Finde alle Parteien, die den Kampf beobachten k�nnen: */
     for (u = r->units; u; u = u->next) {
         if (u->number > 0) {
             if (!fval(u->faction, FFL_MARK)) {
@@ -3766,18 +3767,18 @@ static void join_allies(battle * b)
 
             for (s = b->sides; s != s_end; ++s) {
                 side *se;
-                /* Wenn alle attackierten noch FFL_NOAID haben, dann k�mpfe nicht mit. */
+                /* Wenn alle attackierten noch FFL_NOAID haben, dann k�mpfe nicht mit. */
                 if (fval(s->faction, FFL_NOAID))
                     continue;
                 if (s->faction != f) {
                     /* Wenn wir attackiert haben, kommt niemand mehr hinzu: */
                     if (s->bf->attacker)
                         continue;
-                    /* alliiert m�ssen wir schon sein, sonst ist's eh egal : */
+                    /* alliiert m�ssen wir schon sein, sonst ist's eh egal : */
                     if (!alliedunit(u, s->faction, HELP_FIGHT))
                         continue;
                     /* wenn die partei verborgen ist, oder gar eine andere
-                     * vorgespiegelt wird, und er sich uns gegen�ber nicht zu
+                     * vorgespiegelt wird, und er sich uns gegen�ber nicht zu
                      * erkennen gibt, helfen wir ihm nicht */
                     if (s->stealthfaction) {
                         if (!allysfm(s, u->faction, HELP_FSTEALTH)) {
@@ -3785,7 +3786,7 @@ static void join_allies(battle * b)
                         }
                     }
                 }
-                /* einen alliierten angreifen d�rfen sie nicht, es sei denn, der
+                /* einen alliierten angreifen d�rfen sie nicht, es sei denn, der
                  * ist mit einem alliierten verfeindet, der nicht attackiert
                  * hat: */
                 for (se = b->sides; se != s_end; ++se) {
@@ -3799,7 +3800,7 @@ static void join_allies(battle * b)
                 }
                 if (se == s_end)
                     continue;
-                /* Wenn die Einheit belagert ist, mu� auch einer der Alliierten belagert sein: */
+                /* Wenn die Einheit belagert ist, mu� auch einer der Alliierten belagert sein: */
                 if (besieged(u)) {
                     fighter *ally;
                     for (ally = s->fighters; ally; ally = ally->next) {
@@ -3810,7 +3811,7 @@ static void join_allies(battle * b)
                     if (ally == NULL)
                         continue;
                 }
-                /* keine Einw�nde, also soll er mitmachen: */
+                /* keine Einw�nde, also soll er mitmachen: */
                 if (c == NULL) {
                     if (join_battle(b, u, false, &c)) {
                         if (battledebug) {
@@ -3926,7 +3927,7 @@ static bool start_battle(region * r, battle ** bp)
                         continue;
                     }
 
-                    /* ist ein Fl�chtling aus einem andern Kampf */
+                    /* ist ein Fl�chtling aus einem andern Kampf */
                     if (fval(u, UFL_LONGACTION))
                         continue;
 
@@ -3947,7 +3948,7 @@ static bool start_battle(region * r, battle ** bp)
                                 cmistake(u, ord, 234, MSG_BATTLE);
                             }
                             else {
-                                /* Fehler: "Das Schiff mu� erst verlassen werden" */
+                                /* Fehler: "Das Schiff mu� erst verlassen werden" */
                                 cmistake(u, ord, 19, MSG_BATTLE);
                             }
                             continue;
@@ -4032,8 +4033,8 @@ static bool start_battle(region * r, battle ** bp)
                         freset(u2->faction, FFL_NOAID);
 
                     if (c1 != NULL && c2 != NULL) {
-                        /* Merken, wer Angreifer ist, f�r die R�ckzahlung der
-                         * Pr�combataura bei kurzem Kampf. */
+                        /* Merken, wer Angreifer ist, f�r die R�ckzahlung der
+                         * Pr�combataura bei kurzem Kampf. */
                         c1->side->bf->attacker = true;
 
                         if (set_enemy(c1->side, c2->side, true) && battledebug) {
@@ -4066,7 +4067,7 @@ static void battle_attacks(battle * b)
             && get_tactics(s, NULL) == b->max_tactics)) {
             for (fig = s->fighters; fig; fig = fig->next) {
 
-                /* ist in dieser Einheit noch jemand handlungsf�hig? */
+                /* ist in dieser Einheit noch jemand handlungsf�hig? */
                 if (fig->fighting <= 0)
                     continue;
 
@@ -4110,7 +4111,7 @@ static void battle_flee(battle * b)
                 unit *u = fig->unit;
                 troop dt;
                 int runners = 0;
-                /* Flucht nicht bei mehr als 600 HP. Damit Wyrme t�tbar bleiben. */
+                /* Flucht nicht bei mehr als 600 HP. Damit Wyrme t�tbar bleiben. */
                 int runhp = _min(600, (int)(0.9 + unit_max_hp(u) * hpflee(u->status)));
 
                 if (u->ship && fval(u->region->terrain, SEA_REGION)) {
@@ -4230,7 +4231,7 @@ void do_battle(region * r)
         return;
 
     /* Bevor wir die alliierten hineinziehen, sollten wir schauen, *
-     * Ob jemand fliehen kann. Dann er�brigt sich das ganze ja
+     * Ob jemand fliehen kann. Dann er�brigt sich das ganze ja
      * vielleicht schon. */
     print_header(b);
     if (!fighting) {
@@ -4279,8 +4280,8 @@ void do_battle(region * r)
     if (rule_force_leave(FORCE_LEAVE_POSTCOMBAT)) {
         force_leave(b->region, b);
     }
-    /* Hier ist das Gefecht beendet, und wir k�nnen die
-     * Hilfsstrukturen * wieder l�schen: */
+    /* Hier ist das Gefecht beendet, und wir k�nnen die
+     * Hilfsstrukturen * wieder l�schen: */
 
     if (b) {
         free_battle(b);
diff --git a/src/battle.h b/src/battle.h
index 3e156070d..6984a0d62 100644
--- a/src/battle.h
+++ b/src/battle.h
@@ -30,7 +30,7 @@ extern "C" {
 #define FS_HELP  2
 
     /***** Verteidigungslinien.
-    * Eressea hat 4 Verteidigungslinien. 1 ist vorn, 5. enth�lt Summen
+    * Eressea hat 4 Verteidigungslinien. 1 ist vorn, 5. enth�lt Summen
     */
 
 #define NUMROWS 5
@@ -74,7 +74,7 @@ extern "C" {
         struct fighter *fighters;
         int index;                  /* Eintrag der Fraktion in b->matrix/b->enemies */
         int size[NUMROWS];          /* Anzahl Personen in Reihe X. 0 = Summe */
-        int nonblockers[NUMROWS];   /* Anzahl nichtblockierender K�mpfer, z.B. Schattenritter. */
+        int nonblockers[NUMROWS];   /* Anzahl nichtblockierender K�mpfer, z.B. Schattenritter. */
         int alive;                  /* Die Partei hat den Kampf verlassen */
         int removed;                /* stoned */
         int flee;
@@ -131,7 +131,7 @@ extern "C" {
 
     /*** fighter::person::flags ***/
 #define FL_TIRED      1
-#define FL_DAZZLED  2           /* durch Untote oder D�monen eingesch�chtert */
+#define FL_DAZZLED  2           /* durch Untote oder D�monen eingesch�chtert */
 #define FL_PANICED  4
 #define FL_COURAGE  8           /* Helden fliehen nie */
 #define FL_SLEEPING 16
@@ -156,17 +156,17 @@ extern "C" {
     typedef struct fighter {
         struct fighter *next;
         struct side *side;
-        struct unit *unit;          /* Die Einheit, die hier k�mpft */
-        struct building *building;  /* Geb�ude, in dem die Einheit evtl. steht */
+        struct unit *unit;          /* Die Einheit, die hier k�mpft */
+        struct building *building;  /* Geb�ude, in dem die Einheit evtl. steht */
         status_t status;            /* Kampfstatus */
         struct weapon *weapons;
-        struct armor *armors;       /* Anzahl R�stungen jeden Typs */
+        struct armor *armors;       /* Anzahl R�stungen jeden Typs */
         int alive;                  /* Anzahl der noch nicht Toten in der Einheit */
-        int fighting;               /* Anzahl der K�mpfer in der aktuellen Runde */
+        int fighting;               /* Anzahl der K�mpfer in der aktuellen Runde */
         int removed;                /* Anzahl Kaempfer, die nicht tot sind, aber
                                        aus dem Kampf raus sind (zB weil sie
                                        versteinert wurden).  Diese werden auch
-                                       in alive noch mitgez�hlt! */
+                                       in alive noch mitgez�hlt! */
         int magic;                  /* Magietalent der Einheit  */
         int horses;                 /* Anzahl brauchbarer Pferde der Einheit */
         int elvenhorses;            /* Anzahl brauchbarer Elfenpferde der Einheit */
@@ -179,7 +179,7 @@ extern "C" {
             int defence : 8;            /* (Magie) Paradenbonus der Personen */
             int damage : 8;             /* (Magie) Schadensbonus der Personen im Nahkampf */
             int damage_rear : 8;        /* (Magie) Schadensbonus der Personen im Fernkampf */
-            int flags : 8;              /* (Magie) Diverse Flags auf K�mpfern */
+            int flags : 8;              /* (Magie) Diverse Flags auf K�mpfern */
             int speed : 8;              /* (Magie) Geschwindigkeitsmultiplkator. */
             int reload : 4;             /* Anzahl Runden, die die Waffe x noch laden muss.
                                        * dahinter steckt ein array[RL_MAX] wenn er min. eine hat. */
@@ -224,6 +224,7 @@ extern "C" {
     } meffect;
 
     extern const troop no_troop;
+    extern bool battledebug;
 
     /* BEGIN battle interface */
     side * find_side(battle * b, const struct faction * f, const struct group * g, unsigned int flags, const struct faction * stealthfaction);
diff --git a/src/kernel/config.c b/src/kernel/config.c
index 10b35bce9..28147d509 100644
--- a/src/kernel/config.c
+++ b/src/kernel/config.c
@@ -102,7 +102,6 @@ struct settings global = {
 
 bool lomem = false;
 FILE *logfile;
-bool battledebug = false;
 int turn = -1;
 
 const char *parameters[MAXPARAMS] = {
diff --git a/src/kernel/config.h b/src/kernel/config.h
index ca2686a1b..b9bb3f4d3 100644
--- a/src/kernel/config.h
+++ b/src/kernel/config.h
@@ -167,7 +167,6 @@ struct param;
     extern const char *localenames[];
     extern settings global;
 
-    extern bool battledebug;
     extern bool sqlpatch;
     extern bool lomem;         /* save memory */
     extern int turn;
diff --git a/src/main.c b/src/main.c
index 5fd154b23..16f56bf57 100644
--- a/src/main.c
+++ b/src/main.c
@@ -25,6 +25,7 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 #include <util/filereader.h>
 #include <util/language.h>
 #include "eressea.h"
+#include "battle.h"
 #ifdef USE_CURSES
 #include "gmtool.h"
 #endif

From d5218b99b8faeca61d7a7bca6e70e4cecccd4116 Mon Sep 17 00:00:00 2001
From: Enno Rehling <enno@eressea.de>
Date: Thu, 17 Nov 2016 10:51:58 +0100
Subject: [PATCH 24/42] do not include config.h from util (also, wasn't needed)
 also remove it from monsters.

---
 src/util/language.test.c | 1 -
 1 file changed, 1 deletion(-)

diff --git a/src/util/language.test.c b/src/util/language.test.c
index d86f1b2a7..236eac497 100644
--- a/src/util/language.test.c
+++ b/src/util/language.test.c
@@ -1,5 +1,4 @@
 #include <platform.h>
-#include <config.h>
 #include "language.h"
 
 #include <CuTest.h>

From e3b7e197502943319c7eea6546259f98a1501b30 Mon Sep 17 00:00:00 2001
From: Enno Rehling <enno@eressea.de>
Date: Thu, 17 Nov 2016 10:57:20 +0100
Subject: [PATCH 25/42] sometims we only include config.h for fval. I hate
 fval.

---
 src/items/seed.c    | 8 +++-----
 src/monster.h       | 2 +-
 src/races/zombies.c | 3 +--
 3 files changed, 5 insertions(+), 8 deletions(-)

diff --git a/src/items/seed.c b/src/items/seed.c
index 0e4b54e98..f17e8ed29 100644
--- a/src/items/seed.c
+++ b/src/items/seed.c
@@ -17,13 +17,11 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 **/
 
 #include <platform.h>
-#include <kernel/config.h>
 
 #include "seed.h"
 
 /* kernel includes */
 #include <kernel/build.h>
-#include <kernel/config.h>
 #include <kernel/item.h>
 #include <kernel/region.h>
 
@@ -42,7 +40,7 @@ static void produce_seeds(region * r, const resource_type * rtype, int norders)
 
 static int limit_seeds(const region * r, const resource_type * rtype)
 {
-    if (fval(r, RF_MALLORN)) {
+    if ((r->flags & RF_MALLORN)) {
         return 0;
     }
     return r->land ? r->land->trees[0] : 0;
@@ -68,13 +66,13 @@ void init_seed(void)
 static void
 produce_mallornseeds(region * r, const resource_type * rtype, int norders)
 {
-    assert(fval(r, RF_MALLORN));
+    assert(r->flags & RF_MALLORN);
     r->land->trees[0] -= norders;
 }
 
 static int limit_mallornseeds(const region * r, const resource_type * rtype)
 {
-    if (!fval(r, RF_MALLORN)) {
+    if (!(r->flags & RF_MALLORN)) {
         return 0;
     }
     return r->land ? r->land->trees[0] : 0;
diff --git a/src/monster.h b/src/monster.h
index 476bcb73e..0f936b17d 100644
--- a/src/monster.h
+++ b/src/monster.h
@@ -31,7 +31,7 @@ extern "C" {
     void make_zombie(struct unit * u);
 
 #define MONSTER_ID 666
-#define is_monsters(f) (fval(f, FFL_NPC) && f==get_monsters())
+#define is_monsters(f) ((f->flags & FFL_NPC) && f==get_monsters())
 
 #ifdef __cplusplus
 }
diff --git a/src/races/zombies.c b/src/races/zombies.c
index ab4c89988..d7f871dac 100644
--- a/src/races/zombies.c
+++ b/src/races/zombies.c
@@ -15,7 +15,6 @@
 #include <platform.h>
 
 /* kernel includes */
-#include <kernel/config.h>
 #include <kernel/race.h>
 #include <kernel/order.h>
 #include <kernel/unit.h>
@@ -40,7 +39,7 @@ void make_undead_unit(unit * u)
 {
     free_orders(&u->orders);
     name_unit(u);
-    fset(u, UFL_ISNEW);
+    u->flags |= UFL_ISNEW;
 }
 
 void age_undead(unit * u)

From b24f8b28393ba68e482344356e5016951434302b Mon Sep 17 00:00:00 2001
From: Enno Rehling <enno@eressea.de>
Date: Thu, 17 Nov 2016 11:25:02 +0100
Subject: [PATCH 26/42] remove config.h from items/

---
 src/items/artrewards.c | 1 -
 src/items/demonseye.c  | 1 -
 src/items/itemtypes.c  | 1 -
 src/items/speedsail.c  | 1 -
 src/items/weapons.c    | 1 -
 src/items/xerewards.c  | 1 -
 6 files changed, 6 deletions(-)

diff --git a/src/items/artrewards.c b/src/items/artrewards.c
index 0965125fd..602841d23 100644
--- a/src/items/artrewards.c
+++ b/src/items/artrewards.c
@@ -17,7 +17,6 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 **/
 
 #include <platform.h>
-#include <kernel/config.h>
 #include "artrewards.h"
 
 /* kernel includes */
diff --git a/src/items/demonseye.c b/src/items/demonseye.c
index 704e77f4c..ffc1c5179 100644
--- a/src/items/demonseye.c
+++ b/src/items/demonseye.c
@@ -17,7 +17,6 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 **/
 
 #include <platform.h>
-#include <kernel/config.h>
 #include "demonseye.h"
 
 /* kernel includes */
diff --git a/src/items/itemtypes.c b/src/items/itemtypes.c
index ca56b1273..930829668 100644
--- a/src/items/itemtypes.c
+++ b/src/items/itemtypes.c
@@ -11,7 +11,6 @@
  */
 
 #include <platform.h>
-#include <kernel/config.h>
 #include "itemtypes.h"
 
 #include "xerewards.h"
diff --git a/src/items/speedsail.c b/src/items/speedsail.c
index 9d5aad747..8bdaa41ab 100644
--- a/src/items/speedsail.c
+++ b/src/items/speedsail.c
@@ -17,7 +17,6 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 **/
 
 #include <platform.h>
-#include <kernel/config.h>
 #include "speedsail.h"
 
 /* kernel includes */
diff --git a/src/items/weapons.c b/src/items/weapons.c
index f5015e39a..1806e61a0 100644
--- a/src/items/weapons.c
+++ b/src/items/weapons.c
@@ -17,7 +17,6 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 **/
 
 #include <platform.h>
-#include <kernel/config.h>
 #include "weapons.h"
 #include "battle.h"
 
diff --git a/src/items/xerewards.c b/src/items/xerewards.c
index 98e099070..ab5226a32 100644
--- a/src/items/xerewards.c
+++ b/src/items/xerewards.c
@@ -17,7 +17,6 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 **/
 
 #include <platform.h>
-#include <kernel/config.h>
 #include "xerewards.h"
 
 #include "magic.h"

From d1d1bee8f6e58c189d1bdd11a769a17fdc1a1554 Mon Sep 17 00:00:00 2001
From: Enno Rehling <enno@eressea.de>
Date: Thu, 17 Nov 2016 11:27:20 +0100
Subject: [PATCH 27/42] missing struct declarations in curse.h remove config.h
 from spells and curses.

---
 src/kernel/curse.h                | 2 ++
 src/spells/buildingcurse.c        | 1 -
 src/spells/magicresistance.c      | 1 -
 src/spells/magicresistance.test.c | 1 -
 src/spells/regioncurse.c          | 3 +--
 src/spells/shipcurse.c            | 1 -
 src/spells/unitcurse.c            | 1 -
 7 files changed, 3 insertions(+), 7 deletions(-)

diff --git a/src/kernel/curse.h b/src/kernel/curse.h
index 0de1211c7..29498f4d2 100644
--- a/src/kernel/curse.h
+++ b/src/kernel/curse.h
@@ -30,6 +30,8 @@ extern "C" {
     struct curse_type;
     struct gamedata;
     struct storage;
+    struct attrib;
+    struct faction;
 
     /* Sprueche in der struct region und auf Einheiten, Schiffen oder Burgen
      * (struct attribute)
diff --git a/src/spells/buildingcurse.c b/src/spells/buildingcurse.c
index d3b5ddf36..01b0435ab 100644
--- a/src/spells/buildingcurse.c
+++ b/src/spells/buildingcurse.c
@@ -12,7 +12,6 @@
  */
 
 #include <platform.h>
-#include <kernel/config.h>
 #include "buildingcurse.h"
 
 /* kernel includes */
diff --git a/src/spells/magicresistance.c b/src/spells/magicresistance.c
index 3587a1be6..a897ea348 100644
--- a/src/spells/magicresistance.c
+++ b/src/spells/magicresistance.c
@@ -1,5 +1,4 @@
 #include <platform.h>
-#include <kernel/config.h>
 #include <kernel/curse.h>
 #include <kernel/messages.h>
 #include <util/language.h>
diff --git a/src/spells/magicresistance.test.c b/src/spells/magicresistance.test.c
index 4b0d69388..e9cc98e34 100644
--- a/src/spells/magicresistance.test.c
+++ b/src/spells/magicresistance.test.c
@@ -1,5 +1,4 @@
 #include <platform.h>
-#include <kernel/config.h>
 #include <kernel/curse.h>
 #include <kernel/building.h>
 #include <kernel/faction.h>
diff --git a/src/spells/regioncurse.c b/src/spells/regioncurse.c
index 382b13b86..3d7593484 100644
--- a/src/spells/regioncurse.c
+++ b/src/spells/regioncurse.c
@@ -12,7 +12,6 @@
  */
 
 #include <platform.h>
-#include <kernel/config.h>
 #include "regioncurse.h"
 #include "magic.h"
 
@@ -50,7 +49,7 @@ static message *cinfo_cursed_by_the_gods(const void *obj, objtype_t typ,
     unused_arg(self);
     assert(typ == TYP_REGION);
 
-    if (fval(r->terrain, SEA_REGION)) {
+    if (r->terrain->flags & SEA_REGION) {
         return msg_message("curseinfo::godcurseocean", "id", c->no);
     }
     return msg_message("curseinfo::godcurse", "id", c->no);
diff --git a/src/spells/shipcurse.c b/src/spells/shipcurse.c
index 8da3c7c89..59cc534d4 100644
--- a/src/spells/shipcurse.c
+++ b/src/spells/shipcurse.c
@@ -12,7 +12,6 @@
  */
 
 #include <platform.h>
-#include <kernel/config.h>
 #include "shipcurse.h"
 
 /* kernel includes */
diff --git a/src/spells/unitcurse.c b/src/spells/unitcurse.c
index 944db2032..6e769145e 100644
--- a/src/spells/unitcurse.c
+++ b/src/spells/unitcurse.c
@@ -12,7 +12,6 @@
  */
 
 #include <platform.h>
-#include <kernel/config.h>
 #include "unitcurse.h"
 
 /* kernel includes */

From 38f1d538287d953facd95b39fbac8729e2f53bf7 Mon Sep 17 00:00:00 2001
From: Enno Rehling <enno@eressea.de>
Date: Thu, 17 Nov 2016 11:39:36 +0100
Subject: [PATCH 28/42] temporarily enable osx builds

---
 .travis.yml | 1 +
 1 file changed, 1 insertion(+)

diff --git a/.travis.yml b/.travis.yml
index 78aaf3648..92ac2a93d 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -15,6 +15,7 @@ addons:
       - valgrind
 os:
   - linux
+  - osx
 notifications:
   slack:
     secure: F89aXLWaE125PaJIlETv12jT4EfH6wLXJmGCPZzrN3OcLn2ahDWqjwuzR7lOEDf2nAISmeMPyDZMhEHXLNHAE5qP6lg9yliYQw5hzGmDK9m1xUq/pPEne/b2Y7K3my1mkRZ6n3asbHgSmBWAfCIk1JN8R5Rv+rmbLuWLc+zofts=

From 476c655cd35edad9e39a7c0f2d14c90444620df3 Mon Sep 17 00:00:00 2001
From: Enno Rehling <enno@eressea.de>
Date: Thu, 17 Nov 2016 12:43:37 +0100
Subject: [PATCH 29/42] disable osx builds again

---
 .travis.yml | 1 -
 1 file changed, 1 deletion(-)

diff --git a/.travis.yml b/.travis.yml
index 92ac2a93d..78aaf3648 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -15,7 +15,6 @@ addons:
       - valgrind
 os:
   - linux
-  - osx
 notifications:
   slack:
     secure: F89aXLWaE125PaJIlETv12jT4EfH6wLXJmGCPZzrN3OcLn2ahDWqjwuzR7lOEDf2nAISmeMPyDZMhEHXLNHAE5qP6lg9yliYQw5hzGmDK9m1xUq/pPEne/b2Y7K3my1mkRZ6n3asbHgSmBWAfCIk1JN8R5Rv+rmbLuWLc+zofts=

From 6c9e1fb3453d8f8bc49bb644e75bccfced8513ab Mon Sep 17 00:00:00 2001
From: Enno Rehling <enno@eressea.de>
Date: Thu, 17 Nov 2016 17:06:31 +0100
Subject: [PATCH 30/42] more config.h removal. freset/fset/fval must die!

---
 src/kernel/config.c       |  8 -----
 src/kernel/config.h       |  1 -
 src/kernel/race.h         | 34 +++++++++---------
 src/kernel/ship.h         | 16 ++++-----
 src/spells.c              | 32 ++++++++---------
 src/spells/combatspells.c | 74 +++++++++++++++++++--------------------
 src/spells/flyingship.c   | 19 +++++-----
 src/util/rand.c           |  8 +++++
 src/util/rand.h           | 11 +++---
 tolua                     |  1 +
 10 files changed, 102 insertions(+), 102 deletions(-)
 create mode 160000 tolua

diff --git a/src/kernel/config.c b/src/kernel/config.c
index 28147d509..e673dd31f 100644
--- a/src/kernel/config.c
+++ b/src/kernel/config.c
@@ -905,14 +905,6 @@ int wage(const region * r, const faction * f, const race * rc, int in_turn)
     return default_wage(r, f, rc, in_turn);
 }
 
-int lovar(double xpct_x2)
-{
-    int n = (int)(xpct_x2 * 500) + 1;
-    if (n == 0)
-        return 0;
-    return (rng_int() % n + rng_int() % n) / 1000;
-}
-
 void kernel_init(void)
 {
     register_reports();
diff --git a/src/kernel/config.h b/src/kernel/config.h
index b9bb3f4d3..a0a0d8588 100644
--- a/src/kernel/config.h
+++ b/src/kernel/config.h
@@ -56,7 +56,6 @@ struct param;
 
     const char * game_name(void);
     int game_id(void);
-    int lovar(double xpct_x2);
     /* returns a value between [0..xpct_2], generated with two dice */
 
     void init_locale(struct locale *lang);
diff --git a/src/kernel/race.h b/src/kernel/race.h
index dc3becabb..80b09fbbf 100644
--- a/src/kernel/race.h
+++ b/src/kernel/race.h
@@ -117,7 +117,7 @@ extern "C" {
         float healing;
         double maxaura;            /* Faktor auf Maximale Aura */
         double regaura;            /* Faktor auf Regeneration */
-        double recruit_multi;      /* Faktor f�r Bauernverbrauch */
+        double recruit_multi;      /* Faktor f�r Bauernverbrauch */
         int index;
         int recruitcost;
         int maintenance;
@@ -132,8 +132,8 @@ extern "C" {
         int armor;
         int at_default;             /* Angriffsskill Unbewaffnet (default: -2) */
         int df_default;             /* Verteidigungsskill Unbewaffnet (default: -2) */
-        int at_bonus;               /* Ver�ndert den Angriffsskill (default: 0) */
-        int df_bonus;               /* Ver�ndert den Verteidigungskill (default: 0) */
+        int at_bonus;               /* Ver�ndert den Angriffsskill (default: 0) */
+        int df_bonus;               /* Ver�ndert den Verteidigungskill (default: 0) */
         struct param *parameters;   // additional properties, for an example see natural_armor
         const struct spell *precombatspell;
         signed char *study_speed;   /* study-speed-bonus in points/turn (0=30 Tage) */
@@ -190,20 +190,20 @@ extern "C" {
 #define RCF_LEARN          (1<<6)       /* Lernt automatisch wenn struct faction == 0 */
 #define RCF_FLY            (1<<7)       /* kann fliegen */
 #define RCF_SWIM           (1<<8)       /* kann schwimmen */
-#define RCF_WALK           (1<<9)       /* kann �ber Land gehen */
+#define RCF_WALK           (1<<9)       /* kann �ber Land gehen */
 #define RCF_NOLEARN        (1<<10)      /* kann nicht normal lernen */
 #define RCF_NOTEACH        (1<<11)      /* kann nicht lehren */
 #define RCF_HORSE          (1<<12)      /* Einheit ist Pferd, sozusagen */
 #define RCF_DESERT         (1<<13)      /* 5% Chance, das Einheit desertiert */
 #define RCF_ILLUSIONARY    (1<<14)      /* (Illusion & Spell) Does not drop items. */
-#define RCF_ABSORBPEASANTS (1<<15)      /* T�tet und absorbiert Bauern */
+#define RCF_ABSORBPEASANTS (1<<15)      /* T�tet und absorbiert Bauern */
 #define RCF_NOHEAL         (1<<16)      /* Einheit kann nicht geheilt werden */
 #define RCF_NOWEAPONS      (1<<17)      /* Einheit kann keine Waffen benutzen */
 #define RCF_SHAPESHIFT     (1<<18)      /* Kann TARNE RASSE benutzen. */
 #define RCF_SHAPESHIFTANY  (1<<19)      /* Kann TARNE RASSE "string" benutzen. */
 #define RCF_UNDEAD         (1<<20)      /* Undead. */
-#define RCF_DRAGON         (1<<21)      /* Drachenart (f�r Zauber) */
-#define RCF_COASTAL        (1<<22)      /* kann in Landregionen an der K�ste sein */
+#define RCF_DRAGON         (1<<21)      /* Drachenart (f�r Zauber) */
+#define RCF_COASTAL        (1<<22)      /* kann in Landregionen an der K�ste sein */
 #define RCF_UNARMEDGUARD   (1<<23)      /* kann ohne Waffen bewachen */
 #define RCF_CANSAIL        (1<<24)      /* Einheit darf Schiffe betreten */
 #define RCF_INVISIBLE      (1<<25)      /* not visible in any report */
@@ -213,16 +213,16 @@ extern "C" {
 #define RCF_ATTACK_MOVED   (1<<29)      /* may attack if it has moved */
 
     /* Economic flags */
-#define ECF_KEEP_ITEM       (1<<1)   /* gibt Gegenst�nde weg */
-#define GIVEPERSON     (1<<2)   /* �bergibt Personen */
-#define GIVEUNIT       (1<<3)   /* Einheiten an andere Partei �bergeben */
-#define GETITEM        (1<<4)   /* nimmt Gegenst�nde an */
+#define ECF_KEEP_ITEM       (1<<1)   /* gibt Gegenst�nde weg */
+#define GIVEPERSON     (1<<2)   /* �bergibt Personen */
+#define GIVEUNIT       (1<<3)   /* Einheiten an andere Partei �bergeben */
+#define GETITEM        (1<<4)   /* nimmt Gegenst�nde an */
 #define ECF_REC_ETHEREAL   (1<<7)       /* Rekrutiert aus dem Nichts */
 #define ECF_REC_UNLIMITED  (1<<8)       /* Rekrutiert ohne Limit */
 
     /* Battle-Flags */
-#define BF_EQUIPMENT    (1<<0)  /* Kann Ausr�stung benutzen */
-#define BF_NOBLOCK      (1<<1)  /* Wird in die R�ckzugsberechnung nicht einbezogen */
+#define BF_EQUIPMENT    (1<<0)  /* Kann Ausr�stung benutzen */
+#define BF_NOBLOCK      (1<<1)  /* Wird in die R�ckzugsberechnung nicht einbezogen */
 #define BF_RES_PIERCE   (1<<2)  /* Halber Schaden durch PIERCE */
 #define BF_RES_CUT      (1<<3)  /* Halber Schaden durch CUT */
 #define BF_RES_BASH     (1<<4)  /* Halber Schaden durch BASH */
@@ -232,10 +232,10 @@ extern "C" {
     const char *racename(const struct locale *lang, const struct unit *u,
         const race * rc);
 
-#define playerrace(rc) (!fval((rc), RCF_NPC))
-#define dragonrace(rc) (fval(rc, RCF_DRAGON))
-#define humanoidrace(rc) (fval((rc), RCF_UNDEAD) || (rc)==get_race(RC_DRACOID) || playerrace(rc))
-#define illusionaryrace(rc) (fval(rc, RCF_ILLUSIONARY))
+#define playerrace(rc) (!((rc)->flags & RCF_NPC))
+#define dragonrace(rc) ((rc)->flags & RCF_DRAGON)
+#define humanoidrace(rc) (((rc)->flags & RCF_UNDEAD) || (rc)==get_race(RC_DRACOID) || playerrace(rc))
+#define illusionaryrace(rc) ((rc)->flags & RCF_ILLUSIONARY)
 
     bool allowed_dragon(const struct region *src,
         const struct region *target);
diff --git a/src/kernel/ship.h b/src/kernel/ship.h
index 73b8a9718..748315d44 100644
--- a/src/kernel/ship.h
+++ b/src/kernel/ship.h
@@ -51,8 +51,8 @@ extern "C" {
         int minskill;               /* min. skill to sail this (crew) */
         int sumskill;               /* min. sum of crew+captain */
 
-        int at_bonus;               /* Ver�ndert den Angriffsskill (default: 0) */
-        int df_bonus;               /* Ver�ndert den Verteidigungskill (default: 0) */
+        int at_bonus;               /* Ver�ndert den Angriffsskill (default: 0) */
+        int df_bonus;               /* Ver�ndert den Verteidigungskill (default: 0) */
         float tac_bonus;
 
         struct terrain_type ** coasts; /* coast that this ship can land on */
@@ -70,12 +70,12 @@ extern "C" {
 
 #define NOSHIP NULL
 
-#define SF_DRIFTED 1<<0
-#define SF_MOVED   1<<1
-#define SF_DAMAGED 1<<2         /* for use in combat */
-#define SF_SELECT  1<<3         /* previously FL_DH */
-#define SF_FISHING 1<<4         /* was on an ocean, can fish */
-#define SF_FLYING  1<<5         /* the ship can fly */
+#define SF_DRIFTED (1<<0)
+#define SF_MOVED   (1<<1)
+#define SF_DAMAGED (1<<2)         /* for use in combat */
+#define SF_SELECT  (1<<3)         /* previously FL_DH */
+#define SF_FISHING (1<<4)         /* was on an ocean, can fish */
+#define SF_FLYING  (1<<5)         /* the ship can fly */
 
 #define SFL_SAVEMASK (SF_FLYING)
 #define INCOME_FISHING 10
diff --git a/src/spells.c b/src/spells.c
index da2b73c5e..61e6e8b72 100644
--- a/src/spells.c
+++ b/src/spells.c
@@ -446,7 +446,7 @@ report_effect(region * r, unit * mage, message * seen, message * unseen)
  * Vertrauten sehen, und durch den Vertrauten zaubern, allerdings nur
  * mit seiner halben Stufe. Je nach Vertrautem erhaelt der Magier
  * evtl diverse Skillmodifikationen.  Der Typ des Vertrauten ist
- * zufaellig bestimmt, wird aber durch Magiegebiet und Rasse beeinflu�t.
+ * zufaellig bestimmt, wird aber durch Magiegebiet und Rasse beeinflu�t.
  * "Tierische" Vertraute brauchen keinen Unterhalt.
  *
  * Ein paar Moeglichkeiten:
@@ -1599,7 +1599,7 @@ static int sp_create_stonegolem(castorder * co)
 }
 
 /* ------------------------------------------------------------- */
-/* Name:       Gro�e Duerre
+/* Name:       Gro�e Duerre
  * Stufe:      17
  * Kategorie:  Region, negativ
  * Gebiet:     Gwyrrd
@@ -1907,7 +1907,7 @@ static int sp_treewalkexit(castorder * co)
         return 0;
     }
 
-    /* Koordinaten setzen und Region loeschen fuer �berpruefung auf
+    /* Koordinaten setzen und Region loeschen fuer �berpruefung auf
      * Gueltigkeit */
     rt = pa->param[0]->data.r;
     tax = rt->x;
@@ -2194,7 +2194,7 @@ static int sp_ironkeeper(castorder * co)
     setstatus(keeper, ST_AVOID);  /* kaempft nicht */
     setguard(keeper, true);
     fset(keeper, UFL_ISNEW);
-    /* Parteitarnen, damit man nicht sofort wei�, wer dahinter steckt */
+    /* Parteitarnen, damit man nicht sofort wei�, wer dahinter steckt */
     if (rule_stealth_anon()) {
         fset(keeper, UFL_ANON_FACTION);
     }
@@ -2572,7 +2572,7 @@ void patzer_fumblecurse(const castorder * co)
  *
  * Wirkung:
  *  In einer Wueste, Sumpf oder Gletscher gezaubert kann innerhalb der
- *  naechsten 6 Runden ein bis 6 Dracheneinheiten bis Groe�e Wyrm
+ *  naechsten 6 Runden ein bis 6 Dracheneinheiten bis Groe�e Wyrm
  *  entstehen.
  *
  *  Mit Stufe 12-15 erscheinen Jung- oder normaler Drachen, mit Stufe
@@ -2817,7 +2817,7 @@ static int change_hitpoints(unit * u, int value)
 
     hp += value;
 
-    /* Jede Person ben�tigt mindestens 1 HP */
+    /* Jede Person ben�tigt mindestens 1 HP */
     if (hp < u->number) {
         if (hp < 0) {               /* Einheit tot */
             hp = 0;
@@ -3764,7 +3764,7 @@ static int sp_rallypeasantmob(castorder * co)
  * Gebiet:   Cerddor
  * Wirkung:
  *  Wiegelt 60% bis 90% der Bauern einer Region auf.  Bauern werden ein
- *  gro�er Mob, der zur Monsterpartei gehoert und die Region bewacht.
+ *  gro�er Mob, der zur Monsterpartei gehoert und die Region bewacht.
  *  Regionssilber sollte auch nicht durch Unterhaltung gewonnen werden
  *  koennen.
  *
@@ -4025,7 +4025,7 @@ static int sp_recruit(castorder * co)
         return 0;
     }
     /* Immer noch zuviel auf niedrigen Stufen. Deshalb die Rekrutierungskosten
-     * mit einfliessen lassen und dafuer den Exponenten etwas groe�er.
+     * mit einfliessen lassen und dafuer den Exponenten etwas groe�er.
      * Wenn die Rekrutierungskosten deutlich hoeher sind als der Faktor,
      * ist das Verhaeltniss von ausgegebene Aura pro Bauer bei Stufe 2
      * ein mehrfaches von Stufe 1, denn in beiden Faellen gibt es nur 1
@@ -4056,7 +4056,7 @@ static int sp_recruit(castorder * co)
 }
 
 /* ------------------------------------------------------------- */
-/* Name:    Wanderprediger - Gro�e Anwerbung
+/* Name:    Wanderprediger - Gro�e Anwerbung
  * Stufe:   14
  * Gebiet:  Cerddor
  * Wirkung:
@@ -4112,8 +4112,8 @@ static int sp_bigrecruit(castorder * co)
  * Gebiet:   Cerddor
  * Wirkung:
  *  Erliegt die Einheit dem Zauber, so wird sie dem Magier alles
- *  erzaehlen, was sie ueber die gefragte Region wei�. Ist in der Region
- *  niemand ihrer Partei, so wei� sie nichts zu berichten.  Auch kann
+ *  erzaehlen, was sie ueber die gefragte Region wei�. Ist in der Region
+ *  niemand ihrer Partei, so wei� sie nichts zu berichten.  Auch kann
  *  sie nur das erzaehlen, was sie selber sehen koennte.
  * Flags:
  *   (UNITSPELL | TESTCANSEE)
@@ -4176,7 +4176,7 @@ static int sp_pump(castorder * co)
  * Stufe:   6
  * Gebiet:   Cerddor
  * Wirkung:
- *  Betoert eine Einheit, so das sie ihm den groe�ten Teil ihres Bargelds
+ *  Betoert eine Einheit, so das sie ihm den groe�ten Teil ihres Bargelds
  *  und 50% ihres Besitzes schenkt. Sie behaelt jedoch immer soviel, wie
  *  sie zum ueberleben braucht. Wirkt gegen Magieresistenz.
  *  _min(Stufe*1000$, u->money - maintenace)
@@ -4333,7 +4333,7 @@ static int sp_headache(castorder * co)
     if (target->number == 0 || pa->param[0]->flag == TARGET_NOTFOUND)
         return 0;
 
-    /* finde das groe�te Talent: */
+    /* finde das groe�te Talent: */
     for (i = 0; i != target->skill_size; ++i) {
         skill *sv = target->skills + i;
         if (smax == NULL || skill_compare(sv, smax) > 0) {
@@ -4479,7 +4479,7 @@ int sp_puttorest(castorder * co)
     return co->level;
 }
 
-/* Name:       Traumschloe�chen
+/* Name:       Traumschloe�chen
  * Stufe:      3
  * Kategorie:  Region, Gebaeude, positiv
  * Gebiet:     Illaun
@@ -4514,7 +4514,7 @@ int sp_icastle(castorder * co)
 
     b = new_building(bt_illusion, r, mage->faction->locale);
 
-    /* Groe�e festlegen. */
+    /* Groe�e festlegen. */
     if (type == bt_illusion) {
         b->size = (rng_int() % (int)((power * power) + 1) * 10);
     }
@@ -4692,7 +4692,7 @@ int sp_baddreams(castorder * co)
  * Kategorie:
  * Wirkung:
  *   Dieser Zauber ermoeglicht es dem Traeumer, den Schlaf aller aliierten
- *   Einheiten in der Region so zu beeinflussen, da� sie fuer einige Zeit
+ *   Einheiten in der Region so zu beeinflussen, da� sie fuer einige Zeit
  *   einen Bonus von 1 Talentstufe in allen Talenten
  *   bekommen. Der Zauber wirkt erst im Folgemonat.
  * Flags:
diff --git a/src/spells/combatspells.c b/src/spells/combatspells.c
index bf122729a..da7e7085a 100644
--- a/src/spells/combatspells.c
+++ b/src/spells/combatspells.c
@@ -10,7 +10,6 @@
  without prior permission by the authors of Eressea.
  */
 #include <platform.h>
-#include <kernel/config.h>
 #include "combatspells.h"
 
 /* kernel includes */
@@ -81,7 +80,7 @@ static const char *spell_damage(int sp)
 {
     switch (sp) {
     case 0:
-        /* meist t�dlich 20-65 HP */
+        /* meist t�dlich 20-65 HP */
         return "5d10+15";
     case 1:
         /* sehr variabel 4-48 HP */
@@ -90,7 +89,7 @@ static const char *spell_damage(int sp)
         /* leicht verwundet 4-18 HP */
         return "2d8+2";
     case 3:
-        /* fast immer t�dlich 30-50 HP */
+        /* fast immer t�dlich 30-50 HP */
         return "5d5+25";
     case 4:
         /* verwundet 11-26 HP */
@@ -382,11 +381,11 @@ int sp_combatrosthauch(struct castorder * co)
     ql_free(fgs);
 
     if (k == 0) {
-        /* keine Waffen mehr da, die zerst�rt werden k�nnten */
+        /* keine Waffen mehr da, die zerst�rt werden k�nnten */
         message *msg = msg_message("rust_effect_1", "mage", fi->unit);
         message_all(b, msg);
         msg_release(msg);
-        fi->magic = 0;              /* k�mpft nichtmagisch weiter */
+        fi->magic = 0;              /* k�mpft nichtmagisch weiter */
         level = 0;
     }
     else {
@@ -453,7 +452,7 @@ int sp_speed(struct castorder * co)
 
     allies =
         count_allies(fi->side, FIGHT_ROW, BEHIND_ROW, SELECT_ADVANCE, ALLY_ANY);
-    /* maximal 2*allies Versuche ein Opfer zu finden, ansonsten best�nde
+    /* maximal 2*allies Versuche ein Opfer zu finden, ansonsten best�nde
      * die Gefahr eine Endlosschleife*/
     allies *= 2;
 
@@ -546,7 +545,7 @@ int sp_mindblast_temp(struct castorder * co)
 
         assert(dt.fighter);
         du = dt.fighter->unit;
-        if (fval(du, UFL_MARK)) {
+        if (du->flags & UFL_MARK) {
             /* not this one again */
             continue;
         }
@@ -564,7 +563,7 @@ int sp_mindblast_temp(struct castorder * co)
             }
             force -= du->number;
         }
-        fset(du, UFL_MARK);
+        du->flags |= UFL_MARK;
         reset = 1;
         enemies -= du->number;
     }
@@ -572,7 +571,7 @@ int sp_mindblast_temp(struct castorder * co)
     if (reset) {
         unit *u;
         for (u = b->region->units; u; u = u->next) {
-            freset(u, UFL_MARK);
+            u->flags &= ~UFL_MARK;
         }
     }
 
@@ -612,7 +611,7 @@ int sp_mindblast(struct castorder * co)
 
         assert(dt.fighter);
         du = dt.fighter->unit;
-        if (fval(du, UFL_MARK)) {
+        if (du->flags & UFL_MARK) {
             /* not this one again */
             continue;
         }
@@ -640,7 +639,7 @@ int sp_mindblast(struct castorder * co)
         else {
             /* only works against humanoids, don't try others. but do remove them
              * from 'force' once or we may never terminate. */
-            fset(du, UFL_MARK);
+            du->flags |= UFL_MARK;
             reset = 1;
         }
         enemies -= du->number;
@@ -649,7 +648,7 @@ int sp_mindblast(struct castorder * co)
     if (reset) {
         unit *u;
         for (u = b->region->units; u; u = u->next) {
-            freset(u, UFL_MARK);
+            u->flags &= ~UFL_MARK;
         }
     }
 
@@ -866,8 +865,8 @@ static fighter *summon_allies(const fighter *fi, const race *rc, int number) {
     
     u->hp = u->number * unit_max_hp(u);
     
-    if (fval(mage, UFL_ANON_FACTION)) {
-        fset(u, UFL_ANON_FACTION);
+    if (mage->flags & UFL_ANON_FACTION) {
+        u->flags |= UFL_ANON_FACTION;
     }
     
     a = a_new(&at_unitdissolve);
@@ -932,8 +931,8 @@ int sp_shadowknights(struct castorder * co)
 
     u->hp = u->number * unit_max_hp(u);
 
-    if (fval(mage, UFL_ANON_FACTION)) {
-        fset(u, UFL_ANON_FACTION);
+    if (mage->flags & UFL_ANON_FACTION) {
+        u->flags |= UFL_ANON_FACTION;
     }
 
     a = a_new(&at_unitdissolve);
@@ -1016,7 +1015,7 @@ int sp_chaosrow(struct castorder * co)
             continue;
         if (power <= 0.0)
             break;
-        /* force sollte wegen des _max(0,x) nicht unter 0 fallen k�nnen */
+        /* force sollte wegen des _max(0,x) nicht unter 0 fallen k�nnen */
 
         if (is_magic_resistant(mage, df->unit, 0))
             continue;
@@ -1068,7 +1067,7 @@ int sp_chaosrow(struct castorder * co)
 }
 
 /* Gesang der Furcht (Kampfzauber) */
-/* Panik (Pr�kampfzauber) */
+/* Panik (Pr�kampfzauber) */
 
 int sp_flee(struct castorder * co)
 {
@@ -1114,13 +1113,13 @@ int sp_flee(struct castorder * co)
             if (force < 0)
                 break;
 
-            if (df->person[n].flags & FL_PANICED) {   /* bei SPL_SONG_OF_FEAR m�glich */
+            if (df->person[n].flags & FL_PANICED) {   /* bei SPL_SONG_OF_FEAR m�glich */
                 df->person[n].attack -= 1;
                 --force;
                 ++panik;
             }
             else if (!(df->person[n].flags & FL_COURAGE)
-                || !fval(u_race(df->unit), RCF_UNDEAD)) {
+                || !(u_race(df->unit)->flags & RCF_UNDEAD)) {
                 if (!is_magic_resistant(mage, df->unit, 0)) {
                     df->person[n].flags |= FL_PANICED;
                     ++panik;
@@ -1165,7 +1164,7 @@ int sp_hero(struct castorder * co)
 
     allies =
         count_allies(fi->side, FIGHT_ROW, BEHIND_ROW, SELECT_ADVANCE, ALLY_ANY);
-    /* maximal 2*allies Versuche ein Opfer zu finden, ansonsten best�nde
+    /* maximal 2*allies Versuche ein Opfer zu finden, ansonsten best�nde
      * die Gefahr eine Endlosschleife*/
     allies *= 2;
 
@@ -1222,7 +1221,7 @@ int sp_berserk(struct castorder * co)
 
     allies =
         count_allies(fi->side, FIGHT_ROW, BEHIND_ROW - 1, SELECT_ADVANCE, ALLY_ANY);
-    /* maximal 2*allies Versuche ein Opfer zu finden, ansonsten best�nde
+    /* maximal 2*allies Versuche ein Opfer zu finden, ansonsten best�nde
      * die Gefahr eine Endlosschleife*/
     allies *= 2;
 
@@ -1419,7 +1418,7 @@ int sp_reeling_arrows(struct castorder * co)
 }
 
 /* Magier weicht dem Kampf aus. Wenn er sich bewegen kann, zieht er in
- * eine Nachbarregion, wobei ein NACH ber�cksichtigt wird. Ansonsten
+ * eine Nachbarregion, wobei ein NACH ber�cksichtigt wird. Ansonsten
  * bleibt er stehen und nimmt nicht weiter am Kampf teil. */
 int sp_denyattack(struct castorder * co)
 {
@@ -1432,17 +1431,16 @@ int sp_denyattack(struct castorder * co)
     region *r = b->region;
     message *m;
 
-    /* Fliehende Einheiten verlassen auf jeden Fall Geb�ude und Schiffe. */
-    if (!fval(r->terrain, SEA_REGION)) {
+    /* Fliehende Einheiten verlassen auf jeden Fall Geb�ude und Schiffe. */
+    if (!(r->terrain->flags & SEA_REGION)) {
         leave(mage, false);
     }
     /* und bewachen nicht */
     setguard(mage, false);
     /* irgendwie den langen befehl sperren */
-    /* fset(fi, FIG_ATTACKED); */
 
-    /* wir tun so, als w�re die Person geflohen */
-    fset(fi, FIG_NOLOOT);
+    /* wir tun so, als w�re die Person geflohen */
+    fi->flags |= FIG_NOLOOT;
     fi->run.hp = mage->hp;
     fi->run.number = mage->number;
     /* fighter leeren */
@@ -1480,7 +1478,7 @@ int sp_armorshield(struct castorder * co)
     message_all(b, m);
     msg_release(m);
 
-    /* gibt R�stung +effect f�r duration Treffer */
+    /* gibt R�stung +effect f�r duration Treffer */
 
     switch (sp->id) {
     case SPL_ARMORSHIELD:
@@ -1539,7 +1537,7 @@ int sp_fumbleshield(struct castorder * co)
     message_all(b, m);
     msg_release(m);
 
-    /* der erste Zauber schl�gt mit 100% fehl  */
+    /* der erste Zauber schl�gt mit 100% fehl  */
 
     switch (sp->id) {
     case SPL_DRAIG_FUMBLESHIELD:
@@ -1605,7 +1603,7 @@ int sp_reanimate(struct castorder * co)
             && u_race(tf->unit) != get_race(RC_DAEMON)
             && (chance(c))) {
             assert(tf->alive < tf->unit->number);
-            /* t.fighter->person[].hp beginnt mit t.index = 0 zu z�hlen,
+            /* t.fighter->person[].hp beginnt mit t.index = 0 zu z�hlen,
              * t.fighter->alive ist jedoch die Anzahl lebender in der Einheit,
              * also sind die hp von t.fighter->alive
              * t.fighter->hitpoints[t.fighter->alive-1] und der erste Tote
@@ -1668,7 +1666,7 @@ static int heal_fighters(quicklist * fgs, int *power, bool heal_monsters)
             break;
 
         /* Untote kann man nicht heilen */
-        if (df->unit->number == 0 || fval(u_race(df->unit), RCF_NOHEAL))
+        if (df->unit->number == 0 || (u_race(df->unit)->flags & RCF_NOHEAL))
             continue;
 
         /* wir heilen erstmal keine Monster */
@@ -1711,8 +1709,8 @@ int sp_healing(struct castorder * co)
     message *msg;
     bool use_item = has_ao_healing(mage);
 
-    /* bis zu 11 Personen pro Stufe (einen HP m�ssen sie ja noch
-     * haben, sonst w�ren sie tot) k�nnen geheilt werden */
+    /* bis zu 11 Personen pro Stufe (einen HP m�ssen sie ja noch
+     * haben, sonst w�ren sie tot) k�nnen geheilt werden */
 
     if (use_item) {
         healhp *= 2;
@@ -1758,7 +1756,7 @@ int sp_undeadhero(struct castorder * co)
     int force = (int)get_force(power, 0);
     double c = 0.50 + 0.02 * power;
 
-    /* Liste aus allen K�mpfern */
+    /* Liste aus allen K�mpfern */
     fgs = fighters(b, fi->side, FIGHT_ROW, AVOID_ROW, FS_ENEMY | FS_HELP);
     scramble_fighters(fgs);
 
@@ -1776,7 +1774,7 @@ int sp_undeadhero(struct castorder * co)
         if (df->alive + df->run.number < du->number) {
             int j = 0;
 
-            /* Wieviele Untote k�nnen wir aus dieser Einheit wecken? */
+            /* Wieviele Untote k�nnen wir aus dieser Einheit wecken? */
             for (n = df->alive + df->run.number; n != du->number; n++) {
                 if (chance(c)) {
                     ++j;
@@ -1818,8 +1816,8 @@ int sp_undeadhero(struct castorder * co)
                 }
 
                 /* inherit stealth from magician */
-                if (fval(mage, UFL_ANON_FACTION)) {
-                    fset(u, UFL_ANON_FACTION);
+                if (mage->flags & UFL_ANON_FACTION) {
+                    u->flags |= UFL_ANON_FACTION;
                 }
 
                 /* transfer dead people to new unit, set hitpoints to those of old unit */
diff --git a/src/spells/flyingship.c b/src/spells/flyingship.c
index 4a3c62e5e..2057b72e0 100644
--- a/src/spells/flyingship.c
+++ b/src/spells/flyingship.c
@@ -1,5 +1,4 @@
 #include <platform.h>
-#include <kernel/config.h>
 #include "flyingship.h"
 
 #include <kernel/build.h>
@@ -27,8 +26,8 @@
 * Stufe:      6
 *
 * Wirkung:
-* Lae�t ein Schiff eine Runde lang fliegen.  Wirkt nur auf Boote
-* bis Kapazit�t 50.
+* Lae�t ein Schiff eine Runde lang fliegen.  Wirkt nur auf Boote
+* bis Kapazit�t 50.
 * Kombinierbar mit "Guenstige Winde", aber nicht mit "Sturmwind".
 *
 * Flag:
@@ -81,18 +80,20 @@ int sp_flying_ship(castorder * co)
 
     /* melden, 1x pro Partei */
     for (u = r->units; u; u = u->next)
-        freset(u->faction, FFL_SELECT);
+        u->faction->flags &= ~FFL_SELECT;
     for (u = r->units; u; u = u->next) {
         /* das sehen natuerlich auch die Leute an Land */
-        if (!fval(u->faction, FFL_SELECT)) {
-            fset(u->faction, FFL_SELECT);
-            if (!m)
+        if (!(u->faction->flags & FFL_SELECT)) {
+            u->faction->flags |= FFL_SELECT;
+            if (!m) {
                 m = msg_message("flying_ship_result", "mage ship", mage, sh);
+            }
             add_message(&u->faction->msgs, m);
         }
     }
-    if (m)
+    if (m) {
         msg_release(m);
+    }
     return cast_level;
 }
 
@@ -120,7 +121,7 @@ static int flyingship_age(curse * c)
 {
     ship *sh = (ship *)c->data.v;
     if (sh && c->duration == 1) {
-        freset(sh, SF_FLYING);
+        sh->flags &= ~SF_FLYING;
         return 1;
     }
     return 0;
diff --git a/src/util/rand.c b/src/util/rand.c
index d98b9b8f9..b92b4aff3 100644
--- a/src/util/rand.c
+++ b/src/util/rand.c
@@ -28,6 +28,14 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 #include <float.h>
 #include <ctype.h>
 
+int lovar(double xpct_x2)
+{
+    int n = (int)(xpct_x2 * 500) + 1;
+    if (n == 0)
+        return 0;
+    return (rng_int() % n + rng_int() % n) / 1000;
+}
+
 /* NormalRand aus python, random.py geklaut, dort ist Referenz auf
 * den Algorithmus. mu = Mittelwert, sigma = Standardabweichung.
 * http://de.wikipedia.org/wiki/Standardabweichung#Diskrete_Gleichverteilung.2C_W.C3.BCrfel
diff --git a/src/util/rand.h b/src/util/rand.h
index e9e5d19ee..9fb3f2f69 100644
--- a/src/util/rand.h
+++ b/src/util/rand.h
@@ -23,13 +23,14 @@ extern "C" {
 #endif
 
     /* in dice.c: */
-    extern int dice_rand(const char *str);
-    extern int dice(int count, int value);
+    int dice_rand(const char *str);
+    int dice(int count, int value);
 
     /* in rand.c: */
-    extern double normalvariate(double mu, double sigma);
-    extern int ntimespprob(int n, double p, double mod);
-    extern bool chance(double x);
+    int lovar(double xpct_x2);
+    double normalvariate(double mu, double sigma);
+    int ntimespprob(int n, double p, double mod);
+    bool chance(double x);
 
     /* a random source that generates numbers in [0, 1).
        By calling the random_source_inject... functions you can set a special random source,
diff --git a/tolua b/tolua
new file mode 160000
index 000000000..de289b60c
--- /dev/null
+++ b/tolua
@@ -0,0 +1 @@
+Subproject commit de289b60c5009b6ac8e786f39432c08eadbb69b7

From 2f305f16d93ca28236a325d0e48faab9f1ee68b9 Mon Sep 17 00:00:00 2001
From: Enno Rehling <enno.rehling@gmail.com>
Date: Thu, 17 Nov 2016 21:08:35 +0100
Subject: [PATCH 31/42] additional testing for renumber.

---
 src/kernel/unit.c   |   6 ++-
 src/renumber.c      |  11 +---
 src/renumber.test.c | 122 +++++++++++++++++++++++++++++++++++++++++++-
 3 files changed, 128 insertions(+), 11 deletions(-)

diff --git a/src/kernel/unit.c b/src/kernel/unit.c
index 28e95b941..95c689ded 100644
--- a/src/kernel/unit.c
+++ b/src/kernel/unit.c
@@ -494,6 +494,10 @@ attrib_type at_alias = {
     NO_READ
 };
 
+/** remember old unit.no (for the creport, mostly)
+ * if alias is positive, then this unit was a TEMP
+ * if alias is negative, then this unit has been RENUMBERed
+ */
 int ualias(const unit * u)
 {
     attrib *a = a_find(u->attribs, &at_alias);
@@ -1716,7 +1720,7 @@ void renumber_unit(unit *u, int no) {
     uunhash(u);
     if (!ualias(u)) {
         attrib *a = a_add(&u->attribs, a_new(&at_alias));
-        a->data.i = -u->no; // TODO: why is the alias negative? confusing!
+        a->data.i = -u->no;
     }
     u->no = no;
     uhash(u);
diff --git a/src/renumber.c b/src/renumber.c
index 259dfcc2b..de2b5a490 100644
--- a/src/renumber.c
+++ b/src/renumber.c
@@ -36,7 +36,6 @@ void renumber_factions(void)
         attrib *a = a_find(f->attribs, &at_number);
         int want;
         struct renum **rn;
-        faction *old;
 
         if (!a)
             continue;
@@ -45,12 +44,6 @@ void renumber_factions(void)
             ADDMSG(&f->msgs, msg_message("renumber_twice", "id", want));
             continue;
         }
-        old = findfaction(want);
-        if (old) {
-            a_remove(&f->attribs, a);
-            ADDMSG(&f->msgs, msg_message("renumber_inuse", "id", want));
-            continue;
-        }
         if (!faction_id_is_unused(want)) {
             a_remove(&f->attribs, a);
             ADDMSG(&f->msgs, msg_message("renumber_inuse", "id", want));
@@ -151,7 +144,7 @@ int renumber_cmd(unit * u, order * ord)
                 cmistake(u, ord, 114, MSG_EVENT);
                 break;
             }
-            if (findship(i) || findbuilding(i)) {
+            if (findship(i)) {
                 cmistake(u, ord, 115, MSG_EVENT);
                 break;
             }
@@ -180,7 +173,7 @@ int renumber_cmd(unit * u, order * ord)
                 cmistake(u, ord, 114, MSG_EVENT);
                 break;
             }
-            if (findship(i) || findbuilding(i)) {
+            if (findbuilding(i)) {
                 cmistake(u, ord, 115, MSG_EVENT);
                 break;
             }
diff --git a/src/renumber.test.c b/src/renumber.test.c
index 3fabaf4c1..9ab6b1e7b 100644
--- a/src/renumber.test.c
+++ b/src/renumber.test.c
@@ -29,6 +29,25 @@ static void test_renumber_faction(CuTest *tc) {
     test_cleanup();
 }
 
+static void test_renumber_faction_duplicate(CuTest *tc) {
+    unit *u;
+    faction *f, *f2;
+    int no;
+    const struct locale *lang;
+
+    test_setup_ex(tc);
+    f2 = test_create_faction(0);
+    u = test_create_unit(f = test_create_faction(0), test_create_region(0, 0, 0));
+    no = f->no;
+    lang = f->locale;
+    u->thisorder = create_order(K_NUMBER, lang, "%s %s", LOC(lang, parameters[P_FACTION]), itoa36(f2->no));
+    renumber_cmd(u, u->thisorder);
+    renumber_factions();
+    CuAssertPtrNotNull(tc, test_find_messagetype(f->msgs, "renumber_inuse"));
+    CuAssertIntEquals(tc, no, u->faction->no);
+    test_cleanup();
+}
+
 static void test_renumber_building(CuTest *tc) {
     unit *u;
     int uno, no;
@@ -46,6 +65,26 @@ static void test_renumber_building(CuTest *tc) {
     test_cleanup();
 }
 
+static void test_renumber_building_duplicate(CuTest *tc) {
+    unit *u;
+    faction *f;
+    int uno, no;
+    const struct locale *lang;
+
+    test_setup_ex(tc);
+    u = test_create_unit(f = test_create_faction(0), test_create_region(0, 0, 0));
+    u->building = test_create_building(u->region, 0);
+    uno = u->building->no;
+    u->building = test_create_building(u->region, 0);
+    no = u->building->no;
+    lang = f->locale;
+    u->thisorder = create_order(K_NUMBER, lang, "%s %s", LOC(lang, parameters[P_BUILDING]), itoa36(uno));
+    renumber_cmd(u, u->thisorder);
+    CuAssertPtrNotNull(tc, test_find_messagetype(f->msgs, "error115"));
+    CuAssertIntEquals(tc, no, u->building->no);
+    test_cleanup();
+}
+
 static void test_renumber_ship(CuTest *tc) {
     unit *u;
     int uno, no;
@@ -63,6 +102,26 @@ static void test_renumber_ship(CuTest *tc) {
     test_cleanup();
 }
 
+static void test_renumber_ship_duplicate(CuTest *tc) {
+    unit *u;
+    faction *f;
+    int uno, no;
+    const struct locale *lang;
+
+    test_setup_ex(tc);
+    u = test_create_unit(f = test_create_faction(0), test_create_region(0, 0, 0));
+    u->ship = test_create_ship(u->region, 0);
+    uno = u->ship->no;
+    u->ship = test_create_ship(u->region, 0);
+    no = u->ship->no;
+    lang = f->locale;
+    u->thisorder = create_order(K_NUMBER, lang, "%s %s", LOC(lang, parameters[P_SHIP]), itoa36(uno));
+    renumber_cmd(u, u->thisorder);
+    CuAssertPtrNotNull(tc, test_find_messagetype(f->msgs, "error115"));
+    CuAssertIntEquals(tc, no, u->ship->no);
+    test_cleanup();
+}
+
 static void test_renumber_unit(CuTest *tc) {
     unit *u;
     int uno, no;
@@ -76,7 +135,62 @@ static void test_renumber_unit(CuTest *tc) {
     u->thisorder = create_order(K_NUMBER, lang, "%s %s", LOC(lang, parameters[P_UNIT]), itoa36(uno));
     renumber_cmd(u, u->thisorder);
     CuAssertIntEquals(tc, uno, u->no);
-    CuAssertIntEquals(tc, -no, ualias(u)); // TODO: why is ualias negative?
+    CuAssertIntEquals(tc, -no, ualias(u));
+    test_cleanup();
+}
+
+static void test_renumber_unit_duplicate(CuTest *tc) {
+    unit *u, *u2;
+    faction *f;
+    int no;
+    const struct locale *lang;
+
+    test_setup_ex(tc);
+    u = test_create_unit(f = test_create_faction(0), test_create_region(0, 0, 0));
+    no = u->no;
+    u2 = test_create_unit(f, u->region);
+    lang = f->locale;
+    u->thisorder = create_order(K_NUMBER, lang, "%s %s", LOC(lang, parameters[P_UNIT]), itoa36(u2->no));
+    renumber_cmd(u, u->thisorder);
+    CuAssertIntEquals(tc, no, u->no);
+    CuAssertPtrNotNull(tc, test_find_messagetype(f->msgs, "error115"));
+    CuAssertIntEquals(tc, 0, ualias(u));
+    test_cleanup();
+}
+
+static void test_renumber_unit_limit(CuTest *tc) {
+    unit *u;
+    faction *f;
+    int no;
+    const struct locale *lang;
+
+    test_setup_ex(tc);
+    u = test_create_unit(f = test_create_faction(0), test_create_region(0, 0, 0));
+    no = u->no;
+    lang = f->locale;
+    u->thisorder = create_order(K_NUMBER, lang, "%s 10000", LOC(lang, parameters[P_UNIT]));
+    renumber_cmd(u, u->thisorder);
+    CuAssertIntEquals(tc, no, u->no);
+    CuAssertPtrNotNull(tc, test_find_messagetype(f->msgs, "error114"));
+    CuAssertIntEquals(tc, 0, ualias(u));
+    test_cleanup();
+}
+
+static void test_renumber_unit_invalid(CuTest *tc) {
+    unit *u;
+    faction *f;
+    int no;
+    const struct locale *lang;
+
+    test_setup_ex(tc);
+    u = test_create_unit(f = test_create_faction(0), test_create_region(0, 0, 0));
+    no = u->no;
+    lang = f->locale;
+    u->thisorder = create_order(K_NUMBER, lang, "%s TEMP", LOC(lang, parameters[P_UNIT]));
+    renumber_cmd(u, u->thisorder);
+    CuAssertIntEquals(tc, no, u->no);
+    CuAssertPtrNotNull(tc, test_find_messagetype(f->msgs, "error116"));
+    CuAssertIntEquals(tc, 0, ualias(u));
     test_cleanup();
 }
 
@@ -84,8 +198,14 @@ CuSuite *get_renumber_suite(void)
 {
     CuSuite *suite = CuSuiteNew();
     SUITE_ADD_TEST(suite, test_renumber_unit);
+    SUITE_ADD_TEST(suite, test_renumber_unit_limit);
+    SUITE_ADD_TEST(suite, test_renumber_unit_duplicate);
+    SUITE_ADD_TEST(suite, test_renumber_unit_invalid);
     SUITE_ADD_TEST(suite, test_renumber_building);
+    SUITE_ADD_TEST(suite, test_renumber_building_duplicate);
     SUITE_ADD_TEST(suite, test_renumber_ship);
+    SUITE_ADD_TEST(suite, test_renumber_ship_duplicate);
     SUITE_ADD_TEST(suite, test_renumber_faction);
+    SUITE_ADD_TEST(suite, test_renumber_faction_duplicate);
     return suite;
 }

From bc5e7443477fb7afe5dda2548975302ef4c9598d Mon Sep 17 00:00:00 2001
From: Enno Rehling <enno.rehling@gmail.com>
Date: Thu, 17 Nov 2016 21:23:49 +0100
Subject: [PATCH 32/42] i2b is a bullshit macro.

---
 src/battle.c        | 2 +-
 src/creport.c       | 4 ++--
 src/kernel/config.h | 2 --
 src/magic.c         | 4 ++--
 4 files changed, 5 insertions(+), 7 deletions(-)

diff --git a/src/battle.c b/src/battle.c
index 2facbb30f..34d4618a5 100644
--- a/src/battle.c
+++ b/src/battle.c
@@ -3130,7 +3130,7 @@ static void print_stats(battle * b)
 
 static int weapon_weight(const weapon * w, bool missile)
 {
-    if (missile == i2b(fval(w->type, WTF_MISSILE))) {
+    if (missile == !!(fval(w->type, WTF_MISSILE))) {
         return w->attackskill + w->defenseskill;
     }
     return 0;
diff --git a/src/creport.c b/src/creport.c
index b74c5cdef..b63a30ad4 100644
--- a/src/creport.c
+++ b/src/creport.c
@@ -782,7 +782,7 @@ void cr_output_unit(stream *out, const region * r, const faction * f,
         if (sf != u->faction)
             stream_printf(out, "%d;Verkleidung\n", sf->no);
         if (fval(u, UFL_ANON_FACTION))
-            stream_printf(out, "%d;Parteitarnung\n", i2b(fval(u, UFL_ANON_FACTION)));
+            stream_printf(out, "%d;Parteitarnung\n", (u->flags & UFL_ANON_FACTION)!=0);
         if (otherfaction && otherfaction != u->faction) {
             stream_printf(out, "%d;Anderepartei\n", otherfaction->no);
         }
@@ -794,7 +794,7 @@ void cr_output_unit(stream *out, const region * r, const faction * f,
     else {
         if (fval(u, UFL_ANON_FACTION)) {
             /* faction info is hidden */
-            stream_printf(out, "%d;Parteitarnung\n", i2b(fval(u, UFL_ANON_FACTION)));
+            stream_printf(out, "%d;Parteitarnung\n", (u->flags & UFL_ANON_FACTION) != 0);
         }
         else {
             const attrib *a_otherfaction = a_find(u->attribs, &at_otherfaction);
diff --git a/src/kernel/config.h b/src/kernel/config.h
index b9bb3f4d3..fd929e8f7 100644
--- a/src/kernel/config.h
+++ b/src/kernel/config.h
@@ -34,8 +34,6 @@ struct param;
 #define OBJECTIDSIZE        (NAMESIZE+5+IDSIZE) /* max. L�nge der Strings, die
      * von struct unitname, etc. zur�ckgegeben werden. ohne die 0 */
 
-#define i2b(i) ((bool)((i)?(true):(false)))
-
 #define fval(u, i) ((u)->flags & (i))
 #define fset(u, i) ((u)->flags |= (i))
 #define freset(u, i) ((u)->flags &= ~(i))
diff --git a/src/magic.c b/src/magic.c
index 803f20c78..d13be7c07 100644
--- a/src/magic.c
+++ b/src/magic.c
@@ -347,7 +347,7 @@ attrib_type at_mage = {
 
 bool is_mage(const unit * u)
 {
-    return i2b(get_mage(u) != NULL);
+    return get_mage(u) != NULL;
 }
 
 sc_mage *get_mage(const unit * u)
@@ -2167,7 +2167,7 @@ typedef struct familiar_data {
 bool is_familiar(const unit * u)
 {
     attrib *a = a_find(u->attribs, &at_familiarmage);
-    return i2b(a != NULL);
+    return a != NULL;
 }
 
 static void

From 434cf8fce6371942654945f14f4c7416e29213f6 Mon Sep 17 00:00:00 2001
From: Enno Rehling <enno.rehling@gmail.com>
Date: Thu, 17 Nov 2016 21:27:19 +0100
Subject: [PATCH 33/42] the unitid macro is boring.

---
 src/battle.c         | 8 ++++----
 src/kernel/config.h  | 2 --
 src/report.c         | 2 +-
 src/spells.c         | 4 ++--
 src/study.c          | 2 +-
 src/triggers/shock.c | 2 +-
 6 files changed, 9 insertions(+), 11 deletions(-)

diff --git a/src/battle.c b/src/battle.c
index 34d4618a5..b5d767535 100644
--- a/src/battle.c
+++ b/src/battle.c
@@ -1216,7 +1216,7 @@ terminate(troop dt, troop at, int type, const char *damage, bool missile)
 
             while (chance(kritchance)) {
                 if (bdebug) {
-                    fprintf(bdebug, "%s/%d lands a critical hit\n", unitid(au), at.index);
+                    fprintf(bdebug, "%s/%d lands a critical hit\n", itoa36(au->no), at.index);
                 }
                 da += dice_rand(damage);
             }
@@ -1980,10 +1980,10 @@ debug_hit(troop at, const weapon * awp, troop dt, const weapon * dwp,
 int skdiff, int dist, bool success)
 {
     fprintf(bdebug, "%.4s/%d [%6s/%d] %s %.4s/%d [%6s/%d] with %d, distance %d\n",
-        unitid(at.fighter->unit), at.index,
+        itoa36(at.fighter->unit->no), at.index,
         LOC(default_locale, awp ? resourcename(awp->type->itype->rtype,
         0) : "unarmed"), weapon_effskill(at, dt, awp, true, dist > 1),
-        success ? "hits" : "misses", unitid(dt.fighter->unit), dt.index,
+        success ? "hits" : "misses", itoa36(dt.fighter->unit->no), dt.index,
         LOC(default_locale, dwp ? resourcename(dwp->type->itype->rtype,
         0) : "unarmed"), weapon_effskill(dt, at, dwp, false, dist > 1), skdiff,
         dist);
@@ -2194,7 +2194,7 @@ static void attack(battle * b, troop ta, const att * a, int numattack)
                 if (reload && wp && wp->type->reload && !getreload(ta)) {
                     int i = setreload(ta);
                     if (bdebug) {
-                        fprintf(bdebug, "%s/%d reloading %d turns\n", unitid(au),
+                        fprintf(bdebug, "%s/%d reloading %d turns\n", itoa36(au->no),
                             ta.index, i);
                     }
                 }
diff --git a/src/kernel/config.h b/src/kernel/config.h
index fd929e8f7..2f36f6bc9 100644
--- a/src/kernel/config.h
+++ b/src/kernel/config.h
@@ -45,8 +45,6 @@ struct param;
     bool isparam(const char *s, const struct locale * lang, param_t param);
     param_t getparam(const struct locale *lang);
 
-#define unitid(x) itoa36((x)->no)
-
 #define buildingid(x) itoa36((x)->no)
 #define shipid(x) itoa36((x)->no)
 #define factionid(x) itoa36((x)->no)
diff --git a/src/report.c b/src/report.c
index 80ac85974..b3549302a 100644
--- a/src/report.c
+++ b/src/report.c
@@ -1453,7 +1453,7 @@ report_template(const char *filename, report_context * ctx, const char *charset)
                 size = sizeof(buf) - 1;
                 bytes = _snprintf(bufp, size, "%s %s;    %s [%d,%d$",
                     LOC(u->faction->locale, parameters[P_UNIT]),
-                    unitid(u), unit_getname(u), u->number, get_money(u));
+                    itoa36(u->no), unit_getname(u), u->number, get_money(u));
                 if (wrptr(&bufp, &size, bytes) != 0)
                     WARN_STATIC_BUFFER();
                 if (u->building && building_owner(u->building) == u) {
diff --git a/src/spells.c b/src/spells.c
index da2b73c5e..369dab924 100644
--- a/src/spells.c
+++ b/src/spells.c
@@ -6291,7 +6291,7 @@ int sp_q_antimagie(castorder * co)
     {
         unit *u = pa->param[0]->data.u;
         ap = &u->attribs;
-        ts = unitid(u);
+        ts = itoa36(u->no);
         break;
     }
     case SPP_BUILDING:
@@ -6384,7 +6384,7 @@ int sp_break_curse(castorder * co)
         {
             unit *u = pa->param[0]->data.u;
             ap = &u->attribs;
-            ts = unitid(u);
+            ts = itoa36(u->no);
             break;
         }
         case SPP_BUILDING:
diff --git a/src/study.c b/src/study.c
index 1cd8847be..1dd4da8b8 100644
--- a/src/study.c
+++ b/src/study.c
@@ -439,7 +439,7 @@ int teach_cmd(unit * u, struct order *ord)
                 strncat(zOrder, " ", sz - 1);
                 --sz;
             }
-            sz -= strlcpy(zOrder + 4096 - sz, unitid(u2), sz);
+            sz -= strlcpy(zOrder + 4096 - sz, itoa36(u2->no), sz);
 
             if (getkeyword(u2->thisorder) != K_STUDY) {
                 ADDMSG(&u->faction->msgs,
diff --git a/src/triggers/shock.c b/src/triggers/shock.c
index 75904e346..f44219b5f 100644
--- a/src/triggers/shock.c
+++ b/src/triggers/shock.c
@@ -118,7 +118,7 @@ static void shock_write(const trigger * t, struct storage *store)
         next = next->next;
     }
     if (next && u) {
-        log_error("more than one shock-attribut for %s on a unit. FIXED.\n", unitid(u));
+        log_error("more than one shock-attribut for %s on a unit. FIXED.\n", itoa36(u->no));
         write_unit_reference(NULL, store);
     }
     else {

From 303eb863998402c308c46dcfa4bc8bc1e9433885 Mon Sep 17 00:00:00 2001
From: Enno Rehling <enno.rehling@gmail.com>
Date: Thu, 17 Nov 2016 21:29:15 +0100
Subject: [PATCH 34/42] factionid and curseid are also boring.

---
 src/kernel/config.h  | 2 --
 src/kernel/faction.c | 6 +++---
 src/kernel/save.c    | 2 +-
 src/laws.c           | 2 +-
 src/modules/score.c  | 2 +-
 src/report.c         | 2 +-
 src/reports.c        | 8 ++++----
 src/summary.c        | 4 ++--
 8 files changed, 13 insertions(+), 15 deletions(-)

diff --git a/src/kernel/config.h b/src/kernel/config.h
index 2f36f6bc9..a15a77ba4 100644
--- a/src/kernel/config.h
+++ b/src/kernel/config.h
@@ -47,8 +47,6 @@ struct param;
 
 #define buildingid(x) itoa36((x)->no)
 #define shipid(x) itoa36((x)->no)
-#define factionid(x) itoa36((x)->no)
-#define curseid(x) itoa36((x)->no)
 
     const char * game_name(void);
     int game_id(void);
diff --git a/src/kernel/faction.c b/src/kernel/faction.c
index 0172ea835..6d2430de4 100755
--- a/src/kernel/faction.c
+++ b/src/kernel/faction.c
@@ -273,11 +273,11 @@ faction *addfaction(const char *email, const char *password,
     addlist(&factions, f);
     fhash(f);
 
-    slprintf(buf, sizeof(buf), "%s %s", LOC(loc, "factiondefault"), factionid(f));
+    slprintf(buf, sizeof(buf), "%s %s", LOC(loc, "factiondefault"), itoa36(f->no));
     f->name = _strdup(buf);
 
     if (!f->race) {
-        log_warning("creating a faction that has no race", factionid(f));
+        log_warning("creating a faction that has no race", itoa36(f->no));
     }
 
     return f;
@@ -828,7 +828,7 @@ int writepasswd(void)
 
         for (f = factions; f; f = f->next) {
             fprintf(F, "%s:%s:%s:%u\n",
-                factionid(f), f->email, f->_password, f->subscription);
+                itoa36(f->no), f->email, f->_password, f->subscription);
         }
         fclose(F);
         return 0;
diff --git a/src/kernel/save.c b/src/kernel/save.c
index fa2beabc6..83fa72f76 100644
--- a/src/kernel/save.c
+++ b/src/kernel/save.c
@@ -1291,7 +1291,7 @@ faction *read_faction(struct gamedata * data)
 	};
     f->banner = _strdup(name);
 
-    log_debug("   - Lese Partei %s (%s)", f->name, factionid(f));
+    log_debug("   - Lese Partei %s (%s)", f->name, itoa36(f->no));
 
     READ_STR(data->store, name, sizeof(name));
     if (set_email(&f->email, name) != 0) {
diff --git a/src/laws.c b/src/laws.c
index 0ba3f4077..fd4f50b78 100644
--- a/src/laws.c
+++ b/src/laws.c
@@ -997,7 +997,7 @@ int quit_cmd(unit * u, struct order *ord)
         char buffer[64];
         write_order(ord, buffer, sizeof(buffer));
         cmistake(u, ord, 86, MSG_EVENT);
-        log_warning("QUIT with illegal password for faction %s: %s\n", factionid(f), buffer);
+        log_warning("QUIT with illegal password for faction %s: %s\n", itoa36(f->no), buffer);
     }
     return 0;
 }
diff --git a/src/modules/score.c b/src/modules/score.c
index 89cf90655..8213b8985 100644
--- a/src/modules/score.c
+++ b/src/modules/score.c
@@ -169,7 +169,7 @@ void score(void)
                 fprintf(scoreFP, "%30.30s (%3.3s) %5s (%3d)\n",
                     f->name,
                     f->race->_name,
-                    factionid(f),
+                    itoa36(f->no),
                     f->age);
             }
         fclose(scoreFP);
diff --git a/src/report.c b/src/report.c
index b3549302a..569674403 100644
--- a/src/report.c
+++ b/src/report.c
@@ -1406,7 +1406,7 @@ report_template(const char *filename, report_context * ctx, const char *charset)
     newline(out);
     newline(out);
 
-    sprintf(buf, "%s %s \"password\"", LOC(f->locale, "ERESSEA"), factionid(f));
+    sprintf(buf, "%s %s \"password\"", LOC(f->locale, "ERESSEA"), itoa36(f->no));
     rps_nowrap(out, buf);
     newline(out);
     newline(out);
diff --git a/src/reports.c b/src/reports.c
index 837ea1a31..fa39f0a85 100644
--- a/src/reports.c
+++ b/src/reports.c
@@ -140,7 +140,7 @@ static char *groupid(const struct group *g, const struct faction *f)
     static name idbuf[8];
     static int nextbuf = 0;
     char *buf = idbuf[(++nextbuf) % 8];
-    sprintf(buf, "%s (%s)", g->name, factionid(f));
+    sprintf(buf, "%s (%s)", g->name, itoa36(f->no));
     return buf;
 }
 
@@ -1418,7 +1418,7 @@ int write_reports(faction * f, time_t ltime)
             do {
                 char filename[32];
                 char path[MAX_PATH];
-                sprintf(filename, "%d-%s.%s", turn, factionid(f),
+                sprintf(filename, "%d-%s.%s", turn, itoa36(f->no),
                     rtype->extension);
                 join_path(reportpath(), filename, path, sizeof(path));
                 errno = 0;
@@ -1441,7 +1441,7 @@ int write_reports(faction * f, time_t ltime)
         }
     }
     if (!gotit) {
-        log_warning("No report for faction %s!", factionid(f));
+        log_warning("No report for faction %s!", itoa36(f->no));
     }
     finish_reports(&ctx);
     return 0;
@@ -1452,7 +1452,7 @@ static void write_script(FILE * F, const faction * f)
     report_type *rtype;
     char buf[1024];
 
-    fprintf(F, "faction=%s:email=%s:lang=%s", factionid(f), f->email,
+    fprintf(F, "faction=%s:email=%s:lang=%s", itoa36(f->no), f->email,
         locale_name(f->locale));
     if (f->options & (1 << O_BZIP2))
         fputs(":compression=bz2", F);
diff --git a/src/summary.c b/src/summary.c
index 8e9dea65d..b82c3a50e 100644
--- a/src/summary.c
+++ b/src/summary.c
@@ -96,12 +96,12 @@ int update_nmrs(void)
             int nmr = turn - f->lastorders + 1;
             if (timeout>0) {
                 if (nmr < 0 || nmr > timeout) {
-                    log_error("faction %s has %d NMR", factionid(f), nmr);
+                    log_error("faction %s has %d NMR", itoa36(f->no), nmr);
                     nmr = _max(0, nmr);
                     nmr = _min(nmr, timeout);
                 }
                 if (nmr > 0) {
-                    log_debug("faction %s has %d NMR", factionid(f), nmr);
+                    log_debug("faction %s has %d NMR", itoa36(f->no), nmr);
                 }
                 ++nmrs[nmr];
             }

From 27605f18baf4e7ed6a4451bf7f0a0e6acf08df68 Mon Sep 17 00:00:00 2001
From: Enno Rehling <enno.rehling@gmail.com>
Date: Thu, 17 Nov 2016 21:31:11 +0100
Subject: [PATCH 35/42] more boring macros removed.

---
 src/kernel/building.c | 2 +-
 src/kernel/config.h   | 3 ---
 src/kernel/ship.c     | 2 +-
 src/report.c          | 2 +-
 src/spells.c          | 8 ++++----
 5 files changed, 7 insertions(+), 10 deletions(-)

diff --git a/src/kernel/building.c b/src/kernel/building.c
index 8789e40b2..60fd420fb 100644
--- a/src/kernel/building.c
+++ b/src/kernel/building.c
@@ -426,7 +426,7 @@ building *new_building(const struct building_type * btype, region * r,
         bname = parameters[P_GEBAEUDE];
     }
     assert(bname);
-    slprintf(buffer, sizeof(buffer), "%s %s", bname, buildingid(b));
+    slprintf(buffer, sizeof(buffer), "%s %s", bname, itoa36(b->no));
     b->name = _strdup(bname);
     return b;
 }
diff --git a/src/kernel/config.h b/src/kernel/config.h
index a15a77ba4..6e1059092 100644
--- a/src/kernel/config.h
+++ b/src/kernel/config.h
@@ -45,9 +45,6 @@ struct param;
     bool isparam(const char *s, const struct locale * lang, param_t param);
     param_t getparam(const struct locale *lang);
 
-#define buildingid(x) itoa36((x)->no)
-#define shipid(x) itoa36((x)->no)
-
     const char * game_name(void);
     int game_id(void);
     int lovar(double xpct_x2);
diff --git a/src/kernel/ship.c b/src/kernel/ship.c
index 02a980b68..d01d0a788 100644
--- a/src/kernel/ship.c
+++ b/src/kernel/ship.c
@@ -201,7 +201,7 @@ ship *new_ship(const ship_type * stype, region * r, const struct locale *lang)
         sname = parameters[P_SHIP];
     }
     assert(sname);
-    slprintf(buffer, sizeof(buffer), "%s %s", sname, shipid(sh));
+    slprintf(buffer, sizeof(buffer), "%s %s", sname, itoa36(sh->no));
     sh->name = _strdup(buffer);
     shash(sh);
     if (r) {
diff --git a/src/report.c b/src/report.c
index 569674403..dc52c38a3 100644
--- a/src/report.c
+++ b/src/report.c
@@ -1479,7 +1479,7 @@ report_template(const char *filename, report_context * ctx, const char *charset)
                     }
                     if (wrptr(&bufp, &size, bytes) != 0)
                         WARN_STATIC_BUFFER();
-                    bytes = (int)strlcpy(bufp, shipid(u->ship), size);
+                    bytes = (int)strlcpy(bufp, itoa36(u->ship->no), size);
                     if (wrptr(&bufp, &size, bytes) != 0)
                         WARN_STATIC_BUFFER();
                 }
diff --git a/src/spells.c b/src/spells.c
index 369dab924..941b50014 100644
--- a/src/spells.c
+++ b/src/spells.c
@@ -6298,14 +6298,14 @@ int sp_q_antimagie(castorder * co)
     {
         building *b = pa->param[0]->data.b;
         ap = &b->attribs;
-        ts = buildingid(b);
+        ts = itoa36(b->no);
         break;
     }
     case SPP_SHIP:
     {
         ship *sh = pa->param[0]->data.sh;
         ap = &sh->attribs;
-        ts = shipid(sh);
+        ts = itoa36(sh->no);
         break;
     }
     default:
@@ -6391,14 +6391,14 @@ int sp_break_curse(castorder * co)
         {
             building *b = pa->param[0]->data.b;
             ap = &b->attribs;
-            ts = buildingid(b);
+            ts = itoa36(b->no);
             break;
         }
         case SPP_SHIP:
         {
             ship *sh = pa->param[0]->data.sh;
             ap = &sh->attribs;
-            ts = shipid(sh);
+            ts = itoa36(sh->no);
             break;
         }
         default:

From cb6be542b9ec5d0c3a87f4372c27a0acc5ce8af0 Mon Sep 17 00:00:00 2001
From: Enno Rehling <enno.rehling@gmail.com>
Date: Thu, 17 Nov 2016 21:32:24 +0100
Subject: [PATCH 36/42] remove unused variables.

---
 src/kernel/config.c | 1 -
 src/kernel/config.h | 2 --
 2 files changed, 3 deletions(-)

diff --git a/src/kernel/config.c b/src/kernel/config.c
index 28147d509..7206c501f 100644
--- a/src/kernel/config.c
+++ b/src/kernel/config.c
@@ -101,7 +101,6 @@ struct settings global = {
 };
 
 bool lomem = false;
-FILE *logfile;
 int turn = -1;
 
 const char *parameters[MAXPARAMS] = {
diff --git a/src/kernel/config.h b/src/kernel/config.h
index 6e1059092..011c487b1 100644
--- a/src/kernel/config.h
+++ b/src/kernel/config.h
@@ -158,10 +158,8 @@ struct param;
     extern const char *localenames[];
     extern settings global;
 
-    extern bool sqlpatch;
     extern bool lomem;         /* save memory */
     extern int turn;
-    extern bool getunitpeasants;
 
 #ifdef __cplusplus
 }

From dc2452e2c1bbb2760e5522ebebb924469c9a5b24 Mon Sep 17 00:00:00 2001
From: Enno Rehling <enno.rehling@gmail.com>
Date: Thu, 17 Nov 2016 22:10:41 +0100
Subject: [PATCH 37/42] config.h globals cleanup.

---
 src/kernel/config.h          |  1 -
 src/triggers/changefaction.c |  1 -
 src/triggers/changerace.c    |  1 -
 src/triggers/clonedied.c     |  1 -
 src/util/language.h          | 29 +++++++++++++++--------------
 5 files changed, 15 insertions(+), 18 deletions(-)

diff --git a/src/kernel/config.h b/src/kernel/config.h
index 011c487b1..3e3aa2c2b 100644
--- a/src/kernel/config.h
+++ b/src/kernel/config.h
@@ -155,7 +155,6 @@ struct param;
     void free_config(void);
 
     extern const char *parameters[];
-    extern const char *localenames[];
     extern settings global;
 
     extern bool lomem;         /* save memory */
diff --git a/src/triggers/changefaction.c b/src/triggers/changefaction.c
index 218a8461f..37d993f4a 100644
--- a/src/triggers/changefaction.c
+++ b/src/triggers/changefaction.c
@@ -17,7 +17,6 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 **/
 
 #include <platform.h>
-#include <kernel/config.h>
 #include "changefaction.h"
 
 /* kernel includes */
diff --git a/src/triggers/changerace.c b/src/triggers/changerace.c
index 0e7fc997e..f38b7f3d5 100644
--- a/src/triggers/changerace.c
+++ b/src/triggers/changerace.c
@@ -17,7 +17,6 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 **/
 
 #include <platform.h>
-#include <kernel/config.h>
 #include "changerace.h"
 
 /* kernel includes */
diff --git a/src/triggers/clonedied.c b/src/triggers/clonedied.c
index 37693fdbf..642b50ab0 100644
--- a/src/triggers/clonedied.c
+++ b/src/triggers/clonedied.c
@@ -17,7 +17,6 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 **/
 
 #include <platform.h>
-#include <kernel/config.h>
 #include "clonedied.h"
 
 #include "magic.h"
diff --git a/src/util/language.h b/src/util/language.h
index a8d9096e7..a90398cc0 100644
--- a/src/util/language.h
+++ b/src/util/language.h
@@ -30,33 +30,34 @@ extern "C" {
     struct locale;
     struct critbit_tree;
 
+    extern const char *localenames[];
+    extern struct locale *default_locale;
+    extern struct locale *locales;
+    extern struct locale *nextlocale(const struct locale *lang);
+
     /** managing multiple locales: **/
-    extern struct locale *get_locale(const char *name);
-    extern struct locale *get_or_create_locale(const char *key);
+    struct locale *get_locale(const char *name);
+    struct locale *get_or_create_locale(const char *key);
     void init_locales(void);
     void free_locales(void);
     void reset_locales(void);
 
     /** operations on locales: **/
-    extern void locale_setstring(struct locale *lang, const char *key,
+    void locale_setstring(struct locale *lang, const char *key,
         const char *value);
-    extern const char *locale_getstring(const struct locale *lang,
+    const char *locale_getstring(const struct locale *lang,
         const char *key);
-    extern const char *locale_string(const struct locale *lang, const char *key, bool warn); /* does fallback */
-    extern unsigned int locale_index(const struct locale *lang);
-    extern const char *locale_name(const struct locale *lang);
+    const char *locale_string(const struct locale *lang, const char *key, bool warn); /* does fallback */
+    unsigned int locale_index(const struct locale *lang);
+    const char *locale_name(const struct locale *lang);
 
-    extern const char *mkname(const char *namespc, const char *key);
-    extern char *mkname_buf(const char *namespc, const char *key, char *buffer);
+    const char *mkname(const char *namespc, const char *key);
+    char *mkname_buf(const char *namespc, const char *key, char *buffer);
 
-    extern void make_locales(const char *str);
+    void make_locales(const char *str);
 
 #define LOC(lang, s) (lang?locale_string(lang, s, true):s)
 
-    extern struct locale *default_locale;
-    extern struct locale *locales;
-    extern struct locale *nextlocale(const struct locale *lang);
-
     enum {
         UT_PARAMS,
         UT_KEYWORDS,

From 8b46e1323a119ec8c1c753758ab4163f23fb116f Mon Sep 17 00:00:00 2001
From: Enno Rehling <enno@eressea.de>
Date: Fri, 18 Nov 2016 11:11:21 +0100
Subject: [PATCH 38/42] declare struct before use

---
 src/triggers/changerace.h | 1 +
 1 file changed, 1 insertion(+)

diff --git a/src/triggers/changerace.h b/src/triggers/changerace.h
index 1b08110b3..e6b19dcb0 100644
--- a/src/triggers/changerace.h
+++ b/src/triggers/changerace.h
@@ -26,6 +26,7 @@ extern "C" {
     struct trigger_type;
     struct trigger;
     struct unit;
+    struct race;
 
     extern struct trigger_type tt_changerace;
 

From 4d5c00be901198fb6beaf6c3662ee34a85b7f803 Mon Sep 17 00:00:00 2001
From: Enno Rehling <enno@raskesider.no>
Date: Fri, 18 Nov 2016 11:38:50 +0100
Subject: [PATCH 39/42] git rm --cached tolua, to fix travis builds?

---
 tolua | 1 -
 1 file changed, 1 deletion(-)
 delete mode 160000 tolua

diff --git a/tolua b/tolua
deleted file mode 160000
index de289b60c..000000000
--- a/tolua
+++ /dev/null
@@ -1 +0,0 @@
-Subproject commit de289b60c5009b6ac8e786f39432c08eadbb69b7

From 7d874f16065a34df6e25935c9b9986b6ecc8cec8 Mon Sep 17 00:00:00 2001
From: Enno Rehling <enno@eressea.de>
Date: Fri, 18 Nov 2016 13:24:50 +0100
Subject: [PATCH 40/42] fix clang builds

---
 src/CMakeLists.txt         | 6 ++++--
 src/kernel/messages.test.c | 3 ++-
 src/spells/flyingship.h    | 3 ++-
 src/util/functions.c       | 3 ++-
 4 files changed, 10 insertions(+), 5 deletions(-)

diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index 34cea4037..7d7fba859 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -17,10 +17,12 @@ set_source_files_properties(kernel/version.c PROPERTIES
 COMPILE_DEFINITIONS ERESSEA_VERSION="${ERESSEA_VERSION}")
 ENDIF()
 
-IF(CMAKE_COMPILER_IS_GNUCC OR CMAKE_COMPILER_IS_CLANG)
+IF (CMAKE_COMPILER_IS_GNUCC)
+    SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wno-error=unused-but-set-variable")
+ENDIF()
+IF (CMAKE_COMPILER_IS_GNUCC OR CMAKE_C_COMPILER_ID MATCHES "Clang")
 #    SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wconversion -Wno-sign-conversion")
     SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -pedantic -Wsign-compare -Wall -Werror -Wno-unknown-pragmas -Wstrict-prototypes -Wpointer-arith -Wno-char-subscripts -Wno-long-long")
-    SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wno-error=unused-but-set-variable")
     SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -std=c99")
     add_definitions(-DHAVE__BOOL)
 ELSEIF(MSVC)
diff --git a/src/kernel/messages.test.c b/src/kernel/messages.test.c
index fc6079dfe..c391c8720 100644
--- a/src/kernel/messages.test.c
+++ b/src/kernel/messages.test.c
@@ -74,4 +74,5 @@ CuSuite *get_messages_suite(void) {
     SUITE_ADD_TEST(suite, test_merge_split);
     SUITE_ADD_TEST(suite, test_message);
     return suite;
-}
\ No newline at end of file
+}
+
diff --git a/src/spells/flyingship.h b/src/spells/flyingship.h
index 087357b9e..8b7bf0874 100644
--- a/src/spells/flyingship.h
+++ b/src/spells/flyingship.h
@@ -22,4 +22,5 @@ extern "C" {
 }
 #endif
 
-#endif
\ No newline at end of file
+#endif
+
diff --git a/src/util/functions.c b/src/util/functions.c
index 82792faaf..3776820eb 100644
--- a/src/util/functions.c
+++ b/src/util/functions.c
@@ -51,4 +51,5 @@ void register_function(pf_generic fun, const char *name)
 
 void free_functions(void) {
     cb_clear(&cb_functions);
-}
\ No newline at end of file
+}
+

From ecbd0ba83c113b8bf6f6b89b635317b224c48e8b Mon Sep 17 00:00:00 2001
From: Enno Rehling <enno@eressea.de>
Date: Fri, 18 Nov 2016 13:30:24 +0100
Subject: [PATCH 41/42] github issue #606 disable volcano terrain change for
 snowglobe test

---
 scripts/tests/xmas.lua | 1 +
 src/volcano.c          | 3 ++-
 2 files changed, 3 insertions(+), 1 deletion(-)

diff --git a/scripts/tests/xmas.lua b/scripts/tests/xmas.lua
index 3667de0b6..153052d5a 100644
--- a/scripts/tests/xmas.lua
+++ b/scripts/tests/xmas.lua
@@ -7,6 +7,7 @@ function setup()
     eressea.settings.set("nmr.timeout", "0")
     eressea.settings.set("rules.grow.formula", "0")
     eressea.settings.set("rules.peasants.growth.factor", "0")
+    eressea.settings.set("volcano.active.percent", "4")
 end
 
 function test_snowglobe_fail()
diff --git a/src/volcano.c b/src/volcano.c
index bd8c56b30..60beeaed7 100644
--- a/src/volcano.c
+++ b/src/volcano.c
@@ -284,7 +284,8 @@ void volcano_update(void)
             }
         }
         else if (r->terrain == t_volcano) {
-            if (rng_int() % 100 < 4) {
+            int volcano_chance = config_get_int("volcano.active.percent", 4);
+            if (rng_int() % 100 < volcano_chance) {
                 ADDMSG(&r->msgs, msg_message("volcanostartsmoke", "region", r));
                 r->terrain = t_active;
             }

From 14b4ae5859245151c3416051a3c2e09c3749f968 Mon Sep 17 00:00:00 2001
From: Enno Rehling <enno@eressea.de>
Date: Fri, 18 Nov 2016 22:31:06 +0100
Subject: [PATCH 42/42] set volcano acitvation chance to 0 during test. should
 fix issue #606 for good. also: additional tests for renumbering ships,
 Xolgrim is wrong.

---
 scripts/tests/common.lua | 15 +++++++++++++++
 scripts/tests/xmas.lua   |  2 +-
 src/renumber.test.c      | 22 ++++++++++++++++++++++
 3 files changed, 38 insertions(+), 1 deletion(-)

diff --git a/scripts/tests/common.lua b/scripts/tests/common.lua
index c39f2ce30..670060816 100644
--- a/scripts/tests/common.lua
+++ b/scripts/tests/common.lua
@@ -380,6 +380,21 @@ function test_events()
   assert(fail==0)
 end
 
+function test_renumber_ship()
+    local r = region.create(0, 0, "plain")
+    local f = faction.create("noreply4@eressea.de", "human", "de")
+    local u = unit.create(f, r)
+    local s = ship.create(r, config.ships[1])
+    u.ship = s
+    u:add_order("NUMMER SCHIFF 1")
+    process_orders()
+    assert_equal(1, s.id)
+    u:clear_orders()
+    u:add_order("NUMMER SCHIFF 2")
+    process_orders()
+    assert_equal(2, s.id)
+end
+
 function test_recruit2()
     local r = region.create(0, 0, "plain")
     local f = faction.create("noreply4@eressea.de", "human", "de")
diff --git a/scripts/tests/xmas.lua b/scripts/tests/xmas.lua
index 153052d5a..7ac4ce731 100644
--- a/scripts/tests/xmas.lua
+++ b/scripts/tests/xmas.lua
@@ -7,7 +7,7 @@ function setup()
     eressea.settings.set("nmr.timeout", "0")
     eressea.settings.set("rules.grow.formula", "0")
     eressea.settings.set("rules.peasants.growth.factor", "0")
-    eressea.settings.set("volcano.active.percent", "4")
+    eressea.settings.set("volcano.active.percent", "0")
 end
 
 function test_snowglobe_fail()
diff --git a/src/renumber.test.c b/src/renumber.test.c
index 9ab6b1e7b..6c3f0f17b 100644
--- a/src/renumber.test.c
+++ b/src/renumber.test.c
@@ -102,6 +102,27 @@ static void test_renumber_ship(CuTest *tc) {
     test_cleanup();
 }
 
+static void test_renumber_ship_twice(CuTest *tc) {
+    unit *u;
+    int uno, no;
+    const struct locale *lang;
+
+    test_setup_ex(tc);
+    u = test_create_unit(test_create_faction(0), test_create_region(0, 0, 0));
+    u->ship = test_create_ship(u->region, 0);
+    no = u->ship->no;
+    uno = (no > 1) ? no - 1 : no + 1;
+    lang = u->faction->locale;
+    u->thisorder = create_order(K_NUMBER, lang, "%s %s", LOC(lang, parameters[P_SHIP]), itoa36(uno));
+    renumber_cmd(u, u->thisorder);
+    CuAssertIntEquals(tc, uno, u->ship->no);
+    free_order(u->thisorder);
+    u->thisorder = create_order(K_NUMBER, lang, "%s %s", LOC(lang, parameters[P_SHIP]), itoa36(no));
+    renumber_cmd(u, u->thisorder);
+    CuAssertIntEquals(tc, no, u->ship->no);
+    test_cleanup();
+}
+
 static void test_renumber_ship_duplicate(CuTest *tc) {
     unit *u;
     faction *f;
@@ -204,6 +225,7 @@ CuSuite *get_renumber_suite(void)
     SUITE_ADD_TEST(suite, test_renumber_building);
     SUITE_ADD_TEST(suite, test_renumber_building_duplicate);
     SUITE_ADD_TEST(suite, test_renumber_ship);
+    SUITE_ADD_TEST(suite, test_renumber_ship_twice);
     SUITE_ADD_TEST(suite, test_renumber_ship_duplicate);
     SUITE_ADD_TEST(suite, test_renumber_faction);
     SUITE_ADD_TEST(suite, test_renumber_faction_duplicate);