diff --git a/src/economy.c b/src/economy.c index 4c54cb5da..70b48e9ce 100644 --- a/src/economy.c +++ b/src/economy.c @@ -863,7 +863,7 @@ static void manufacture(unit * u, const item_type * itype, int want) typedef struct allocation { struct allocation *next; int want, get; - double save; + variant save; unsigned int flags; unit *unit; } allocation; @@ -883,17 +883,18 @@ enum { AFL_LOWSKILL = 1 << 1 }; -struct message * get_modifiers(unit *u, const resource_mod *mod, double *savep, int *skillp) { +struct message * get_modifiers(unit *u, const resource_mod *mod, variant *savep, int *skillp) { struct building *b = inside_building(u); const struct building_type *btype = building_is_active(b) ? b->type : NULL; - double save = 1.0; + int save_n = 1, save_d = 1; int skill = 0; for (; mod->flags != 0; ++mod) { if (mod->btype == NULL || mod->btype == btype) { if (mod->race == NULL || mod->race == u_race(u)) { if (mod->flags & RMF_SAVEMATERIAL) { - save *= mod->value.f; + save_n *= mod->value.sa[0]; + save_d *= mod->value.sa[1]; } if (mod->flags & RMF_SKILL) { skill += mod->value.i; @@ -904,7 +905,12 @@ struct message * get_modifiers(unit *u, const resource_mod *mod, double *savep, } } *skillp = skill; - *savep = save; + assert(save_n < SHRT_MAX); + assert(save_n > SHRT_MIN); + assert(save_d < SHRT_MAX); + assert(save_d > SHRT_MIN); + savep->sa[0] = (short)save_n; + savep->sa[1] = (short)save_d; return NULL; } @@ -919,7 +925,7 @@ static void allocate_resource(unit * u, const resource_type * rtype, int want) resource_limit *rdata = (resource_limit *)a->data.v; const resource_type *rring; int amount, skill, skill_mod = 0; - double save_mod = 1.0; + variant save_mod; /* momentan kann man keine ressourcen abbauen, wenn man daf�r * Materialverbrauch hat: */ @@ -947,6 +953,10 @@ static void allocate_resource(unit * u, const resource_type * rtype, int want) return; } } + else { + save_mod.sa[0] = 1; + save_mod.sa[1] = 1; + } /* Bergw�chter k�nnen Abbau von Eisen/Laen durch Bewachen verhindern. * Als magische Wesen 'sehen' Bergw�chter alles und werden durch @@ -1023,9 +1033,9 @@ static void allocate_resource(unit * u, const resource_type * rtype, int want) alist->data = al; } -static int required(int want, double save) +static int required(int want, variant save) { - int req = (int)(want * save); + int req = (int)(want * save.sa[0] / save.sa[1]); return req; } @@ -1088,7 +1098,7 @@ leveled_allocation(const resource_type * rtype, region * r, allocation * alist) use += x; nreq -= want; need -= x; - al->get = MIN(al->want, al->get + (int)(1 + x / al->save)); + al->get = MIN(al->want, al->get + x * al->save.sa[1] / al->save.sa[0]); } } if (use) { @@ -1126,12 +1136,13 @@ attrib_allocation(const resource_type * rtype, region * r, allocation * alist) if (avail > 0) { int want = required(al->want, al->save); int x = avail * want / nreq; - /* Wenn Rest, dann w�rfeln, ob ich was bekomme: */ - if (rng_int() % nreq < (avail * want) % nreq) - ++x; + int rx = (avail * want) % nreq; + /* Wenn Rest, dann wuerfeln, ob ich was bekomme: */ + if (rx>0 && rng_int() % nreq < rx) ++x; avail -= x; nreq -= want; - al->get = MIN(al->want, (int)(x / al->save)); + al->get = x * al->save.sa[0] / al->save.sa[1]; + al->get = MIN(al->want, al->get); if (rdata->produce) { int use = required(al->get, al->save); if (use) @@ -2619,8 +2630,9 @@ expandwork(region * r, request * work_begin, request * work_end, int maxwork) if (jobs >= working) workers = u->number; else { + int r = (u->number * jobs) % working; workers = u->number * jobs / working; - if (rng_int() % working < (u->number * jobs) % working) + if (r > 0 && rng_int() % working < r) workers++; } diff --git a/src/economy.test.c b/src/economy.test.c index 7101d859a..d9f9b82e8 100644 --- a/src/economy.test.c +++ b/src/economy.test.c @@ -350,6 +350,7 @@ static void test_make_item(CuTest *tc) { resource_type *rtype; attrib *a; resource_limit *rdata; + double d = 0.6; test_setup(); init_resources(); @@ -397,7 +398,8 @@ static void test_make_item(CuTest *tc) { rdata->modifiers = calloc(2, sizeof(resource_mod)); rdata->modifiers[0].flags = RMF_SAVEMATERIAL; rdata->modifiers[0].race = u->_race; - rdata->modifiers[0].value.f = (float)0.6; + rdata->modifiers[0].value.sa[0] = (short)(0.5+100*d); + rdata->modifiers[0].value.sa[1] = 100; make_item(u, itype, 10); split_allocations(u->region); CuAssertIntEquals(tc, 21, get_item(u, itype)); diff --git a/src/kernel/item.h b/src/kernel/item.h index 39a2d0687..e6301c314 100644 --- a/src/kernel/item.h +++ b/src/kernel/item.h @@ -91,8 +91,7 @@ extern "C" { /* resource-limits for regions */ #define RMF_SKILL 0x01 /* int, bonus on resource production skill */ -#define RMF_SAVEMATERIAL 0x02 /* float, multiplier on resource usage */ -#define RMF_SAVERESOURCE 0x03 /* int, bonus on resource production skill */ +#define RMF_SAVEMATERIAL 0x02 /* fraction (sa[0]/sa[1]), multiplier on resource usage */ #define RMF_REQUIREDBUILDING 0x04 /* building, required to build */ typedef struct resource_mod { diff --git a/src/kernel/xmlreader.c b/src/kernel/xmlreader.c index 5ce6800ef..5cecc4fdb 100644 --- a/src/kernel/xmlreader.c +++ b/src/kernel/xmlreader.c @@ -1025,13 +1025,10 @@ static int parse_resources(xmlDocPtr doc) rdata->modifiers[k].flags = RMF_SKILL; } else if (strcmp((const char *)propValue, "material") == 0) { - rdata->modifiers[k].value.f = (float)xml_fvalue(node, "value", 0); + rdata->modifiers[k].value.sa[0] = (short)(0.5+100*xml_fvalue(node, "value", 0)); + rdata->modifiers[k].value.sa[1] = 100; rdata->modifiers[k].flags = RMF_SAVEMATERIAL; } - else if (strcmp((const char *)propValue, "resource") == 0) { - rdata->modifiers[k].value.f = (float)xml_fvalue(node, "value", 0); - rdata->modifiers[k].flags = RMF_SAVERESOURCE; - } else if (strcmp((const char *)propValue, "require") == 0) { xmlChar *propBldg = xmlGetProp(node, BAD_CAST "building"); if (propBldg != NULL) {