diff --git a/res/core/messages.xml b/res/core/messages.xml
index 48a76b390..52dab404c 100644
--- a/res/core/messages.xml
+++ b/res/core/messages.xml
@@ -942,8 +942,8 @@
- "Die Region ist im Besitz von $faction($faction)."
- "The region is owned by $faction($faction)."
+ " Die Region ist im Besitz von $faction($faction)."
+ " The region is owned by $faction($faction)."
diff --git a/src/laws.c b/src/laws.c
index 86f09bcd3..acb15e747 100755
--- a/src/laws.c
+++ b/src/laws.c
@@ -97,8 +97,6 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
#include
#include
-#include
-
/* chance that a peasant dies of starvation: */
#define PEASANT_STARVATION_CHANCE 0.9F
/* Pferdevermehrung */
@@ -240,7 +238,7 @@ static void calculate_emigration(region * r)
}
for (i = 0; max_immigrants > 0 && i != MAXDIRECTIONS; i++) {
- int dir = (turn + i) % MAXDIRECTIONS;
+ int dir = (turn + 1 + i) % MAXDIRECTIONS;
region *rc = rconnect(r, (direction_t)dir);
if (rc != NULL && fval(rc->terrain, LAND_REGION)) {
@@ -265,7 +263,7 @@ static float peasant_growth_factor(void)
}
#ifdef SLOWLUCK
-int peasant_luck_effect(int peasants, int luck, int maxp, float variance) {
+int peasant_luck_effect(int peasants, int luck, int maxp, double variance) {
int n, births=0;
float factor = peasant_growth_factor();
for (n = peasants; n && luck; --n) {
@@ -294,11 +292,15 @@ static float peasant_luck_factor(void)
return get_param_flt(global.parameters, "rules.peasants.peasantluck.factor", PEASANTLUCK);
}
-int peasant_luck_effect(int peasants, int luck, int maxp, float variance)
+int peasant_luck_effect(int peasants, int luck, int maxp, double variance)
{
int births = 0;
- double mean = _min(luck, peasants) * peasant_luck_factor()
- * peasant_growth_factor() * ((peasants / (float)maxp < .9) ? 1 :
+ double mean;
+
+ if (luck == 0) return 0;
+
+ mean = _min(luck, peasants) * peasant_luck_factor()
+ * peasant_growth_factor() * ((peasants / (double)maxp < .9) ? 1 :
PEASANTFORCE);
births = RAND_ROUND(normalvariate(mean, variance * mean));
@@ -330,9 +332,8 @@ static void peasants(region * r)
}
luck = peasant_luck_effect(peasants, luck, maxp, .5);
-#ifdef STORCH_SPAM_BUG_2072
- ADDMSG(&r->msgs, msg_message("peasantluck_success", "births", luck));
-#endif
+ if (luck > 0)
+ ADDMSG(&r->msgs, msg_message("peasantluck_success", "births", luck));
peasants += births + luck;
}
diff --git a/src/laws.h b/src/laws.h
index 3e9c44013..4f4188448 100755
--- a/src/laws.h
+++ b/src/laws.h
@@ -106,7 +106,7 @@ extern "C" {
const struct unit *u, int modifier);
int armedmen(const struct unit *u, bool siege_weapons);
void force_leave(struct region *r);
- int peasant_luck_effect(int peasants, int luck, int maxp, float variance);
+ int peasant_luck_effect(int peasants, int luck, int maxp, double variance);
#ifdef __cplusplus
}
diff --git a/src/laws.test.c b/src/laws.test.c
index 7524e6267..75c19a798 100644
--- a/src/laws.test.c
+++ b/src/laws.test.c
@@ -6,6 +6,7 @@
#include
#include
#include
+#include
#include
#include
#include
@@ -13,6 +14,7 @@
#include
#include
+#include
#include
#include
#include
@@ -457,7 +459,7 @@ struct pay_fixture {
};
static double level_taxes(const building * b, int level) {
- return b->size*level*2.0;
+ return b->size * level * 2.0;
}
static void setup_pay_cmd(struct pay_fixture *fix) {
@@ -693,8 +695,7 @@ static void test_reserve_self(CuTest *tc) {
}
static void statistic_test(CuTest *tc, int peasants, int luck, int maxp,
- float variance, int min_value, int max_value)
-{
+ double variance, int min_value, int max_value) {
int effect, i;
for (i = 0; i < 1000; ++i) {
effect = peasant_luck_effect(peasants, luck, maxp, variance);
@@ -703,19 +704,50 @@ static void statistic_test(CuTest *tc, int peasants, int luck, int maxp,
}
}
-static void test_peasant_luck_effect(CuTest *tc)
-{
+static void test_peasant_luck_effect(CuTest *tc) {
+ const char *plf = get_param(global.parameters, "rules.peasants.peasantluck.factor");
+ const char *gf = get_param(global.parameters, "rules.peasants.growth.factor");
set_param(&global.parameters, "rules.peasants.peasantluck.factor", "10");
set_param(&global.parameters, "rules.peasants.growth.factor", "0.001");
+ statistic_test(tc, 100, 0, 1000, 0, 0, 0);
statistic_test(tc, 100, 2, 1000, 0, 1, 1);
statistic_test(tc, 1000, 400, 1000, 0, (int)(400 * 10 * 0.001 * .75),
(int)(400 * 10 * 0.001 * .75));
- statistic_test(tc, 1000, 1000, 2000, .5f, 1, 501);
+ statistic_test(tc, 1000, 1000, 2000, .5, 1, 501);
set_param(&global.parameters, "rules.peasants.growth.factor", "1");
statistic_test(tc, 1000, 1000, 1000, 0, 501, 501);
+
+ set_param(&global.parameters, "rules.peasants.peasantluck.factor", plf);
+ set_param(&global.parameters, "rules.peasants.growth.factor", gf);
+}
+
+static void test_luck_message(CuTest *tc) {
+ region* r;
+ const message_type *msg_types[1];
+
+ test_cleanup();
+ r = test_create_region(0, 0, NULL);
+ rsetpeasants(r, 1);
+
+ msg_types[0] = register_msg("peasantluck_success", 1, "births:int");
+
+ demographics();
+
+ CuAssertPtrEquals_Msg(tc, "unexpected message", (void *)NULL, r->msgs);
+
+ attrib *a = (attrib *)a_find(r->attribs, &at_peasantluck);
+ if (!a)
+ a = a_add(&r->attribs, a_new(&at_peasantluck));
+ a->data.i += 10;
+
+ demographics();
+
+ assert_messages(tc, r->msgs->begin, msg_types, 1, true, 0);
+
+ test_cleanup();
}
CuSuite *get_laws_suite(void)
@@ -749,6 +781,7 @@ CuSuite *get_laws_suite(void)
SUITE_ADD_TEST(suite, test_force_leave_ships);
SUITE_ADD_TEST(suite, test_force_leave_ships_on_ocean);
SUITE_ADD_TEST(suite, test_peasant_luck_effect);
+ SUITE_ADD_TEST(suite, test_luck_message);
return suite;
}
diff --git a/src/tests.c b/src/tests.c
index 0d113229b..108cde2a4 100644
--- a/src/tests.c
+++ b/src/tests.c
@@ -20,6 +20,8 @@
#include
#include
+#include
+
#include
#include
#include
@@ -35,7 +37,13 @@ struct race *test_create_race(const char *name)
struct region *test_create_region(int x, int y, const terrain_type *terrain)
{
region *r = new_region(x, y, NULL, 0);
- terraform_region(r, terrain ? terrain : get_or_create_terrain("plain"));
+ if (!terrain) {
+ terrain_type *t = get_or_create_terrain("plain");
+ t->size = 1000;
+ fset(t, LAND_REGION);
+ terraform_region(r, t);
+ } else
+ terraform_region(r, terrain);
rsettrees(r, 0, 0);
rsettrees(r, 1, 0);
rsettrees(r, 2, 0);
@@ -213,3 +221,54 @@ const char * test_get_messagetype(const message *msg) {
return name;
}
+const message_type *register_msg(const char *type, int n_param, ...) {
+ char **argv;
+ va_list args;
+ int i;
+
+ va_start(args, n_param);
+
+ argv = malloc(sizeof(char *) * (n_param + 1));
+ for (i = 0; i < n_param; ++i) {
+ argv[i] = va_arg(args, char *);
+ }
+ argv[n_param] = 0;
+ va_end(args);
+ return mt_register(mt_new(type, (const char **)argv));
+}
+
+void assert_messages(struct CuTest * tc, struct mlist *msglist, const message_type **types,
+ int num_msgs, bool exact_match, ...) {
+ va_list args;
+ int found, argc;
+ struct message *msg;
+ bool match = true;
+
+ va_start(args, exact_match);
+
+ found = 0;
+ while (msglist) {
+ if (found >= num_msgs) {
+ if (exact_match) {
+ CuFail(tc, "too many messages");
+ } else {
+ break;
+ }
+ }
+ msg = msglist->msg;
+ if (exact_match || match)
+ argc = va_arg(args, int);
+
+ match = strcmp(types[argc]->name, msg->type->name) == 0;
+ if (match)
+ ++found;
+ else if (exact_match)
+ CuAssertStrEquals(tc, types[argc]->name, msg->type->name);
+
+ msglist = msglist->next;
+ }
+
+ CuAssertIntEquals_Msg(tc, "not enough messages", num_msgs, found);
+
+ va_end(args);
+}
diff --git a/src/tests.h b/src/tests.h
index b83beab40..e517a6fb7 100644
--- a/src/tests.h
+++ b/src/tests.h
@@ -15,11 +15,14 @@ extern "C" {
struct ship;
struct message;
struct message_list;
+ struct mlist;
struct item_type;
struct building_type;
struct ship_type;
struct terrain_type;
+ struct CuTest;
+
void test_cleanup(void);
struct terrain_type * test_create_terrain(const char * name, unsigned int flags);
@@ -40,6 +43,10 @@ extern "C" {
const char * test_get_messagetype(const struct message *msg);
struct message * test_get_last_message(struct message_list *mlist);
+ const struct message_type *register_msg(const char *type, int n_param, ...);
+ void assert_messages(struct CuTest * tc, struct mlist *msglist, const struct message_type **types,
+ int num_msgs, bool exact_match, ...);
+
#ifdef __cplusplus
}
#endif