From aee68fbd0fb0bc5ec2c159ce4812ef7749dd1fc2 Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Sat, 18 Feb 2017 11:19:42 +0100 Subject: [PATCH 1/2] github issue #658 MACHE 1 EISEN use 1 iron even with savings. --- src/economy.c | 2 ++ src/economy.test.c | 5 +++++ 2 files changed, 7 insertions(+) diff --git a/src/economy.c b/src/economy.c index 70b48e9ce..ab1875eed 100644 --- a/src/economy.c +++ b/src/economy.c @@ -1036,6 +1036,8 @@ static void allocate_resource(unit * u, const resource_type * rtype, int want) static int required(int want, variant save) { int req = (int)(want * save.sa[0] / save.sa[1]); + int r = want * save.sa[0] % save.sa[1]; + if (r>0) ++req; return req; } diff --git a/src/economy.test.c b/src/economy.test.c index d9f9b82e8..fdc218844 100644 --- a/src/economy.test.c +++ b/src/economy.test.c @@ -405,6 +405,11 @@ static void test_make_item(CuTest *tc) { CuAssertIntEquals(tc, 21, get_item(u, itype)); CuAssertIntEquals(tc, 284, u->region->resources->amount); /* 60% saving = 6 stones make 10 stones */ + make_item(u, itype, 1); + split_allocations(u->region); + CuAssertIntEquals(tc, 22, get_item(u, itype)); + CuAssertIntEquals(tc, 283, u->region->resources->amount); /* no free lunches */ + rdata->modifiers[0].flags = RMF_REQUIREDBUILDING; rdata->modifiers[0].race = NULL; rdata->modifiers[0].btype = bt_get_or_create("mine"); From 9682d6b48c751a236844d7a3c3d8dff2bf0be74e Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Sat, 18 Feb 2017 15:45:57 +0100 Subject: [PATCH 2/2] implement quick-and-dirty gcd --- src/kernel/xmlreader.c | 26 ++++++++++++++++++++------ 1 file changed, 20 insertions(+), 6 deletions(-) diff --git a/src/kernel/xmlreader.c b/src/kernel/xmlreader.c index 36f003e80..3a4b351dd 100644 --- a/src/kernel/xmlreader.c +++ b/src/kernel/xmlreader.c @@ -905,6 +905,22 @@ static int parse_rules(xmlDocPtr doc) return 0; } +static int gcd(int num, int den) { + const int primes[] = { 3, 5, 7, 11, 0 }; + int i=0, g = 1, p = 2; + while (p && p<=den && p<=num) { + if (num % p == 0 && den % p == 0) { + num /= p; + den /= p; + g *= p; + } + else { + p = primes[i++]; + } + } + return g; +} + static int parse_resources(xmlDocPtr doc) { xmlXPathContextPtr xpath = xmlXPathNewContext(doc); @@ -1025,15 +1041,13 @@ static int parse_resources(xmlDocPtr doc) rdata->modifiers[k].flags = RMF_SKILL; } else if (strcmp((const char *)propValue, "material") == 0) { - int num, den = 100; + int g, num, den = 100; double fval = xml_fvalue(node, "value", 0); // TODO: extract into a function for reading fractions? num = (int)(fval * den + 0.5); - if (num % 10 == 0) { - // TODO: calculating a GCD would be better than this - num /= 10; - den /= 10; - } + g = gcd(num, den); + num /= g; + den /= g; rdata->modifiers[k].value.sa[0] = (short)num; rdata->modifiers[k].value.sa[1] = (short)den; rdata->modifiers[k].flags = RMF_SAVEMATERIAL;